Skip to content

Instantly share code, notes, and snippets.

@adamu
Last active September 14, 2021 07:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamu/6155478ca7a4791877e871907e618f0a to your computer and use it in GitHub Desktop.
Save adamu/6155478ca7a4791877e871907e618f0a to your computer and use it in GitHub Desktop.
Elixirを使ってLineのチャットボットを作ろう

これはfukuoka.ex Elixir/Phoenix Advent Calendar 2019の13日の記事です。 ElixirでLineのチャットボットを作る方法を紹介します。 🧪🤖🧪

昨日はsanpo_shihoさんの「Rails経験者に贈るPhoenix入門」でした。

English version.

  1. 先ずはLine Developers ConsoleMessaging API Channelを作成する必要があります。 そして作成されたチャネルIDとチャネルシークレットを後で使用するためメモしておき、ボットと友達になります。

  2. Supervision treeありのElixirのアプリを作ります。

    mix new advent --sup

  3. cd advent

  4. gitを使いたい場合はリポジトリを作ります(任意):

    git init && git add . && git commit -m 'Initial commit'

    このガイドで今後gitについては話しません。

  5. アプリが動いているかを確認します:

    $ iex -S mix
    Erlang/OTP 22 [erts-10.5] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [hipe]
    
    Interactive Elixir (1.9.2) - press Ctrl+C to exit (type h() ENTER for help)
    iex(1)> Advent.hello
    :world
    
  6. line_botとその他必要なライブラリーをmix.exsに追加します

    defp deps do
      [
        {:line_bot, "~> 0.1.0"},
        {:plug_cowboy, "~> 2.0"}
      ]
    end
  7. mix deps.getline_botのパッケージをフェッチします。

  8. config/config.exsでコンフィグファイルをを作ります。

    import Config
    config :line_bot,
      client_id: "YOUR_CLIENT_ID",
      client_secret: "YOUR_CLIENT_SECRET",
      # TODO remove this before deployment!
      skip_validation: true

    client_idclient_secretは上記でメモしておいたLine Developer ConsoleのチャネルIDとチャネルシークレットです。

  9. :advent:line_botのエリクサーのアプリが自動的に開始されることを確認します。

    $ iex -S mix
    Erlang/OTP 22 [erts-10.5] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [hipe]
    
    Interactive Elixir (1.9.2) - press Ctrl+C to exit (type h() ENTER for help)
    iex(1)> Application.started_applications
    [
      {:advent, 'advent', '0.1.0'},
      {:line_bot, 'A package for creating chatbots with the Line messenger',
       '0.1.0'},
    ...
    
  10. Lineサーバーのwebhookのrequestに対応できるようにするため、lib/advent/router.exにPlugのrouterを書きます。

    defmodule Advent.Router do
      use Plug.Router
      plug :match
      plug :dispatch
      forward "/bot", to: LineBot.Webhook, callback: Advent
    end
  11. Routerを開始するためにlib/advent/application.exに以下を設定します。

    children = [
      Plug.Cowboy.child_spec(scheme: :http, plug: Advent.Router, options: [port: 4000])
    ]
  12. iex -S mixでアプリを再起動して、テストリクエストに反応があるかどうかを確認します。

    curl http://localhost:4000/bot
    

    以下の通りに出力されること。

    19:31:18.051 [warn]  Skipping signature validation because :skip_validation is enabled.
    
    19:31:18.051 [debug] Webhook Request:
    

    今サーバーが動いていて、webhookのイベントを受け取っている状態です。インターネットに接続しましょう。

  13. Lineサーバーのリクエストをローカル環境に届けるために、ngrokというHTTPSのproxyが便利です。 ポート4000で起動してください。

    $ ngrok http 4000
    ngrok by @inconshreveable                                                                              (Ctrl+C to quit)
    
    Session Status                online
    Account                       Adam Millerchip (Plan: Free)
    Version                       2.3.35
    Region                        United States (us)
    Web Interface                 http://127.0.0.1:4040
    Forwarding                    http://xxxxxxxx.ngrok.io -> http://localhost:4000
    Forwarding                    https://xxxxxxxx.ngrok.io -> http://localhost:4000
    
  14. ngrokが出力したURLの末尾に/botを追加して、https://xxxxxxxx.ngrok.io/botをLine Developer ConsoleのWebhook URLに貼り付けてください。

  15. それでは、ボットのコードを実装しましょう. lib/advent.exを以下に書き換えます。

    defmodule Advent do
      use LineBot
    end
  16. 今、ボットがイベントに反応しているかどうかを確認できます。 ラインでチャットを開いてボットにメッセージを送ってください。 iexのコンソールに上記のメッセージに対するWebhook Requestが届くことを確認します。 例えば、「Hello, bot!」と送信した場合

    19:34:48.510 [debug] Webhook Request: {"events":[{"type":"message","replyToken":"xxxxxxxxx","source":{"userId":"U123456789abcdefghijllmnopqrstuvw","type":"user"},"timestamp":1575801287666,"message":{"type":"text","id":"0","text":"Hello, Bot!"}}],"destination":"Uyyyyyyyyyy"}

  17. ボットがメッセージに返信できるように実装しましょう。先ずは簡単にechoボットを実装します。

    defmodule Advent do
      use LineBot
      
      def handle_message(%{"type" => "text", "text" => message}, _info, reply_token) do
        reply = %LineBot.Message.Text{text: message}
        LineBot.send_reply(reply_token, reply)
      end
    end

    上手くいけば、ボットが送られたメッセージをそのまま返してくれます。

    image
  18. iexから直接メッセージを送信することができます。このボット用の自分のユーザーIDを確認してください。   Webhook Requestのログに記載があるはずです。自分に「Hello from iex!」とメッセージを送りましょう。

    iex> me = "U123456789abcdefghijllmnopqrstuvw"
    "U123456789abcdefghijllmnopqrstuvw"
    
    iex> message = %LineBot.Message.Text{text: "Hello from iex!"}
    %LineBot.Message.Text{quickReply: nil, text: "Hello from iex!", type: :text}
    
    iex> LineBot.send_push(me, message)
    19:55:02.919 [debug] API Response: %HTTPoison.Response{status_code: 200, request_url: "https://api.line.me/v2/bot/message/reply", ...}
    {:ok, %{}}

    上手くいけば、ラインのトークに届きます。

    image
  19. 開発しながら直接HTTP Requestをアプリに送信するのが便利ですが、ラインサーバーからのメッセージを受け取れる状況のため他人のサーバーから悪用できないように、ラインの証明書を確認する設定をしましょう。

    config/config.exs

    import Config
    config :line_bot,
      client_id: "YOUR_CLIENT_ID",
      client_secret: "YOUR_CLIENT_SECRET",
      skip_validation: false

これだけです!ラインサーバーからリクエストを受け取って返信するだけのシンプルなラインボットを作りました。 開発しながらコマンドラインから直接メッセージを送信する方法も紹介しました。

使用可能なAPIのコマンドと全ての対応できるイベントタイプはLineBotに書いてあります.

全ての機能に対応してるサンプルアプリもあります。line_bot_sample.exlib/advent.exにコピペして動かしてみませんか?

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment