donate notify not fin

This commit is contained in:
Jay 2018-07-19 00:40:07 +08:00
parent fa11f24e3a
commit 9d964268e8
11 changed files with 204 additions and 4 deletions

View File

@ -2,6 +2,8 @@ const cron = require('cron')
const DB = require('./libs/database') const DB = require('./libs/database')
const fbParser = require('./libs/facebook-pageparse') const fbParser = require('./libs/facebook-pageparse')
const api = require('./libs/api-action') const api = require('./libs/api-action')
const event = require('./event')
const axios = require('axios')
new cron.CronJob({ // eslint-disable-line new cron.CronJob({ // eslint-disable-line
cronTime: '00 */2 * * * *', cronTime: '00 */2 * * * *',
@ -204,7 +206,7 @@ new cron.CronJob({ //eslint-disable-line
let db = await DB.connect() let db = await DB.connect()
try { try {
let time = Date.now() + (4 * 1000 * 60 * 60) 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 text = `select "id", "name", "lastvideo", "expire" from "public"."youtube_channel" where "expire" = -1 or "expire" < $1`
let values = [time] let values = [time]
let result = await db.query({ let result = await db.query({
@ -231,3 +233,68 @@ const regYoutubeWebhook = async (yt = null) => {
console.log(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()
// donate response format
// {
// "donateid": "10821396",
// "name": "XXX",
// "amount": 100,
// "msg": "這是一筆贊助測試~"
// }
try {
let result = await axios({
url,
method: 'post'
})
if ('data' in result && Array.isArray(result.data) && result.data.length > 0) {
let ids = result.data.map(t => t.donateid)
let dbres = await db.query({
text: `select * from "public"."donate_list" where "donate_id" in ($1)`,
values: [ids]
})
let list = result.data.filter(t => {
for (let i of dbres.rows) {
if (i.donate_id === t.donateid) return false
}
return true
})
}
} catch (err) {
console.log(err)
}
db.release()
}

View File

@ -9,7 +9,8 @@
{"file": "20180711-1.sql", "version": 7}, {"file": "20180711-1.sql", "version": 7},
{"file": "20180712-1.sql", "version": 8}, {"file": "20180712-1.sql", "version": 8},
{"file": "20180716-1.sql", "version": 9}, {"file": "20180716-1.sql", "version": 9},
{"file": "20180718-1.sql", "version": 10} {"file": "20180718-1.sql", "version": 10},
{"file": "20180719-1.sql", "version": 11}
], ],
"test": [] "test": []
} }

View File

@ -21,5 +21,9 @@ module.exports = {
user: process.env.DB_USER || 'postgres', user: process.env.DB_USER || 'postgres',
pass: process.env.DB_PASS || '', pass: process.env.DB_PASS || '',
dbname: process.env.DB_NAME || 'mtfosbot' dbname: process.env.DB_NAME || 'mtfosbot'
},
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: process.env.REDIS_PORT || 6379
} }
} }

6
event.js Normal file
View File

@ -0,0 +1,6 @@
const EventEmitter = require('events')
class EventCls extends EventEmitter {
}
module.exports = new EventCls()

View File

@ -7,3 +7,6 @@ try {
} catch (err) {} } catch (err) {}
require('./app') require('./app')
require('./background') require('./background')
require('./event')
const twitchChat = require('./libs/twitch-bot')
twitchChat.runBot()

View File

@ -5,7 +5,8 @@
"paths": { "paths": {
"@libs/*": ["libs/*"], "@libs/*": ["libs/*"],
"@config/*": ["config/*"], "@config/*": ["config/*"],
"@route/*": ["route/*"] "@route/*": ["route/*"],
"@root/*": ["./*"]
} }
} }
} }

91
libs/redis.js Normal file
View File

