From de3a5d0949962528b9e427a06c4059224e393326 Mon Sep 17 00:00:00 2001 From: Bruce Fitzsimons Date: Thu, 18 Aug 2016 09:41:25 +1000 Subject: [PATCH] Add Read event support. Update description of Delivered events (#7) * Added Read message support Delivered message suppport already existed but was commented as indicating that a message was read by a user. As of the 1 July 2016 API release this isn't true, there is another event. This commit adds read event support and corrects the description of delivered events. Also added to the example bot. * go fmt * Added new profile fields from July 1st API update * gofmt --- actions.go | 7 +++++-- cmd/bot/main.go | 9 +++++++-- message.go | 21 ++++++++++++++++++--- messenger.go | 20 ++++++++++++++++++-- profile.go | 3 +++ receiving.go | 2 ++ 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/actions.go b/actions.go index 9143573..6f122fc 100644 --- a/actions.go +++ b/actions.go @@ -8,9 +8,12 @@ const ( UnknownAction Action = iota - 1 // TextAction means that the event was a text message (May contain attachments). TextAction - // DeliveryAction means that the event was a previous recipient reading their respective - // messages. + // DeliveryAction means that the event was advising of a successful delivery to a + // previous recipient. DeliveryAction + // ReadAction means that the event was a previous recipient reading their respective + // messages. + ReadAction // PostBackAction represents post call back PostBackAction ) diff --git a/cmd/bot/main.go b/cmd/bot/main.go index b3e61cc..50bee2f 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -42,9 +42,14 @@ func main() { r.Text(fmt.Sprintf("Hello, %v!", p.FirstName)) }) - // Setup a handler to be triggered when a message is read + // Setup a handler to be triggered when a message is delivered client.HandleDelivery(func(d messenger.Delivery, r *messenger.Response) { - fmt.Println(d.Watermark().Format(time.UnixDate)) + fmt.Println("Delivered at:", d.Watermark().Format(time.UnixDate)) + }) + + // Setup a handler to be triggered when a message is read + client.HandleDelivery(func(m messenger.Read, r *messenger.Response) { + fmt.Println("Read at:", m.Watermark().Format(time.UnixDate)) }) fmt.Println("Serving messenger bot on localhost:8080") diff --git a/message.go b/message.go index f1d8027..d7a1a48 100644 --- a/message.go +++ b/message.go @@ -21,12 +21,22 @@ type Message struct { Attachments []Attachment `json:"attachments"` } -// Delivery represents a the event fired when a recipient reads one of Messengers sent -// messages. +// Delivery represents a the event fired when Facebook delivers a message to the +// recipient. type Delivery struct { // Mids are the IDs of the messages which were read. Mids []string `json:"mids"` - // RawWatermark is the timestamp contained in the message of when the read was. + // RawWatermark is the timestamp of when the delivery was. + RawWatermark int64 `json:"watermark"` + // Seq is the sequence the message was sent in. + Seq int `json:"seq"` +} + +// Delivery represents a the event fired when a message is read by the +// recipient. +type Read struct { + // RawWatermark is the timestamp before which all messages have been read + // by the user RawWatermark int64 `json:"watermark"` // Seq is the sequence the message was sent in. Seq int `json:"seq"` @@ -48,3 +58,8 @@ type PostBack struct { func (d Delivery) Watermark() time.Time { return time.Unix(d.RawWatermark, 0) } + +// Watermark is the RawWatermark timestamp rendered as a time.Time. +func (r Read) Watermark() time.Time { + return time.Unix(r.RawWatermark, 0) +} diff --git a/messenger.go b/messenger.go index b72f904..e5a7a20 100644 --- a/messenger.go +++ b/messenger.go @@ -30,9 +30,12 @@ type Options struct { // MessageHandler is a handler used for responding to a message containing text. type MessageHandler func(Message, *Response) -// DeliveryHandler is a handler used for responding to a read receipt. +// DeliveryHandler is a handler used for responding to a delivery receipt. type DeliveryHandler func(Delivery, *Response) +// ReadHandler is a handler used for responding to a read receipt. +type ReadHandler func(Read, *Response) + // PostBackHandler is a handler used postback callbacks. type PostBackHandler func(PostBack, *Response) @@ -41,6 +44,7 @@ type Messenger struct { mux *http.ServeMux messageHandlers []MessageHandler deliveryHandlers []DeliveryHandler + readHandlers []ReadHandler postBackHandlers []PostBackHandler token string verifyHandler func(http.ResponseWriter, *http.Request) @@ -70,11 +74,17 @@ func (m *Messenger) HandleMessage(f MessageHandler) { } // HandleDelivery adds a new DeliveryHandler to the Messenger which will be triggered -// when a previously sent message is read by the recipient. +// when a previously sent message is delivered to the recipient. func (m *Messenger) HandleDelivery(f DeliveryHandler) { m.deliveryHandlers = append(m.deliveryHandlers, f) } +// HandleRead adds a new DeliveryHandler to the Messenger which will be triggered +// when a previously sent message is read by the recipient. +func (m *Messenger) HandleRead(f ReadHandler) { + m.readHandlers = append(m.readHandlers, f) +} + // HandlePostBack adds a new PostBackHandler to the Messenger func (m *Messenger) HandlePostBack(f PostBackHandler) { m.postBackHandlers = append(m.postBackHandlers, f) @@ -159,6 +169,10 @@ func (m *Messenger) dispatch(r Receive) { for _, f := range m.deliveryHandlers { f(*info.Delivery, resp) } + case ReadAction: + for _, f := range m.readHandlers { + f(*info.Read, resp) + } case PostBackAction: for _, f := range m.postBackHandlers { message := *info.PostBack @@ -178,6 +192,8 @@ func (m *Messenger) classify(info MessageInfo, e Entry) Action { return TextAction } else if info.Delivery != nil { return DeliveryAction + } else if info.Read != nil { + return ReadAction } else if info.PostBack != nil { return PostBackAction } diff --git a/profile.go b/profile.go index 0cf093c..f773c4a 100644 --- a/profile.go +++ b/profile.go @@ -5,4 +5,7 @@ type Profile struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` ProfilePicURL string `json:"profile_pic"` + Locale string `json:"locale"` + Timezone int `json:"timezone"` + Gender string `json:"gender"` } diff --git a/receiving.go b/receiving.go index f4c0aca..aa9799d 100644 --- a/receiving.go +++ b/receiving.go @@ -35,6 +35,8 @@ type MessageInfo struct { Delivery *Delivery `json:"delivery"` PostBack *PostBack `json:"postback"` + + Read *Read `json:"read"` } // Sender is who the message was sent from.