1
0
mirror of synced 2024-11-22 04:46:05 +03:00
messenger/messenger.go
Harrison Shoebridge 7fed4ecf28 Add message sending
2016-04-13 17:02:02 +10:00

118 lines
2.2 KiB
Go

package messenger
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
const (
WebhookURL = "/webhook"
)
type MessengerOptions struct {
Verify bool
VerifyToken string
Token string
}
type MessageHandler func(Message, *Response)
type Messenger struct {
mux *http.ServeMux
handlers map[Action]MessageHandler
token string
}
func New(mo MessengerOptions) *Messenger {
m := &Messenger{
mux: http.NewServeMux(),
handlers: make(map[Action]MessageHandler),
token: mo.Token,
}
if mo.Verify {
m.mux.HandleFunc(WebhookURL, newVerifyHandler(mo.VerifyToken))
} else {
m.mux.HandleFunc(WebhookURL, m.handle)
}
return m
}
func (m *Messenger) Handle(a Action, f MessageHandler) {
m.handlers[a] = f
}
func (m *Messenger) Handler() http.Handler {
return m.mux
}
func (m *Messenger) handle(w http.ResponseWriter, r *http.Request) {
var rec Receive
err := json.NewDecoder(r.Body).Decode(&rec)
if err != nil {
fmt.Println(err)
fmt.Fprintln(w, `{status: 'not ok'}`)
return
}
if rec.Object != "page" {
fmt.Println("Object is not page, undefined behaviour. Got", rec.Object)
}
m.dispatch(rec)
fmt.Fprintln(w, `{status: 'ok'}`)
}
func (m *Messenger) dispatch(r Receive) {
for _, entry := range r.Entry {
for _, info := range entry.Messaging {
a := m.classify(info, entry)
if a == UnknownAction {
fmt.Println("Unknown action:", info)
continue
}
if f := m.handlers[a]; f != nil {
message := Message{
Sender: info.Sender.ID,
Recipient: info.Recipient.ID,
Time: time.Unix(info.Timestamp, 0),
Text: info.Message.Text,
}
response := &Response{
to: Recipient{info.Sender.ID},
token: m.token,
}
f(message, response)
}
}
}
}
func (m *Messenger) classify(info MessageInfo, e Entry) Action {
if info.Message != nil {
return TextAction
}
return UnknownAction
}
func newVerifyHandler(token string) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.FormValue("hub.verify_token") == token {
fmt.Fprintln(w, r.FormValue("hub.challenge"))
return
}
fmt.Fprintln(w, "Incorrect verify token.")
}
}