GoのFacebook Messenger Platform APIライブラリを作った

先日からLINE BOTで遊んでいたところ、今朝のfacebookのDeveloper Conferenceのf8でMessenger Platformが公開されたので、合わせてGoのライブラリを作ってみました。

github.com

いつものechobotはこんな感じです。

f:id:stanaka:20160413144318p:plain

Callback URLはhttps必須ですので、herokuなどで動かすのがお手軽でしょう。LINE BOT APIとは異なりIPアドレスホワイトリスト設定は不要なので、Fixieアドオンなどなしで普通にheroku上で動かすことができます。FB_TOKENとVerify用のFB_VERIFY_TOKEN環境変数として設定します。

また、最初にcallbackのverifyが必要ですので、その処理が入ってます。この処理はVerifyが終われば消しても問題ありません。もちろんCallback URLを変更する際は再度verifyが必要です。

facebook Messenger Platformは最初にfacebook appやpageを作ったりいろいろ手順が必要ですので、公式ドキュメントに沿って進めるのが良いでしょう。あと別の人がbotに話しかけてもcallbackが飛んでこなったりすることもあるようで、まだ細かい挙動や条件がよくわからないところもいくつかありますが、そのあたりの熟れてないのを味わうのも初物の面白さなので、いろいろ触って楽しむのがいいんじゃないかと思っています。

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "os"

    fbmsg "github.com/stanaka/facebook-messenger"
)

var debug bool
var fb *fbmsg.FacebookMessenger

func callbackHandler(w http.ResponseWriter, r *http.Request) {
    b, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Printf("Something wrong: %s\n", err.Error())
        return
    }
    if debug {
        log.Println("RecievedMessage Body:", string(b))
    }

    m, _ := url.ParseQuery(r.URL.RawQuery)
    fmt.Println(m["hub.verify_token"])
    if len(m["hub.verify_token"]) > 0 && m["hub.verify_token"][0] == os.Getenv("FB_VERIFY_TOKEN") && len(m["hub.challenge"]) > 0 {
        fmt.Fprintf(w, m["hub.challenge"][0])
        return
    }

    var msg fbmsg.CallbackMessage
    err = json.Unmarshal(b, &msg)
    if err != nil {
        fmt.Printf("Something wrong: %s\n", err.Error())
        return
    }

    for _, event := range msg.Entry[0].Messaging {
        sender := event.Sender.ID
        if event.Message != nil {
            fmt.Printf("Recieved Text: %s\n", event.Message.Text)
            err := fb.SendTextMessage(sender, event.Message.Text)
            if err != nil {
                fmt.Printf("Something wrong: %s\n", err.Error())
            }
        }
    }

}

func main() {
    debug = true
    fb = &fbmsg.FacebookMessenger{
        Token: os.Getenv("FB_TOKEN"),
    }

    http.HandleFunc("/fbbot/callback", callbackHandler)

    port := os.Getenv("PORT")
    addr := fmt.Sprintf(":%s", port)
    http.ListenAndServe(addr, nil)
}