1
0
mirror of synced 2024-11-21 20:36:06 +03:00

Api update

Postback action handler
Dynamic WebHook
Button Template Message
Generic Template Message
This commit is contained in:
Panich Maxim 2016-05-03 16:42:25 +03:00
parent 494b974cb2
commit eb0e72a5dc
5 changed files with 172 additions and 20 deletions

View File

@ -11,4 +11,6 @@ const (
// DeliveryAction means that the event was a previous recipient reading their respective
// messages.
DeliveryAction
// PostBackAction represents post call back
PostBackAction
)

View File

@ -32,6 +32,18 @@ type Delivery struct {
Seq int `json:"seq"`
}
// PostBack represents postback callback
type PostBack struct {
// Sender is who the message was sent from.
Sender Sender `json:"-"`
// Recipient is who the message was sent to.
Recipient Recipient `json:"-"`
// Time is when the message was sent.
Time time.Time `json:"-"`
// PostBack ID
Payload string `json:"payload"`
}
// Watermark is the RawWatermark timestamp rendered as a time.Time.
func (d Delivery) Watermark() time.Time {
return time.Unix(d.RawWatermark, 0)

View File

@ -8,9 +8,6 @@ import (
)
const (
// WebhookURL is where the Messenger client should listen for webhook events.
WebhookURL = "/webhook"
// ProfileURL is the API endpoint used for retrieving profiles.
// Used in the form: https://graph.facebook.com/v2.6/<USER_ID>?fields=first_name,last_name,profile_pic&access_token=<PAGE_ACCESS_TOKEN>
ProfileURL = "https://graph.facebook.com/v2.6/"
@ -26,6 +23,8 @@ type Options struct {
VerifyToken string
// Token is the access token of the Facebook page to send messages from.
Token string
// WebhookURL is where the Messenger client should listen for webhook events.
WebhookURL string
}
// MessageHandler is a handler used for responding to a message containing text.
@ -34,11 +33,15 @@ type MessageHandler func(Message, *Response)
// DeliveryHandler is a handler used for responding to a read receipt.
type DeliveryHandler func(Delivery, *Response)
// PostBackHandler is a handler used postback callbacks.
type PostBackHandler func(PostBack, *Response)
// Messenger is the client which manages communication with the Messenger Platform API.
type Messenger struct {
mux *http.ServeMux
messageHandlers []MessageHandler
deliveryHandlers []DeliveryHandler
postBackHandlers []PostBackHandler
token string
verifyHandler func(http.ResponseWriter, *http.Request)
}
@ -51,7 +54,7 @@ func New(mo Options) *Messenger {
}
m.verifyHandler = newVerifyHandler(mo.VerifyToken)
m.mux.HandleFunc(WebhookURL, m.handle)
m.mux.HandleFunc(mo.WebhookURL, m.handle)
return m
}
@ -68,6 +71,11 @@ func (m *Messenger) HandleDelivery(f DeliveryHandler) {
m.deliveryHandlers = append(m.deliveryHandlers, f)
}
// HandlePostBack adds a new PostBackHandler to the Messenger
func (m *Messenger) HandlePostBack(f PostBackHandler) {
m.postBackHandlers = append(m.postBackHandlers, f)
}
// Handler returns the Messenger in HTTP client form.
func (m *Messenger) Handler() http.Handler {
return m.mux
@ -106,7 +114,6 @@ func (m *Messenger) handle(w http.ResponseWriter, r *http.Request) {
err := json.NewDecoder(r.Body).Decode(&rec)
if err != nil {
fmt.Println(err)
fmt.Fprintln(w, `{status: 'not ok'}`)
return
}
@ -136,19 +143,26 @@ func (m *Messenger) dispatch(r Receive) {
}
switch a {
case TextAction:
for _, f := range m.messageHandlers {
message := *info.Message
message.Sender = info.Sender
message.Recipient = info.Recipient
message.Time = time.Unix(info.Timestamp, 0)
f(message, resp)
}
case DeliveryAction:
for _, f := range m.deliveryHandlers {
f(*info.Delivery, resp)
}
case TextAction:
for _, f := range m.messageHandlers {
message := *info.Message
message.Sender = info.Sender
message.Recipient = info.Recipient
message.Time = time.Unix(info.Timestamp, 0)
f(message, resp)
}
case DeliveryAction:
for _, f := range m.deliveryHandlers {
f(*info.Delivery, resp)
}
case PostBackAction:
for _, f := range m.postBackHandlers {
message := *info.PostBack
message.Sender = info.Sender
message.Recipient = info.Recipient
message.Time = time.Unix(info.Timestamp, 0)
f(message, resp)
}
}
}
}
@ -160,8 +174,9 @@ func (m *Messenger) classify(info MessageInfo, e Entry) Action {
return TextAction
} else if info.Delivery != nil {
return DeliveryAction
} else if info.PostBack != nil {
return PostBackAction
}
return UnknownAction
}
@ -172,7 +187,6 @@ func newVerifyHandler(token string) func(w http.ResponseWriter, r *http.Request)
fmt.Fprintln(w, r.FormValue("hub.challenge"))
return
}
fmt.Fprintln(w, "Incorrect verify token.")
}
}

