背景
以下を参考にさせてもらいました。
LINE Developer Trialを GAE/Go で始める #linedevday
ソース
GAE環境の準備
- GAE/Go SDKをダウンロードする
- Cloud Consoleで新しいプロジェクトを作成してprojectIDをメモする
LINE Developers設定
MessageAPIを始める
- LINE BUSINESS CENTERでMessageAPIを始める
- Bot設定から[APIを利用する]ボタンを押して有効したのち、bot設定を以下のように設定する
項目 設定 Webhook送信 利用する Botのグループトーク参加 利用する 自動応答メッセージ 利用しない(デフォルトは利用する) 友だち追加時あいさつ 利用する - LINE Developersで「Channel Secret」と「Channel Access Token」をメモする1
- 同じ画面の下の方に、EDITとあるので編集画面に行きWebhookに
https://<projectID>.appspot.com/callback
と設定する
SDKをインストール
go getでインストール
$ go get -u github.com/line/line-bot-sdk-go/linebot
$ go get -u github.com/joho/godotenv
$ go get -u google.golang.org/appengine
GAEにdeployするための、app.yamlを作成
$ mkdir linebot;cd linebot
$ vi app.yaml
<projectID>にprojectIDを入力してください。
python:
application: <projectID>
version: 1
runtime: go
api_version: go1
handlers:
- url: /task.*
script: _go_app
login: admin
secure: always
- url: /.*
script: _go_app
secure: always
line.envを作成する
「Channel Secret」と「Channel Access Token」を環境変数として入力します。
このファイルの取り扱いには注意が必要です。ソースコードをgithubで保管する場合は.gitignoreに/line.env
と記入してpushされないようにしてください。
LINE_BOT_CHANNEL_SECRET=[Your secret]
LINE_BOT_CHANNEL_TOKEN=[Your Channel Token]
app.goを作成する
LINEでテキストを送信すると「ok」と返すだけのコードです。
※ソースコードの解説は省きます。
package main
import (
"encoding/base64"
"encoding/json"
"net/http"
"net/url"
"os"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
"google.golang.org/appengine/taskqueue"
"google.golang.org/appengine/urlfetch"
"golang.org/x/net/context"
"github.com/joho/godotenv"
"github.com/line/line-bot-sdk-go/linebot"
"github.com/line/line-bot-sdk-go/linebot/httphandler"
)
var botHandler *httphandler.WebhookHandler
func init() {
err := godotenv.Load("line.env")
if err != nil {
panic(err)
}
botHandler, err = httphandler.New(
os.Getenv("LINE_BOT_CHANNEL_SECRET"),
os.Getenv("LINE_BOT_CHANNEL_TOKEN"),
)
botHandler.HandleEvents(handleCallback)
http.Handle("/callback", botHandler)
http.HandleFunc("/task", handleTask)
}
func newLINEBot(c context.Context) (*linebot.Client, error) {
return botHandler.NewClient(
linebot.WithHTTPClient(urlfetch.Client(c)),
)
}
// newContext は appengine.NewContext を短く書くための関数
func newContext(r *http.Request) context.Context {
return appengine.NewContext(r)
}
// logf は log.Infof を短く書くための関数
func logf(c context.Context, format string, args ...interface{}) {
log.Infof(c, format, args...)
}
// errorf は log.Errorf を短く書くための関数
func errorf(c context.Context, format string, args ...interface{}) {
log.Errorf(c, format, args...)
}
// Webhook を受け取って TaskQueueに詰める関数
func handleCallback(evs []*linebot.Event, r *http.Request) {
c := newContext(r)
ts := make([]*taskqueue.Task, len(evs))
for i, e := range evs {
j, err := json.Marshal(e)
if err != nil {
errorf(c, "json.Marshal: %v", err)
return
}
data := base64.StdEncoding.EncodeToString(j)
t := taskqueue.NewPOSTTask("/task", url.Values{"data": {data}})
ts[i] = t
}
taskqueue.AddMulti(c, ts, "")
}
// 受け取ったメッセージを処理する関数
func handleTask(w http.ResponseWriter, r *http.Request) {
c := newContext(r)
data := r.FormValue("data")
if data == "" {
errorf(c, "No data")
return
}
j, err := base64.StdEncoding.DecodeString(data)
if err != nil {
errorf(c, "base64 DecodeString: %v", err)
return
}
e := new(linebot.Event)
err = json.Unmarshal(j, e)
if err != nil {
errorf(c, "json.Unmarshal: %v", err)
return
}
bot, err := newLINEBot(c)
if err != nil {
errorf(c, "newLINEBot: %v", err)
return
}
logf(c, "EventType: %s\nMessage: %#v", e.Type, e.Message)
m := linebot.NewTextMessage("ok")
if _, err = bot.ReplyMessage(e.ReplyToken, m).WithContext(c).Do(); err != nil {
errorf(c, "ReplayMessage: %v", err)
return
}
w.WriteHeader(200)
}
デプロイする
$ goapp deploy
もしここで、
ERROR appcfg.py:2411 An error occurred processing file '': HTTP Error 403: Forbidden Unexpected HTTP status 403. Aborting.
と出たら、ホームディレクトリに.appcfg_oauth2_tokens
が生成されているためなので、このファイルを削除してdeployを再実行してください。うまくいくとブラウザが開き、googleアカウントでログインする画面が表示されます。
ログインするとデプロイ処理が進みます。Compile failedが出る場合はソースコードに誤りがあります。直して再デプロイしてください。Deployment successful.
と表示されたら成功です。
GCP Consoleでロギングを確認。

「!!」アイコンの行を展開すると、最下段に
ReplayMessage: linebot: APIError 403 Access to this API denied due to the following reason: Your ip address [Your IP address] is not allowed to access this API. Please add your IP to the IP whitelist in the developer center.
と表示されているのがわかります。
これはLINE DevelopersのServer IP Whitelistに[Your IP address]が登録されていないために、GCPからLINE APIの使用が許可されていないことを表すエラーメッセージとなります。
IP AddressをServer IP Whitelistに登録
10月18日時点の状態です。現在は制限が無く、IP Whitelistへの追加は不要かもしれません。
LINE DevelopersのServer IP WhitelistにGCPで確認したIP Addressを追加します。2
LINEで友達登録しテキスト送信
