Merge branch 'master' of https://git.trj.tw/mtfos/mtfosbot
This commit is contained in:
commit
8b75f41d55
@ -5,6 +5,9 @@ RUN mkdir -p /data
|
||||
WORKDIR /data
|
||||
COPY . .
|
||||
RUN rm -f .env
|
||||
RUN apt-get update -qqy
|
||||
RUN apt-get install -qqy imagemagick graphicsmagick
|
||||
RUN apt-get clean
|
||||
RUN npm install
|
||||
EXPOSE ${NODE_PORT}
|
||||
CMD ["npm", "run", "dbrun"]
|
@ -6,7 +6,8 @@
|
||||
{"file": "20180702-1.sql", "version": 4},
|
||||
{"file": "20180706-1.sql", "version": 5},
|
||||
{"file": "20180710-1.sql", "version": 6},
|
||||
{"file": "20180711-1.sql", "version": 7}
|
||||
{"file": "20180711-1.sql", "version": 7},
|
||||
{"file": "20180712-1.sql", "version": 8}
|
||||
],
|
||||
"test": []
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-unused-expressions */
|
||||
require('module-alias/register')
|
||||
const pg = require('pg')
|
||||
const config = require('../config')
|
||||
const config = require('@config/index')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
port: process.env.NODE_PORT || 10230,
|
||||
url: process.env.HOST_URL || '',
|
||||
image_root: process.env.IMAGE_ROOT || '/image',
|
||||
line: {
|
||||
secret: process.env.LINE_SECRET || '',
|
||||
access: process.env.LINE_ACCESS || ''
|
||||
|
1
index.js
1
index.js
@ -1,3 +1,4 @@
|
||||
require('module-alias/register')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
try {
|
||||
|
11
jsconfig.json
Normal file
11
jsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@libs/*": ["libs/*"],
|
||||
"@config/*": ["config/*"],
|
||||
"@route/*": ["route/*"]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
const axios = require('axios')
|
||||
const config = require('../../config')
|
||||
const config = require('@config/index')
|
||||
const qs = require('querystring')
|
||||
|
||||
const queryYoutubeName = async (id = '') => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const axios = require('axios')
|
||||
const config = require('../../config')
|
||||
const config = require('@config/index')
|
||||
|
||||
const client = axios.create({
|
||||
baseURL: 'https://api.line.me/v2/bot',
|
||||
@ -44,6 +44,16 @@ const textObject = (txt = '') => {
|
||||
}
|
||||
}
|
||||
|
||||
const imageObject = (txt = '') => {
|
||||
if (typeof txt !== 'string' || txt.trim().length === 0) return null
|
||||
txt = txt.split(';')
|
||||
return {
|
||||
type: 'image',
|
||||
originalContentUrl: txt[0],
|
||||
previewImageUrl: txt[1]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* send reply message
|
||||
* @param {string} replyToken line message reply token
|
||||
@ -59,6 +69,7 @@ const replyMessage = async (replyToken, message) => {
|
||||
if (m !== null && m.length > 1) {
|
||||
switch (m[1]) {
|
||||
case 'image':
|
||||
obj = imageObject(message)
|
||||
break
|
||||
case 'text':
|
||||
obj = textObject(message)
|
||||
@ -66,6 +77,8 @@ const replyMessage = async (replyToken, message) => {
|
||||
default:
|
||||
obj = textObject(message)
|
||||
}
|
||||
} else {
|
||||
obj = textObject(message)
|
||||
}
|
||||
|
||||
if (obj !== null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const axios = require('axios')
|
||||
const config = require('../../config')
|
||||
const config = require('@config/index')
|
||||
const client = axios.create({
|
||||
baseURL: 'https://api.twitch.tv/helix',
|
||||
headers: {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const pg = require('pg')
|
||||
const config = require('../config')
|
||||
const config = require('@config/index')
|
||||
|
||||
const pool = new pg.Pool({
|
||||
user: config.database.user,
|
||||
|
@ -1,5 +1,5 @@
|
||||
const api = require('../../../api-action')
|
||||
const DB = require('../../../database')
|
||||
const api = require('@libs/api-action')
|
||||
const DB = require('@libs/database')
|
||||
const axios = require('axios')
|
||||
|
||||
async function run (fn = null, txt, source) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
const DB = require('../../database')
|
||||
const DB = require('@libs/database')
|
||||
const actions = require('./actions')
|
||||
|
||||
const parseCMD = async (text = '', source = {}) => {
|
||||
@ -7,7 +7,8 @@ const parseCMD = async (text = '', source = {}) => {
|
||||
let txt = text.trim()
|
||||
let arr = txt.split(' ').map(t => t.trim())
|
||||
if (arr.length === 0) return null
|
||||
if (arr[0][0] !== '!') return null
|
||||
let cmdMsg = false
|
||||
if (arr[0][0] === '!') cmdMsg = true
|
||||
let cmd = arr[0].replace(/^!/, '')
|
||||
cmd = cmd.toLowerCase()
|
||||
|
||||
@ -16,56 +17,70 @@ const parseCMD = async (text = '', source = {}) => {
|
||||
|
||||
try {
|
||||
// query normal command
|
||||
let result = await db.query({
|
||||
text: `select "message", "group" from "public"."commands" where "cmd" = $1 and ("group" = '' or "group" = $2)`,
|
||||
values: [cmd, source.groupId]
|
||||
})
|
||||
if (result.rowCount > 0) {
|
||||
let obj = result.rows.filter(t => t.group === source.groupId)
|
||||
if (obj.length === 0) obj = result.rows[0]
|
||||
else obj = obj[0]
|
||||
let content = obj.message
|
||||
let m = content.match(/{{(.+?)}}/g)
|
||||
if (m !== null && m.length > 0) {
|
||||
for (let i = 0; i < m.length; i++) {
|
||||
let c = m[i].replace(/^{{/, '').replace(/}}$/, '')
|
||||
let carr = c.split('=')
|
||||
if (carr.length > 1) c = carr
|
||||
let res = await actions(c, arr.slice(1).join(' '), source)
|
||||
content = content.replace(m[i], res || '')
|
||||
if (cmdMsg) {
|
||||
let result = await db.query({
|
||||
text: `select "message", "group" from "public"."commands" where "cmd" = $1 and ("group" = '' or "group" = $2)`,
|
||||
values: [cmd, source.groupId]
|
||||
})
|
||||
if (result.rowCount > 0) {
|
||||
let obj = result.rows.filter(t => t.group === source.groupId)
|
||||
if (obj.length === 0) obj = result.rows[0]
|
||||
else obj = obj[0]
|
||||
let content = obj.message
|
||||
let m = content.match(/{{(.+?)}}/g)
|
||||
if (m !== null && m.length > 0) {
|
||||
for (let i = 0; i < m.length; i++) {
|
||||
let c = m[i].replace(/^{{/, '').replace(/}}$/, '')
|
||||
let carr = c.split('=')
|
||||
if (carr.length > 1) c = carr
|
||||
let res = await actions(c, arr.slice(1).join(' '), source)
|
||||
content = content.replace(m[i], res || '')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (content.trim().length > 0) {
|
||||
reply = {
|
||||
reply: content
|
||||
if (content.trim().length > 0) {
|
||||
reply = {
|
||||
reply: content
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reply === null) {
|
||||
console.log('enter key command')
|
||||
// query keyword commands
|
||||
let keyCMD = await db.query({
|
||||
text: `select "message", "group", "cmd" from "public"."key_commands" where ("group" = '' or "group" = $1)`,
|
||||
text: `select "message", "group", "key" from "public"."key_commands" where ("group" = '' or "group" = $1)`,
|
||||
values: [source.groupId]
|
||||
})
|
||||
console.log(keyCMD.rows)
|
||||
if (keyCMD.rowCount > 0) {
|
||||
let obj = keyCMD.rows.filter(t => t.group === '')
|
||||
let obj2 = keyCMD.rows.filter(t => t.group === source.groupId)
|
||||
obj = obj.map(t => {
|
||||
for (let i of obj2) {
|
||||
if (i.cmd === t.cmd && i.group !== '') return i
|
||||
if (i.key === t.key && i.group !== '') return i
|
||||
}
|
||||
return t
|
||||
})
|
||||
let tmp = obj2.filter(t => {
|
||||
for (let i of obj) {
|
||||
if (i.key === t.key) return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
obj = [...obj, ...tmp]
|
||||
let regex = null
|
||||
let txt = ''
|
||||
console.log('obj ::: ', obj)
|
||||
for (let i of obj) {
|
||||
txt += (txt.length > 0 ? '|' : '') + i.cmd
|
||||
txt += (txt.length > 0 ? '|' : '') + i.key
|
||||
}
|
||||
regex = new RegExp(`(${txt})`)
|
||||
let m = arr.slice(1).join(' ').match(regex)
|
||||
console.log(regex)
|
||||
let m = text.match(regex)
|
||||
console.log('match :::: ', m)
|
||||
if (m !== null && m.length > 0) {
|
||||
let key = obj.filter(t => t.cmd === m[0])
|
||||
let key = obj.filter(t => t.key === m[0])
|
||||
if (key.length > 0) {
|
||||
let content = key[0].message
|
||||
let m = content.match(/{{(.+?)}}/g)
|
||||
@ -74,7 +89,7 @@ const parseCMD = async (text = '', source = {}) => {
|
||||
let c = m[i].replace(/^{{/, '').replace(/}}$/, '')
|
||||
let carr = c.split('=')
|
||||
if (carr.length > 1) c = carr
|
||||
let res = await actions(c, arr.slice(1).join(' '), source)
|
||||
let res = await actions(c, text, source)
|
||||
content = content.replace(m[i], res || '')
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
const commands = require('./commands')
|
||||
const api = require('../api-action')
|
||||
const DB = require('@libs/database')
|
||||
const api = require('@libs/api-action')
|
||||
|
||||
/**
|
||||
* parse text message object
|
||||
|
@ -1,4 +1,4 @@
|
||||
const config = require('../../config')
|
||||
const config = require('@config/index')
|
||||
const rawBody = require('raw-body')
|
||||
const crypto = require('crypto')
|
||||
|
||||
|
@ -17,10 +17,12 @@
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"cron": "^1.3.0",
|
||||
"dotenv": "^6.0.0",
|
||||
"gm": "^1.23.1",
|
||||
"koa": "^2.5.1",
|
||||
"koa-body": "^4.0.3",
|
||||
"koa-logger": "^3.2.0",
|
||||
"koa-router": "^7.4.0",
|
||||
"module-alias": "^2.1.0",
|
||||
"pg": "^7.4.3",
|
||||
"raw-body": "^2.3.3",
|
||||
"request": "^2.87.0",
|
||||
@ -28,5 +30,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"standard": "^11.0.1"
|
||||
},
|
||||
"_moduleAliases": {
|
||||
"@libs": "libs",
|
||||
"@config": "config",
|
||||
"@route": "route"
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ const r = new Router()
|
||||
// const koaBody = require('koa-body')
|
||||
const {
|
||||
getRaw
|
||||
} = require('../../libs/middleware')
|
||||
const api = require('../../libs/api-action')
|
||||
const DB = require('../../libs/database')
|
||||
} = require('@libs/middleware')
|
||||
const api = require('@libs/api-action')
|
||||
const DB = require('@libs/database')
|
||||
|
||||
r.get('/youtube/webhook', async (c, n) => {
|
||||
let db = await DB.connect()
|
||||
|
@ -1,5 +1,103 @@
|
||||
const Router = require('koa-router')
|
||||
const r = new Router()
|
||||
const gm = require('gm')
|
||||
const config = require('@config/index')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const getImageToRes = async (c, n) => {
|
||||
let filepath = path.resolve(config.image_root, c.state.file)
|
||||
console.log(filepath)
|
||||
try {
|
||||
fs.accessSync(filepath)
|
||||
} catch (err) {
|
||||
c.throw(404, 'image not found')
|
||||
}
|
||||
|
||||
let buf = null
|
||||
|
||||
let imgSize = await getImageSize(filepath)
|
||||
if (imgSize === null) c.throw(500)
|
||||
if (c.state.ori === true) {
|
||||
// max 1024x1024
|
||||
if (imgSize.width > 1024 || imgSize.height > 1024) {
|
||||
buf = await resizeImage(filepath, 1024)
|
||||
if (buf === null) c.throw(500)
|
||||
}
|
||||
} else {
|
||||
// max 240x240
|
||||
if (imgSize.width > 240 || imgSize.height > 240) {
|
||||
buf = await resizeImage(filepath, 240)
|
||||
if (buf === null) c.throw(500)
|
||||
}
|
||||
}
|
||||
|
||||
if (buf === null) {
|
||||
let format = await getImageFormat(filepath)
|
||||
if (format === null) c.throw(500)
|
||||
if (format !== 'JPEG') {
|
||||
buf = await convertToJPEG(filepath)
|
||||
if (buf === null) c.throw(500)
|
||||
} else {
|
||||
buf = fs.readFileSync(filepath)
|
||||
}
|
||||
}
|
||||
|
||||
c.type = 'image/jpeg'
|
||||
c.body = buf
|
||||
}
|
||||
|
||||
const convertToJPEG = async (file = null) => {
|
||||
let buf = await new Promise((resolve) => {
|
||||
gm(file).toBuffer('JPEG', (err, buf) => {
|
||||
resolve(err ? null : buf)
|
||||
})
|
||||
})
|
||||
return buf
|
||||
}
|
||||
|
||||
const getImageFormat = async (file = null) => {
|
||||
let format = await new Promise((resolve) => {
|
||||
gm(file).format((err, format) => {
|
||||
resolve(err ? null : format)
|
||||
})
|
||||
})
|
||||
return format
|
||||
}
|
||||
|
||||
const getImageSize = async (file = null) => {
|
||||
let size = await new Promise((resolve) => {
|
||||
gm(file).size((err, val) => {
|
||||
resolve(err ? null : val)
|
||||
})
|
||||
})
|
||||
return size
|
||||
}
|
||||
|
||||
const resizeImage = async (file = null, size = 1024) => {
|
||||
let buf = await new Promise((resolve) => {
|
||||
gm(file).resize(size, size).toBuffer('JPEG', (err, buf) => {
|
||||
resolve(err ? null : buf)
|
||||
})
|
||||
})
|
||||
return buf
|
||||
}
|
||||
|
||||
r.get('/image/origin/:name', async (c, n) => {
|
||||
c.state.ori = true
|
||||
let name = c.params.name || ''
|
||||
if (typeof name !== 'string' || name.trim().length === 0) c.throw('image name not valid', 400)
|
||||
c.state.file = name
|
||||
return n()
|
||||
}, getImageToRes)
|
||||
|
||||
r.get('/image/thumbnail/:name', async (c, n) => {
|
||||
c.state.ori = false
|
||||
let name = c.params.name || ''
|
||||
if (typeof name !== 'string' || name.trim().length === 0) c.throw('image name not valid', 400)
|
||||
c.state.file = name
|
||||
return n()
|
||||
}, getImageToRes)
|
||||
|
||||
r.use('/line', require('./line').routes())
|
||||
r.use('/google', require('./google').routes())
|
||||
|
@ -4,10 +4,10 @@ const r = new Router()
|
||||
const {
|
||||
verifyLine,
|
||||
getRaw
|
||||
} = require('../../libs/middleware')
|
||||
} = require('@libs/middleware')
|
||||
const {
|
||||
textMessage
|
||||
} = require('../../libs/line-message')
|
||||
} = require('@libs/line-message')
|
||||
|
||||
r.post('/', getRaw, verifyLine, async (c, n) => {
|
||||
console.log(JSON.stringify(c.request.body, null, 2))
|
||||
|
@ -2,9 +2,9 @@ const Router = require('koa-router')
|
||||
const r = new Router()
|
||||
const {
|
||||
getRaw
|
||||
} = require('../../libs/middleware')
|
||||
const DB = require('../../libs/database')
|
||||
const api = require('../../libs/api-action')
|
||||
} = require('@libs/middleware')
|
||||
const DB = require('@libs/database')
|
||||
const api = require('@libs/api-action')
|
||||
// const config = require('../../config')
|
||||
|
||||
r.get('/webhook', async (c, n) => {
|
||||
|
Loading…
Reference in New Issue
Block a user