const WebSocket = require('ws') const config = require('@config/index') const DB = require('@libs/database') const { msgSplit } = require('./parser') class WS { constructor () { /** @type {WebSocket} */ this.ws = null this.join = [] } runBot () { if (!config.twitch.chat_host || !config.twitch.bot_oauth) return if (this.ws !== null) return this.ws = new WebSocket(`wss://${config.twitch.chat_host}:443`, 'irc') this.ws.on('open', this.handleOpen.bind(this)) this.ws.on('message', this.handleMessage.bind(this)) this.ws.on('error', this.handleError.bind(this)) this.ws.on('close', this.handleExit.bind(this)) } handleError (err) { console.log(err) this.ws = null this.runBot() } handleExit (code) { this.ws = null this.runBot() } handleMessage (data) { // socket message convert to string let d = data.toString() // split message with \n // filter array remove empty element // replace \r to empty let darr = d.split(/\n/).filter(t => t).map(t => t.replace(/\r$/, '')) for (let i in darr) { // parse message console.log('IRC:::: ', darr[i]) msgSplit(this.ws, darr[i]).then(() => { /* pass */ }) } } async handleOpen () { // from pool get db connection let db = await DB.connect() // login to twitch irc this.ws.send('PASS ' + config.twitch.bot_oauth) this.ws.send('NICK mtfosbot') this.ws.send('CAP REQ :twitch.tv/membership :twitch.tv/commands') // 取得要加入的頻道列表 let text = `select "name" from "public"."twitch_channel where "join" = true` let result = await db.query({ text }) // release pool connection await db.release() this.joinChannel = [] if (result !== null && result.rowCount > 0) { for (let row of result.rows) { if ('name' in row) { this.ws.send('JOIN #' + row.name) this.join.push(row.name) } } } } sendMsg (channel = null, message = null) { if (this.ws === null || !('send' in this.ws) || typeof this.ws.send !== 'function') return null if (channel === null || typeof channel !== 'string' || channel.trim().length === 0) return null if (message === null || typeof message !== 'string' || message.trim().length === 0) return null if (this.join.indexOf(channel) === -1) return null this.ws.send(`PRIVMSG #${channel} :${message}`) } joinChannel (channel = null) { if (this.ws === null || !('send' in this.ws) || typeof this.ws.send !== 'function') return null if (channel === null || typeof channel !== 'string' || channel.trim().length === 0) return null this.ws.send(`JOIN #${channel.trim()}`) this.join.push(channel.trim()) } } module.exports = new WS()