はじめに
前回は応答通知を作成したので、今回はプッシュ通知に挑戦してみました。
正しい実装かどうかは不明ですが参考程度になりましたら幸いです。
背景
今年の6月からGoogleのspreadsheetを使って家計簿をつけ始めました。
最初はいくら使ったのか気になって、お金を使ってもいないのに見ていました。
7月は興味が薄れて最終的に何にどれくらい使ったか、把握できていませんでした。
そこで、決まったタイミングで支出がどのくらいになっているのか通知しれくれたら便利だなと思い作成しました。
アウトプット
目次
・LINE Developersの登録とチャンネル作成
・Google APIの登録とGoogle Sheets APIの登録
・Google Sheets API実装
・プッシュ通知実装
・スケジューリング
・結果
開発環境
Node.js:v14.16.1
yarn:1.15.2
LINE Developersの登録とチャンネル作成
前回記事で作成しているため割愛します。
Google APIの登録とGoogle Sheets APIの登録
Google Sheets APIの準備はこちらをご参照ください。
※一部現時点での画面表示と異なる部分があります。
Google Sheets API実装
実装もこちらの記事を参考にさせていただきました。
module.exports = async function fetchSpreadSheet(){
// JSON Web Token(JWT) の認証
await jwtClient.authorize();
// シートを読み込む
const sheet = await sheets.spreadsheets.values.get({
auth: jwtClient,
spreadsheetId: sheet,
range: cells
})
.then(response => {
return response.data.values;
})
.catch(error => {
console.log('The API returned an error: ' + error);
return;
});
return sheet;
}
こちらからパラメータを確認することができます。
取得したデータは以下のような形式で取得されます。
// シートのA1:C3の範囲を取得した場合
["A1", "B1", "C1"]
["A2", "B2", "C2"]
["A3", "B3", "C3"]
これを表示方法に従って整える必要があります。
プッシュ通知実装
チュートリアルで作成したサンプルBOTをベースにして以下のように実装しました。
async function pushMessage() {
const dataString = JSON.stringify({
// ユーザID
to: "U33c6dc~~~",
messages: [
{
"type": "text",
"text": `${commonFunction.format(await fetchSpreadSheet())}`
}
]
})
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + TOKEN
}
const webhookOptions = {
"hostname": "api.line.me",
"path": "/v2/bot/message/push",
"method": "POST",
"headers": headers,
"body": dataString
}
const request = https.request(webhookOptions, (res) => {
res.on("data", (d) => {
process.stdout.write(d)
})
})
request.on("error", (err) => {
console.error(err)
})
request.write(dataString)
request.end()
}
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
pushMessage();
})
ユーザIDは一般的にどのように取得するのか把握できていませんが、
私はLINE Developersのトップ > プロバイダー > チャンネル
配下の
あなたのユーザID
という項目から取得しました。
その後npm start
コマンドでLINEに通知が来ることを確認します。
スケジューリング
Heroku Schedulerを使用します。
設定手順はこちらをご参照ください。
週末の昼頃に通知が欲しいのですが、日次までしかなかったのでひとまず日次で設定します。
また時差は9時間あるので、3時を設定しておきます。
実行するコマンドはnpm start
です。
※無料で使えるのですがクレジットカードの登録が必要です。
このままでは毎日通知が来てしまいます。
Heroku Schedulerでは選択肢がなかったため実装でカバーしました。
(もっと方法があるとは思うのですが妥協してしまいました。)
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
const today = new Date();
// 日曜日のみ動作するように設定
if (today.getDay() === 0) {
pushMessage();
}
})
結果
日曜日の午後0時に予定通り通知が来ました!
※罪は酒代です。また、いろいろマイナスになっていますが問題ないです。
最後に
私個人用かつとりあえず動かすという目的のため、きれいではない実装をしてしまっていますので
今後は少しでも見ていただきやすい記事になるように気を付けて実装できればと思いました。
どなたかの参考になりましたら幸いです。
参考
Node.js googleapis npmパッケージで Google スプレッドシートを await/async で読み取るメモ
Heroku Schedulerの設定方法