Go와 Docker와 Heroku에서 LINEBOT을 위해 시도

소개



상기의 조합의 Qiita의 기사가 없었기 때문에 정리해 보았습니다.
Git, Docker, Heroku의 최소 지식을 전제로 합니다.

디렉토리 구성



linebot_go
| - Dockerfile
| - heroku.yml
| - main.go

Go와 Docker와 Heroku 환경 준비



LINEBOT을 도입하기 전에 먼저 이 기사를 참고하여 준비합니다.
Go로 작성한 서버를 Heroku에 Docker Deploy

푸시하면 Heroku에 자동 배포됩니다.



위의 기사라면 매번 배포하는데 2명령을 쳐야 하므로 1명령으로 배포할 수 있도록 합니다.

・위 기사(2명령)
$ heroku container:push web
$ heroku container:release web

· 1명령
$ git push heroku master

루트 디렉토리에 heroku.yml를 추가하십시오.
내용은 다음과 같습니다.

heroku.yml
build:
  docker:
    web: Dockerfile

참고 : Building Docker Images with heroku.yml

LINEBOT 도입



LINE 계정 생성, SDK 설치



이 기사를 참고하여 계정을 만들고 SDK를 설치합니다.
Go 입문! ? LineAPI와 GO로 앵무새 반환 bot 만들기
⇒Line 계정 준비, Line SDK 설치

main.go 수정



SDK에 있는 다음 샘플을 참고하여 main.go를 수정합니다.line-bot-sdk-go/examples/echo_bot/server.go
main.go
package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
    "strconv"

    "github.com/line/line-bot-sdk-go/linebot"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello world!\n")
}

func lineHandler(w http.ResponseWriter, r *http.Request) {
    bot, err := linebot.New(
        "(自分のシークレットを入力)",
        "(自分のアクセストークンを入力)",
    )
    if err != nil {
        log.Fatal(err)
    }

    events, err := bot.ParseRequest(r)
    if err != nil {
        if err == linebot.ErrInvalidSignature {
            w.WriteHeader(400)
        } else {
            w.WriteHeader(500)
        }
        return
    }
    for _, event := range events {
        if event.Type == linebot.EventTypeMessage {
            switch message := event.Message.(type) {
            case *linebot.TextMessage:
                replyMessage := message.Text
                if replyMessage == "ぶりぶり" {
                    replyMessage = fmt.Sprintf("あああああああああああああああああああああああああああああああ!!!!!!!!!!!(ブリブリブリブリュリュリュリュリュリュ!!!!!!ブツチチブブブチチチチブリリイリブブブブゥゥゥゥッッッ!!!!!!!)")
                }
                if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(replyMessage)).Do(); err != nil {
                    log.Print(err)
                }
            case *linebot.StickerMessage:
                replyMessage := fmt.Sprintf(
                    "sticker id is %s, stickerResourceType is %s", message.StickerID, message.StickerResourceType)
                if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(replyMessage)).Do(); err != nil {
                    log.Print(err)
                }
            }
        }
    }
}

func main() {
    port, _ := strconv.Atoi(os.Args[1])
    fmt.Printf("Starting server at Port %d", port)
    http.HandleFunc("/", handler)
    http.HandleFunc("/callback", lineHandler)
    http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}

Dockerfile 수정



그대로의 Dockerfile이라고 LINE의 SDK가 Heroku에 인스톨 되지 않기 때문에 이하의 커멘드를 추기합니다.RUN go get github.com/line/line-bot-sdk-go/linebot
Dockerfile
FROM golang:latest as builder

ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
WORKDIR /go/src/github.com/yokoe/go-server-example
COPY . .
RUN go get github.com/line/line-bot-sdk-go/linebot
RUN go build main.go

# runtime image
FROM alpine
COPY --from=builder /go/src/github.com/yokoe/go-server-example /app

CMD /app/main $PORT

Heroku에 push


git push heroku master 에서 push.

LINE Developers Webhook에 Heroku URL 설정



LINE Developers > Messaging API 설정 > Webhook 설정
에 Heroku URL을 입력합니다.


BOT를 친구 추가하고 굳이!



좋은 웹페이지 즐겨찾기