はじめに
個人アカウントでLINEとGASを連携したBotを運用していました。
そのBotを複数のグループに導入し、定期実行と特定のコメントに返答できるようにしていて、いずれの機能も正常に動いていました。
ある日、ビジネスアカウントで同じ機能を持ったBotを作りたいという事情があったので、ビジネスアカウントからBotを作って、処理は移行前に書いて実行していたGASを実行してみました。
すると、特定のコメントへの返答は機能するのですが、定期実行ができなくなったのです。
ここで原因がわからずにハマりにハマってしまって、なんとか解決したので備忘として書き残すようにしました。
発生したエラー
400エラーということは、どこかに不正リクエストになりうるパラメーターが起きているのだなぁと、、
Exception: Request failed for https://api.line.me returned code 400. Truncated server response: {"message":"Failed to send messages"} (use muteHttpExceptions option to examine full response)
発生箇所
発生箇所と関連する部分を簡単にまとめています。
定期実行のテキストをPUSHする部分でエラーが起きていました。
const PUSH_URL = "https://api.line.me/v2/bot/message/push";
UrlFetchApp.fetch(PUSH_URL, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
'method': 'POST',
'payload': JSON.stringify({
'to': [送信する先],
'messages': [{
'type': 'text',
'text': [適当なテキスト],
}]
})
})
試したこと・確認したこと
- 上位のPUSHに関わるUrlFetchApp周りに問題がないか
- pushのAPI URLが変わっていないか
- 移行したBotのチャンネルアクセストークンが元のBotに戻っていないか
- 送信先のグループIDを一部消したりしちゃっていないか
- 移行するときにBotの設定を間違えていないか
- 応答メッセージやBotのオン/オフの設定を間違えていないか
どれも違う(=移行前と同じ設定やコード)、、なんでや
と、困っていました。
原因と解決策
ちゃんと公式のFAQを見たら書いていた。
存在していないユーザーIDに対してメッセージを送信した場合は、ステータスコード400とともに以下のエラーが返ります。
でも、移行前はグループに正常に送信していたのでこれは違うかなぁ🤔
しかし後の文に
なお、ユーザーIDはプロバイダーごとに発行される値です。別のプロバイダーで発行されたユーザーIDを指定してメッセージを送信した場合も、存在していないユーザーIDにメッセージを送信したという扱いになります。
これっぽいな🤔
と、いうことで移行前と移行後のBotでユーザーID(グループID)が変わっているんじゃないかを見てみました。
グループIDの検証
debug
メソッドを定義し、doPost
メソッド内で呼ぶようにします。
function doPost(e) {
// WebHookで受信した情報
const event = JSON.parse(e.postData.contents).events[0];
// WebHookで受信した応答用Token
const replyToken = event.replyToken;
// スプレッドシートに記述
debug(event);
}
function debug(value='デバッグテスト') {
const sheet = SpreadsheetApp.openById('スプレッドシートID');
const ss = sheet.getSheetByName('シート名');
const date = new Date();
const targetRow = ss.getLastRow() + 1;
ss.getRange('A' + targetRow).setValue(date);
ss.getRange('B' + targetRow).setValue(value);
}
これをBotに適用してBotのいるLINEグループで適当に呟くと、指定したスプレッドシートに下記のようにログが流れてきます。
このgroupId
というものをPUSHの送信先に指定しています。
これを移行前のBotと移行後のBotで確認してみると、移行前がAAAAAAAAAAAAA
みたいなものだったのですが、移行後ではBBBBBBBBBBBB
みたいなIDに変わっていたのです。
同じグループなのにここが変わっているとは。。
これは知っていないとできないわ😅
ということで、'BBBBBBBBBBBB'(移行後のBotでデバッグして見つかったgroupID)の方をGASの方で指定してあげたら無事に定期実行が届きました。
ちなみに特定のコメントに返答できていたのは、届いたコメントの情報からリプライトークンを抽出し、そのトークンを指定して送り返していたから機能していた。ということだったのかと悟りました。
下記がイメージのコードですが、replyToken
がそれに値します。
function doPost(e) {
// WebHookで受信した情報
const event = JSON.parse(e.postData.contents).events[0];
// WebHookで受信した応答用Token
const replyToken = event.replyToken;
// ユーザに送るのメッセージ
const message = '送りたいメッセージ';
UrlFetchApp.fetch(url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': replyToken,
'messages': [{
'type': 'text',
'text': message,
}],
}),
});
まとめ
図にしてみるとこんな感じ。
同じ処理内容のBotを持たせたとしても、プロバイダーが異なれば送信先の指定に必要なグループIDが変わるので、指定し直さなければ動かないということなんですね。
地味にハマって個人開発で数日悩まされていたので、同様に困っている方の助けになると幸いです。
ちょっと検証できていないのですが、FAQの説明文を読む感じだと、プロバイダーが同じであれば、その中でBot1をBot2に移行する場合はグループIDは変わらないはずです。
こちらは興味ある方で試してみてください。