twitch-bot/libs/botClient.js

120 lines
2.7 KiB
JavaScript
Raw Normal View History

2018-02-12 15:08:42 +00:00
const WebSocket = require('ws')
const config = require('../config')
2018-02-12 16:34:26 +00:00
const dbPool = require('./database')
const request = require('request')
const log = require('debug')('BOT:IRC')
2018-02-13 05:41:32 +00:00
const {
msgSplit
} = require('./twitchParser')
2018-02-12 15:08:42 +00:00
2018-02-13 05:41:32 +00:00
/** @type {WebSocket} */
var ws = null
2018-02-12 15:08:42 +00:00
2018-02-13 15:30:09 +00:00
if (config.twitch.refresh_token && typeof config.twitch.refresh_token === 'string' && config.twitch.refresh_token.length > 0) {
runBot()
}
2018-02-13 05:16:30 +00:00
2018-02-13 05:41:32 +00:00
function runBot() {
ws = new WebSocket(`wss://${config.twitch.chat_host}:443`, 'irc')
2018-02-13 05:16:30 +00:00
2018-02-13 05:41:32 +00:00
ws.on('open', handleOpen)
ws.on('message', handleMessage)
ws.on('error', handleError)
ws.on('close', handleExit)
}
function handleError(err) {
2018-02-13 05:16:30 +00:00
console.error(err)
2018-02-13 05:41:32 +00:00
ws = null
runBot()
// do reconnect
}
2018-02-13 05:16:30 +00:00
2018-02-13 05:41:32 +00:00
function handleExit(code) {
// do reconnect
ws = null
runBot()
}
2018-02-13 05:16:30 +00:00
2018-02-13 05:41:32 +00:00
function handleMessage(data) {
2018-02-13 15:30:09 +00:00
// socket message convert to string
2018-02-13 05:16:30 +00:00
let d = data.toString()
2018-02-13 15:30:09 +00:00
// split message with \n
// filter array remove empty element
// replace \r to empty
2018-02-13 05:16:30 +00:00
let darr = d.split(/\n/).filter(t => t).map(t => t.replace(/\r$/, ''))
for (let i in darr) {
log(darr[i])
2018-02-13 15:30:09 +00:00
// parse message
msgSplit(ws, darr[i]).then(() => { /* pass */ })
2018-02-13 05:16:30 +00:00
}
}
2018-02-13 15:30:09 +00:00
/**
* WebSocket Open Action
*/
2018-02-13 05:41:32 +00:00
async function handleOpen() {
2018-02-13 15:30:09 +00:00
// from pool get db connection
2018-02-12 16:34:26 +00:00
let db = await dbPool.connect()
2018-02-12 15:08:42 +00:00
2018-02-12 16:34:26 +00:00
let body = null
try {
let options = {
method: 'POST',
url: config.twitch.token_url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
},
form: {
grant_type: 'refresh_token',
refresh_token: config.twitch.refresh_token,
client_id: config.twitch.client_id,
client_secret: config.twitch.secret
}
}
body = await new Promise((resolve, reject) => {
2018-02-13 15:30:09 +00:00
// get new token with refresh_token
2018-02-12 16:34:26 +00:00
request(options, function (error, response, body) {
if (error) {
reject(error)
return
}
2018-02-13 05:16:30 +00:00
if (typeof body === 'string') body = JSON.parse(body)
2018-02-12 16:34:26 +00:00
resolve(body)
})
})
} catch (err) {
console.log(err)
}
2018-02-13 05:41:32 +00:00
2018-02-12 16:34:26 +00:00
if (body === null || !('access_token' in body)) throw new Error('access token not found')
2018-02-13 15:30:09 +00:00
// login to twitch irc
2018-02-12 16:34:26 +00:00
ws.send('PASS oauth:' + body.access_token)
ws.send('NICK mtfosbot')
ws.send('CAP REQ :twitch.tv/membership :twitch.tv/commands')
2018-02-13 15:30:09 +00:00
// 取得要加入的頻道列表
2018-02-12 16:34:26 +00:00
let query = `select "name", "join" from "public"."channels" where "join" = $1`
let param = [true]
let result = await db.query(query, param)
2018-02-13 15:30:09 +00:00
// release pool connection
2018-02-13 05:16:30 +00:00
await db.end()
2018-02-13 15:30:09 +00:00
2018-02-12 16:34:26 +00:00
if (result !== null && result.rows.length > 0) {
for (let row of result.rows) {
if ('name' in row) {
ws.send('JOIN #' + row.name)
}
}
}
2018-02-13 05:16:30 +00:00
}
2018-02-12 15:08:42 +00:00
2018-02-13 15:30:09 +00:00
module.exports = ws