嗨~ 各位肥宅同袍,我是Robin。
咳咳嗯~
這篇要分享上次肥宅的第一步後續,
還沒看的可以先回去看看,裡面有這次小專案的故事背景動機,
來了各位!
經過我內心非常積極但實際行動緩慢的這一兩週時間,
沒日沒夜的研究,終於先寫出一個過渡品,
至少能滿足現在我的需求。
實際上其實這兩週睡得很好xDD,然後前幾天同事約我去吃麥當勞,
我還是沒有優惠券用 TAT
於是在這兩天努力寫出來xDD
更新一下現況
一次解決了上篇的打 API 延遲和 Heroku 的機器休眠。然後我是用 ec2 免費套餐所以管控好使用方式基本上是不會造成費用的,像我就是設定 如果超過 0.5 美金就寄信提醒我。
(超級客家做法
就因為時不時要與同事增進感情吃麥當勞,沒有優惠券整個就不對了,所以先行實施自肥計畫,長遠的就持續更新囉。
這篇目標也只有一個,每天自動領取並且通知我領到什麼。
這目前只是我個人想做的專案,如果我構思上不夠完整或是有更好的方式,可以在下面留言跟我交流,身為小菜雞的我一定會努力盡我所能的學習,感恩。
如果你也是小菜雞,也可以跟我提出你疑問 :+1:
如果我回答不出來太艱深的問題是很正常的~
因為~~~
打 API 開始自動領取
Line Notify 主動通知
至官方登入 點我連結
申請權杖(Token)
申請傳送至1對1聊天室,並設定名稱(我這邊就亂取叫油光降臨)
拿取 Token
測試 token 能否發送訊息
curl --request POST \
--url https://notify-api.line.me/api/notify \
--header 'authorization: Bearer <yourToken>'
--form 'message=Test'
一樣我不會一一解釋,但是我會說明寫的時候的目的和想法。
如果有疑問可以底下留言(搞不好只是我單純犯蠢 xD。
目的只有一個,就是增加一個 Endpont 目的就是自動領取。
增加以下內容
const subscriptionRouter = require('./routes/subscriptionRouter');
app.use('/api/subscription', subscriptionRouter);
增加以下內容,進來之後到 subscriptionController
const express = require('express');
const subscriptionController = require('../controllers/subscriptionController');
const router = express.Router();
router.post('/', subscriptionController);
module.exports = router;
這邊目的就是接收 request
的內容並且傳遞給呼叫寫好的排程 model ,並回傳結果和排程的名稱。
const subscription = require('../models/subscription.js');
module.exports = async (req, res) => {
const resp = await subscription(
req.body.accessToken,
req.body.lineNotifiyToken,
req.body.cronFormat,
);
res.status(200);
await res.json({
name: resp.name,
message: 'success',
});
};
這部分會有兩個
這邊就是單純寫一個你給我 token 和訊息內容我就幫你打出去~
const { postRequest } = require('./request');
module.exports = async (messageContent, lineNotifiyToken) => {
const options = {
url: 'https://notify-api.line.me/api/notify',
headers: {
'content-type': 'multipart/form-data',
authorization: `Bearer ${lineNotifiyToken}`,
},
formData: { message: messageContent },
};
const resp = await postRequest(options);
return resp;
};
這邊主要是使用人家寫好的 module -> node-schedule
基本上這邊邏輯就是打進來開始設定排程,時間是依照 cron format,
我這邊預設的 .env
檔案會設定以下,預設是每天的 00:01:00
。
CRON_FORMAT = '1 0 * * *'
如果拿優惠券 status code
或是 rc
有問題就送出領取失敗的訊息。
否則就直接告知我領取結果。
檔案內容:
const { scheduleJob } = require('node-schedule');
const sendLineNotify = require('./sendLineNotify.js');
const { getLottery } = require('./lottery');
require('dotenv').config();
module.exports = (accessToken, lineNotifiyToken, cronFormat = process.env.CRON_FORMAT) => {
const resp = scheduleJob(cronFormat, async () => {
const getLotteryResp = await getLottery(accessToken);
if (getLotteryResp.statusCode !== 200) return sendLineNotify(`領取失敗,因為 statusCode 拿到 ${getLotteryResp.statusCode}`, lineNotifiyToken);
if (getLotteryResp.body.rc !== 1) return sendLineNotify(`領取失敗,因為麥當勞報報 API RC 拿到 ${getLotteryResp.body.rc}`, lineNotifiyToken);
return sendLineNotify(`\n${getLotteryResp.body.results.coupon.object_info.title}`, lineNotifiyToken);
});
return resp;
};
專案持續更新,直到我做到完全滿足我的需求為止。
GitHub Link: mcdonaldLottery
這兩天實作過程中發現還有很多需要改進的地方...
目前窘境:
如果要分享給不會打 API 的人使用整個就是不可能,
(除非他願意給出帳號密碼,這樣又不太妥。
所以可能需要一個介面讓他輸入帳號密碼拿取 Token
-> 輸入 Line Notify 的 Token
-> 介面按下送出自動領取並傳送至他給的 Line Notify。
看了一下文件發現 node-schedule 要在事後取消單一 job 好像有點困難,所以我如果要取消就是把所有取消,然後在伺服器重開之後所有 job 都會無效需要重新再打一次 API。
目前想法是要用 DB 紀錄每個打進來的 user 狀態,重啟的時候依照狀態去決定要不要重新自動排程。
傳送進來的 request 格式其實我都沒做檢查,例外處理也沒做,整個不及格xDDD
沒什想法,就是要花時間做。QQ
應該做一個可以查詢自己目前有沒有在自動領取的排程中,然後可以回傳說下次領取時間為何。
我寫完之後 local 測試都正常,找了很久才發現是 ec2 時區跟我不一樣,我以為架設在日本就是日本,結果最後發現他還是 utc+0
...
所以記得要設定時區,不要跟我一樣犯蠢。
sudo timedatectl set-timezone Asia/Taipei
以上
歡迎留言或私訊討論~
感謝你