const cron = require('cron') const DB = require('./libs/database') const fbParser = require('./libs/facebook-pageparse') const api = require('./libs/api-action') const event = require('./event') const axios = require('axios') new cron.CronJob({ // eslint-disable-line cronTime: '00 */2 * * * *', onTick: async () => { console.log('run cron') let db = await DB.connect() let text = `select "id" as page, "lastpost" as post from "public"."facebook_page"` let res = await db.query({ text }) console.log('rows length :::: ', res.rowCount) if (res.rows.legnth === 0) return res.rows.forEach(t => { runCheckPage(t) }) db.release() }, runOnInit: true, start: true, timeZone: 'Asia/Taipei' }) const runCheckPage = async function (t) { let db = await DB.connect() let data = null try { data = await fbParser.getLastPost(t.page) } catch (err) { db.release() } if (data === null) { db.release() return } let n = Math.floor(Date.now() / 1000) if (t.post === data.id || data.time < (n - 10 * 60)) { db.release() return } t.post = data.id try { let text = `update "public"."facebook_page" set "lastpost" = $1, "mtime" = now() where "id" = $2` let values = [data.id, t.page] await db.query({ text, values }) } catch (err) { console.log(err) } let rt = null try { let text = `select rt."facebook" as page, rt."tmpl" as tmpl, rt."line" as group from "public"."line_fb_rt" rt left join "public"."line_group" line on line."id" = rt."line" where line."notify" = true and rt."facebook" = $1` let values = [t.page] rt = await db.query({ text, values }) } catch (err) { console.log(err) } if (rt === null || rt.rowCount === 0) { db.release() return } for (let i in rt.rows) { let tmp = rt.rows[i] let msg = tmp.tmpl || '' if (typeof msg !== 'string' || msg.trim().length === 0) { msg = `${data.txt}\n${data.link}` } else { msg = msg.replace(/{link}/, data.link).replace(/{txt}/, data.txt).replace(/\\n/, '\n') } api.line.pushMessage(tmp.group, msg).then(() => { }).catch(() => { }) } db.release() } // check twitch streaming status new cron.CronJob({ //eslint-disable-line cronTime: '*/20 * * * * *', onTick: async () => { let db = await DB.connect() let text = `select "id" from "public"."twitch_channel"` try { let twch = await db.query({ text }) let ids = twch.rows.map(t => t.id) let streams = await api.twitchPublic.getUserStream(ids) if (streams !== null && Array.isArray(streams)) { streams.forEach(t => { sendStreamNotify(t).then(() => {}).catch(() => {}) }) } } catch (err) { console.log(err) db.release() return } db.release() }, runOnInit: true, start: true, timeZone: 'Asia/Taipei' }) const sendStreamNotify = async (streamer = null) => { if (streamer === null || typeof streamer !== 'object' || !('user_id' in streamer) || !('id' in streamer)) return null let db = await DB.connect() try { let result = await db.query({ text: `select "id" from "public"."twitch_channel" where "id" = $1 and "laststream" = $2`, values: [streamer.user_id, streamer.id] }) if (result.rowCount > 0) { db.release() return } } catch (err) { console.log(err) db.release() return } try { let text = `update "public"."twitch_channel" set "laststream" = $1, "mtime" = now() where "id" = $2` let values = [streamer.id, streamer.user_id] await db.query({ text, values }) } catch (err) { console.log(err) } let rt = null try { let text = `select rt."tmpl" as tmpl, line."id" as group, twitch."laststream" as laststream, twitch."name" as user from "public"."line_twitch_rt" rt left join "public"."line_group" line on line."id" = rt."line" left join "public"."twitch_channel" twitch on twitch."id" = rt."twitch" where twitch."id" = $1 and line."notify" = true and rt."type" = 'live'` let values = [streamer.user_id] rt = await db.query({ text, values }) } catch (err) { console.log(err) db.release() return } if (rt === null || rt.rowCount === 0) { db.release() return } let twLink = 'https://twitch.tv/' for (let i in rt.rows) { let tmp = rt.rows[i] let link = twLink + tmp.user let msg = tmp.tmpl || '' if (typeof msg !== 'string' || msg.trim().length === 0) { msg = `${streamer.title || ''}\n${link}` } else { msg = msg.replace(/{link}/, link).replace(/{txt}/, streamer.title).replace(/\\n/, '\n') } api.line.pushMessage(tmp.group, msg).then(() => { }).catch(() => { }) } db.release() } // check youtube webhook new cron.CronJob({ //eslint-disable-line cronTime: '00 00 */3 * * *', onTick: async () => { let db = await DB.connect() try { let time = Math.floor((Date.now() + (4 * 1000 * 60 * 60)) / 1000) let text = `select "id", "name", "lastvideo", "expire" from "public"."youtube_channel" where "expire" = -1 or "expire" < $1` let values = [time] let result = await db.query({ text, values }) result.rows.forEach(t => { regYoutubeWebhook(t).then(() => {}).catch(() => {}) }) } catch (err) {} db.release() }, runOnInit: true, start: true, timeZone: 'Asia/Taipei' }) const regYoutubeWebhook = async (yt = null) => { if (yt === null || typeof yt !== 'object' || !('id' in yt)) return null try { await api.google.subYoutube(yt.id) } catch (err) { console.log(err) } } // check donate new cron.CronJob({ //eslint-disable-line cronTime: '*/5 * * * * *', onTick: async () => { let db = await DB.connect() try { let text = `select "name", "id", "opayid" from "public"."twitch_channel" where "opayid" != '' and "join" = true` let result = await db.query({ text }) if (result.rowCount > 0) { result.rows.forEach(t => { checkDonate(t.name, t.opayid).then(() => {}).catch(() => {}) }) } } catch (err) { console.log(err) } db.release() }, runOnInit: true, start: true, timeZone: 'Asia/Taipei' }) const checkDonate = async (loginName = null, opayid = null) => { if (typeof loginName !== 'string' || loginName.trim().length === 0) return null if (typeof opayid !== 'string' || opayid.trim().length === 0) return null let url = `https://payment.opay.tw/Broadcaster/CheckDonate/${opayid}` let db = await DB.connect() // console.log('check donate :::: ', loginName, opayid) // donate response format // { // "donateid": "10821396", // "name": "XXX", // "amount": 100, // "msg": "這是一筆贊助測試~" // } try { let result = await axios({ url, data: {}, headers: { 'Content-Type': 'application/json' }, method: 'post' }) // console.log(loginName, 'http response :::: ', JSON.stringify(result.data)) if ('data' in result && 'lstDonate' in result.data && Array.isArray(result.data.lstDonate) && result.data.lstDonate.length > 0) { // console.log(`${loginName} donate :::: ${JSON.stringify(result.data)}`) let ids = result.data.lstDonate.map(t => t.donateid) let inparams = ids.map((t, idx) => `$${(idx + 1)}`) let dbres = await db.query({ text: `select * from "public"."opay_donate_list" where "donate_id" in (${inparams.join(',')})`, values: [...ids] }) let list = result.data.lstDonate.filter(t => { for (let i of dbres.rows) { if (i.donate_id === t.donateid) return false } return true }) for (let i of list) { let text = `insert into "public"."opay_donate_list" ("opayid", "donate_id", "price", "text", "name") values ($1, $2, $3, $4, $5)` let values = [opayid, i.donateid, i.amount || 0, i.msg || '', i.name || ''] try { await db.query({ text, values }) let msg = `/me 感謝 ${i.name} 贊助了 ${i.amount} 元, ${i.msg}` event.emit('twitchSend', { msg, channel: loginName }) } catch (err) { console.log(err) } } } } catch (err) { console.log(err) } db.release() }