お久しぶりです。最近は社内ですら「最近何やってるんですか?」って聞かれるので、最近ちょっと試していたAkkaHTTP で LINE bot を作るやり方をご紹介します。

LINEの提供するMessaging APIを使えば、LINE@で作成したLINEアカウントを使ってユーザーに任意のタイミングでメッセージを送ったり、ユーザーからのメッセージに返答することができます。

Messaging APIは登録してシークレットとアクセスキーさえ発行できれば、あとはJSONでやり取りする普通のAPIなので、AkkaHTTPがあれば簡単にbotが作れてしまいます。もちろんビジネスロジックはこっちで考えないといけないけど、細かいことはいいからまずは動くものをサクッと作って見てから考えるのはいかがでしょうか?

できること

  • ともだち登録してくれたユーザーにメッセージ
  • ユーザーからの発言に答える
  • 任意のタイミングでpushメッセージを送る

*ただし、pushメッセージはプロ(API)プランでないと送ることができないようです。テストだけなら、テスト用アカウントで送れるので試すことはできます。
参考:Messaging APIのご紹介 | LINE Business Center

作り方

大まかな動作としては以下のような動きをさせることになります。

  1. webhookを受け付ける
  2. 署名検証して本物のLINEからのメッセージであることを確かめる
  3. 受け取ったwebhookの Event をパースする
  4. Event ごとに処理を決めつつとりあえず応答(200)を返す
  5. APIを叩いてユーザーにメッセージを送る
  6. 任意のタイミングでpushメッセージを送信する

署名検証は簡単な実装でなんとかなるし、webhookをEventに変換したり、逆にこちらからLINEのAPIを叩いたりはJSONを扱うライブラリにお任せ。OAuthにももちろん対応しており、「OAuth使ってね」って書くだけの簡単な実装で済みます。

準備するもの

  • LINE Business Centerで会社を登録
  • ビジネスアカウントを作成する
  • 検証用なら “Developer Trialを始める” から検証用アカウントが作れます
  • LINE@ MANAGERでBot利用を設定し、Webhookを有効にする
  • LINE developersでChannel SecretとChannel Access Tokenを確認しておく
  • webhookが受け付けられるサーバー
  • そのサーバーをwebhookに設定しておく

ちなみに私はサーバーはherokuで試しました。HTTPS周りで面倒、と聞いていたのですが特に何かするわけでもなくすんなり使えました。

1.webhookを受け付ける

AkkaHTTPを活用して、httpリクエストを受け付けましょう。

これだけで、 http://localhost:8080/line/callback に来た post リクエストに対して 200 を返すことができます。

2. 署名検証して本物のLINEからのメッセージであることを確かめる

署名検証自体はそこまで難しいものではありません。LINEのAPI Referenceに載ってるJavaの例をそのまま使って、とりあえず署名検証クラスを作ることにしましょう。

使い方はこんな感じです

これを活用して、 Directive を作ることで、 routes の中にこの署名検証を組み込むことができます。

これで、 post かつ署名検証がパスしたものだけが処理されるようになります。試しにローカルで動かして見てください。署名がないので怒られることを確認しましょう。

3. 受け取ったwebhookの Event をパースする

さて、webhookで受け取るのはイベントを表すJSONです。JSONはAkkaHTTPでサクッとパースしましょう。

まずはEventやその小要素のためのcase classを用意して

それをパースするtraitを作ります。

今回はおそらく一般的と思われるSprayJsonで。JSONの扱いはSprayJsonである必要はなく、いろんなライブラリが使えますからぜひお気に入りのパーサーでパースしてくださいね。(本筋からはそれるのでここでは語りません)

あとはこれを最初に作ったBootに混ぜ込んでやれば良いのです。

4. Event ごとに処理を決めつつとりあえず応答(200)を返す

routes をちょちょっといじって、 Event に対応させましょう。

entity(as[Events]) で、そのリクエストを Events として解釈できたものだけ処理することができます。 Event ではなく複数なことに注意しなくてはいけません。そのためこの段階では、一度それぞれはただprintlnするだけにして、最後に complete("OK") しています。

5. APIを叩いてユーザーにメッセージを送る

いよいよAPIを叩いてユーザーに返事を返しましょう。

APIを叩くにはOAuth認証をどうにかする必要があります。が、これはAkkaHTTPがなんとかしてくれます。

これだけです。 reply に必要なデータを詰め込めば、たったこれだけでOAuthをよしなになんとかしてくれます。

じゃあこの reply は何をすればいいの?って話なのですが。API Referenceに基づいて、replyTokenとSend message objectを詰め込んでやりましょう。Eventと同じ要領でJsonSupportに追記してやれば、パースだけではなくJSONを作ることもできるようになります。( reply がパース、 write がJSONの書き出しになります)

6. 任意のタイミングでpushメッセージを送信する

基本的に返事を返すReplyと大差ありません。

必要なものは、送るメッセージの他にOAuth用のアクセストークン、そして送り先のIdentifierになります。

こちらに詰め込む pushSend message objectの他に、replyTokenの代わりに送信先識別子というものを詰め込みます。これはどうしようか迷うところだけど、一番手っ取り早いのはLINE developersで Channels > Basic information を見たときの一番下にあるYour userIdです。それは、あなた自身のIdentifierなはずなので、そこに送ればあなたに届きます。

最後に

さあ、サーバーにアップロードしてLINEで友達登録したり、メッセージを送ったりして見ましょう。うまく動きましたか?普段使ってるLINEが、こうやって自分の手で作ったbotでメッセージを返してくれるとなんか嬉しくなりますよね。

さて、これで基本はバッチリです。あとはAPI Referenceを色々見て、他の様々なメッセージに対応したり、メッセージの本文をちゃんと読んでビジネスロジックをがっつり組み込んでやったりしてください。Messaging APIはあくまでもAPI、どう活かすかは自分次第です。

参考情報

Getting started with the Messaging API