View File

@ -33,6 +33,8 @@ type MessageInfo struct {
// Delivery is the contents of a message if it is a DeliveryAction.
// Nil if it is not a DeliveryAction.
Delivery *Delivery `json:"delivery"`
PostBack *PostBack `json:"postback"`
}
// Sender is who the message was sent from.

View File

@ -97,6 +97,85 @@ func (r *Response) Image(im image.Image) error {
return nil
}
func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButton) error {
m := SendStructuredMessage {
Recipient: r.to,
Message: StructuredMessageData {
Attachment: StructuredMessageAttachment {
Type: "template",
Payload: StructuredMessagePayload {
TemplateType: "button",
Text: text,
Buttons: buttons,
Elements: nil,
},
},
},
}
fmt.Println(m)
data, err := json.Marshal(m)
if err != nil {
return nil
}
req, err := http.NewRequest("POST", SendMessageURL, bytes.NewBuffer(data))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.URL.RawQuery = "access_token=" + r.token
client := &http.Client{}
resp, err := client.Do(req)
fmt.Println(resp)
defer resp.Body.Close()
return err
}
func (r *Response) GenericTemplate(text string, elements *[]StructuredMessageElement) error {
m := SendStructuredMessage {
Recipient: r.to,
Message: StructuredMessageData {
Attachment: StructuredMessageAttachment {
Type: "template",
Payload: StructuredMessagePayload {
TemplateType: "generic",
Buttons: nil,
Elements: elements,
},
},
},
}
fmt.Println(m)
data, err := json.Marshal(m)
if err != nil {
return nil
}
req, err := http.NewRequest("POST", SendMessageURL, bytes.NewBuffer(data))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.URL.RawQuery = "access_token=" + r.token
client := &http.Client{}
resp, err := client.Do(req)
fmt.Println(resp)
defer resp.Body.Close()
return err
}
// SendMessage is the information sent in an API request to Facebook.
type SendMessage struct {
Recipient Recipient `json:"recipient"`
@ -107,3 +186,46 @@ type SendMessage struct {
type MessageData struct {
Text string `json:"text,omitempty"`
}
// SendStructuredMessage is a structured message template
type SendStructuredMessage struct {
Recipient Recipient `json:"recipient"`
Message StructuredMessageData `json:"message"`
}
type StructuredMessageData struct {
Attachment StructuredMessageAttachment `json:"attachment"`
}
type StructuredMessageAttachment struct {
// Template allways
Type string `json:"type"`
// Payload is the information for the file which was sent in the attachment.
Payload StructuredMessagePayload `json:"payload"`
}
type StructuredMessagePayload struct {
// button, generic, receipt
TemplateType string `json:"template_type"`
Text string `json:"text,omitempty"`
Elements *[]StructuredMessageElement `json:"elements,omitempty"`
Buttons *[]StructuredMessageButton `json:"buttons,omitempty"`
}
// StructuredMessageElement - Generic Template
type StructuredMessageElement struct {
Title string `json:"title"`
ImageURL string `json:"image_url"`
Subtitle string `json:"subtitle"`
Buttons []StructuredMessageButton `json:"buttons"`
}
// StructuredMessageButton - Button Template
type StructuredMessageButton struct {
Type string `json:"type"`
URL string `json:"url"`
Title string `json:"title"`
}