【LINE×GAS】動いていたBotの処理を別のBotに移行したら、400エラーでFailed to send messagesとなり動かない

# はじめに
個人アカウントで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する部分でエラーが起きていました。

```javascript
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](https://developers.line.biz/ja/faq/#what-error-is-returned-when-a-message-is-sent-to-a-nonexisting-user)を見たら書いていた。

>存在していないユーザーIDに対してメッセージを送信した場合は、ステータスコード400とともに以下のエラーが返ります。

でも、移行前はグループに正常に送信していたのでこれは違うかなぁ🤔

しかし後の文に
>なお、ユーザーIDはプロバイダーごとに発行される値です。別のプロバイダーで発行されたユーザーIDを指定してメッセージを送信した場合も、存在していないユーザーIDにメッセージを送信したという扱いになります。

これっぽいな🤔
と、いうことで**移行前と移行後のBotでユーザーID（グループID）が変わっている**んじゃないかを見てみました。

## グループIDの検証

`debug`メソッドを定義し、`doPost`メソッド内で呼ぶようにします。

```javascript
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グループで適当に呟くと、指定したスプレッドシートに下記のようにログが流れてきます。

|<img width="800" alt="logsample.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550560/09721ff5-4b07-a957-4a6c-e9628847e0d5.png">|
|:--|

この`groupId`というものをPUSHの送信先に指定しています。

これを移行前のBotと移行後のBotで確認してみると、移行前が`AAAAAAAAAAAAA`みたいなものだったのですが、移行後では`BBBBBBBBBBBB`みたいなIDに変わっていたのです。

同じグループなのにここが変わっているとは。。

これは知っていないとできないわ😅

ということで、'BBBBBBBBBBBB'（移行後のBotでデバッグして見つかったgroupID）の方をGASの方で指定してあげたら無事に定期実行が届きました。


ちなみに特定のコメントに返答できていたのは、**届いたコメントの情報からリプライトークンを抽出し、そのトークンを指定して送り返していた**から機能していた。ということだったのかと悟りました。
下記がイメージのコードですが、`replyToken`がそれに値します。

```javascript
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が変わる**ので、指定し直さなければ動かないということなんですね。

地味にハマって個人開発で数日悩まされていたので、同様に困っている方の助けになると幸いです。

|<img width="900" alt="linegassysytem.001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550560/a67d8f7b-a91d-7b0c-3729-974d7d35105b.png">|
|:--|

ちょっと検証できていないのですが、FAQの説明文を読む感じだと、プロバイダーが同じであれば、その中でBot1をBot2に移行する場合はグループIDは変わらないはずです。
こちらは興味ある方で試してみてください。


# 参照

1. [FAQ | LINE Developers](https://developers.line.biz/ja/faq/#what-error-is-returned-when-a-message-is-sent-to-a-nonexisting-user)
1. [GAS × Line Messaging Api のデバッグ](https://qiita.com/Ko001/items/f72f7dc59116d961581e)