diff --git a/CPBLClass.js b/CPBLClass.js index 3277abb..a8b594a 100644 --- a/CPBLClass.js +++ b/CPBLClass.js @@ -2,11 +2,13 @@ const dateFormat = require('dateformat'); const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; const schedule = require('node-schedule'); const { decode } = require('querystring'); +const LINENotifyClass = require('../api/LINENotifyClass'); /** CPBL */ class CPBLClass { constructor(app) { this.app = app; + this.LINENotify = new LINENotifyClass(); this.TimeList = []; // var rule = new schedule.RecurrenceRule(); // // rule.minute = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]; @@ -33,24 +35,25 @@ class CPBLClass { } async AddTime(Data, event) { - let game_id = Data["game_id"]; - let cpbldata = Data["cpbldata"]; + let replyMsg = ""; + let GameSno = Data["GameSno"]; let LineID = Data["LineID"]; + let access_token = Data["access_token"]; - let Isgame_id = false; - let IsLineID = false; + let IsHaveGameSno = false; + let IsHaveLineID = false; let Time = { - game_id: game_id, - cpbldata: cpbldata, - LineID: [LineID] + GameSno: GameSno, + LineID: [LineID], + access_token: [access_token] } for (let i = 0; i < this.TimeList.length; i++) { - if (this.TimeList[i]["game_id"] === game_id) { - Isgame_id = true; + if (this.TimeList[i]["GameSno"] === GameSno) { + IsHaveGameSno = true; Time = this.TimeList[i]; for (let j = 0; j < this.TimeList[i]["LineID"].length; j++) { if (this.TimeList[i]["LineID"][j] === LineID) { - IsLineID = true; + IsHaveLineID = true; break; } } @@ -58,37 +61,46 @@ class CPBLClass { } } let IsRUN = true; - let Response = await this.GetCPBL(Time); - if (Response[Response.length - 1]["title"].indexOf("比賽結束") !== -1) { + let Response = await this.GetCPBL(GameSno); + if (Response === "比賽尚未開始" || Response[Response.length - 1].indexOf("比賽結束") !== -1) { IsRUN = false; } - let replyMsg = ""; - for (let i = 0; i < Response.length; i++) { - replyMsg += Response[i]["title"]; - if (i !== Response.length - 1) { - replyMsg += "\n\n"; + if (Response === "比賽尚未開始") { + // await this.LINENotify.Send(access_token, Response); + } else { + let PushMsg = ""; + for (let i = 0; i < Response.length; i++) { + let ThisPushMsg = Response[i]; + if (PushMsg.length + ThisPushMsg.length > 1000) { + // await this.LINENotify.Send(access_token, PushMsg); + PushMsg = ThisPushMsg; + } else { + PushMsg += ThisPushMsg; + } } + // await this.LINENotify.Send(access_token, PushMsg); } if (IsRUN) { - if (!Isgame_id) { + if (!IsHaveGameSno) { // 沒有這場賽事 if (this.TimeList.length === 0) { this.StartTime(); } this.TimeList.push(Time); - } else if (Isgame_id && !IsLineID) { + } else if (IsHaveGameSno && !IsHaveLineID) { // 有這場賽事但沒這個帳號 Time["LineID"].push(LineID); + Time["access_token"].push(access_token); } let Extra = { - cpbldata: cpbldata, + GameSno: GameSno, count: Response.length } let datetime = dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss"); let Query = `UPDATE \`line-cost-status\` SET \`datetime\`='${datetime}', \`Status\`='CPBL RUN', \`Extra\`='${JSON.stringify(Extra)}' WHERE (\`userid\`='${LineID}');`; let res_Query = await this.app.Tools_MYSQLDB.Query(Query); } else { - replyMsg += "\n\n已停止中職轉播功能"; + replyMsg = "已停止中職轉播功能"; } if (event) { event.reply(replyMsg).then(function (data) { @@ -100,7 +112,7 @@ class CPBLClass { } StartTime() { - // var rule = '0 1 * * * *'; + // var rule = '2 * * * * *'; // * * * * * * // ┬ ┬ ┬ ┬ ┬ ┬ // │ │ │ │ │ | @@ -111,6 +123,12 @@ class CPBLClass { // │ └──────────── 分,取值:0 - 59 // └─────────────── 秒,取值:0 - 59(可选) var rule = new schedule.RecurrenceRule(); + // rule.date = "*"; + // rule.dayOfWeek = "*"; + // rule.hour = "*"; + // rule.minute = "*"; + // rule.year = "*"; + // rule.month = "*"; let minute = 2; let minute_arr = []; for (let i = 0; i < 60; i++) { @@ -118,28 +136,33 @@ class CPBLClass { minute_arr.push(i); } } - rule.minute = minute_arr; + + rule.second = new schedule.Range(0, 59, 2); + // rule.minute = minute_arr; // rule.second = [0]; // rule.second = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]; - // console.log(`設定任務 每${JSON.stringify(rule.minute)}分鐘 現在時間: ` + dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss")); - // console.log(`設定任務 每${JSON.stringify(rule.second)}秒鐘 現在時間: ` + dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss")); - this.Timer = schedule.scheduleJob(rule, this.Update.bind(this)); + // console.log(`設定任務 每${minute}分鐘 現在時間: ` + dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss")); + console.log(`設定任務 每${minute}秒鐘 現在時間: ` + dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss")); + // this.Timer = schedule.scheduleJob(rule, this.Update.bind(this)); + this.Timer = schedule.scheduleJob(rule, () => { + console.log(`現在時間: ${dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss")}`); + }); } CloseTime() { this.Timer.cancel(); } - async GetCPBL(Time) { - let game_id = Time["game_id"]; - let cpbldata = Time["cpbldata"]; - let LineID = Time["LineID"]; - let url = "https://jianmiau.ml:3333/CPBL"; + async GetCPBL(GameSno) { let Data = { - URL: `http://www.cpbl.com.tw/games/play_by_play.html?&game_type=${cpbldata["game_type"]}&game_id=${cpbldata["game_id"]}&game_date=${cpbldata["game_date"]}&pbyear=${cpbldata["pbyear"]}` + GameSno: GameSno, + KindCode: "A", + Year: dateFormat(new Date(), "yyyy") }; + let url = "https://jianmiau.ml:3333/CPBL"; let Response = await this.GetData(url, Data); - Response = [].concat.apply([], JSON.parse(Response)); + Response = JSON.parse(Response); + // Response = [].concat.apply([], JSON.parse(Response)); return new Promise((resolve, reject) => { // 傳入 resolve 與 reject,表示資料成功與失敗 resolve(Response); @@ -159,17 +182,12 @@ class CPBLClass { } async RunTime(Time) { - let game_id = Time["game_id"]; - let cpbldata = Time["cpbldata"]; + let GameSno = Time["GameSno"]; let LineID = Time["LineID"]; - let url = "https://jianmiau.ml:3333/CPBL"; - let Data = { - URL: `http://www.cpbl.com.tw/games/play_by_play.html?&game_type=${cpbldata["game_type"]}&game_id=${cpbldata["game_id"]}&game_date=${cpbldata["game_date"]}&pbyear=${cpbldata["pbyear"]}` - }; - let Response = await this.GetData(url, Data); - Response = [].concat.apply([], JSON.parse(Response)); + let access_token = Time["access_token"]; + let Response = await this.GetCPBL(GameSno); let IsRUN = true; - if (Response[Response.length - 1]["title"].indexOf("比賽結束") !== -1 || Response[Response.length - 1]["title"].indexOf("final") !== -1) { + if (Response === "比賽尚未開始" || Response[Response.length - 1].indexOf("比賽結束") !== -1) { IsRUN = false; } for (let i = 0; i < LineID.length; i++) { @@ -179,19 +197,23 @@ class CPBLClass { let Status = Data[0]['Status']; if (Status === "CPBL RUN") { let Extra = JSON.parse(Data[0]["Extra"]); - let cpbldata = Extra["cpbldata"]; + let GameSno = Extra["GameSno"]; let count = Extra["count"]; if (Response.length > count) { - let replyMsg = ""; - for (let j = count; j < Response.length; j++) { - replyMsg += Response[j]["title"]; - if (j !== Response.length - 1) { - replyMsg += "\n\n"; + let PushMsg = ""; + for (let i = count; i < Response.length; i++) { + let ThisPushMsg = Response[i]; + if (PushMsg.length + ThisPushMsg.length > 1000) { + await this.LINENotify.Send(access_token, PushMsg); + PushMsg = ThisPushMsg; + } else { + PushMsg += ThisPushMsg; } } + await this.LINENotify.Send(access_token, PushMsg); if (IsRUN) { let Extra = { - cpbldata: cpbldata, + GameSno: GameSno, count: Response.length } let datetime = dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss"); @@ -201,9 +223,10 @@ class CPBLClass { let datetime = dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss"); let Query = `UPDATE \`line-cost-status\` SET \`datetime\`='${datetime}', \`Status\`='', \`Extra\`='' WHERE (\`userid\`='${LineID[i]}');`; let res_Query = await this.app.Tools_MYSQLDB.Query(Query); - replyMsg += "\n\n已停止中職轉播功能"; + PushMsg = "已停止中職轉播功能"; + let res_Msg = this.app.bot.push(LineID[i], PushMsg); } - let res_Msg = this.app.bot.push(LineID[i], replyMsg); + // await this.LINENotify.Send(access_token, PushMsg); } } } @@ -212,13 +235,14 @@ class CPBLClass { } } - async GetCPBLList(Date) { + async GetCPBLList(DateTime, access_token) { // let game_id = Time["game_id"]; // let cpbldata = Time["cpbldata"]; // let LineID = Time["LineID"]; let url = "https://jianmiau.ml:3333/CPBLList"; let Data = { - Date: Date + today: DateTime + // today: "2021-09-26" }; let Response = await this.GetData(url, Data); Response = [].concat.apply([], JSON.parse(Response)); @@ -227,36 +251,35 @@ class CPBLClass { let img = []; let team = []; let data = ""; - let href = Response[i]["href"]; - for (let j = 1; j <= 2; j++) { - if (Response[i][`img${j}`].indexOf("AJL011_logo_01") !== -1) { - img.push("https://jianmiau.ml/MyWeb/Resources/CPBL/R.png"); - team.push("樂天桃猿"); - } else if (Response[i][`img${j}`].indexOf("B04_logo_01") !== -1) { - img.push("https://jianmiau.ml/MyWeb/Resources/CPBL/F.png"); - team.push("富邦悍將"); - } else if (Response[i][`img${j}`].indexOf("D01_logo_01") !== -1) { - img.push("https://jianmiau.ml/MyWeb/Resources/CPBL/D.png"); - team.push("味全龍"); - } else if (Response[i][`img${j}`].indexOf("E02_logo_01") !== -1) { - img.push("https://jianmiau.ml/MyWeb/Resources/CPBL/B.png"); - team.push("中信兄弟"); - } else if (Response[i][`img${j}`].indexOf("L01_logo_01") !== -1) { - img.push("https://jianmiau.ml/MyWeb/Resources/CPBL/L.png"); - team.push("統一獅"); - } + let game = Response[i]; + let info = { + "樂天桃猿": { + img: "https://jianmiau.ml/MyWeb/Resources/CPBL/R.png" + }, + "富邦悍將": { + img: "https://jianmiau.ml/MyWeb/Resources/CPBL/F.png" + }, + "味全龍": { + img: "https://jianmiau.ml/MyWeb/Resources/CPBL/D.png" + }, + "中信兄弟": { + img: "https://jianmiau.ml/MyWeb/Resources/CPBL/B.png" + }, + "統一7-ELEVEn獅": { + img: "https://jianmiau.ml/MyWeb/Resources/CPBL/L.png" + }, } - if (href["time"]) { - data = `action=nogame&game_type=${href["game_type"]}&game_id=${href["game_id"]}&game_date=${href["game_date"]}&pbyear=${href["game_date"].substr(0, 4)}&time=${href["time"]}`; - } else { - data = `action=hasgame&game_type=${href["game_type"]}&game_id=${href["game_id"]}&game_date=${href["game_date"]}&pbyear=${href["game_date"].substr(0, 4)}`; - } - let url = `http://www.cpbl.com.tw/games/play_by_play.html?&game_type=${href["game_type"]}&game_id=${href["game_id"]}&game_date=${href["game_date"]}&pbyear=${href["game_date"].substr(0, 4)}`; + let url = `https://karolchang.github.io/cpbl-vue/#/record/${game.GameSno}/A/2021`; + let gametime = game.PreExeDate.split("T"); + // let nowUNIXtime = Date.now(); + // let gameUNIXtime = new Date(`${gametime[0]} ${gametime[1]}`).getTime(); + // let IsStart = nowUNIXtime - gameUNIXtime > 0; + data = `action=hasgame&game_date=${gametime[0]}&time=${gametime[1]}&GameSno=${game.GameSno}&access_token=${access_token}`; let Data_columns = { - "thumbnailImageUrl": img[0], + "thumbnailImageUrl": info[game.HomeTeamName].img, "imageBackgroundColor": "#FFFFFF", - "title": `${team[0]} VS ${team[1]}`, - "text": `比賽場地 ${Response[i]["address"]} ${href["game_date"]}`, + "title": `${game.VisitingTeamName} VS ${game.HomeTeamName}`, + "text": `比賽場地 ${game.FieldAbbe} ${gametime[0]} ${gametime[1]}`, "defaultAction": { "type": "uri", "label": "比賽網站", @@ -264,6 +287,9 @@ class CPBLClass { }, "actions": [ { + // "type": "uri", + // "label": "比賽網站", + // "uri": url "type": "postback", "label": "追蹤比賽", "data": data @@ -319,6 +345,37 @@ class CPBLClass { }); } + async CPBLBind(Date) { + let url = `https://notify-bot.line.me/oauth/authorize?response_type=code&scope=notify&response_mode=form_post&client_id=Jj4K1D7XxtmDeXJGF3c0vV&redirect_uri=https://jianmiau.ml:3333/LINENotify&state=${userId}$${displayName}`; + let shorturl = await this.Tools.shorturl(url); + let Data_columns = [ + { + "thumbnailImageUrl": "https://www.line-community.me/awards/uimage/5b46aedf851f74a6af8eaab8", + "imageBackgroundColor": "#FFFFFF", + "title": "點擊綁定", + "text": "點擊後將會進行綁定", + "defaultAction": { + "type": "uri", + "label": "點擊綁定", + "uri": shorturl + }, + "actions": [ + { + "type": "uri", + "label": "點擊綁定", + "uri": shorturl + } + ] + } + ]; + + return new Promise((resolve, reject) => { + // 傳入 resolve 與 reject,表示資料成功與失敗 + resolve(Data_columns); + // reject() + }); + } + /** * 取得表 * @param Url Url diff --git a/MessageClass.js b/MessageClass.js index a2b629e..ada44db 100644 --- a/MessageClass.js +++ b/MessageClass.js @@ -1,10 +1,12 @@ const dateFormat = require('dateformat'); const { decode } = require('querystring'); +const ToolsClass = require('./ToolsClass'); /** Message */ class MessageClass { constructor(app) { this.app = app; + this.Tools = new ToolsClass(); // this.app.CPBL.AddTime({ // game_id: 64, // cpbldata: { @@ -140,23 +142,41 @@ class MessageClass { } case "中職": { - let URL = Msg[1]; - let Isplay_by_play = URL.indexOf("play_by_play"); - let data = decode(URL); - if (Isplay_by_play === -1 || !data["game_id"]) { + // let URL = Msg[1]; + // let Isplay_by_play = URL.indexOf("play_by_play"); + // let data = decode(URL); + // if (Isplay_by_play === -1 || !data["game_id"]) { + // return; + // } + // this.app.CPBL.AddTime({ + // game_id: data["game_id"], + // cpbldata: data, + // LineID: userId + // }, event); + + let GameSno = Msg[1]; + if (!GameSno) { return; } + let Query = `SELECT UserData.LINENotify FROM \`UserData\` WHERE \`userId\` = '${userId}' LIMIT 1;`; + let res_Query = await this.app.Tools_MYSQLDB.Query(Query); + let access_token = res_Query[0]["LINENotify"]; this.app.CPBL.AddTime({ - game_id: data["game_id"], - cpbldata: data, - LineID: userId + GameSno: GameSno, + LineID: userId, + access_token: access_token }, event); + // replyMsg = await this.app.CPBL.GetCPBL1(userId, GameSno); + // event.reply(replyMsg) return; } case "今日賽事": case "我愛建喵今日賽事": { - let columns = await this.app.CPBL.GetCPBLList(Msg[1] ? Msg[1] : dateFormat(new Date(), "yyyymmdd")); + let Query = `SELECT UserData.LINENotify FROM \`UserData\` WHERE \`userId\` = '${userId}' LIMIT 1;`; + let res_Query = await this.app.Tools_MYSQLDB.Query(Query); + let access_token = res_Query[0]["LINENotify"]; + let columns = await this.app.CPBL.GetCPBLList(Msg[1] ? Msg[1] : dateFormat(new Date(), "yyyy-mm-dd"), access_token); if (columns.length > 0) { let res_reply = event.replyimagemap("建喵也愛你", columns).then(function (data) { // 當訊息成功回傳後的處理 @@ -176,6 +196,39 @@ class MessageClass { return; } + case "CPBL綁定": { + let url = `https://notify-bot.line.me/oauth/authorize?response_type=code&scope=notify&response_mode=form_post&client_id=Jj4K1D7XxtmDeXJGF3c0vV&redirect_uri=https://jianmiau.ml:3333/LINENotify&state=${userId}$${displayName}`; + let shorturl = await this.Tools.shorturl(url); + let Data_columns = [ + { + "thumbnailImageUrl": "https://www.line-community.me/awards/uimage/5b46aedf851f74a6af8eaab8", + "imageBackgroundColor": "#FFFFFF", + "title": "點擊綁定", + "text": "點擊後將會進行綁定", + "defaultAction": { + "type": "uri", + "label": "點擊綁定", + "uri": shorturl + }, + "actions": [ + { + "type": "uri", + "label": "點擊綁定", + "uri": shorturl + } + ] + } + ]; + event.replyimagemap("點擊綁定", Data_columns) + .then(function (data) { + // 當訊息成功回傳後的處理 + }) + .catch(function (error) { + // 當訊息回傳失敗後的處理 + }); + return; + } + default: { let Query = `SELECT * FROM \`line-cost-status\` WHERE \`userId\` = '${userId}' LIMIT 1;`; let res_Query = await this.app.Tools_MYSQLDB.Query(Query); diff --git a/PostbackClass.js b/PostbackClass.js index 27dbb89..ca98ef9 100644 --- a/PostbackClass.js +++ b/PostbackClass.js @@ -11,11 +11,6 @@ class PostbackClass { let action = event.postback.data; let data = decode(action); switch (data["action"]) { - case 'nogame': { - this.NoGame(event, data); - break; - } - case 'hasgame': { this.HasGame(event, data); break; @@ -26,23 +21,22 @@ class PostbackClass { } } - NoGame(event, data) { - let replyMsg = `比賽還沒開始\n時間是${data["game_date"]} ${data["time"]}`; - if (event) { - event.reply(replyMsg).then(function (data) { - // 當訊息成功回傳後的處理 - }).catch(function (error) { - // 當訊息回傳失敗後的處理 - }); - } - } - HasGame(event, data) { - this.app.CPBL.AddTime({ - game_id: data["game_id"], - cpbldata: data, - LineID: event.source.userId - }, event); + let game_date = data["game_date"]; + let time = data["time"]; + let nowUNIXtime = Date.now(); + let gameUNIXtime = new Date(`${game_date} ${time}`).getTime(); + let IsStart = nowUNIXtime - gameUNIXtime > 0; + if (IsStart) { + this.app.CPBL.AddTime({ + GameSno: data["GameSno"], + access_token: data["access_token"], + LineID: event.source.userId + }, event); + } else { + let replyMsg = `比賽還沒開始\n時間是${game_date} ${time}`; + event.reply(replyMsg); + } } } diff --git a/ToolsClass.js b/ToolsClass.js new file mode 100644 index 0000000..57b0874 --- /dev/null +++ b/ToolsClass.js @@ -0,0 +1,37 @@ + +const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; + +/** ToolsClass */ +class ToolsClass { + // constructor() { + // } + + /** + * shorturl + * @param url url + */ + shorturl(url) { + return new Promise((resolve, reject) => { + var xhr = new XMLHttpRequest(); + xhr.withCredentials = true; + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status >= 200 && xhr.status < 400) { + var response = JSON.parse(xhr.responseText); + resolve(response.link); + } + } + }; + xhr.open("POST", "https://api-ssl.bitly.com/v4/shorten"); + xhr.setRequestHeader("Authorization", "Bearer 88188dfe42e71c8da237fd49ffe5979d0fc69bd6"); + xhr.setRequestHeader("Content-Type", "application/json"); + let encodedData = JSON.stringify({ + "long_url": url, + "domain": "bit.ly" + }); + xhr.send(encodedData); + }); + } +} + +module.exports = ToolsClass \ No newline at end of file diff --git a/Tools_MYSQLDBClass.js b/Tools_MYSQLDBClass.js index e6c124b..a2a2c04 100644 --- a/Tools_MYSQLDBClass.js +++ b/Tools_MYSQLDBClass.js @@ -6,7 +6,8 @@ class Tools_MYSQLDBClass { constructor() { let datetime = dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss"); let config = { - host: 'jianmiau.tk', + // host: 'jianmiau.tk', + host: '192.168.168.15', user: 'jianmiau', password: 'VQ*ZetC7xcc9%dTW', database: 'line-cost-php', diff --git a/app.js b/app.js index 75563c6..edbb7c5 100644 --- a/app.js +++ b/app.js @@ -4,6 +4,8 @@ // npm run dev // Debug nodemon --inspect=192.168.168.15:9229 app.js +// git clone ssh://JianMiau@192.168.168.15:1922/volume1/github/line-cost-js + const dateFormat = require('dateformat'); require('dotenv').config() // require("./plug/DateFormat"); @@ -12,9 +14,9 @@ var linebot = require('linebot'); const fs = require('fs'); //讀取憑證及金鑰 -const prikey = fs.readFileSync('privkey.pem', 'utf8'); -const cert = fs.readFileSync('cert.pem', 'utf8'); -const cafile = fs.readFileSync('chain.pem', 'utf-8'); +const prikey = fs.readFileSync('../certificate/privkey.pem', 'utf8'); +const cert = fs.readFileSync('../certificate/cert.pem', 'utf8'); +const cafile = fs.readFileSync('../certificate/chain.pem', 'utf-8'); //建立憑證及金鑰 const credentials = { @@ -41,36 +43,4 @@ const LineBotAPI = require('./LineBotClass'); const path = process.env.URLPATH || "/"; const port = process.env.PORT || 3001; -new LineBotAPI(path, port, credentials, bot, JianMiaubot); - -// // 當有人傳送訊息給Bot時 -// bot.on('event', function (event) { -// switch (event.type) { -// case 'message': { -// Message.Message(event); -// break; -// } - -// case 'postback': { -// Postback.Postback(this, event); -// break; -// } - -// case 'join': -// case 'leave': -// case 'follow': -// case 'unfollow': -// case 'memberJoin': -// case 'memberLeave': -// case 'accountLink': -// case 'fallback': -// default: -// break; -// } -// }); -// bot.listen(path, port, credentials, function () { -// let datetime = dateFormat(new Date(), "yyyy-mm-dd HH:MM:ss"); -// console.log(`${datetime} listening on ${port}`); -// console.log(`${datetime} [BOT已準備就緒]`); -// // Tools_MYSQLDB.readData(); -// }); \ No newline at end of file +new LineBotAPI(path, port, credentials, bot, JianMiaubot); \ No newline at end of file diff --git a/package.json b/package.json index 17c2215..e390883 100644 --- a/package.json +++ b/package.json @@ -22,4 +22,4 @@ "keywords": [], "author": "", "license": "ISC" -} \ No newline at end of file +}