diff --git a/src/backend/chatClient/clientActions/addVip/index.ts b/src/backend/chatClient/clientActions/addVip/index.ts new file mode 100644 index 0000000..cf93db9 --- /dev/null +++ b/src/backend/chatClient/clientActions/addVip/index.ts @@ -0,0 +1,18 @@ +import { chatClient } from "../.."; +import { say } from ".."; + +// adds a user to vips +async function addVip( + channel: string, + username: string, + message?: string +): Promise { + if (!message) { + message = `Otorgado VIP a @${username}.`; + } + + await chatClient.addVip(channel, username); + say(channel, message); +} + +export { addVip }; diff --git a/src/backend/chatClient/clientActions/index.ts b/src/backend/chatClient/clientActions/index.ts new file mode 100644 index 0000000..9a8a92b --- /dev/null +++ b/src/backend/chatClient/clientActions/index.ts @@ -0,0 +1,6 @@ +import { addVip } from "./addVip"; +import { removeVip } from "./removeVip"; +import { say } from "./say"; +import { timeout } from "./timeout"; + +export { say, timeout, addVip, removeVip }; diff --git a/src/backend/chatClient/clientActions/removeVip/index.ts b/src/backend/chatClient/clientActions/removeVip/index.ts new file mode 100644 index 0000000..1b9c3ac --- /dev/null +++ b/src/backend/chatClient/clientActions/removeVip/index.ts @@ -0,0 +1,18 @@ +import { chatClient } from "../.."; +import { say } from ".."; + +// removes a user from vips +async function removeVip( + channel: string, + username: string, + message?: string +): Promise { + if (!message) { + message = `VIP de @${username} eliminado.`; + } + + await chatClient.removeVip(channel, username); + say(channel, message); +} + +export { removeVip }; diff --git a/src/backend/chatClient/clientActions/say/index.ts b/src/backend/chatClient/clientActions/say/index.ts new file mode 100644 index 0000000..89d7626 --- /dev/null +++ b/src/backend/chatClient/clientActions/say/index.ts @@ -0,0 +1,8 @@ +import { chatClient } from "../.."; + +// send a chat message +async function say(channel: string, message: string): Promise { + await chatClient.say(channel, message); +} + +export { say }; diff --git a/src/backend/chatClient/clientActions/timeout/index.ts b/src/backend/chatClient/clientActions/timeout/index.ts new file mode 100644 index 0000000..3d145bc --- /dev/null +++ b/src/backend/chatClient/clientActions/timeout/index.ts @@ -0,0 +1,25 @@ +import { chatClient } from "../.."; + +// timeouts a user in a channel +async function timeout( + channel: string, + username: string, + time?: number, + reason?: string +): Promise { + if (!time) { + time = 60; + } + + if (!reason) { + reason = ""; + } + + try { + await chatClient.timeout(channel, username, time, reason); + } catch (e) { + // user cannot be timed out + } +} + +export { timeout }; diff --git a/src/backend/chatClient/index.ts b/src/backend/chatClient/index.ts new file mode 100644 index 0000000..85aeafd --- /dev/null +++ b/src/backend/chatClient/index.ts @@ -0,0 +1,73 @@ +import { addVip, removeVip, say, timeout } from "./clientActions"; +import { getAuthProvider, getUsernameFromId } from "../helpers/twitch"; + +import { Action } from "../../interfaces/actions/Action"; +import { ChatClient } from "twitch-chat-client"; +import { broadcast } from "../helpers/webServer"; +import { start } from "../helpers/scheduledActions"; + +let chatClient: ChatClient; + +export { chatClient, connect, handleClientAction, say, LOG_PREFIX }; + +const LOG_PREFIX = "[ChatClient] "; + +async function connect(channels: Array): Promise { + const authProvider = await getAuthProvider(); + + if (chatClient && (chatClient.isConnecting || chatClient.isConnected)) { + return; + } + + chatClient = new ChatClient(authProvider, { channels: channels }); + + chatClient.onConnect(onConnect); + + chatClient.onDisconnect((e: any) => { + console.log(`${LOG_PREFIX}Disconnected ${e.message}`); + }); + + chatClient.onNoPermission((channel, message) => { + console.log(`${LOG_PREFIX}No permission on ${channel}: ${message}`); + }); + + await chatClient.connect(); +} + +async function onConnect(): Promise { + console.log(`${LOG_PREFIX}Connected`); + + start(); +} + +async function handleClientAction(action: Action): Promise { + const [channel, username] = await Promise.all([ + getUsernameFromId(parseInt(action.channelId)), + getUsernameFromId(parseInt(action.userId)) + ]); + + if (!channel || !username) { + console.log(`${[LOG_PREFIX]}ChannelId or userId could not be solved`); + return; + } + + switch (action.type) { + case "say": + say(channel, action.data.message); + break; + case "timeout": + await timeout(channel, username, action.data.time, action.data.reason); + break; + case "broadcast": + broadcast(action.data.message); + break; + case "addVip": + await addVip(channel, username); + break; + case "removeVip": + await removeVip(channel, username); + break; + default: + console.log(`${[LOG_PREFIX]}Couldn't handle action:`, action); + } +} diff --git a/src/backend/helpers/chatClient.ts b/src/backend/helpers/chatClient.ts deleted file mode 100644 index 77cf489..0000000 --- a/src/backend/helpers/chatClient.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { getAuthProvider, getUsernameFromId } from "./twitch"; - -import { ChatClient } from "twitch-chat-client"; -import { broadcast } from "./webServer"; -import { start } from "./scheduledActions"; - -let chatClient: ChatClient; - -export { - chatClient, - connect, - handleClientAction, - say -}; - -// TODO: clean/refactor code - -const LOG_PREFIX = "[ChatClient] "; - -async function connect(channels: Array): Promise { - const authProvider = await getAuthProvider(); - - if ( - chatClient && - ( - chatClient.isConnecting || - chatClient.isConnected - ) - ) { - return; - } - - chatClient = new ChatClient(authProvider, { channels: channels }); - - chatClient.onConnect(onConnect); - - chatClient.onDisconnect((e: any) => { - console.log(`${LOG_PREFIX}Disconnected ${e.message}`); - }); - - chatClient.onNoPermission((channel, message) => { - console.log(`${LOG_PREFIX}No permission on ${channel}: ${message}`); - }); - - await chatClient.connect(); -} - -async function onConnect(): Promise { - console.log(`${LOG_PREFIX}Connected`); - - start(); -} - -async function handleClientAction(action: any): Promise { - if ( - action.channel && - !isNaN(action.channel) - ) { - action.channel = await getUsernameFromId(parseInt(action.channel)); - } - - if ( - action.username && - !isNaN(action.username) - ) { - action.username = await getUsernameFromId(parseInt(action.username)); - } - - // TODO: create a interface for action messages - if (!action.channel) { - action.channel = "alexbcberio"; - } - - switch (action.action) { - case "say": - say(action.channel, action.message); - break; - case "timeout": - await timeout( - action.channel, - action.username, - action.time, - action.reason - ); - break; - case "broadcast": - broadcast(action.message); - break; - case "addVip": - await addVip(action.channel, action.username); - break; - case "removeVip": - await removeVip(action.channel, action.username); - break; - default: - console.log(`${[LOG_PREFIX]}Couldn't handle action:`, action); - } -} - -// send a chat message -async function say(channel: string, message: string): Promise { - await chatClient.say(channel, message); -} - -// timeouts a user in a channel -async function timeout( - channel: string, - username: string, - time?: number, - reason?: string -): Promise { - if (!time) { - time = 60; - } - - if (!reason) { - reason = ""; - } - - try { - await chatClient.timeout(channel, username, time, reason); - } catch (e) { - // user cannot be timed out - } -} - -// adds a user to vips -async function addVip( - channel: string, - username: string, - message?: string -): Promise { - if (!message) { - message = `Otorgado VIP a @${username}.`; - } - - await chatClient.addVip(channel, username); - say(channel, message); -} - -// removes a user from vips -async function removeVip( - channel: string, - username: string, - message?: string -): Promise { - if (!message) { - message = `VIP de @${username} eliminado.`; - } - - await chatClient.removeVip(channel, username); - say(channel, message); -} diff --git a/src/backend/helpers/scheduledActions.ts b/src/backend/helpers/scheduledActions.ts index 5b2351f..dd883c0 100644 --- a/src/backend/helpers/scheduledActions.ts +++ b/src/backend/helpers/scheduledActions.ts @@ -1,5 +1,5 @@ import { promises as fs } from "fs"; -import { handleClientAction } from "./chatClient"; +import { handleClientAction } from "../chatClient"; import { resolve } from "path"; export { diff --git a/src/backend/helpers/webServer.ts b/src/backend/helpers/webServer.ts index 9073fa9..d49267d 100644 --- a/src/backend/helpers/webServer.ts +++ b/src/backend/helpers/webServer.ts @@ -1,11 +1,12 @@ import { IncomingMessage, Server } from "http"; import { saveScheduledActions, scheduledActions } from "./scheduledActions"; +import { Action } from "../../interfaces/actions/Action"; import { AddressInfo } from "net"; import { Socket } from "net"; import WebSocket from "ws"; import express from "express"; -import { handleClientAction } from "./chatClient"; +import { handleClientAction } from "../chatClient"; import { isDevelopment } from "./util"; import { join } from "path"; @@ -93,7 +94,9 @@ async function onMessage(msg: string) { return; } - for (const action of data.actions) { + const actions: Array = data.actions; + + for (const action of actions) { if (!action.scheduledAt) { await handleClientAction(action); } else { diff --git a/src/backend/index.ts b/src/backend/index.ts index 9d30143..afd2cd3 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -1,4 +1,4 @@ -import { connect } from "./helpers/chatClient"; +import { connect } from "./chatClient"; import { listen } from "./helpers/webServer"; import { registerUserListener } from "./helpers/pubSubClient";