add bot client
This commit is contained in:
parent
5d67834adf
commit
702a6db83b
83
libs/twitch-bot/index.js
Normal file
83
libs/twitch-bot/index.js
Normal file
@ -0,0 +1,83 @@
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
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.replace()
|
||||
|
||||
if (result !== null && result.rowCount > 0) {
|
||||
for (let row of result.rows) {
|
||||
if ('name' in row) {
|
||||
this.ws.send('JOIN #' + row.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
joinChannel (channel = null) {
|
||||
if (channel === null || typeof channel !== 'string' || channel.trim().length === 0) return null
|
||||
this.ws.send(`JOIN #${channel.trim()}`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WS()
|
44
libs/twitch-bot/parser.js
Normal file
44
libs/twitch-bot/parser.js
Normal file
@ -0,0 +1,44 @@
|
||||
const DB = require('@libs/database') // eslint-disable-line
|
||||
const config = require('@config/index')
|
||||
/**
|
||||
* @param {WebSocket} ws
|
||||
* @param {string} msg
|
||||
*/
|
||||
const msgSplit = async function (ws, msg) {
|
||||
if (!msg || typeof msg !== 'string') return null
|
||||
let txtarr = msg.split(' ')
|
||||
|
||||
if (txtarr.length > 2) {
|
||||
// server heartbeat message
|
||||
if (/^ping$/i.test(txtarr[0])) {
|
||||
// reply server heartbeat
|
||||
ws.send(`PONG ${txtarr[1]}`)
|
||||
return
|
||||
}
|
||||
// chat message
|
||||
if (/^privmsg$/i.test(txtarr[1])) {
|
||||
// message format
|
||||
// :user!user@user.tmi.twitch.tv PRIVMSG #channel :message
|
||||
let user = txtarr[0].split('!')[0].substr(1)
|
||||
if (user === config.twitch.bot_account) return
|
||||
let channel = txtarr[2] // eslint-disable-line
|
||||
|
||||
// get message
|
||||
txtarr = txtarr.slice(3, txtarr.length)
|
||||
// remove message first :
|
||||
let m = txtarr.join(' ').substr(1) // eslint-disable-line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sendMsg = async (ws, channel = null, msg = null) => {
|
||||
if (!ws || !('send' in ws) || typeof ws.send !== 'function') return null
|
||||
if (channel === null || typeof channel !== 'string' || channel.trim().length === 0) return null
|
||||
if (msg === null || typeof msg !== 'string' || msg.trim().length === 0) return null
|
||||
ws.send(`PRIVMSG #${channel} :${msg}`)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
msgSplit,
|
||||
sendMsg
|
||||
}
|
2
schema/20180716-1.sql
Normal file
2
schema/20180716-1.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE public.twitch_channel ADD "join" boolean DEFAULT false NOT NULL;
|
||||
ALTER TABLE public.twitch_channel ADD opayid varchar(150) DEFAULT '' NOT NULL;
|
Loading…
Reference in New Issue
Block a user