Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
111 lines (90 sloc) 2.72 KB
package messenger
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
)
// Bot handles communication to and from Messenger
type Bot struct {
pageAccessToken string
verificationToken string
messagingHandler func(m Messaging) error
httpClient http.Client
}
// New creates a new Bot with the appropriate tokens and messaging handler.
func New(pageAccessToken, verificationToken string, messagingHandler func(m Messaging) error) *Bot {
return &Bot{
pageAccessToken: pageAccessToken,
verificationToken: verificationToken,
messagingHandler: messagingHandler,
}
}
// HandleWebhookPost executes the messagingHandler callback for each Messaging present.
func (m *Bot) HandleWebhookPost(w http.ResponseWriter, r *http.Request) {
var webhookData WebhookRequest
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&webhookData)
if err != nil {
http.Error(w, "Error decoding request body", http.StatusBadRequest)
return
}
for _, entry := range webhookData.Entries {
for _, messaging := range entry.Messagings {
if messaging.Message != nil {
go func(msg Messaging) {
err := m.messagingHandler(msg)
if err != nil {
log.Println("Error executing messaging handler:", err)
}
}(messaging)
}
}
}
w.WriteHeader(200)
}
// SendGenericTemplateReply uses the Send API to send a message to a user
func (m *Bot) SendGenericTemplateReply(recipientID int64, elements []GenericTemplateElement) (err error) {
var r GenericTemplateReply
r.Recipient.ID = recipientID
r.Message.Attachment.Type = "template"
r.Message.Attachment.Payload.TemplateType = "generic"
r.Message.Attachment.Payload.Elements = elements
marshalled, err := json.Marshal(r)
if err != nil {
return
}
req, err := http.NewRequest("POST", "https://graph.facebook.com/v2.6/me/messages", bytes.NewBuffer(marshalled))
if err != nil {
return
}
req.Header.Set("Content-Type", "application/json")
q := req.URL.Query()
q.Add("access_token", m.pageAccessToken)
req.URL.RawQuery = q.Encode()
resp, err := m.httpClient.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return
}
var sendError SendError
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(&sendError)
if err != nil {
return
}
return fmt.Errorf("Error sending response: %s", sendError.Error.Message)
}
// HandleVerificationChallenge allows Facebook to verify this bot.
func (m *Bot) HandleVerificationChallenge(w http.ResponseWriter, r *http.Request) {
givenVerificationToken := r.URL.Query().Get("hub.verify_token")
if givenVerificationToken != m.verificationToken {
http.Error(w, "Incorrect verification token", http.StatusUnauthorized)
} else {
w.Write([]byte(r.URL.Query().Get("hub.challenge")))
}
}