1
0
mirror of synced 2024-11-25 14:26:09 +03:00

Add handling receiving messages

This commit is contained in:
Harrison Shoebridge 2016-04-13 16:14:23 +10:00
parent 8f272bbf30
commit 5006304edf
6 changed files with 123 additions and 2 deletions

3
.gitignore vendored
View File

@ -22,3 +22,6 @@ _testmain.go
*.exe *.exe
*.test *.test
*.prof *.prof
# Configuration
cmd/bot/config.json

8
actions.go Normal file
View File

@ -0,0 +1,8 @@
package messenger
type Action int
const (
UnknownAction Action = iota - 1
TextAction
)

View File

@ -3,6 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"time"
"github.com/paked/configure" "github.com/paked/configure"
"github.com/paked/messenger" "github.com/paked/messenger"
@ -26,6 +27,11 @@ func main() {
VerifyToken: *verifyToken, VerifyToken: *verifyToken,
}) })
m.Handle(messenger.TextAction, func(m messenger.Message) {
fmt.Printf("%v (Sent, %v)\n", m.Text, m.Time.Format(time.UnixDate))
})
fmt.Println("Serving messenger bot on localhost:8080") fmt.Println("Serving messenger bot on localhost:8080")
http.ListenAndServe("localhost:8080", m.Handler()) http.ListenAndServe("localhost:8080", m.Handler())
} }

10
message.go Normal file
View File

@ -0,0 +1,10 @@
package messenger
import "time"
type Message struct {
Sender int64
Recipient int64
Time time.Time
Text string
}

View File

@ -1,8 +1,10 @@
package messenger package messenger
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"time"
) )
const ( const (
@ -14,26 +16,85 @@ type MessengerOptions struct {
VerifyToken string VerifyToken string
} }
type MessageHandler func(Message)
type Messenger struct { type Messenger struct {
mux *http.ServeMux mux *http.ServeMux
handlers map[Action]MessageHandler
} }
func New(mo MessengerOptions) *Messenger { func New(mo MessengerOptions) *Messenger {
m := &Messenger{ m := &Messenger{
mux: http.NewServeMux(), mux: http.NewServeMux(),
handlers: make(map[Action]MessageHandler),
} }
if mo.Verify { if mo.Verify {
m.mux.HandleFunc(WebhookURL, newVerifyHandler(mo.VerifyToken)) m.mux.HandleFunc(WebhookURL, newVerifyHandler(mo.VerifyToken))
} else {
m.mux.HandleFunc(WebhookURL, m.handle)
} }
return m return m
} }
func (m *Messenger) Handle(a Action, f MessageHandler) {
m.handlers[a] = f
}
func (m *Messenger) Handler() http.Handler { func (m *Messenger) Handler() http.Handler {
return m.mux 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 {
f(Message{
Sender: info.Sender.ID,
Recipient: info.Recipient.ID,
Time: time.Unix(info.Timestamp, 0),
Text: info.Message.Text,
})
}
}
}
}
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) { func newVerifyHandler(token string) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if r.FormValue("hub.verify_token") == token { if r.FormValue("hub.verify_token") == token {

33
receiving.go Normal file
View File

@ -0,0 +1,33 @@
package messenger
type Receive struct {
Object string `json:"object"`
Entry []Entry `json:"entry"`
}
type Entry struct {
ID int64 `json:"id"`
Time int64 `json:"time"`
Messaging []MessageInfo `json:"messaging"`
}
type MessageInfo struct {
Sender Sender `json:"sender"`
Recipient Recipient `json:"recipient"`
Timestamp int64 `json:"timestamp"`
Message *MessageCallback `json:"message"`
}
type Sender struct {
ID int64 `json:"id"`
}
type Recipient struct {
ID int64 `json:"id"`
}
type MessageCallback struct {
Mid string `json:"mid"`
Seq int `json:"seq"`
Text string `json:"text"`
}