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

Pointer instead of slice in StructuredMessageElement (#3)

This commit is contained in:
Pavel 2021-02-17 15:15:29 +03:00 committed by GitHub
parent b23ab4492c
commit d4acc115a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 53 deletions

View File

@ -14,11 +14,11 @@ const (
// ReadAction means that the event was a previous recipient reading their respective // ReadAction means that the event was a previous recipient reading their respective
// messages. // messages.
ReadAction ReadAction
// PostBackAction represents post call back // PostBackAction represents post call back.
PostBackAction PostBackAction
// OptInAction represents opting in through the Send to Messenger button // OptInAction represents opting in through the Send to Messenger button.
OptInAction OptInAction
// ReferralAction represents ?ref parameter in m.me URLs // ReferralAction represents ?ref parameter in m.me URLs.
ReferralAction ReferralAction
// AccountLinkingAction means that the event concerns changes in account linking // AccountLinkingAction means that the event concerns changes in account linking
// status. // status.

View File

@ -56,7 +56,7 @@ type Read struct {
Seq int `json:"seq"` Seq int `json:"seq"`
} }
// PostBack represents postback callback // PostBack represents postback callback.
type PostBack struct { type PostBack struct {
// Sender is who the message was sent from. // Sender is who the message was sent from.
Sender Sender `json:"-"` Sender Sender `json:"-"`
@ -94,7 +94,7 @@ func (r Read) Watermark() time.Time {
} }
// GetNLP simply unmarshals the NLP entities to the given struct and returns // GetNLP simply unmarshals the NLP entities to the given struct and returns
// an error if it's not possible // an error if it's not possible.
func (m *Message) GetNLP(i interface{}) error { func (m *Message) GetNLP(i interface{}) error {
return json.Unmarshal(m.NLP, &i) return json.Unmarshal(m.NLP, &i)
} }

View File

@ -135,17 +135,17 @@ func (m *Messenger) HandleRead(f ReadHandler) {
m.readHandlers = append(m.readHandlers, f) m.readHandlers = append(m.readHandlers, f)
} }
// HandlePostBack adds a new PostBackHandler to the Messenger // HandlePostBack adds a new PostBackHandler to the Messenger.
func (m *Messenger) HandlePostBack(f PostBackHandler) { func (m *Messenger) HandlePostBack(f PostBackHandler) {
m.postBackHandlers = append(m.postBackHandlers, f) m.postBackHandlers = append(m.postBackHandlers, f)
} }
// HandleReferral adds a new ReferralHandler to the Messenger // HandleReferral adds a new ReferralHandler to the Messenger.
func (m *Messenger) HandleReferral(f ReferralHandler) { func (m *Messenger) HandleReferral(f ReferralHandler) {
m.referralHandlers = append(m.referralHandlers, f) m.referralHandlers = append(m.referralHandlers, f)
} }
// HandleAccountLinking adds a new AccountLinkingHandler to the Messenger // HandleAccountLinking adds a new AccountLinkingHandler to the Messenger.
func (m *Messenger) HandleAccountLinking(f AccountLinkingHandler) { func (m *Messenger) HandleAccountLinking(f AccountLinkingHandler) {
m.accountLinkingHandlers = append(m.accountLinkingHandlers, f) m.accountLinkingHandlers = append(m.accountLinkingHandlers, f)
} }
@ -163,7 +163,7 @@ func (m *Messenger) Handler() http.Handler {
// - Name // - Name
// - First Name // - First Name
// - Last Name // - Last Name
// - Profile Picture // - Profile Picture.
func (m *Messenger) ProfileByID(id int64, profileFields []string) (Profile, error) { func (m *Messenger) ProfileByID(id int64, profileFields []string) (Profile, error) {
p := Profile{} p := Profile{}
url := fmt.Sprintf("%v%v", ProfileURL, id) url := fmt.Sprintf("%v%v", ProfileURL, id)
@ -204,7 +204,7 @@ func (m *Messenger) ProfileByID(id int64, profileFields []string) (Profile, erro
return p, err return p, err
} }
// GreetingSetting sends settings for greeting // GreetingSetting sends settings for greeting.
func (m *Messenger) GreetingSetting(text string) (QueryResponse, error) { func (m *Messenger) GreetingSetting(text string) (QueryResponse, error) {
var qr QueryResponse var qr QueryResponse
@ -239,7 +239,7 @@ func (m *Messenger) GreetingSetting(text string) (QueryResponse, error) {
return getFacebookQueryResponse(resp.Body) return getFacebookQueryResponse(resp.Body)
} }
// CallToActionsSetting sends settings for Get Started or Persistent Menu // CallToActionsSetting sends settings for Get Started or Persistent Menu.
func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsItem) (QueryResponse, error) { func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsItem) (QueryResponse, error) {
var qr QueryResponse var qr QueryResponse
@ -296,7 +296,7 @@ func (m *Messenger) handle(w http.ResponseWriter, r *http.Request) {
} }
if rec.Object != "page" { if rec.Object != "page" {
fmt.Println("Object is not page, undefined behaviour. Got", rec.Object) fmt.Println("Object is not page, undefined behavior. Got", rec.Object)
respond(w, http.StatusUnprocessableEntity) respond(w, http.StatusUnprocessableEntity)
return return
} }
@ -319,7 +319,7 @@ func respond(w http.ResponseWriter, code int) {
fmt.Fprintf(w, `{"code": %d, "status": "%s"}`, code, http.StatusText(code)) fmt.Fprintf(w, `{"code": %d, "status": "%s"}`, code, http.StatusText(code))
} }
// checkIntegrity checks the integrity of the requests received // checkIntegrity checks the integrity of the requests received.
func (m *Messenger) checkIntegrity(r *http.Request) error { func (m *Messenger) checkIntegrity(r *http.Request) error {
if m.appSecret == "" { if m.appSecret == "" {
return xerrors.New("missing app secret") return xerrors.New("missing app secret")
@ -424,7 +424,7 @@ func (m *Messenger) dispatch(r Receive) {
} }
} }
// Response returns new Response object // Response returns new Response object.
func (m *Messenger) Response(to int64) *Response { func (m *Messenger) Response(to int64) *Response {
return &Response{ return &Response{
to: Recipient{to}, to: Recipient{to},
@ -437,7 +437,7 @@ func (m *Messenger) Send(to Recipient, message string, messagingType MessagingTy
return m.SendWithReplies(to, message, nil, messagingType, metadata, tags...) return m.SendWithReplies(to, message, nil, messagingType, metadata, tags...)
} }
// SendGeneralMessage will send the GenericTemplate message // SendGeneralMessage will send the GenericTemplate message.
func (m *Messenger) SendGeneralMessage(to Recipient, elements *[]StructuredMessageElement, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) { func (m *Messenger) SendGeneralMessage(to Recipient, elements *[]StructuredMessageElement, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) {
r := &Response{ r := &Response{
token: m.token, token: m.token,
@ -515,7 +515,7 @@ func (m *Messenger) classify(info MessageInfo) Action {
return UnknownAction return UnknownAction
} }
// newVerifyHandler returns a function which can be used to handle webhook verification // newVerifyHandler returns a function which can be used to handle webhook verification.
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 {

View File

@ -1,6 +1,6 @@
package messenger package messenger
// Profile is the public information of a Facebook user // Profile is the public information of a Facebook user.
type Profile struct { type Profile struct {
Name string `json:"name"` Name string `json:"name"`
FirstName string `json:"first_name"` FirstName string `json:"first_name"`

View File

@ -58,7 +58,7 @@ type OptIn struct {
Ref string `json:"ref"` Ref string `json:"ref"`
} }
// ReferralMessage represents referral endpoint // ReferralMessage represents referral endpoint.
type ReferralMessage struct { type ReferralMessage struct {
*Referral *Referral
@ -70,7 +70,7 @@ type ReferralMessage struct {
Time time.Time `json:"-"` Time time.Time `json:"-"`
} }
// Referral represents referral info // Referral represents referral info.
type Referral struct { type Referral struct {
// Data originally passed in the ref param // Data originally passed in the ref param
Ref string `json:"ref"` Ref string `json:"ref"`
@ -112,13 +112,13 @@ type QuickReply struct {
// Payload is the information on where an attachment is. // Payload is the information on where an attachment is.
type Payload struct { type Payload struct {
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`
// Coordinates is Lat/Long pair of location pin // Coordinates is Lat/Long pair of location pin
Coordinates *Coordinates `json:"coordinates,omitempty"` Coordinates *Coordinates `json:"coordinates,omitempty"`
} }
// Coordinates is a pair of latitude and longitude // Coordinates is a pair of latitude and longitude.
type Coordinates struct { type Coordinates struct {
// Lat is latitude // Lat is latitude
Lat float64 `json:"lat"` Lat float64 `json:"lat"`

View File

@ -39,13 +39,13 @@ const (
// FileAttachment is file attachment type. // FileAttachment is file attachment type.
FileAttachment AttachmentType = "file" FileAttachment AttachmentType = "file"
// ResponseType is response messaging type // ResponseType is response messaging type.
ResponseType MessagingType = "RESPONSE" ResponseType MessagingType = "RESPONSE"
// UpdateType is update messaging type // UpdateType is update messaging type.
UpdateType MessagingType = "UPDATE" UpdateType MessagingType = "UPDATE"
// MessageTagType is message_tag messaging type // MessageTagType is message_tag messaging type.
MessageTagType MessagingType = "MESSAGE_TAG" MessageTagType MessagingType = "MESSAGE_TAG"
// NonPromotionalSubscriptionType is NON_PROMOTIONAL_SUBSCRIPTION messaging type // NonPromotionalSubscriptionType is NON_PROMOTIONAL_SUBSCRIPTION messaging type.
NonPromotionalSubscriptionType MessagingType = "NON_PROMOTIONAL_SUBSCRIPTION" NonPromotionalSubscriptionType MessagingType = "NON_PROMOTIONAL_SUBSCRIPTION"
// TopElementStyle is compact. // TopElementStyle is compact.
@ -60,14 +60,14 @@ const (
) )
// QueryResponse is the response sent back by Facebook when setting up things // QueryResponse is the response sent back by Facebook when setting up things
// like greetings or call-to-actions // like greetings or call-to-actions.
type QueryResponse struct { type QueryResponse struct {
Error *QueryError `json:"error,omitempty"` Error *QueryError `json:"error,omitempty"`
RecipientID string `json:"recipient_id"` RecipientID string `json:"recipient_id"`
MessageID string `json:"message_id"` MessageID string `json:"message_id"`
} }
// QueryError is representing an error sent back by Facebook // QueryError is representing an error sent back by Facebook.
type QueryError struct { type QueryError struct {
Message string `json:"message"` Message string `json:"message"`
Type string `json:"type"` Type string `json:"type"`
@ -76,7 +76,7 @@ type QueryError struct {
FBTraceID string `json:"fbtrace_id"` FBTraceID string `json:"fbtrace_id"`
} }
// QueryError implements error // QueryError implements error.
func (e QueryError) Error() string { func (e QueryError) Error() string {
return e.Message return e.Message
} }
@ -126,7 +126,8 @@ func (r *Response) Text(message string, messagingType MessagingType, metadata st
// TextWithReplies sends a textual message with some replies // TextWithReplies sends a textual message with some replies
// messagingType should be one of the following: "RESPONSE","UPDATE","MESSAGE_TAG","NON_PROMOTIONAL_SUBSCRIPTION" // messagingType should be one of the following: "RESPONSE","UPDATE","MESSAGE_TAG","NON_PROMOTIONAL_SUBSCRIPTION"
// only supply tags when messagingType == "MESSAGE_TAG" (see https://developers.facebook.com/docs/messenger-platform/send-messages#messaging_types for more) // only supply tags when messagingType == "MESSAGE_TAG"
// (see https://developers.facebook.com/docs/messenger-platform/send-messages#messaging_types for more).
func (r *Response) TextWithReplies(message string, replies []QuickReply, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) { func (r *Response) TextWithReplies(message string, replies []QuickReply, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) {
var tag string var tag string
if len(tags) > 0 { if len(tags) > 0 {
@ -147,7 +148,7 @@ func (r *Response) TextWithReplies(message string, replies []QuickReply, messagi
return r.DispatchMessage(&m) return r.DispatchMessage(&m)
} }
// AttachmentWithReplies sends a attachment message with some replies // AttachmentWithReplies sends a attachment message with some replies.
func (r *Response) AttachmentWithReplies(attachment *StructuredMessageAttachment, replies []QuickReply, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) { func (r *Response) AttachmentWithReplies(attachment *StructuredMessageAttachment, replies []QuickReply, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) {
var tag string var tag string
if len(tags) > 0 { if len(tags) > 0 {
@ -204,15 +205,15 @@ func (r *Response) Attachment(dataType AttachmentType, url string, messagingType
return r.DispatchMessage(&m) return r.DispatchMessage(&m)
} }
// copied from multipart package // copied from multipart package.
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"") var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
// copied from multipart package // copied from multipart package.
func escapeQuotes(s string) string { func escapeQuotes(s string) string {
return quoteEscaper.Replace(s) return quoteEscaper.Replace(s)
} }
// copied from multipart package with slight changes due to fixed content-type there // copied from multipart package with slight changes due to fixed content-type there.
func createFormFile(filename string, w *multipart.Writer, contentType string) (io.Writer, error) { func createFormFile(filename string, w *multipart.Writer, contentType string) (io.Writer, error) {
h := make(textproto.MIMEHeader) h := make(textproto.MIMEHeader)
h.Set("Content-Disposition", h.Set("Content-Disposition",
@ -267,7 +268,7 @@ func (r *Response) AttachmentData(dataType AttachmentType, filename string, file
return getFacebookQueryResponse(resp.Body) return getFacebookQueryResponse(resp.Body)
} }
// ButtonTemplate sends a message with the main contents being button elements // ButtonTemplate sends a message with the main contents being button elements.
func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButton, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) { func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButton, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) {
var tag string var tag string
if len(tags) > 0 { if len(tags) > 0 {
@ -295,7 +296,7 @@ func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButto
return r.DispatchMessage(&m) return r.DispatchMessage(&m)
} }
// GenericTemplate is a message which allows for structural elements to be sent // GenericTemplate is a message which allows for structural elements to be sent.
func (r *Response) GenericTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) { func (r *Response) GenericTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, metadata string, tags ...string) (QueryResponse, error) {
var tag string var tag string
if len(tags) > 0 { if len(tags) > 0 {
@ -321,7 +322,7 @@ func (r *Response) GenericTemplate(elements *[]StructuredMessageElement, messagi
return r.DispatchMessage(&m) return r.DispatchMessage(&m)
} }
// ListTemplate sends a list of elements // ListTemplate sends a list of elements.
func (r *Response) ListTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) (QueryResponse, error) { func (r *Response) ListTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string var tag string
if len(tags) > 0 { if len(tags) > 0 {
@ -347,7 +348,7 @@ func (r *Response) ListTemplate(elements *[]StructuredMessageElement, messagingT
return r.DispatchMessage(&m) return r.DispatchMessage(&m)
} }
// SenderAction sends a info about sender action // SenderAction sends a info about sender action.
func (r *Response) SenderAction(action string) (QueryResponse, error) { func (r *Response) SenderAction(action string) (QueryResponse, error) {
m := SendSenderAction{ m := SendSenderAction{
Recipient: r.to, Recipient: r.to,
@ -356,7 +357,7 @@ func (r *Response) SenderAction(action string) (QueryResponse, error) {
return r.DispatchMessage(&m) return r.DispatchMessage(&m)
} }
// DispatchMessage posts the message to messenger, return the error if there's any // DispatchMessage posts the message to messenger, return the error if there's any.
func (r *Response) DispatchMessage(m interface{}) (QueryResponse, error) { func (r *Response) DispatchMessage(m interface{}) (QueryResponse, error) {
var res QueryResponse var res QueryResponse
data, err := json.Marshal(m) data, err := json.Marshal(m)
@ -453,7 +454,7 @@ type StructuredMessageAttachment struct {
Payload StructuredMessagePayload `json:"payload"` Payload StructuredMessagePayload `json:"payload"`
} }
// StructuredMessagePayload is the actual payload of an attachment // StructuredMessagePayload is the actual payload of an attachment.
type StructuredMessagePayload struct { type StructuredMessagePayload struct {
// TemplateType must be button, generic or receipt // TemplateType must be button, generic or receipt
TemplateType string `json:"template_type,omitempty"` TemplateType string `json:"template_type,omitempty"`
@ -500,14 +501,14 @@ type Adjustment struct {
Amount float32 `json:"amount,omitempty"` Amount float32 `json:"amount,omitempty"`
} }
// StructuredMessageElement is a response containing structural elements // StructuredMessageElement is a response containing structural elements.
type StructuredMessageElement struct { type StructuredMessageElement struct {
Title string `json:"title"` Title string `json:"title"`
ImageURL string `json:"image_url"` ImageURL string `json:"image_url"`
ItemURL string `json:"item_url,omitempty"` ItemURL string `json:"item_url,omitempty"`
Subtitle string `json:"subtitle"` Subtitle string `json:"subtitle"`
DefaultAction *DefaultAction `json:"default_action,omitempty"` DefaultAction *DefaultAction `json:"default_action,omitempty"`
Buttons []StructuredMessageButton `json:"buttons"` Buttons *[]StructuredMessageButton `json:"buttons"`
ReceiptMessageElement ReceiptMessageElement
} }
@ -517,7 +518,7 @@ type ReceiptMessageElement struct {
Currency string `json:"currency,omitempty"` Currency string `json:"currency,omitempty"`
} }
// DefaultAction is a response containing default action properties // DefaultAction is a response containing default action properties.
type DefaultAction struct { type DefaultAction struct {
Type string `json:"type"` Type string `json:"type"`
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
@ -527,7 +528,7 @@ type DefaultAction struct {
WebviewShareButton string `json:"webview_share_button,omitempty"` WebviewShareButton string `json:"webview_share_button,omitempty"`
} }
// StructuredMessageButton is a response containing buttons // StructuredMessageButton is a response containing buttons.
type StructuredMessageButton struct { type StructuredMessageButton struct {
Type string `json:"type"` Type string `json:"type"`
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
@ -540,7 +541,7 @@ type StructuredMessageButton struct {
ShareContents *StructuredMessageData `json:"share_contents,omitempty"` ShareContents *StructuredMessageData `json:"share_contents,omitempty"`
} }
// SendSenderAction is the information about sender action // SendSenderAction is the information about sender action.
type SendSenderAction struct { type SendSenderAction struct {
Recipient Recipient `json:"recipient"` Recipient Recipient `json:"recipient"`
SenderAction string `json:"sender_action"` SenderAction string `json:"sender_action"`

View File

@ -17,25 +17,25 @@ const (
WebviewFull = "full" WebviewFull = "full"
) )
// GreetingSetting is the setting for greeting message // GreetingSetting is the setting for greeting message.
type GreetingSetting struct { type GreetingSetting struct {
SettingType string `json:"setting_type"` SettingType string `json:"setting_type"`
Greeting GreetingInfo `json:"greeting"` Greeting GreetingInfo `json:"greeting"`
} }
// GreetingInfo contains greeting message // GreetingInfo contains greeting message.
type GreetingInfo struct { type GreetingInfo struct {
Text string `json:"text"` Text string `json:"text"`
} }
// CallToActionsSetting is the settings for Get Started and Persist Menu // CallToActionsSetting is the settings for Get Started and Persist Menu.
type CallToActionsSetting struct { type CallToActionsSetting struct {
SettingType string `json:"setting_type"` SettingType string `json:"setting_type"`
ThreadState string `json:"thread_state"` ThreadState string `json:"thread_state"`
CallToActions []CallToActionsItem `json:"call_to_actions"` CallToActions []CallToActionsItem `json:"call_to_actions"`
} }
// CallToActionsItem contains Get Started button or item of Persist Menu // CallToActionsItem contains Get Started button or item of Persist Menu.
type CallToActionsItem struct { type CallToActionsItem struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`