LINE Botが返信しないときの切り分け手順|Webhook・応答設定・処理側の3層をどの順で潰すか
LINE Botが返信しないときの切り分け手順|Webhook・応答設定・処理側の3層をどの順で潰すか
LINE公式アカウントにBotを繋いだのに、メッセージを送っても何も返ってこない。エラーも出ない。この状態でまずやるべきことは、コードを見直すことでも、トークンを再発行することでもありません。
「どこまで届いていて、どこで止まったのか」を先に確定させることです。
LINEのBotは、少なくとも3つの層を経由して動きます。無反応というのは「どこかの層で止まった」という結果だけを示していて、原因の場所は何も示していません。にもかかわらず、多くの場合はいちばん触りやすい層(自分が書いたコード)から疑い始めます。そこが原因でないとき、この順番は最も時間を溶かします。
先に全体像を示します。
| 層 | 何が起きる場所 | 止まっているときの見え方 | 確認手段 |
|---|---|---|---|
| 1. LINE側 | 受け取ったメッセージをBotに渡すかどうかの判定 | 完全に無反応。処理側に記録が一切残らない | 管理画面の応答設定・Webhookの利用状態 |
| 2. 疎通 | LINEから受け取り先URLへの送信 | 無反応。またはLINE側の検証だけ失敗する | Webhook URLの検証機能 |
| 3. 処理側 | 受け取った内容の処理と、返信の送信 | 受信はしているが返信が来ない。片方だけ動く | 実行ログ・受信ログ |
この記事では、3層を上から順に潰す手順と、実務で誤診しやすい箇所をまとめます。自分で開発していない方も、制作会社や外注先に「どこまで確認したか」を聞く基準として使えます。
最初にやること:受信ログを1行書いて、層2と層3の境界を可視化する
順番としては層1から確認したくなりますが、その前に1回だけコード側に手を入れておくと、以降の切り分けが一気に速くなります。
受け取り処理のいちばん先頭で、届いた内容をスプレッドシートやログに1行書き出す。処理も判定も何もせず、ただ「届いた」という事実だけを記録します。
function doPost(e) {
// 最初に無条件で記録する(判定より前)
SpreadsheetApp.openById(SHEET_ID)
.getSheetByName('受信ログ')
.appendRow([new Date(), e.postData ? e.postData.contents : '(空)']);
// ここから通常の処理
}
これで、次の判定が一発でつきます。
- ログに行が増える → 層1と層2は生きている。原因は層3にある
- ログに何も増えない → 層3より手前で止まっている。コードを読んでも原因は出てこない
地味ですが、これを入れずに進めると「コードを直す→試す→変わらない」を何周もすることになります。無反応の相談で最も多いのは、実は処理側にそもそも一度も届いていないケースです。
なお、この記録は判定や条件分岐の中に入れてはいけません。既存の条件分岐の内側に仕込んだ処理は、その分岐に入らなかったときに何も残さず、結果として「動いていないのか、通っていないのか」が分からなくなります。切り分け用のログは、必ず分岐の外側・処理の先頭に独立して置きます。
層1:LINE側でBotに渡っているかを確認する
処理側にログが残っていなければ、次はLINE側の設定です。ここで見るのは3つだけです。
Webhookが「利用する」になっているか
LINE公式アカウントの管理画面(またはLINE Developers)で、Webhookの利用がオフになっていると、メッセージはBotに一切渡りません。設定を保存したつもりでオフのまま、というのは実際によくあります。
応答モードと「チャット」の優先関係
LINE公式アカウントには、手動対応のチャット機能があります。チャットが有効で、かつ応答時間内に設定されていると、自動応答側が動かない組み合わせが成立します。Botを繋いだ直後に無反応なら、ここを最初に疑う価値があります。
Webhookの宛先は「1つ」しか持てない
これが実務でいちばん効いてくる仕様です。
Messaging APIのチャネルに設定できるWebhookの宛先は1つだけです。つまり、エルメやLステップなどの拡張ツールを導入した時点で、その宛先はツール側のURLに書き換わります。自分で作ったBotのURLは、そこには残りません。
弊社が構築した物販アカウントでも、拡張ツールを導入済みのアカウントに対して、別途スクリプトからメッセージを送る仕組みを繋ごうとして、送信が通らない状態になったことがあります。このときトークンも宛先IDも正しく、コード側にも問題はありませんでした。原因は、そのアカウントのWebhookをすでに拡張ツールが握っていたことにあります。
拡張ツールを入れているアカウントに、自作のBotを後から同居させることは基本的にできません。この前提を知らないまま原因を探すと、正しいコードを何度も書き直すことになります。対処は後述します。
層2:疎通を確認する
層1に問題がなければ、LINEから受け取り先URLへ実際に届くかを確認します。LINE Developersの管理画面には、設定したWebhook URLに対してテスト送信を行う検証機能があります。ここで失敗するなら、原因はURLか、受け取り側の応答内容です。
確認する点は次の3つです。
- URLが最新のものか。Google Apps Scriptで作っている場合、ウェブアプリのURLはデプロイのたびに変わる設定と、変わらない設定があります。作り直したときに古いURLが残っていると、当然どこにも届きません
- アクセス権限が正しいか。実行ユーザーとアクセスできる範囲の指定を誤ると、LINE側から見て弾かれた状態になります
- 正常に応答を返しているか。受け取り側が処理の途中でエラーになると、LINEからは「送ったが失敗した」と見えます。処理が重い場合も同様です
検証が成功するのに実メッセージで無反応、という場合は層3の問題です。逆に検証が失敗するなら、コードの中身より先にURLと権限を疑います。
層3:処理側で止まっているケース
ここまで来たら、原因は処理側にあります。頻度が高いのは次の3つです。
直したはずのコードが反映されていない
Google Apps Scriptのウェブアプリは、エディタ上で保存しただけでは公開されているコードは変わりません。デプロイを更新して初めて反映されます。「直したのに変わらない」の相当数がこれです。まず、公開中のバージョンが最新かを確認します。
実行はされているが、中で落ちている
実行ログを見れば、呼ばれたかどうか、どこで例外になったかが分かります。ここで注意したいのが、「実行された」と「処理が成功した」は別物だという点です。
弊社で運用している別の自動処理では、定期実行そのものは正常終了し続けているのに、中身は認証に失敗して何もしていない、という状態が長期間続いたことがあります。ログ上は成功、実際の成果はゼロ。動作確認は実行ログではなく、結果として残るはずのデータ側で行うのが確実です。Botなら「返信が届いたか」、通知なら「通知先に実際に出たか」を見ます。
返信ではなく送信で失敗している
「返信が来ない」という症状のうち、実際には返信処理そのものが呼ばれていて、送信の段階で失敗しているケースがあります。この場合、送信APIはエラーを返しているので、そのレスポンスを記録していれば原因はすぐ分かります。逆に、送信結果を捨てているコードだと、外からは無反応と区別がつきません。
送信処理のレスポンスは必ず記録しておく。これは切り分けのためだけでなく、後から「いつから壊れていたか」を追うためにも効きます。
誤診を避ける2つの型
切り分けで時間を失うのは、たいてい原因の特定を誤ったときです。実務で効いた予防策を2つ挙げます。
変更していない対象で対照実験する
異常を観測したとき、直前に自分が触った箇所を疑うのは自然です。ただし、自分の変更と無関係な対象でも同じ異常が出るかを先に確かめると、切り分けが1手で終わることがあります。
別案件では、テンプレートを更新した直後にプレビューが真っ白になり、自分の変更で壊したと判断して巻き戻しかけたことがあります。ところが触っていない別のテンプレートでも同じ症状が出ており、原因はサービス側の一時的な不具合でした。正しい実装を撤回する寸前で助かった形です。
LINE Botなら、別のテスト用アカウントや、送信だけを行うテスト関数で同じ症状が出るかを見ます。同じなら、原因は自分のコードの外にあります。
前回の診断結果をそのまま前提にしない
同じ不具合に日をまたいで取り組むとき、前回立てた仮説を出発点にすると早い——ように見えて、これが外れることがあります。環境側の変更で症状が変わっていたり、自然に解消していたりするためです。
実際、前述の送信エラーは、こちらが特に修正を加えないまま解消していたことが後に判明しました。原因は結局特定できていません。再開時は「前回の見立てが今も成立しているか」を現況の確認から始めるのが、遠回りに見えて確実です。
あわせて、間違いだと分かった診断は記録に残しておくと効きます。前述の事例では「宛先IDが違うのではないか」「そもそもBotがグループに入っていないのではないか」という2つの仮説を検証しましたが、どちらも誤りでした。後者は、確認に使ったAPIのパスが誤っていて存在しないURLを叩いており、その404を「いない証拠」と読んでしまったものです。確認手段そのものが壊れている可能性は、切り分けの候補に入れておく必要があります。
Webhookの競合が避けられないときの設計
層1で触れた「Webhookの宛先は1つ」という制約は、設定では回避できません。取れる手段は次の2つです。
通知専用のチャネルを別に用意する
拡張ツールが握っているアカウントとは別に、Messaging APIのチャネルをもう1つ作り、そちらを通知用途に使う方法です。友だちとの会話は既存アカウント、社内向けの通知は新チャネル、と役割を分けます。ツール側の動作に影響を与えないのが利点です。
リアルタイム受信をあきらめ、定期実行に寄せる
もう1つは、Webhookを使わない構成に切り替える方法です。フォームの回答や受信メールを一度スプレッドシートやメールボックスに落とし、それを数分おきに確認して通知する。弊社で稼働している問い合わせ通知の仕組みは、この方式で組んでいます。
- 5分おきに新着行を確認する
- 初回実行時は基準となる行番号を記録するだけにして、過去分を一斉送信しない
- どこまで通知したかを保存し、再実行しても重複しないようにする
即時性は数分落ちますが、Webhookの取り合いが起きず、拡張ツールの仕様変更にも影響されません。社内通知のように「数分の遅れが実害にならない」用途では、こちらのほうが安定します。
なお、この方式に切り替える際、初回に基準行を記録する処理を省くと、蓄積されていた過去の分がすべて通知として流れます。件数が多いアカウントでは実害が出るため、最初の1回は記録だけして送らないという設計を必ず入れておきます。
よくある質問
Q. 昨日まで動いていたのに、今日から返らなくなりました。何を疑えばよいですか?
まず、その間にアカウント側で何か追加していないかを確認してください。拡張ツールの導入や再連携が入ると、Webhookの宛先が書き換わります。心当たりがなければ、受信ログが増えているかを見て層を切り分けます。なお、外部サービス側の一時的な不調で数時間だけ不安定になり、こちらが何もせず戻るケースも実際にあります。慌てて設定を変える前に、現況を1回記録しておくと、原因の特定と復旧判断の両方が楽になります。
Q. 自分で開発していません。外注先に何を聞けばよいですか?
「Webhookは届いていますか、それとも処理側で止まっていますか」の1問で足ります。この質問に即答できる状態なら、受信の記録が残っている=切り分けができる体制です。答えが曖昧なら、まず記録を入れるところから依頼してください。
Q. テストはどうやりますか?
送信部分だけを呼ぶテスト関数を用意し、末端から確認します。いきなり実メッセージで試すと、原因が3層のどこにあるか分からないまま結果だけを見ることになります。末端が動くことを先に確定させてから、上流へ遡るのが最短です。
まとめ:推測より先に、境界を1つ確定させる
LINE Botが無反応になったときの手順を整理します。
- 受け取り処理の先頭に、無条件のログを1行入れる。層2と層3の境界がこれで確定する
- ログが増えないなら層1へ。Webhookの利用状態・チャットとの優先関係・Webhookの宛先を確認する
- 拡張ツールを導入しているアカウントに、自作Botは同居できない。別チャネルか、定期実行方式に切り替える
- 疎通は検証機能で確認する。失敗するならコードより先にURLと権限
- ログが増えているなら層3。デプロイの反映・実行ログ・送信APIのレスポンスの順に見る
- 実行された≠成功した。健全性は結果として残るデータで確認する
- 原因の特定に迷ったら、触っていない対象で同じ症状が出るかを試す
無反応というのは情報量がゼロの症状です。だからこそ、最初にやるべきは原因の推測ではなく、「ここまでは動いている」という境界を1つ確定させることです。境界が1つ決まれば、疑う範囲は半分になります。
LINE公式アカウントと業務システムの連携で、すでに動かなくなっている仕組みの引き取りや、拡張ツールを入れた状態からの追加開発を検討されている場合は、graciautoにご相談ください。現状の構成を伺えば、どの層に手を入れるべきかの見立てからお伝えします。