import { EventEmitter } from 'stream'; import WebSocket from 'ws' import { TwitchChatOptions, Metadata, MessageType, MessageTypes } from '../../../types/scraping/Chat' import { parseUsername } from './utils'; import { logger } from '../../logger'; export declare interface TwitchChat { on(event: 'PRIVMSG', listener: (username: string, messageType: MessageType, channel: string, message: string) => void): this } export class TwitchChat extends EventEmitter{ public channels: string[] private url = 'wss://irc-ws.chat.twitch.tv:443' private ws: WebSocket | null; private isConnected: boolean = false private manualDisconnect: boolean = false constructor(options: TwitchChatOptions) { super() this.channels = options.channels this.ws = null } private parser() { this.ws?.on('message', (data) => { console.log(this.channels) let normalData = data.toString() let splitted = normalData.split(":") let metadata = splitted[1].split(' ') let message = splitted[2] if(!MessageTypes.includes(metadata[1])) return; let parsedMetadata: Metadata = { username: parseUsername(metadata[0]), messageType: metadata[1], channel: metadata[2].replace('#', ''), message: message } this.createEmit(parsedMetadata) }) } private createEmit(data: Metadata) { this.emit(data.messageType, ...Object.values(data)) } public async connect() { console.log('ss') this.ws = new WebSocket(this.url) this.isConnected = true this.ws.onclose = () => { logger.info('Disconnected from twitch IRC'), logger.info(`Subscribed to channels ${this.channels}`) if(this.manualDisconnect) return const toEmit = { type: 'SERVERMSG', message: 'Disconnected' } this.emit(JSON.stringify(toEmit)) this.ws = null this.isConnected = false this.connect() } this.ws.onopen = () => { if(this.ws) { this.ws.send('PASS none') this.ws.send('NICK justinfan333333333333') for(let channel of this.channels) { this.ws.send(`JOIN #${channel}`) } this.parser() return Promise.resolve() } } } public addStreamer(streamerName: string) { if(!this.isConnected) return; this.channels.push(streamerName) this.ws!.send(`JOIN #${streamerName}`) } }