目薬の時間を教えてくれるBOTから通知が来なくなった
眼圧をコントロールする目薬を1日3回点眼するために、こんな通知システムを作って使っています。
何年を使っていますが、とても役立っています。
ところが最近になって通知が来なくなりました。
調べてみると、LINE Messaging APIから、"月間送信メッセージの上限に達した"という意味のエラーが返ってきていました。
何かの誤動作で大量のリクエストを送ったのかと思いきや、2023年6月からLINE Messaging API を使うLINE公式アカウントの料金プランと制限が変更されていました。
https://www.linebiz.com/jp/news/20221031/
無料の「コミュニケーションプラン」場合はこれまでの1ヶ月1000通までから200通までに大幅に減ってしまいました。
毎回、最初の通知が来た時に必ず点眼していれば、3通×31日で93通と200通に収まります。
しかし、実際にはすぐに点眼せずに何度も繰り返しリマインドされることが多いので、あっという間に200通を越えていました。
課金すると回数制限が増えます。愛用システムなので月300円くらいで1000通に戻せたら課金してもいいかなと思いましたが、安い方のライトプランが5000円で5000通ということで、システム改変で対応することにしました。
LINE Notifyの制限は1000通だった
色々な方法を検討してみましたが、どうやら最も簡単な対応はPUSH通知をLINE Notifyに変えることでした。
念のため、LINE Notify APIのREPLYヘッダで回数制限を確認してみると、確かに1000回でした。
LIMIT CHECK
API call remaining : 998 / 1000
Image upload remaining : 50 / 50 by an hour
Reset time UTC : 1686808086
HTTP status code : 200
LINE Notify APIのREPLYヘッダを見るプログラムはこちらからお借りしました。感謝。
【ラズパイで猫ちゃんカメラ】その6 LINE NotifyのAPI制限を確認する
公式アカウントでもユーザーからの返信はカウント対象外?
通知だけならLINEを使う必要はありません。LINE公式アカウント(LINE Messaging API)のメリットは、ユーザーからのメッセージに対応できることです。
例えば、点眼時間の通知がきた後で、なんでも良いからメッセージを送ると点眼したと解釈して通知が止まります。
また、「スキップ」というメッセージを送ると次の通知を一回お休みできます。
このシステムは、PUSH通知が出来なくなったあとでも、ユーザーからのメッセージに回答する機能はちゃんと動いていて返事も来ていました。
例えば、通知が来た(はず)の時間に何かメッセージを送信すると、「点眼を確認しました」というメッセージが返ってきました。
どうやら、ユーザーからのメッセージに対する返信は制限の対象外っぽいです(未確認ですが)。
そこで、PUSH通知はLINE Notifyを使い、BOTの制御(常にこちらが先にメッセージを送り、BOTは返信する)は公式アカウント(LINE Massaging API)を使うことにしました。
トークルームを使い分けるのでちょっとUXは下がりますが、まぁ自分のためのシステムなので問題ないです。
sendLineNotify関数を作って、pushMessage関数から呼び出す
ここではコードの追加と変更部分を抜き出します。
まず、LINE Notifyを使うための定数を定義しました。
APIを使うためのトークンをスプレッドシートのB19欄に入れるようにしました。
var LINE_NOTIFY_TOKEN = sheet.getRange('B19').getValue();
var LINE_NOTIFY_ENDPOINT = "https://notify-api.line.me/api/notify";
sendLineNotify()という関数を作ります。
これは玄関の鍵を掛けたことを通知してくれるシステムから流用しました。
function sendLineNotify(MSG) {
if (!MSG) MSG = "これはテストです";
const options = {
"method": "post",
"headers": { "Authorization": "Bearer " + LINE_NOTIFY_TOKEN },
"payload": { "message": MSG }
};
try {
const response = UrlFetchApp.fetch(LINE_NOTIFY_ENDPOINT, options);
Logger.log(response);
// sheet.getRange("B5").setValue(response);
}
catch (error) {
Logger.log(error);
// sheet.getRange("B5").setValue(error);
}
}
最後にpush通知に使っているpushMessage()関数の先頭でsendLineNotify()関数を呼ぶようにします。pushMessage関数内の他のコードはそのまま残しています。
いかにも付け焼き刃な対応ですが、まぁ自分用アプリなのでいいでしょう。またLINE Messaging API使うかもしれないし。
function pushMessage(msg) {
sendLineNotify(msg);
return;
この改造で通知が届くようになりました。
ただ、BOTへの返事は別のトークルームから行う必要があります。
マイコン内蔵の目薬ケースで点眼確認する分にはなんの不便もありません。
将来的にはSlackとかかなぁ
今回はとりあえず別のAPIを使うことで対処しましたが、外部APIを使うシステムは常にこういうリスクが伴います。
BOTの乗り換え先としては、以前はTwitterが有力候補でしたが、今はSlackでしょうか。
Slack BOTはN予備校のプログラミング講座で作ったことがあります。将来に備えてこのシステムのSlack対応版を作ってみてもいいかもしれません(作るとは言ってない)。