1
0
Fork 0
mirror of synced 2025-04-04 21:53:37 +03:00

add processing response from facebook

This commit is contained in:
DmitryZagorulko 2018-07-10 15:03:41 +03:00 committed by Neur0toxine
parent 14c1f126e4
commit b88edd8392
2 changed files with 54 additions and 49 deletions

View file

@ -202,7 +202,9 @@ func (m *Messenger) ProfileByID(id int64, profileFields []string) (Profile, erro
}
// GreetingSetting sends settings for greeting
func (m *Messenger) GreetingSetting(text string) error {
func (m *Messenger) GreetingSetting(text string) (QueryResponse, error) {
var qr QueryResponse
d := GreetingSetting{
SettingType: "greeting",
Greeting: GreetingInfo{
@ -212,12 +214,12 @@ func (m *Messenger) GreetingSetting(text string) error {
data, err := json.Marshal(d)
if err != nil {
return err
return qr, err
}
req, err := http.NewRequest("POST", SendSettingsURL, bytes.NewBuffer(data))
if err != nil {
return err
return qr, err
}
req.Header.Set("Content-Type", "application/json")
@ -227,15 +229,17 @@ func (m *Messenger) GreetingSetting(text string) error {
resp, err := client.Do(req)
if err != nil {
return err
return qr, err
}
defer resp.Body.Close()
return checkFacebookError(resp.Body)
return getFacebookQueryResponse(resp.Body)
}
// CallToActionsSetting sends settings for Get Started or Persistent Menu
func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsItem) error {
func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsItem) (QueryResponse, error) {
var qr QueryResponse
d := CallToActionsSetting{
SettingType: "call_to_actions",
ThreadState: state,
@ -244,12 +248,12 @@ func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsIt
data, err := json.Marshal(d)
if err != nil {
return err
return qr, err
}
req, err := http.NewRequest("POST", SendSettingsURL, bytes.NewBuffer(data))
if err != nil {
return err
return qr, err
}
req.Header.Set("Content-Type", "application/json")
@ -259,11 +263,11 @@ func (m *Messenger) CallToActionsSetting(state string, actions []CallToActionsIt
resp, err := client.Do(req)
if err != nil {
return err
return qr, err
}
defer resp.Body.Close()
return checkFacebookError(resp.Body)
return getFacebookQueryResponse(resp.Body)
}
// handle is the internal HTTP handler for the webhooks.
@ -426,12 +430,12 @@ func (m *Messenger) Response(to int64) *Response {
}
// Send will send a textual message to a user. This user must have previously initiated a conversation with the bot.
func (m *Messenger) Send(to Recipient, message string, messagingType MessagingType, tags ...string) error {
func (m *Messenger) Send(to Recipient, message string, messagingType MessagingType, tags ...string) (QueryResponse, error) {
return m.SendWithReplies(to, message, nil, messagingType, tags...)
}
// SendGeneralMessage will send the GenericTemplate message
func (m *Messenger) SendGeneralMessage(to Recipient, elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) error {
func (m *Messenger) SendGeneralMessage(to Recipient, elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) (QueryResponse, error) {
r := &Response{
token: m.token,
to: to,
@ -440,7 +444,7 @@ func (m *Messenger) SendGeneralMessage(to Recipient, elements *[]StructuredMessa
}
// SendWithReplies sends a textual message to a user, but gives them the option of numerous quick response options.
func (m *Messenger) SendWithReplies(to Recipient, message string, replies []QuickReply, messagingType MessagingType, tags ...string) error {
func (m *Messenger) SendWithReplies(to Recipient, message string, replies []QuickReply, messagingType MessagingType, tags ...string) (QueryResponse, error) {
response := &Response{
token: m.token,
to: to,
@ -450,7 +454,7 @@ func (m *Messenger) SendWithReplies(to Recipient, message string, replies []Quic
}
// Attachment sends an image, sound, video or a regular file to a given recipient.
func (m *Messenger) Attachment(to Recipient, dataType AttachmentType, url string, messagingType MessagingType, tags ...string) error {
func (m *Messenger) Attachment(to Recipient, dataType AttachmentType, url string, messagingType MessagingType, tags ...string) (QueryResponse, error) {
response := &Response{
token: m.token,
to: to,

View file

@ -62,8 +62,9 @@ const (
// QueryResponse is the response sent back by Facebook when setting up things
// like greetings or call-to-actions
type QueryResponse struct {
Error *QueryError `json:"error,omitempty"`
Result string `json:"result,omitempty"`
Error *QueryError `json:"error,omitempty"`
RecipientID string `json:"recipient_id"`
MessageID string `json:"message_id"`
}
// QueryError is representing an error sent back by Facebook
@ -80,19 +81,16 @@ func (e QueryError) Error() string {
return e.Message
}
func checkFacebookError(r io.Reader) error {
var err error
func getFacebookQueryResponse(r io.Reader) (QueryResponse, error) {
qr := QueryResponse{}
err = json.NewDecoder(r).Decode(&qr)
err := json.NewDecoder(r).Decode(&qr)
if err != nil {
return xerrors.Errorf("json unmarshal error: %w", err)
return qr, xerrors.Errorf("json unmarshal error: %w", err)
}
if qr.Error != nil {
return xerrors.Errorf("facebook error: %w", qr.Error)
return qr, xerrors.Errorf("facebook error: %w", qr.Error)
}
return nil
return qr, nil
}
// Response is used for responding to events with messages.
@ -107,14 +105,14 @@ func (r *Response) SetToken(token string) {
}
// Text sends a textual message.
func (r *Response) Text(message string, messagingType MessagingType, tags ...string) error {
func (r *Response) Text(message string, messagingType MessagingType, tags ...string) (QueryResponse, error) {
return r.TextWithReplies(message, nil, messagingType, tags...)
}
// TextWithReplies sends a textual message with some replies
// 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)
func (r *Response) TextWithReplies(message string, replies []QuickReply, messagingType MessagingType, tags ...string) error {
func (r *Response) TextWithReplies(message string, replies []QuickReply, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string
if len(tags) > 0 {
tag = tags[0]
@ -134,7 +132,7 @@ func (r *Response) TextWithReplies(message string, replies []QuickReply, messagi
}
// AttachmentWithReplies sends a attachment message with some replies
func (r *Response) AttachmentWithReplies(attachment *StructuredMessageAttachment, replies []QuickReply, messagingType MessagingType, tags ...string) error {
func (r *Response) AttachmentWithReplies(attachment *StructuredMessageAttachment, replies []QuickReply, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string
if len(tags) > 0 {
tag = tags[0]
@ -153,18 +151,20 @@ func (r *Response) AttachmentWithReplies(attachment *StructuredMessageAttachment
}
// Image sends an image.
func (r *Response) Image(im image.Image) error {
func (r *Response) Image(im image.Image) (QueryResponse, error) {
var qr QueryResponse
imageBytes := new(bytes.Buffer)
err := jpeg.Encode(imageBytes, im, nil)
if err != nil {
return err
return qr, err
}
return r.AttachmentData(ImageAttachment, "meme.jpg", imageBytes)
}
// Attachment sends an image, sound, video or a regular file to a chat.
func (r *Response) Attachment(dataType AttachmentType, url string, messagingType MessagingType, tags ...string) error {
func (r *Response) Attachment(dataType AttachmentType, url string, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string
if len(tags) > 0 {
tag = tags[0]
@ -205,11 +205,12 @@ func createFormFile(filename string, w *multipart.Writer, contentType string) (i
}
// AttachmentData sends an image, sound, video or a regular file to a chat via an io.Reader.
func (r *Response) AttachmentData(dataType AttachmentType, filename string, filedata io.Reader) error {
func (r *Response) AttachmentData(dataType AttachmentType, filename string, filedata io.Reader) (QueryResponse, error) {
var qr QueryResponse
filedataBytes, err := ioutil.ReadAll(filedata)
if err != nil {
return err
return qr, err
}
contentType := http.DetectContentType(filedataBytes[:512])
fmt.Println("Content-type detected:", contentType)
@ -218,12 +219,12 @@ func (r *Response) AttachmentData(dataType AttachmentType, filename string, file
multipartWriter := multipart.NewWriter(&body)
data, err := createFormFile(filename, multipartWriter, contentType)
if err != nil {
return err
return qr, err
}
_, err = bytes.NewBuffer(filedataBytes).WriteTo(data)
if err != nil {
return err
return qr, err
}
multipartWriter.WriteField("recipient", fmt.Sprintf(`{"id":"%v"}`, r.to.ID))
@ -231,7 +232,7 @@ func (r *Response) AttachmentData(dataType AttachmentType, filename string, file
req, err := http.NewRequest("POST", SendMessageURL, &body)
if err != nil {
return err
return qr, err
}
req.URL.RawQuery = "access_token=" + r.token
@ -241,15 +242,15 @@ func (r *Response) AttachmentData(dataType AttachmentType, filename string, file
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
return qr, err
}
defer resp.Body.Close()
return checkFacebookError(resp.Body)
return getFacebookQueryResponse(resp.Body)
}
// ButtonTemplate sends a message with the main contents being button elements
func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButton, messagingType MessagingType, tags ...string) error {
func (r *Response) ButtonTemplate(text string, buttons *[]StructuredMessageButton, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string
if len(tags) > 0 {
tag = tags[0]
@ -276,7 +277,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(elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) error {
func (r *Response) GenericTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string
if len(tags) > 0 {
tag = tags[0]
@ -301,7 +302,7 @@ func (r *Response) GenericTemplate(elements *[]StructuredMessageElement, messagi
}
// ListTemplate sends a list of elements
func (r *Response) ListTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) error {
func (r *Response) ListTemplate(elements *[]StructuredMessageElement, messagingType MessagingType, tags ...string) (QueryResponse, error) {
var tag string
if len(tags) > 0 {
tag = tags[0]
@ -327,7 +328,7 @@ func (r *Response) ListTemplate(elements *[]StructuredMessageElement, messagingT
}
// SenderAction sends a info about sender action
func (r *Response) SenderAction(action string) error {
func (r *Response) SenderAction(action string) (QueryResponse, error) {
m := SendSenderAction{
Recipient: r.to,
SenderAction: action,
@ -336,15 +337,16 @@ func (r *Response) SenderAction(action string) error {
}
// DispatchMessage posts the message to messenger, return the error if there's any
func (r *Response) DispatchMessage(m interface{}) error {
func (r *Response) DispatchMessage(m interface{}) (QueryResponse, error) {
var res QueryResponse
data, err := json.Marshal(m)
if err != nil {
return err
return res, err
}
req, err := http.NewRequest("POST", SendMessageURL, bytes.NewBuffer(data))
if err != nil {
return err
return res, err
}
req.Header.Set("Content-Type", "application/json")
@ -352,13 +354,12 @@ func (r *Response) DispatchMessage(m interface{}) error {
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
return res, err
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return nil
}
return checkFacebookError(resp.Body)
return getFacebookQueryResponse(resp.Body)
}
// PassThreadToInbox Uses Messenger Handover Protocol for live inbox