add twitch oauth login
This commit is contained in:
parent
89b24e0bf6
commit
334fce3b9b
@ -5,9 +5,9 @@ RUN mkdir -p /data
|
|||||||
WORKDIR /data
|
WORKDIR /data
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN rm -f .env
|
RUN rm -f .env
|
||||||
RUN apt-get update -qqy
|
RUN apt-get update -qqy \
|
||||||
RUN apt-get install -qqy imagemagick graphicsmagick
|
&& apt-get install -qqy imagemagick graphicsmagick \
|
||||||
RUN apt-get clean
|
&& apt-get clean
|
||||||
RUN npm install
|
RUN npm install
|
||||||
EXPOSE ${NODE_PORT}
|
EXPOSE ${NODE_PORT}
|
||||||
CMD ["npm", "run", "dbrun"]
|
CMD ["npm", "run", "dbrun"]
|
2
app.js
2
app.js
@ -1,10 +1,12 @@
|
|||||||
const config = require('./config')
|
const config = require('./config')
|
||||||
const Koa = require('koa')
|
const Koa = require('koa')
|
||||||
const koaLogger = require('koa-logger')
|
const koaLogger = require('koa-logger')
|
||||||
|
const koaSession = require('koa-session2')
|
||||||
const router = require('./route')
|
const router = require('./route')
|
||||||
const app = new Koa()
|
const app = new Koa()
|
||||||
|
|
||||||
app.use(koaLogger())
|
app.use(koaLogger())
|
||||||
|
app.use(koaSession())
|
||||||
app.use(router.allowedMethods())
|
app.use(router.allowedMethods())
|
||||||
app.use(router.routes())
|
app.use(router.routes())
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ new cron.CronJob({ //eslint-disable-line
|
|||||||
text
|
text
|
||||||
})
|
})
|
||||||
let ids = twch.rows.map(t => t.id)
|
let ids = twch.rows.map(t => t.id)
|
||||||
let streams = await api.twitch.getUserStream(ids)
|
let streams = await api.twitchPublic.getUserStream(ids)
|
||||||
if (streams !== null && Array.isArray(streams)) {
|
if (streams !== null && Array.isArray(streams)) {
|
||||||
streams.forEach(t => {
|
streams.forEach(t => {
|
||||||
sendStreamNotify(t).then(() => {}).catch(() => {})
|
sendStreamNotify(t).then(() => {}).catch(() => {})
|
||||||
@ -283,9 +283,9 @@ const checkDonate = async (loginName = null, opayid = null) => {
|
|||||||
},
|
},
|
||||||
method: 'post'
|
method: 'post'
|
||||||
})
|
})
|
||||||
console.log(loginName, 'http response :::: ', JSON.stringify(result.data))
|
// 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) {
|
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)}`)
|
// console.log(`${loginName} donate :::: ${JSON.stringify(result.data)}`)
|
||||||
let ids = result.data.lstDonate.map(t => t.donateid)
|
let ids = result.data.lstDonate.map(t => t.donateid)
|
||||||
let inparams = ids.map((t, idx) => `$${(idx + 1)}`)
|
let inparams = ids.map((t, idx) => `$${(idx + 1)}`)
|
||||||
let dbres = await db.query({
|
let dbres = await db.query({
|
||||||
|
@ -8,6 +8,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
twitch: {
|
twitch: {
|
||||||
clientid: process.env.TWITCH_CLIENT_ID || '',
|
clientid: process.env.TWITCH_CLIENT_ID || '',
|
||||||
|
clientsecret: process.env.TWITCH_CLIENT_SECRET || '',
|
||||||
subsecret: process.env.TWITCH_SUB_SECRET || '',
|
subsecret: process.env.TWITCH_SUB_SECRET || '',
|
||||||
chat_host: process.env.TWITCH_CHAT_HOST || '',
|
chat_host: process.env.TWITCH_CHAT_HOST || '',
|
||||||
bot_oauth: process.env.TWITCH_BOT_OAUTH || ''
|
bot_oauth: process.env.TWITCH_BOT_OAUTH || ''
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
const twitch = require('./twitch')
|
const twitchPublic = require('./twitch-public')
|
||||||
const line = require('./line')
|
const line = require('./line')
|
||||||
const google = require('./google')
|
const google = require('./google')
|
||||||
|
const twitchNew = require('./twitch-new')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
twitch,
|
twitchPublic,
|
||||||
line,
|
line,
|
||||||
google
|
google,
|
||||||
|
twitchNew
|
||||||
}
|
}
|
||||||
|
32
libs/api-action/twitch-new.js
Normal file
32
libs/api-action/twitch-new.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
const axios = require('axios')
|
||||||
|
const config = require('@config/index')
|
||||||
|
const baseURL = `https://api.twitch.tv/helix`
|
||||||
|
const client = axios.create({
|
||||||
|
baseURL,
|
||||||
|
headers: {
|
||||||
|
'Client-ID': config.twitch.clientid
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const tokenHeader = (token) => {
|
||||||
|
if (typeof token !== 'string' || token.trim().length === 0) return null
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.getUserData = async (token = '') => {
|
||||||
|
let headers = tokenHeader(token)
|
||||||
|
if (headers === null) return null
|
||||||
|
let url = '/users'
|
||||||
|
|
||||||
|
let result = await client({
|
||||||
|
method: 'get',
|
||||||
|
headers,
|
||||||
|
url
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!('data' in result) || !('data' in result.data) || !Array.isArray(result.data.data)) return null
|
||||||
|
if (result.data.data.length === 0) return null
|
||||||
|
return result.data.data[0]
|
||||||
|
}
|
@ -236,7 +236,7 @@ const addTwitch = async (txt = '', source = {}, db) => {
|
|||||||
return { reply }
|
return { reply }
|
||||||
}
|
}
|
||||||
|
|
||||||
let twitchUser = await api.twitch.getUserIDByName(name)
|
let twitchUser = await api.twitchPublic.getUserIDByName(name)
|
||||||
if (twitchUser === null) return null
|
if (twitchUser === null) return null
|
||||||
|
|
||||||
// check channel count
|
// check channel count
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"start": "node index.js 2>&1 | tee runtime.txt",
|
"start": "node index.js 2>&1 | tee runtime.txt",
|
||||||
"dbtool": "node bin/dbtool",
|
"dbtool": "node bin/dbtool",
|
||||||
"dbrun": "npm run dbtool && npm start",
|
"dbrun": "npm run dbtool && npm start",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"postinstall": "npm i otakukaze/koa-session2#master"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "JayChen",
|
"author": "JayChen",
|
||||||
@ -23,6 +24,7 @@
|
|||||||
"koa-body": "^4.0.3",
|
"koa-body": "^4.0.3",
|
||||||
"koa-logger": "^3.2.0",
|
"koa-logger": "^3.2.0",
|
||||||
"koa-router": "^7.4.0",
|
"koa-router": "^7.4.0",
|
||||||
|
"koa-session2": "github:otakukaze/koa-session2#master",
|
||||||
"lodash": "^4.17.10",
|
"lodash": "^4.17.10",
|
||||||
"module-alias": "^2.1.0",
|
"module-alias": "^2.1.0",
|
||||||
"pg": "^7.4.3",
|
"pg": "^7.4.3",
|
||||||
|
@ -103,6 +103,6 @@ r.use('/web', require('./web').routes())
|
|||||||
r.use('/api', require('./api').routes())
|
r.use('/api', require('./api').routes())
|
||||||
r.use('/line', require('./line').routes())
|
r.use('/line', require('./line').routes())
|
||||||
r.use('/google', require('./google').routes())
|
r.use('/google', require('./google').routes())
|
||||||
// r.use('/twitch', require('./twitch').routes())
|
r.use('/twitch', require('./twitch').routes())
|
||||||
|
|
||||||
module.exports = r
|
module.exports = r
|
||||||
|
@ -1,81 +1,105 @@
|
|||||||
const Router = require('koa-router')
|
const Router = require('koa-router')
|
||||||
const r = new Router()
|
const r = new Router()
|
||||||
const {
|
|
||||||
getRaw
|
|
||||||
} = require('@libs/middleware')
|
|
||||||
const DB = require('@libs/database')
|
const DB = require('@libs/database')
|
||||||
const api = require('@libs/api-action')
|
const api = require('@libs/api-action')
|
||||||
// const config = require('../../config')
|
const qs = require('querystring')
|
||||||
|
const config = require('@config/index')
|
||||||
|
const axios = require('axios')
|
||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
r.get('/webhook', async (c, n) => {
|
r.get('/login', async (c, n) => {
|
||||||
let mode = c.query['hub.mode']
|
let redirectUrl = `${config.url.replace(/\/$/, '')}/twitch/oauth`
|
||||||
let token = c.query['hub.secret']
|
let qsObj = {
|
||||||
let challenge = c.query['hub.challenge']
|
client_id: config.twitch.clientid,
|
||||||
console.log(mode, token, challenge)
|
redirect_uri: redirectUrl,
|
||||||
console.log(c.headers)
|
response_type: 'code',
|
||||||
if (mode) {
|
scope: 'user:read:email'
|
||||||
if (mode === 'subscribe') {
|
|
||||||
c.status = 200
|
|
||||||
c.body = challenge
|
|
||||||
} else {
|
|
||||||
c.status = 403
|
|
||||||
c.body = ''
|
|
||||||
}
|
}
|
||||||
|
let qsStr = qs.stringify(qsObj)
|
||||||
|
let toUrl = `https://id.twitch.tv/oauth2/authorize?${qsStr}`
|
||||||
|
|
||||||
|
let backUrl = c.query['tourl'] || ''
|
||||||
|
if (typeof backUrl === 'string' && backUrl.trim().length > 0) {
|
||||||
|
c.session.backUrl = backUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.redirect(toUrl)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.post('/webhook', getRaw, async (c, n) => {
|
r.get('/oauth', async (c, n) => {
|
||||||
// middleware
|
let url = `https://id.twitch.tv/oauth2/token`
|
||||||
c.db = await DB.connect()
|
let redirectUrl = `${config.url.replace(/\/$/, '')}/twitch/oauth`
|
||||||
|
let code = c.query.code || ''
|
||||||
|
if (!code) {
|
||||||
|
c.body = 'oauth login fail'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let qsObj = {
|
||||||
|
client_id: config.twitch.clientid,
|
||||||
|
client_secret: config.twitch.clientsecret,
|
||||||
|
code,
|
||||||
|
grant_type: 'authorization_code',
|
||||||
|
redirect_uri: redirectUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
'access_token': '',
|
||||||
|
'refresh_token': '',
|
||||||
|
'expires_in': 0,
|
||||||
|
'scope': '',
|
||||||
|
'token_type': 'bearer'
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await n()
|
let tokenResult = await axios({
|
||||||
|
method: 'post',
|
||||||
|
url,
|
||||||
|
params: qsObj
|
||||||
|
})
|
||||||
|
if (!('data' in tokenResult)) {
|
||||||
|
c.body = 'read token fail'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data = _.assign({}, data, tokenResult.data)
|
||||||
|
} catch (err) {
|
||||||
|
console.log('request token fail ', err)
|
||||||
|
c.body = 'get token fail'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.session.token = data
|
||||||
|
try {
|
||||||
|
let user = await api.twitchNew.getUserData(data.access_token)
|
||||||
|
c.session.user = user
|
||||||
|
} catch (err) {
|
||||||
|
console.log('get user data fail ::: ', err)
|
||||||
|
c.body = 'get user data fail'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let db = await DB.connect()
|
||||||
|
try {
|
||||||
|
let count = await db.query({
|
||||||
|
text: `select id from "public"."twitch_channel" where id = $1`,
|
||||||
|
values: [c.session.user.id]
|
||||||
|
})
|
||||||
|
if (count.rowCount === 0) {
|
||||||
|
await db.query({
|
||||||
|
text: `insert into "public"."twitch_channel" ("id", "name") values ($1, $2)`,
|
||||||
|
values: [c.session.user.id, c.session.user.login]
|
||||||
|
})
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
|
db.release()
|
||||||
c.db.release()
|
c.session.loginType = 'twitch'
|
||||||
c.body = 'success'
|
if (typeof c.session.backUrl === 'string' && c.session.backUrl.length > 0) {
|
||||||
c.status = 200
|
let url = c.session.backUrl
|
||||||
}, async (c, n) => {
|
delete c.session.backUrl
|
||||||
console.log(JSON.stringify(c.request.body, null, 2))
|
c.redirect(url)
|
||||||
if (!('data' in c.request.body) || !Array.isArray(c.request.body.data)) return
|
|
||||||
if (c.request.body.data.length === 0) return // length > 0 live, length === 0 down
|
|
||||||
let data = c.request.body.data[0]
|
|
||||||
let uid = c.query['uid'] || ''
|
|
||||||
let type = c.query['type'] || ''
|
|
||||||
|
|
||||||
if (!uid || !type) return
|
|
||||||
|
|
||||||
let text = `select rt."line" as group, rt."twitch" as twitch, rt."tmpl" as tmpl, twitch."name" as user from "public"."line_twitch_rt" rt
|
|
||||||
left join "public"."twitch_channel" twitch
|
|
||||||
on twitch."id" = rt."twitch"
|
|
||||||
left join "public"."line_group" line
|
|
||||||
on line."id" = rt."line"
|
|
||||||
where
|
|
||||||
line."notify" = true
|
|
||||||
and twitch."id" = $1
|
|
||||||
and rt."type" = $2`
|
|
||||||
let values = [uid, type]
|
|
||||||
let twch = await c.db.query({
|
|
||||||
text,
|
|
||||||
values
|
|
||||||
})
|
|
||||||
if (twch.rowCount === 0) return
|
|
||||||
|
|
||||||
let chLink = `https://twitch.tv/`
|
|
||||||
|
|
||||||
for (let i in twch.rows) {
|
|
||||||
let tmp = twch.rows[i]
|
|
||||||
let msg = tmp.tmpl || ''
|
|
||||||
let link = chLink + tmp.user
|
|
||||||
if (typeof msg !== 'string' || msg.trim().length === 0) {
|
|
||||||
msg = `${data.title}\n${link}`
|
|
||||||
} else {
|
} else {
|
||||||
msg = msg.replace(/{link}/, link).replace(/{txt}/, data.title).replace(/\\n/, '\n')
|
c.redirect(`${config.url.replace(/\/$/, '')}/web`)
|
||||||
}
|
|
||||||
|
|
||||||
await api.line.pushMessage(tmp.group, msg).then(() => { }).catch(() => { })
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user