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で動かす
まず、起点となるファイル。
package main
var e = createMux()
次にローカルのdev server用の実装。
※1行目のコメントを書き漏らさないようにしてください。
// +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で動かすとき用の実装。
// +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ディレクトリを作って、その下に作ることにします。
<h1>Hello, LineBot!</h1>
※挙動には関係ありませんが、ちゃんとデプロイできたかの確認にも使えるので、作っておくと良いと思います。
次は設定ファイルです。
Your Project ID には GCPのプロジェクトIDを入れてください。
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
やっとメインの実装です。
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 ./