[Go言語]Linebot最短作成手順

はじめに

Line APIを利用して、自動で天気情報を送信するbotを作成したので
準備から公開までの手順をまとめる。

目次

  • 事前準備
  • LINE Developers プロバイダー登録
  • Messaging APIのチャネル作成
  • Linebotサンプルコードを作成

動作環境

事前準備

LINE Developers プロバイダー登録

  1. Line Developersにアクセスする
  2. Log in 押下
  3. Create New Provider 押下
  4. Provider name : Café com Leite (好きな名前)
  5. Create 押下

Messaging APIのチャネル作成

f:id:yuki9431:20190720170058p:plain

  1. Messaging API チャネル作成する 押下
  2. Messaging APIの情報入力

    • アプリ名: CentOS bot (好きな名前)
    • アプリ説明: Learning Line API
    • 大業種、小業種:個人用なので適当に
    • メールアドレス:hoge@hoge.net
  3. 規約に同意して、作成押下

Linebotサンプルコードを作成

  1. Linebotを載せるサーバ(CentOS)にログインして事前準備

    ```$

     # Goのソース保管ディレクトルに移動
     cd $GOPATH/src
    
     # Linebot用のディレクトリ作成
     mkdir linebot/ && cd linebot/;pwd
    
     # サンプルコード作成 (gitでダウンロードするならスキップ)
     vi linebot.go
    
  2. Line公式のサンプルコードをダウンロード (github)

  3. サンプルコードを少し編集する
    ```go:linebot.go

     package main
    
     import (
         "log"
         "net/http"
         "os"
    
         "github.com/line/line-bot-sdk-go/linebot"
         "github.com/line/line-bot-sdk-go/linebot/httphandler"
     )
    
     func main() {
    
         // CHANNEL_SECRETとCHANNEL_TOKENはLine Developersから取得できる
         handler, err := httphandler.New(
             os.Getenv("CHANNEL_SECRET"),
             os.Getenv("CHANNEL_TOKEN"),
         )
         if err != nil {
             log.Fatal(err)
         }
    
         // Setup HTTP Server for receiving requests from LINE platform
         handler.HandleEvents(func(events []*linebot.Event, r *http.Request) {
             bot, err := handler.NewClient()
             if err != nil {
                 log.Print(err)
                 return
             }
             for _, event := range events {
                 if event.Type == linebot.EventTypeMessage {
                     switch message := event.Message.(type) {
                     case *linebot.TextMessage:
                         if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.Text)).Do(); err != nil {
                             log.Print(err)
                         }
                     }
                 }
             }
         })
         http.Handle("/callback", handler)
    
         //if err := http.ListenAndServe(":"+os.Getenv("PORT"), nil); err != nil {
         //  log.Fatal(err)
         //}
    
         // HTTPではLine APIを利用できないため、HTTPSに変更する 
         // CERT_FILEとKEY_FILEはSSL証明書を発行した後に書き換える
         if err := http.ListenAndServeTLS(":443", "CERT_FILE", "KEY_FILE", nil); err != nil {
             logger.Fatal("ListenAndServe: ", err)
         }
     }
    

ルータとファイアウォールの設定

ファイアウォールが有効な場合は、443ポートの通信を許可する。ファイアウォールの設定は無効にして実施したため、ここでは詳細を割愛する。 また、自宅のサーバで公開する場合は443ポートを開けて、対象サーバにポートフォワーディングするように設定する必要がある。設定方法はルータの機器によって異なるが、自宅のルータ(ヤマハ製)では、下記の通り設定している。

    pp select 1
        ip pp secure filter in 200003 ... 300001
        ip pp nat descriptor 1000

    ip filter 300001 pass * <サーバのローカルIPアドレス> tcp * www,https
    nat descriptor type 1000 masquerade
    nat descriptor masquerade static 1000 105 <サーバのローカルIPアドレス> tcp www,https

SSL証明書取得

SSL証明書は無料のLet's Encryptを使用する。
公式チュートリアルでプラットフォームごとの説明があり、非常わかりやすい。
チュートリアルの通りコマンドを叩けば証明書を発行できる。

証明書の場所とAPI Keyをサンプルコードに追記

  1. Channel ScreatとChannel Tokenの確認方法
    1. Line Developersにアクセスする
    2. プロバイダーリストから対象を選ぶ
    3. チャネル基本設定で確認できる(図を参照) f:id:yuki9431:20190720170149p:plainf:id:yuki9431:20190720170153p:plain
  2. CHANNEL_SECRETとCHANNEL_TOKENを書き換え

    ```go:linebot.go

     //handler, err := httphandler.New(
     //    os.Getenv("CHANNEL_SECRET"),
     //    os.Getenv("CHANNEL_TOKEN"),
     //)
    
     handler, err := httphandler.New(
         "CHANNEL_SECRET",
         "CHANNEL_TOKEN",
     )
    
  3. サーバ証明書の場所を追記する

    ```go:linebot.go

     //if err := http.ListenAndServeTLS(":443", "CERT_FILE", "KEY_FILE", nil); err != nil {
     //    logger.Fatal("ListenAndServe: ", err)
     //}
    
     if err := http.ListenAndServeTLS(
         ":443",
         "/etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem",
         "/etc/letsencrypt/live/DOMAIN_NAME/privkey.pem", nil); err != nil {
         logger.Fatal("ListenAndServe: ", err)
     }
    

稼働確認

  1. サンプルコードをコンパイル&実行する

    ```$

     # カレントディレクトリの確認(linebot配下にいること)
     pwd
    
     # ソースファイルをコンパイルする
     go build
    
     # バックグラウンドでLinebotを実行する
     sudo ./linebot &
    
  2. Line Developersで、サーバのグローバルIPアドレスドメインをWebhookに設定する。
    例:"https://myLinebot.com/callback"

  3. 接続確認を押下して、「成功しました。」と表示されたらOK

  4. プロバイダーページにあるQRコードを手持ちのスマホで読み込んで登録する

  5. メッセージを送信して。鸚鵡返しが来たら成功

おわりに

Linebotを公開するまでに一番苦労するのはネットワーク周りの設定だと思う。
Line APISSL通信しか許可されないからサーバ証明書ドメイン取得が必要だし、少し敷居が高いと感じた。
また、私の場合は同時期にヤマハのRTX1200を自宅に入れたばかりだったため、ポートフォワーディングの設定ができるまで時間がかかった。
ネットワーク周りの設定ができてしまえば、あとはAPIを叩くだけので大した作業はない。
openweatherのAPIと組み合わせて、毎日天気配信をするbotを作成したが、無料アカウントだけでいろいろ試せて非常に楽しかった。(https://github.com/yuki9431/myLinebot)