diff --git a/src/backend/helpers/chatClient.ts b/src/backend/helpers/chatClient.ts index 2e993f0..25712b5 100644 --- a/src/backend/helpers/chatClient.ts +++ b/src/backend/helpers/chatClient.ts @@ -1,7 +1,7 @@ -import { getApiClient, getAuthProvider } from "./twitch"; +import { getAuthProvider, getUsernameFromId } from "./twitch"; import { ChatClient } from "twitch-chat-client"; -import { sockets } from "./webServer"; +import { broadcast } from "./webServer"; import { start } from "./scheduledActions"; let chatClient: ChatClient; @@ -10,10 +10,11 @@ export { chatClient, connect, handleClientAction, - broadcast, say }; +const LOG_PREFIX = "[ChatClient] "; + async function connect(channels: Array) { const authProvider = await getAuthProvider( @@ -33,18 +34,18 @@ async function connect(channels: Array) { chatClient.onConnect(onConnect); chatClient.onDisconnect((e: any) => { - console.log(`[ChatClient] Disconnected ${e.message}`); + console.log(`${LOG_PREFIX}Disconnected ${e.message}`); }); chatClient.onNoPermission((channel, message) => { - console.log(`[ChatClient] No permission on ${channel}: ${message}`); + console.log(`${LOG_PREFIX}No permission on ${channel}: ${message}`); }); await chatClient.connect(); } async function onConnect() { - console.log("[ChatClient] Connected"); + console.log(`${LOG_PREFIX}Connected`); start(); } @@ -79,7 +80,7 @@ async function handleClientAction(action: any) { await removeVip(action.channel, action.username); break; default: - console.log(`Couldn't handle action:`, action); + console.log(`${[LOG_PREFIX]}Couldn't handle action:`, action); } } @@ -110,15 +111,6 @@ async function timeout( } } -// broadcast a message to all clients -function broadcast(msg: string, socket?: any) { - const filteredSockets = socket - ? sockets.filter(s => s !== socket) - : sockets; - - filteredSockets.forEach(s => s.send(msg)); -} - // adds a user to vips async function addVip(channel: string, username: string, message?: string) { if (!message) { @@ -132,20 +124,9 @@ async function addVip(channel: string, username: string, message?: string) { // removes a user from vips async function removeVip(channel: string, username: string, message?: string) { if (!message) { - message = `Se ha acabado el chollo, VIP de @${username} eliminado.`; + message = `VIP de @${username} eliminado.`; } await chatClient.removeVip(channel, username); say(channel, message); -} - -async function getUsernameFromId(userId: number) { - const apiClient = await getApiClient(); - const user = await apiClient.helix.users.getUserById(userId); - - if (!user) { - return null; - } - - return user.displayName; } \ No newline at end of file diff --git a/src/backend/helpers/pubSubClient.ts b/src/backend/helpers/pubSubClient.ts index 0b9bb36..67ece54 100644 --- a/src/backend/helpers/pubSubClient.ts +++ b/src/backend/helpers/pubSubClient.ts @@ -1,14 +1,17 @@ import { PubSubClient, PubSubRedemptionMessage } from "twitch-pubsub-client"; -import { broadcast, chatClient, say } from "./chatClient"; +import { chatClient, say } from "./chatClient"; import { getApiClient, getUsernameFromId } from "./twitch"; import { saveScheduledActions, scheduledActions } from "./scheduledActions"; import { UserIdResolvable } from "twitch"; +import { broadcast } from "./webServer"; export { registerUserListener } +const LOG_PREFIX = "[PubSub] "; + async function registerUserListener(user: UserIdResolvable) { const apiClient = await getApiClient(); @@ -16,15 +19,15 @@ async function registerUserListener(user: UserIdResolvable) { const userId = await pubSubClient.registerUserListener(apiClient, user); /*const listener = */ await pubSubClient.onRedemption(userId, onRedemption); - console.log("[Twitch PubSub] Connected & registered"); + console.log(`${LOG_PREFIX}Connected & registered`); } async function onRedemption(message: PubSubRedemptionMessage) { console.log( - `Reward: "${message.rewardName}" (${message.rewardId}) redeemed by ${message.userDisplayName}` + `${LOG_PREFIX}Reward: "${message.rewardName}" (${message.rewardId}) redeemed by ${message.userDisplayName}` ); // @ts-ignore - const reward = message._data.data.redemption.reward; + const reward = message._data.data.redemption.rewºard; let msg: any = { id: message.id, @@ -48,7 +51,7 @@ async function onRedemption(message: PubSubRedemptionMessage) { } if (msg) { - console.log(msg); + console.log(LOG_PREFIX, msg); if (typeof msg !== "string") { msg = JSON.stringify(msg); @@ -57,6 +60,8 @@ async function onRedemption(message: PubSubRedemptionMessage) { } } +// TODO: extract methods + // remove vip from a user to grant it to yourself async function stealVip(msg: { channelId: string; @@ -66,7 +71,7 @@ async function stealVip(msg: { const channel = await getUsernameFromId(parseInt(msg.channelId)); if (!channel) { - console.log("No channel found"); + console.log(`${LOG_PREFIX}No channel found`); return; } diff --git a/src/backend/helpers/scheduledActions.ts b/src/backend/helpers/scheduledActions.ts index 321aa93..24a967c 100644 --- a/src/backend/helpers/scheduledActions.ts +++ b/src/backend/helpers/scheduledActions.ts @@ -9,6 +9,7 @@ export { saveScheduledActions }; +const LOG_PREFIX = "[Scheduled] "; const SCHEDULED_FILE = resolve(process.cwd(), "scheduled.json"); const scheduledActions: Array = []; @@ -49,7 +50,7 @@ async function checkScheduledActions() { const action = scheduledActions.splice(i, 1)[0]; await handleClientAction(action); - console.log(`[Scheduled] Executed: ${JSON.stringify(action)}`); + console.log(`${LOG_PREFIX}Executed: ${JSON.stringify(action)}`); } if (hasToSave) { @@ -63,12 +64,12 @@ function saveScheduledActions() { if (saveScheduledActionsTimeout) { clearTimeout(saveScheduledActionsTimeout); saveScheduledActionsTimeout = null; - console.log("[Scheduled] Removed save timeout."); + console.log(`${LOG_PREFIX}Removed save timeout.`); } saveScheduledActionsTimeout = setTimeout(async () => { await fs.writeFile(SCHEDULED_FILE, JSON.stringify(scheduledActions)); - console.log("[Scheduled] Saved actions."); + console.log(`${LOG_PREFIX}Saved actions.`); saveScheduledActionsTimeout = null; }, 1000 * 30); } diff --git a/src/backend/helpers/webServer.ts b/src/backend/helpers/webServer.ts index a9347be..6560a2c 100644 --- a/src/backend/helpers/webServer.ts +++ b/src/backend/helpers/webServer.ts @@ -1,14 +1,17 @@ import { IncomingMessage, Server } from "http"; -import { broadcast, handleClientAction } from "./chatClient"; import { saveScheduledActions, scheduledActions } from "./scheduledActions"; import { AddressInfo } from "net"; import { Socket } from "net"; import WebSocket from "ws"; import express from "express"; +import { handleClientAction } from "./chatClient"; import { isDevelopment } from "./util"; import { join } from "path"; +const LOG_PREFIX_HTTP = "[HTTP] "; +const LOG_PREFIX_WS = "[WS] "; + const app = express(); const sockets: Array = []; @@ -20,8 +23,7 @@ let server: Server; export { listen, - // TODO: use intermediate class to handle socket messages - sockets + broadcast } wsServer.on("connection", onConnection); @@ -30,7 +32,7 @@ app.use(express.static(join(process.cwd(), "client"))); function listen() { if (server) { - console.log("[Webserver] Server is already running"); + console.log(`${LOG_PREFIX_HTTP}Server is already running`); return; } @@ -42,7 +44,7 @@ function listen() { function onListening() { console.log( - `[Webserver] Listening on port ${(server.address() as AddressInfo).port}` + `${LOG_PREFIX_HTTP}Listening on port ${(server.address() as AddressInfo).port}` ); } @@ -53,7 +55,7 @@ function onUpgrade(req: IncomingMessage, socket: Socket, head: Buffer) { } function onConnection(socket: WebSocket, req: IncomingMessage) { - console.log(`[WS] ${req.socket.remoteAddress} New connection established`); + console.log(`${LOG_PREFIX_WS}${req.socket.remoteAddress} New connection established`); sockets.push(socket); socket.send( JSON.stringify({ @@ -61,12 +63,22 @@ function onConnection(socket: WebSocket, req: IncomingMessage) { }) ); - socket.on("message", (msg: string) => onMessage(msg, socket)); - - socket.on("close", () => onClose(socket)); + socket.on("message", onMessage); + socket.on("close", onClose); } -async function onMessage(msg: string, socket: WebSocket) { +// broadcast a message to all clients +function broadcast(msg: string, socket?: any) { + const filteredSockets = socket + ? sockets.filter(s => s !== socket) + : sockets; + + filteredSockets.forEach(s => s.send(msg)); +} + +async function onMessage(msg: string) { + // @ts-ignore + const socket = this as WebSocket; const data = JSON.parse(msg); if (!data.actions || data.actions.length === 0) { @@ -84,11 +96,14 @@ async function onMessage(msg: string, socket: WebSocket) { } } - console.log(`[WS] Received message with ${data.actions.length} actions:`, data); + console.log(`${LOG_PREFIX_WS}Received message with ${data.actions.length} actions:`, data); } -function onClose(socket: WebSocket) { +function onClose() { + // @ts-ignore + const socket: WebSocket = this as WebSocket; + const socketIdx = sockets.indexOf(socket); sockets.splice(socketIdx, 1); - console.log("[WS] Connection closed"); + console.log(`${LOG_PREFIX_WS}Connection closed`); } \ No newline at end of file