@ -0,0 +1,91 @@
const Redis = require('ioredis')
const config = require('@config/index')
class RedisStore {
constructor () {
this._redis = new Redis(config.redis.port, config.redis.host)
this._expires = 86400 // day (sec)
}
/**
* set data to redis
* @param {string} key
* @param {string|object} data string or json
* @param {number} expires default 1 day
*/
set (key, data = null, expires = null) {
if (!key || typeof key !== 'string') return
if (key.trim().length === 0) return
if (typeof data === 'object') {
try {
data = JSON.stringify(data)
} catch (err) {}
}
if (expires === null || !isFinite(expires)) expires = this._expires
let args = [`${key}`, data]
if (expires > 0) args.push('EX', expires)
this._redis.set(...args)
}
/**
* get data from redis
* @param {string} key
* @param {boolean=} toJSON parse data to json (default true)
*/
async get (key, toJSON = true) {
if (!key || typeof key !== 'string') return null
if (key.trim().length === 0) return null
let self = this
let data = null
try {
data = await self._redis.get(`${key}`)
} catch (err) {
return null
}
if (toJSON === true) {
try {
data = JSON.parse(data)
} catch (err) {
return null
}
}
return data
}
/**
* delete data
* @param {string} key
*/
del (key) {
if (!key || typeof key !== 'string') return null
if (key.trim().length === 0) return null
this._redis.del(`${key}`)
}
/**
* show all this project namespace data
*/
async show () {
// return this._store
let self = this
let json = {}
let keys = await this._redis.keys(`*`)
for (let i in keys) {
try {
let data = await this._redis.get(keys[i])
let j = JSON.parse(data)
let k = keys[i].replace(self._namespace, '')
json[k] = j
} catch (err) {
continue
}
}
return json
}
}
module.exports = new RedisStore()

View File

@ -4,12 +4,19 @@ const DB = require('@libs/database')
const { const {
msgSplit msgSplit
} = require('./parser') } = require('./parser')
const event = require('@root/event')
class WS { class WS {
constructor () { constructor () {
/** @type {WebSocket} */ /** @type {WebSocket} */
this.ws = null this.ws = null
this.join = [] this.join = []
event.on('twitchJoin', (channel) => {
this.joinChannel(channel)
})
event.on('twitchSend', data => {
this.sendMsg(data.channel, data.message)
})
} }
runBot () { runBot () {
@ -89,6 +96,7 @@ class WS {
joinChannel (channel = null) { joinChannel (channel = null) {
if (this.ws === null || !('send' in this.ws) || typeof this.ws.send !== 'function') return 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 (channel === null || typeof channel !== 'string' || channel.trim().length === 0) return null
if (this.join.indexOf(channel) !== -1) return null
this.ws.send(`JOIN #${channel.trim()}`) this.ws.send(`JOIN #${channel.trim()}`)
this.join.push(channel.trim()) this.join.push(channel.trim())
} }

View File

@ -18,6 +18,7 @@
"cron": "^1.3.0", "cron": "^1.3.0",
"dotenv": "^6.0.0", "dotenv": "^6.0.0",
"gm": "^1.23.1", "gm": "^1.23.1",
"ioredis": "^3.2.2",
"koa": "^2.5.1", "koa": "^2.5.1",
"koa-body": "^4.0.3", "koa-body": "^4.0.3",
"koa-logger": "^3.2.0", "koa-logger": "^3.2.0",
@ -35,6 +36,7 @@
"_moduleAliases": { "_moduleAliases": {
"@libs": "libs", "@libs": "libs",
"@config": "config", "@config": "config",
"@route": "route" "@route": "route",
"@root": "."
} }
} }

1
schema/20180718-1.sql Normal file
View File

@ -0,0 +1 @@
ALTER TABLE public.youtube_channel ALTER COLUMN expire TYPE bigint USING expire::bigint;

16
schema/20180719-1.sql Normal file
View File

@ -0,0 +1,16 @@
create extension "uuid-ossp" with schema public;
-- auto-generated definition
create table public.donate_list
(
id uuid default public.uuid_generate_v4() not null
constraint donate_list_pkey
primary key,
opayid varchar(200) not null,
donate_id varchar(200) not null,
price integer default 0 not null,
text varchar(1000) default '' :: character varying not null,
ctime timestamp with time zone default CURRENT_TIMESTAMP not null,
name varchar(100) default '' :: character varying not null
);