LoginSignup
29
31

More than 5 years have passed since last update.

GAE/Go (echoフレームワーク)で Line Message API 使って Bot を作る。

Last updated at Posted at 2016-11-14

Line Message API を使って、おうむ返しするだけのBotを作ってみました。

準備

まず、Line Message API を使用するための準備を行います。
以下の記事を参考にしました。

LINE BOTの作り方を世界一わかりやすく解説(1)【アカウント準備編】

また、GAE/Goのデプロイできる環境は公式ドキュメントこちらの記事などを参考に構築してください。

今回はGolangのフレームワークとしてechoを使用しました。

$ go get -u github.com/labstack/echo

実装

GAEでechoを動かす方法はチュートリアルがあるので、それを見ながら実装します。

実装にあたってはこちらの記事も参考にさせていただきました。
Go製のフレームワークechoを使ってJSONを返すWebサーバーを作り、GoogleAppEngineで動かす

まず、起点となるファイル。

app.go
package main

var e = createMux()

次にローカルのdev server用の実装。
※1行目のコメントを書き漏らさないようにしてください。

app-standalone.go
// +build !appengine,!appenginevm

package main

import (
    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
    "github.com/labstack/echo/middleware"
)

func createMux() *echo.Echo {
    e := echo.New()

    e.Use(middleware.Recover())
    e.Use(middleware.Logger())
    e.Use(middleware.Gzip())

    e.Use(middleware.Static("public"))

    return e
}

func main() {
    e.Run(standard.New(":8080"))
}

で、デプロイしてGAE/SEで動かすとき用の実装。

app-engine.go
// +build appengine

package main

import (
    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
    "net/http"
)

func createMux() *echo.Echo {
    e := echo.New()

    s := standard.New("")
    s.SetHandler(e)
    http.Handle("/", s)

    return e
}

静的なHTMLを作ります。
publicディレクトリを作って、その下に作ることにします。

public/index.html
<h1>Hello, LineBot!</h1>

※挙動には関係ありませんが、ちゃんとデプロイできたかの確認にも使えるので、作っておくと良いと思います。

次は設定ファイルです。
Your Project ID には GCPのプロジェクトIDを入れてください。

app.yaml
application: <Your Project ID>
module: default
version: alpha
runtime: go
api_version: go1

handlers:
- url: /
  mime_type: text/html
  static_files: public/index.html
  upload: public/index.html

- url: /.*
  script: _go_app

やっとメインの実装です。

hook.go
package main

import (
    "math/rand"
    "net/http"
    "strings"
    "time"

    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
    "github.com/labstack/echo/middleware"
    "github.com/line/line-bot-sdk-go/linebot"
    "google.golang.org/appengine"
    "google.golang.org/appengine/log"
    "google.golang.org/appengine/urlfetch"
)

func init() {

    g := e.Group("/hook")
    g.Use(middleware.CORS())

    g.GET("", helloMsg)
    g.POST("", postBot)
}

func helloMsg(c echo.Context) error {
    // 意味ないんですが、一応GETの返却
    return c.JSON(http.StatusOK, "hello!")
}

func postBot(c echo.Context) error {
    // SecretとTokenはLineの設定画面にあります
    channelSecret := "<Your Channel Secret>"
    channelAccessToken := "<Your Channel AccessToken>"

    // appengineのコンテキストからclientを生成します。ここがポイント。
    cx := appengine.NewContext(c.Request().(*standard.Request).Request)
    client := urlfetch.Client(cx)

    bot, err := linebot.New(channelSecret, channelAccessToken, linebot.WithHTTPClient(client))
    if err != nil {
        log.Infof(cx, err.Error())
        return c.JSON(http.StatusInternalServerError, err)
    }

    received, err := bot.ParseRequest(c.Request().(*standard.Request).Request)
    if err != nil {
        log.Infof(cx, err.Error())
        return c.JSON(http.StatusInternalServerError, err)
    }

    for _, event := range received {
        if event.Type == linebot.EventTypeMessage {
            switch message := event.Message.(type) {
            case *linebot.TextMessage:
                log.Infof(cx, "TextMessage %#v", message)
                // 送ったメッセージをおうむ返ししているだけ
                resMessage := linebot.NewTextMessage(message.Text)
                if _, err = bot.ReplyMessage(event.ReplyToken, resMessage).Do(); err != nil {
                    log.Errorf(cx, "send error: %v", err)
                }
            }
        }
    }

    return c.JSON(http.StatusOK, "success")
}

ファイル構成

├─ app.go
├─ app.yaml
├─ app-engine.go
├─ app-standalone.go
├─ hook.go
├─ public
    ├─index.html

デプロイ

あとはデプロイして完成です。
デプロイが終わったら、LineでBotに対してメッセージを送ってみてください。

goapp deploy ./
29
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
31