LINE Messaging API : Reply API におけるリプライトークンの有効期限は30秒 (独自調べ)

前回、LINE Messaging API を利用してユーザにオウム返しするチャットボットを作成したが、その際「Reply API」という API を利用してユーザへの返信を行った。

今回は、この Reply API に関する仕様について。

Reply API とは

Reply API は、リクエストに付与されている「リプライトークン」というモノをキーにして返信処理が行える仕組みだ。開発者はユーザ ID などを知らなくても返信ができ、Messaging API において最も利用される API であろう。

リプライトークンに有効期限がある

この「リプライトークン」には有効期限があるので、メッセージを受信したらできるだけ素早く返信しないといけない。

応答トークンは一定の期間が経過すると無効になるため、メッセージを受信したらすぐに応答を返す必要があります。応答トークンは1回のみ使用できます。

このとおり、公式の API リファレンスでも「一定の期間」と記載があるのは分かったが、具体的にどのくらい経過すると無効になるのかが分からなかった。

たまたまコネがあって、LINE の人に直接問い合わせたことがあったのだが、リプライトークンの有効期限は公表していない、というのが回答だった (LINE はわりかしサポートが不親切な印象)。

自分で調べてみた

そこで、自分で検証することにした。

前回のオウム返し Bot のソースコードをちょっと加工して、「ユーザが発言した秒数だけレスポンスを待つ」というコードを作った。event.message.text を数値に変換して、setTimeout() の第2引数に与えるようにしただけ。こうすれば、ソースコードの変更は1回こっきりで、Reply API のコールを遅延させるタイミングを自在に変えられる。あとはリクエストの受信直後と、Reply API のコール前後で時刻を出力し、経過時間をチェックできるようにした。

それで色々検証した結果、Webhook サーバがメッセージを受信してから30秒以内に Reply API をコールしないと 400 Bad Request が返ってきてしまい、返信できなかった。ユーザからのメッセージを LINE API サーバが受信し、LINE API サーバがリプライトークンを生成した時点から30秒間以内、というのが、恐らくは正確な秒数だろうか。

ネット上で調べた感じでも、「数十秒」とか「30秒」と表現している人が何名かいたので、現時点では「30秒以内に返信しないとダメ」というのが、リプライトークンの仕様だといえるだろう。

30秒以上経った後に返信したい場合は? → Push API を使う

前回、Heroku サーバを利用したが、Heroku は30分間アクセスがないと、Dyno (サーバ) が Sleep 状態になってしまう。再度アクセスがあれば、Dyno が起動後、レスポンスを返してくれるものの、Dyno の起動には30秒くらいかかることもある。

本番利用で無料枠の Heroku を使うこともないと思うし、普通に考えて30秒以上ユーザを待たせるような LINE Bot は使い物にならないが、それはそうとして、30秒以上経過した場合に返信する方法はないのか気になる。

結論からいえば、Push API という別の API を利用すれば、返信できる。コチラはユーザ ID を指定してユーザにメッセージを投稿する API で、本来は定期的な広告配信とか、ユーザ単位にカスタマイズしたメッセージを通知したりする時に使用するモノだ。

Push API は、「Developer Trial」プランか、有償プランでないと利用できない。チャネル作成時に「フリー」プランを選んでしまった場合は残念ながら利用できないので、チャネルから作り直しだ。

LINE API サーバへのレスポンスは1分以内に

ちなみにだが、/callback パスで LINE API サーバからのリクエストを受け取った時に、このリクエストに対するレスポンスは何秒以内に行えば良いのか。

コチラは、LINE 公式から「1分以内を推奨」と云われた。レスポンスにそれ以上かかると、Webhook サーバとの通信エラーとみなされるようだ (だからといって特にペナルティ等はなさそう)。

もっと大量のリクエストを処理するようなチャネルに成長した場合は、/callback パスでリクエストを分解して Reply API をコールして、その結果を待ってからレスポンスする、といった作りは、時間がかかりすぎるので NG だ。

じゃあどうするの、というと、LINE からリクエストを受け取った /callback パスでは、メッセージを DB 等に登録するだけして、さっさと 200 をレスポンスしてしまうのだ。そして、DB に入ったメッセージ情報を処理するのは、別のサーバに任せてしまう、というワケだ。返信は Webhook サーバ自身が行わないといけない、という決まりはないのだ。

DB に入れたメッセージをどうやって処理サーバが検知するかとか、並列処理させて問題ないような作りにするとか、色々と考えないといけないことも増えてくるので、規模に応じて、必要になったら作り変えるのが良いと思う。YAGNI。