modify database schema

This commit is contained in:
Jay 2018-06-27 17:50:56 +08:00
parent 1f3057df69
commit 99e5a455cb
6 changed files with 347 additions and 50 deletions

View File

@ -10,7 +10,12 @@ new cron.CronJob({ // eslint-disable-line
onTick: async () => {
console.log('run cron')
let db = await DB.connect()
let text = `select "pageid", "groupid", "lastpost", "notify", "notify_tmpl" from "public"."page_group_rt"`
let text = `select line."notify" as notify, fb."id" as id, fb."groupid" as group, fb."pageid" as page, fb."tmpl" as tmpl, fb."lastpost" as post
from "public"."facebook_page" fb
left join "public"."line_group" line
on line."id" = fb."groupid"
where
line."notify" = true`
let res = await db.query({
text
})
@ -19,25 +24,25 @@ new cron.CronJob({ // eslint-disable-line
await new Promise(resolve => {
let count = res.rowCount
res.rows.forEach(t => {
fbParser.getLastPost(t.pageid)
fbParser.getLastPost(t.page)
.then((data) => {
let n = Math.floor(Date.now() / 1000)
if (t.lastpost === data.id || data.time < (n - 10 * 60)) {
if (t.post === data.id || data.time < (n - 10 * 60)) {
if (!--count) resolve(null)
return
}
t.lastpost = data.id
let msg = t.notify_tmpl || ''
t.post = data.id
let msg = t.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')
}
if (t.notify) {
pushMessage(t.groupid, msg).then(() => {}).catch(() => {})
pushMessage(t.group, msg).then(() => {}).catch(() => {})
}
let text = `update "public"."page_group_rt" set "lastpost" = $1, "mtime" = now() where "pageid" = $2 and "groupid" = $3`
let values = [data.id, t.pageid, t.groupid]
let text = `update "public"."facebook_page" set "lastpost" = $1, "mtime" = now() where "id" = $2`
let values = [data.id, t.id]
db.query({
text,
values
@ -52,6 +57,18 @@ new cron.CronJob({ // eslint-disable-line
db.release()
},
runOnInit: true,
start: true,
timeZone: 'Asia/Taipei'
})
// register twitch streaming webhook
new cron.CronJob({ //eslint-disable-line
cronTime: '00 00 0,6,12,18 * * *',
onTick: async () => {
},
runOnInit: true,
start: true,
timeZone: 'Asia/Taipei'
})

View File

@ -51,8 +51,9 @@ const getLastPost = async (pageid = '') => {
let time = timeEl.attr('data-utime')
let link = timeEl.parent().attr('href')
let p = t('div.userContent')
let txt = p.first().text()
let txt = p.text() || ''
let id = p.first().attr('id')
if (!id) {
if (/[\?|&]id\=(\d+)/.test(link)) { // eslint-disable-line
let m = link.match(/[\?|&]story_fbid\=(\d+)/) // eslint-disable-line
@ -64,9 +65,15 @@ const getLastPost = async (pageid = '') => {
if (m !== null && m.length > 1) {
id = m[1]
}
} else if (/\/photos\/.+?\/(\d+)/.test(link)) {
let m = link.match(/\/photos\/.+?\/(\d+)/)
if (m !== null && m.length > 1) {
id = m[1]
}
}
}
if (!time || !link || !txt || !id) return null
console.log(time, link, txt, id)
if (!time || !link || !id) return null
let tmp = {
txt,
id,

View File

@ -0,0 +1,110 @@
/**
* add group to database
* @param {string} txt command body format => groupName notifyEnable(0,1)
* @param {object} source
* @param {object} db
*/
const addGroup = async (txt, source = {}, db) => {
if (!db) return null
if (!('type' in source) || !('groupId' in source) || !('userId' in source)) return null
let {groupId, userId} = source
let arr = txt.split(' ')
if (arr.length < 2 || !isFinite(arr[1])) return null
let name = arr[0]
let notify = arr[1]
if (typeof notify === 'string') notify = parseInt(notify)
if (notify !== 0 && notify !== 1) return null
let text = `select "id" from "public"."line_group" where "id" = $1`
let values = [groupId]
let result = await db.query({
text,
values
})
if (result.rowCount > 0) {
let reply = 'group exists'
return { reply }
}
text = `insert into "public"."line_group" ("id", "name", "notify", "owner", "ctime", "mtime") values ($1, $2, $3, $4, now(), now())`
values = [groupId, name, (notify === 1), userId]
await db.query({
text,
values
})
let reply = 'add success'
return { reply }
}
/**
* add facebook page notify to group
* @param {string} txt command body format => pageid name tmpl
* @param {object} source
* @param {object} db
*/
const addPage = async (txt, source = {}, db) => {
if (!db) return null
if (!('type' in source) || !('groupId' in source) || !('userId' in source)) return null
let {groupId, userId} = source
let arr = txt.split(' ')
if (arr.length < 3) return null
let page = arr[0]
let name = arr[1]
let tmpl = arr.slice(2).join(' ')
let text = `select "id","owner" from "public"."line_group" where "id" = $1`
let values = [groupId]
let result = await db.query({
text,
values
})
if (result.rowCount === 0) {
let reply = 'group not register'
return { reply }
}
if (result.rows[0].owner !== userId) {
let reply = 'not owner'
return { reply }
}
// check pageid in group
text = `select fb."id" from "public"."facebook_page" fb
left join "public"."line_group" line
on fb."groupid" = line."id"
where
fb."pageid" = $1`
values = [page]
result = await db.query({
text,
values
})
if (result.rowCount > 0) {
let reply = 'page exists'
return { reply }
}
// check page name in group
text = `select fb."id" from "public"."facebook_page" fb
left join "public"."line_group" line
on fb."groupid" = line."id"
where
fb."name" = $1`
values = [name]
result = await db.query({
text,
values
})
if (result.rowCount > 0) {
let reply = 'page name exists'
return { reply }
}
text = `insert into "public"."facebook_page" ("groupid", "pageid", "name", "tmpl", "ctime", "mtime") values
($1, $2, $3, $4, now(), now())`
values = [groupId, page, name, tmpl]
await db.query({
text,
values
})
let reply = 'add page success'
return { reply }
}
module.exports = {
addgroup: addGroup,
addpage: addPage
}

View File

@ -0,0 +1,31 @@
const DB = require('../../database')
const groupCMD = require('./group')
const cmds = {}
for (let i in groupCMD) {
cmds[i] = groupCMD[i]
}
const parseCMD = async (text = '', source = {}) => {
if (typeof text !== 'string' || text.trim().length === 0) return null
if (!source || typeof source !== 'object' || !('type' in source)) return null
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 cmd = arr[0].replace(/^!/, '')
if (!(cmd in cmds)) return null
let db = await DB.connect()
let result = null
try {
result = await cmds[cmd](arr.slice(1).join(' '), source, db)
} catch (err) {
console.log(err)
}
// if (result === null) return null
db.release()
return result
}
module.exports = parseCMD

View File

@ -1,6 +1,6 @@
const axios = require('axios')
const config = require('../../config')
const DB = require('../database')
const commands = require('./commands')
const client = axios.create({
baseURL: 'https://api.line.me/v2/bot',
@ -33,31 +33,34 @@ const pushMessage = async (target, message = '') => {
}
const textMessage = async (evt) => {
let replyURL = '/message/reply'
let url = '/message/reply'
let {replyToken, source, message} = evt
if (!source || !('type' in source) || source.type !== 'group') return
if (!message || message.type !== 'text') return
let {text} = message
if (typeof text !== 'string') return
text = text.trim()
if (text.length === 0) return
let db = await DB.connect()
// let opts = {
// method: 'post',
// url: replyURL,
// data: {
// replyToken,
// messages: [
// {
// type: 'text',
// text: 'test message'
// }
// ]
// }
// }
let result = await commands(text, source)
if (result === null) return
if (typeof result === 'object' && 'reply' in result) {
let opts = {
method: 'post',
url,
data: {
replyToken,
messages: [
{
type: 'text',
text: result.reply
}
]
}
}
// await client(opts)
db.release()
await client(opts)
}
}
module.exports = {

View File

@ -2,23 +2,33 @@
-- PostgreSQL database dump
--
-- Dumped from database version 10.2 (Debian 10.2-1.pgdg90+1)
-- Dumped by pg_dump version 10.2 (Debian 10.2-1.pgdg90+1)
-- Dumped from database version 9.6.8
-- Dumped by pg_dump version 9.6.8
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
SET search_path = public, pg_catalog;
ALTER TABLE IF EXISTS ONLY public.page_group_rt DROP CONSTRAINT IF EXISTS page_group_rt_pageid_groupid_pk;
ALTER TABLE IF EXISTS ONLY public.twitch_channel DROP CONSTRAINT IF EXISTS twitch_channel_line_group_id_fk;
ALTER TABLE IF EXISTS ONLY public.facebook_page DROP CONSTRAINT IF EXISTS facebook_page_line_group_id_fk;
DROP INDEX IF EXISTS public.line_group_name_uindex;
ALTER TABLE IF EXISTS ONLY public.twitch_channel DROP CONSTRAINT IF EXISTS twitch_channel_pkey;
ALTER TABLE IF EXISTS ONLY public.line_group DROP CONSTRAINT IF EXISTS line_group_pkey;
ALTER TABLE IF EXISTS ONLY public.facebook_page DROP CONSTRAINT IF EXISTS facebook_page_pkey;
ALTER TABLE IF EXISTS public.twitch_channel ALTER COLUMN id DROP DEFAULT;
ALTER TABLE IF EXISTS public.facebook_page ALTER COLUMN id DROP DEFAULT;
DROP TABLE IF EXISTS public.version_ctrl;
DROP TABLE IF EXISTS public.page_group_rt;
DROP SEQUENCE IF EXISTS public.twitch_channel_id_seq;
DROP TABLE IF EXISTS public.twitch_channel;
DROP TABLE IF EXISTS public.line_group;
DROP SEQUENCE IF EXISTS public.facebook_page_id_seq;
DROP TABLE IF EXISTS public.facebook_page;
DROP EXTENSION IF EXISTS plpgsql;
DROP SCHEMA IF EXISTS public;
--
@ -49,44 +59,163 @@ CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: page_group_rt; Type: TABLE; Schema: public; Owner: -
-- Name: facebook_page; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE page_group_rt (
CREATE TABLE public.facebook_page (
id integer NOT NULL,
groupid character varying(100) NOT NULL,
pageid character varying(200) NOT NULL,
groupid character varying(200) NOT NULL,
notify boolean DEFAULT false NOT NULL,
lastpost character varying(200) DEFAULT ''::character varying NOT NULL,
ctime timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
mtime timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
notify_tmpl character varying(500) DEFAULT ''::character varying NOT NULL
name character varying(100) NOT NULL,
lastpost character varying(100) DEFAULT ''::character varying NOT NULL,
tmpl character varying(200) DEFAULT ''::character varying NOT NULL,
ctime timestamp with time zone DEFAULT now() NOT NULL,
mtime timestamp with time zone DEFAULT now() NOT NULL
);
--
-- Name: facebook_page_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.facebook_page_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: facebook_page_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.facebook_page_id_seq OWNED BY public.facebook_page.id;
--
-- Name: line_group; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.line_group (
id character varying(100) NOT NULL,
name character varying(200) NOT NULL,
notify boolean DEFAULT false NOT NULL,
ctime timestamp with time zone DEFAULT now() NOT NULL,
mtime timestamp with time zone DEFAULT now() NOT NULL,
owner character varying(100) DEFAULT ''::character varying NOT NULL
);
--
-- Name: twitch_channel; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.twitch_channel (
id integer NOT NULL,
twitchid character varying(100) NOT NULL,
name character varying(200) NOT NULL,
type character varying(100) DEFAULT ''::character varying NOT NULL,
ctime timestamp with time zone DEFAULT now() NOT NULL,
mtime timestamp with time zone DEFAULT now() NOT NULL,
groupid character varying(100) NOT NULL
);
--
-- Name: twitch_channel_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.twitch_channel_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: twitch_channel_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.twitch_channel_id_seq OWNED BY public.twitch_channel.id;
--
-- Name: version_ctrl; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE version_ctrl (
CREATE TABLE public.version_ctrl (
version integer NOT NULL,
ctime timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
querystr character varying(5000) DEFAULT ''::character varying NOT NULL
ctime timestamp with time zone DEFAULT now() NOT NULL,
querystr text DEFAULT ''::character varying NOT NULL
);
--
-- Name: page_group_rt page_group_rt_pageid_groupid_pk; Type: CONSTRAINT; Schema: public; Owner: -
-- Name: facebook_page id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY page_group_rt
ADD CONSTRAINT page_group_rt_pageid_groupid_pk PRIMARY KEY (pageid, groupid);
ALTER TABLE ONLY public.facebook_page ALTER COLUMN id SET DEFAULT nextval('public.facebook_page_id_seq'::regclass);
--
-- Name: twitch_channel id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.twitch_channel ALTER COLUMN id SET DEFAULT nextval('public.twitch_channel_id_seq'::regclass);
--
-- Name: facebook_page facebook_page_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.facebook_page
ADD CONSTRAINT facebook_page_pkey PRIMARY KEY (id);
--
-- Name: line_group line_group_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.line_group
ADD CONSTRAINT line_group_pkey PRIMARY KEY (id);
--
-- Name: twitch_channel twitch_channel_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.twitch_channel
ADD CONSTRAINT twitch_channel_pkey PRIMARY KEY (id);
--
-- Name: line_group_name_uindex; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX line_group_name_uindex ON public.line_group USING btree (name);
--
-- Name: facebook_page facebook_page_line_group_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.facebook_page
ADD CONSTRAINT facebook_page_line_group_id_fk FOREIGN KEY (groupid) REFERENCES public.line_group(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: twitch_channel twitch_channel_line_group_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.twitch_channel
ADD CONSTRAINT twitch_channel_line_group_id_fk FOREIGN KEY (groupid) REFERENCES public.line_group(id);
--