Skip to content
This repository has been archived by the owner on Jan 1, 2023. It is now read-only.

Commit

Permalink
* Added ability to set greeting setting, get started setting and pers…
Browse files Browse the repository at this point in the history
…istent menu setting

* Added IsEcho in Message which is indicator of own messages
* Added QuickReply in Message for sending of quick reply buttons with message
* Added mux parameter in Messenger constructor. It is useful when single go app processes the several bots
* Added Messenger.SenderAction which allows to show writing and reading status
  • Loading branch information
muxx committed Sep 11, 2016
1 parent 500eec9 commit 47f193f
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 11 deletions.
4 changes: 4 additions & 0 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ type Message struct {
Recipient Recipient `json:"-"`
// Time is when the message was sent.
Time time.Time `json:"-"`
// Message is mine
IsEcho bool `json:"is_echo,omitempty"`
// Mid is the ID of the message.
Mid string `json:"mid"`
// Seq is order the message was sent in relation to other messages.
Expand All @@ -19,6 +21,8 @@ type Message struct {
// Attachments is the information about the attachments which were sent
// with the message.
Attachments []Attachment `json:"attachments"`
// Selected quick reply
QuickReply *QuickReply `json:"quick_reply,omitempty"`
}

// Delivery represents a the event fired when Facebook delivers a message to the
Expand Down
78 changes: 77 additions & 1 deletion messenger.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package messenger

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
Expand All @@ -11,6 +12,8 @@ const (
// 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/"
// SendSettingsURL is API endpoint for saving settings.
SendSettingsURL = "https://graph.facebook.com/v2.6/me/thread_settings"
)

// Options are the settings used when creating a Messenger client.
Expand All @@ -25,6 +28,8 @@ type Options struct {
Token string
// WebhookURL is where the Messenger client should listen for webhook events. Leaving the string blank implies a path of "/".
WebhookURL string
// Mux is shared mux between several Messenger objects
Mux *http.ServeMux
}

// MessageHandler is a handler used for responding to a message containing text.
Expand Down Expand Up @@ -52,8 +57,12 @@ type Messenger struct {

// New creates a new Messenger. You pass in Options in order to affect settings.
func New(mo Options) *Messenger {
if mo.Mux == nil {
mo.Mux = http.NewServeMux()
}

m := &Messenger{
mux: http.NewServeMux(),
mux: mo.Mux,
token: mo.Token,
}

Expand Down Expand Up @@ -116,6 +125,65 @@ func (m *Messenger) ProfileByID(id int64) (Profile, error) {
return p, err
}

// GreetingSetting sends settings for greeting
func (m *Messenger) GreetingSetting(text string) error {
d := GreetingSetting{
SettingType: "greeting",
Greeting: GreetingInfo{
Text: text,
},
}

data, err := json.Marshal(d)
if err != nil {
return err
}

req, err := http.NewRequest("POST", SendSettingsURL, bytes.NewBuffer(data))
if err != nil {
return err
}

req.Header.Set("Content-Type", "application/json")
req.URL.RawQuery = "access_token=" + m.token

client := &http.Client{}

resp, err := client.Do(req)
defer resp.Body.Close()

return err
}

// CallToActionsSetting sends settings for Get Started or Persist Menu
func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsItem) error {
d := CallToActionsSetting{
SettingType: "call_to_actions",
ThreadState: state,
CallToActions: actions,
}

data, err := json.Marshal(d)
if err != nil {
return err
}

req, err := http.NewRequest("POST", SendSettingsURL, bytes.NewBuffer(data))
if err != nil {
return err
}

req.Header.Set("Content-Type", "application/json")
req.URL.RawQuery = "access_token=" + m.token

client := &http.Client{}

resp, err := client.Do(req)
defer resp.Body.Close()

return err
}

// handle is the internal HTTP handler for the webhooks.
func (m *Messenger) handle(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
Expand Down Expand Up @@ -186,6 +254,14 @@ func (m *Messenger) dispatch(r Receive) {
}
}

// Response returns new Response object
func (m *Messenger) Response(to int64) *Response {
return &Response{
to: Recipient{to},
token: m.token,
}
}

// classify determines what type of message a webhook event is.
func (m *Messenger) classify(info MessageInfo, e Entry) Action {
if info.Message != nil {
Expand Down
4 changes: 2 additions & 2 deletions receiving.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ type Attachment struct {
// QuickReply is a file which used in a message.
type QuickReply struct {
// ContentType is the type of reply
ContentType string `json:"content_type"`
ContentType string `json:"content_type,omitempty"`
// Title is the reply title
Title string `json:"title"`
Title string `json:"title,omitempty"`
// Payload is the reply information
Payload string `json:"payload"`
}
Expand Down
53 changes: 45 additions & 8 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (r *Response) TextWithReplies(message string, replies []QuickReply) error {

data, err := json.Marshal(m)
if err != nil {
return nil
return err
}

req, err := http.NewRequest("POST", SendMessageURL, bytes.NewBuffer(data))
Expand Down Expand Up @@ -122,7 +122,7 @@ func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButto

data, err := json.Marshal(m)
if err != nil {
return nil
return err
}

req, err := http.NewRequest("POST", SendMessageURL, bytes.NewBuffer(data))
Expand All @@ -142,7 +142,7 @@ func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButto
}

// GenericTemplate is a message which allows for structural elements to be sent
func (r *Response) GenericTemplate(text string, elements *[]StructuredMessageElement) error {
func (r *Response) GenericTemplate(elements *[]StructuredMessageElement) error {
m := SendStructuredMessage{
Recipient: r.to,
Message: StructuredMessageData{
Expand All @@ -159,7 +159,35 @@ func (r *Response) GenericTemplate(text string, elements *[]StructuredMessageEle

data, err := json.Marshal(m)
if err != nil {
return nil
return err
}

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)
defer resp.Body.Close()

return err
}

// SenderAction sends a info about sender action
func (r *Response) SenderAction(action string) error {
m := SendSenderAction{
Recipient: r.to,
SenderAction: action,
}

data, err := json.Marshal(m)
if err != nil {
return err
}

req, err := http.NewRequest("POST", SendMessageURL, bytes.NewBuffer(data))
Expand Down Expand Up @@ -212,23 +240,32 @@ type StructuredMessageAttachment struct {
// StructuredMessagePayload is the actual payload of an attachment
type StructuredMessagePayload struct {
// TemplateType must be button, generic or receipt
TemplateType string `json:"template_type"`
TemplateType string `json:"template_type,omitempty"`
Text string `json:"text,omitempty"`
Elements *[]StructuredMessageElement `json:"elements,omitempty"`
Buttons *[]StructuredMessageButton `json:"buttons,omitempty"`
Url string `json:"url,omitempty"`
}

// StructuredMessageElement is a response containing structural elements
type StructuredMessageElement struct {
Title string `json:"title"`
ImageURL string `json:"image_url"`
ItemURL string `json:"item_url"`
Subtitle string `json:"subtitle"`
Buttons []StructuredMessageButton `json:"buttons"`
}

// StructuredMessageButton is a response containing buttons
type StructuredMessageButton struct {
Type string `json:"type"`
URL string `json:"url"`
Title string `json:"title"`
Type string `json:"type"`
URL string `json:"url,omitempty"`
Title string `json:"title"`
Payload string `json:"payload,omitempty"`
}

// SendSenderAction is the information about sender action
type SendSenderAction struct {
Recipient Recipient `json:"recipient"`
SenderAction string `json:"sender_action"`
}
27 changes: 27 additions & 0 deletions settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package messenger

// GreetingSetting is the setting for greeting message
type GreetingSetting struct {
SettingType string `json:"setting_type"`
Greeting GreetingInfo `json:"greeting"`
}

// GreetingInfo contains greeting message
type GreetingInfo struct {
Text string `json:"text"`
}

// CallToActionsSetting is the settings for Get Started and Persist Menu
type CallToActionsSetting struct {
SettingType string `json:"setting_type"`
ThreadState string `json:"thread_state"`
CallToActions []CallToActionsItem `json:"call_to_actions"`
}

// CallToActionsItem contains Get Started button or item of Persist Menu
type CallToActionsItem struct {
Type string `json:"type,omitempty"`
Title string `json:"title,omitempty"`
Payload string `json:"payload,omitempty"`
URL string `json:"url,omitempty"`
}

0 comments on commit 47f193f

Please sign in to comment.