この記事は、細々とメンテナンスを続けているランニング記録LINE botの中で、「返信」の活用を試したことをまとめたものです。
LINEのグループチャットでは、返信を使うことがあります。誰かの発言に対して、返信で何かしたことをトリガに、ボットが反応する。そんなシチュエーションを実装したのでざっくりまとめました。
当時、APIが提供されておらず、返信したり返信元の情報を参照することができませんでした。
最近、久しぶりにAPIドキュメントを読み直してみると、なんとサポートされているではありませんか!
最近ぶち当たった課題
ラン仲間が活発にラン画像を共有してくれる結果、「修正」や「削除」で対象の記録をリストから選ぶのに使っていたクイックリプライが、上限13個のリミットに到達することがちょいちょい発生するようになりました。
こうなると14個以上のactionをリストにしてAPIに投げて、エラーになる状況が発生しました。
APIがエラーになっても何も返していなかったため、グループチャット上では何が起きているのか分からず、「ボットがお休みしてしまったのかな?」ということになってしまいます。
この課題に対しては、「エラーが起きないようにすること」「13件を超した場合は直近のものから13件を選択対象にする」ということで回避しましたが、選択できない記録を操作できないという問題が残りました。
そこで、当時は採用できなかった「返信」を使った特定の記録への操作を実装してみました。
quotedMessageIdとReply ResponseのIdで返信元を参照
「返信」で投稿されたメッセージには、Webhookのメッセージ内にquotedMessageIdが含まれるようになり、どのメッセージへの返信かがわかるようになりました。
しかしここで一つ問題が。ボットが応答した「ナイスラン!」の記録表示はボットからの発信でWebhookによる記録はされていませんでした。
① ボットの応答への返信を想定して、まず応答のレスポンスに含まれるIdを記録しておくようにしました。
② 「修正」が投げられた際、それが返信によるものかをquotedMessageIdの有無で確認し、返信先がボットの記録応答であれば、記録修正のためのクイックリプライを返します。
③ クイックリプライ付きのメッセージを組み立てる段階で、キーボードの表示やあらかじめ表示するテキストの指定もおこなわれます。
「追加」にも応用
ボットへの指示を返信で行うことで、対象の選択を省く以外にも、「追加」を使って手動で記録する際、依頼メッセージへの返信で「追加」とすることにより、ひながたの名前を自動的に設定しておくことができ、一手間省けるようになりました。
以下が、このために追加した quotedMessageIdから発言者のUserIdを調べる関数です。
function getQuotedUserId(quotedMessageId) {
var ss = SpreadsheetApp.getActive()
var sheet = ss.getSheetByName('Webhook Log');
const lastRow = sheet.getLastRow();
for (var i = lastRow; i > lastRow - 100; i--) {
// 追加はだいたいすぐに行われるので、記録の下から100件だけ探す。
var requestObj = JSON.parse(sheet.getRange(i, 3).getValue());
if(requestObj.events.length > 0) {
for(j=0; j < requestObj.events.length; j++) {
var event = requestObj.events[j];
if(event.type == 'message' && event.message.id == quotedMessageId) {
return event.source.userId;
}
}
}
}
return 'not found';
}
LTに初登壇します!
2024年11月23日(土・祝)、以下のイベントでLTに初登壇します!
「ラン仲間のグループチャットで使うLINEボットを作った話」