Skip to content

Commit

Permalink
Support sending and receiving stickers for WAC and D3C
Browse files Browse the repository at this point in the history
  • Loading branch information
norkans7 committed Jul 28, 2023
1 parent 40b54ee commit 7e20fe4
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 14 deletions.
33 changes: 26 additions & 7 deletions handlers/dialog360/dialog360.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ type wacMedia struct {
Mimetype string `json:"mime_type"`
SHA256 string `json:"sha256"`
}

type wacSticker struct {
Animated bool `json:"animated"`
ID string `json:"id"`
Mimetype string `json:"mime_type"`
SHA256 string `json:"sha256"`
}
type moPayload struct {
Object string `json:"object"`
Entry []struct {
Expand Down Expand Up @@ -124,11 +131,12 @@ type moPayload struct {
Text struct {
Body string `json:"body"`
} `json:"text"`
Image *wacMedia `json:"image"`
Audio *wacMedia `json:"audio"`
Video *wacMedia `json:"video"`
Document *wacMedia `json:"document"`
Voice *wacMedia `json:"voice"`
Image *wacMedia `json:"image"`
Audio *wacMedia `json:"audio"`
Video *wacMedia `json:"video"`
Document *wacMedia `json:"document"`
Voice *wacMedia `json:"voice"`
Sticker *wacSticker `json:"sticker"`
Location *struct {
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Expand Down Expand Up @@ -267,6 +275,8 @@ func (h *handler) processCloudWhatsAppPayload(ctx context.Context, channel couri
} else if msg.Type == "image" && msg.Image != nil {
text = msg.Image.Caption
mediaURL, err = resolveMediaURL(channel, msg.Image.ID, clog)
} else if msg.Type == "sticker" && msg.Sticker != nil {
mediaURL, err = resolveMediaURL(channel, msg.Sticker.ID, clog)
} else if msg.Type == "video" && msg.Video != nil {
text = msg.Video.Caption
mediaURL, err = resolveMediaURL(channel, msg.Video.ID, clog)
Expand Down Expand Up @@ -475,6 +485,7 @@ type wacMTPayload struct {
Image *wacMTMedia `json:"image,omitempty"`
Audio *wacMTMedia `json:"audio,omitempty"`
Video *wacMTMedia `json:"video,omitempty"`
Sticker *wacMTMedia `json:"sticker,omitempty"`

Interactive *wacInteractive `json:"interactive,omitempty"`

Expand Down Expand Up @@ -621,7 +632,9 @@ func (h *handler) Send(ctx context.Context, msg courier.Msg, clog *courier.Chann

} else if i < len(msg.Attachments()) && (len(qrs) == 0 || len(qrs) > 3) {
attType, attURL := handlers.SplitAttachment(msg.Attachments()[i])
attType = strings.Split(attType, "/")[0]
splitedAttType := strings.Split(attType, "/")
attType = splitedAttType[0]
attFormat := splitedAttType[1]
if attType == "application" {
attType = "document"
}
Expand All @@ -634,7 +647,13 @@ func (h *handler) Send(ctx context.Context, msg courier.Msg, clog *courier.Chann
}

if attType == "image" {
payload.Image = &media
if attFormat == "webp" {
payload.Type = "sticker"
payload.Sticker = &media
} else {
payload.Image = &media
}

} else if attType == "audio" {
payload.Audio = &media
} else if attType == "video" {
Expand Down
27 changes: 27 additions & 0 deletions handlers/dialog360/dialog360_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@ var testCasesD3C = []ChannelHandleTestCase{
ExpectedAttachments: []string{"https://waba-v2.360dialog.io/whatsapp_business/attachments/?mid=id_image"},
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
},
{
Label: "Receive Valid Sticker Message",
URL: d3CReceiveURL,
Data: string(test.ReadFile("./testdata/wac/stickerWAC.json")),
ExpectedRespStatus: 200,
ExpectedBodyContains: "Handled",
NoQueueErrorCheck: true,
NoInvalidChannelCheck: true,
ExpectedMsgText: Sp(""),
ExpectedURN: "whatsapp:5678",
ExpectedExternalID: "external_id",
ExpectedAttachments: []string{"https://waba-v2.360dialog.io/whatsapp_business/attachments/?mid=id_sticker"},
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
},
{
Label: "Receive Valid Video Message",
URL: d3CReceiveURL,
Expand Down Expand Up @@ -347,6 +361,19 @@ var SendTestCasesD3C = []ChannelSendTestCase{
ExpectedExternalID: "157b5e14568e8",
SendPrep: setSendURL,
},
{
Label: "Sticker Send",
MsgText: "sticker caption",
MsgURN: "whatsapp:250788123123",
MsgAttachments: []string{"image/webp:https://foo.bar/sticker.webp"},
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
MockResponseStatus: 201,
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"sticker","sticker":{"link":"https://foo.bar/sticker.webp","caption":"sticker caption"}}`,
ExpectedRequestPath: "/messages",
ExpectedMsgStatus: "W",
ExpectedExternalID: "157b5e14568e8",
SendPrep: setSendURL,
},
{
Label: "Video Send",
MsgText: "video caption",
Expand Down
34 changes: 27 additions & 7 deletions handlers/facebookapp/facebookapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ type wacMedia struct {
Mimetype string `json:"mime_type"`
SHA256 string `json:"sha256"`
}

type wacSticker struct {
Animated bool `json:"animated"`
ID string `json:"id"`
Mimetype string `json:"mime_type"`
SHA256 string `json:"sha256"`
}

type moPayload struct {
Object string `json:"object"`
Entry []struct {
Expand Down Expand Up @@ -160,11 +168,12 @@ type moPayload struct {
Text struct {
Body string `json:"body"`
} `json:"text"`
Image *wacMedia `json:"image"`
Audio *wacMedia `json:"audio"`
Video *wacMedia `json:"video"`
Document *wacMedia `json:"document"`
Voice *wacMedia `json:"voice"`
Image *wacMedia `json:"image"`
Audio *wacMedia `json:"audio"`
Video *wacMedia `json:"video"`
Document *wacMedia `json:"document"`
Voice *wacMedia `json:"voice"`
Sticker *wacSticker `json:"sticker"`
Location *struct {
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Expand Down Expand Up @@ -464,6 +473,8 @@ func (h *handler) processCloudWhatsAppPayload(ctx context.Context, channel couri
} else if msg.Type == "image" && msg.Image != nil {
text = msg.Image.Caption
mediaURL, err = resolveMediaURL(msg.Image.ID, token, clog)
} else if msg.Type == "sticker" && msg.Sticker != nil {
mediaURL, err = resolveMediaURL(msg.Sticker.ID, token, clog)
} else if msg.Type == "video" && msg.Video != nil {
text = msg.Video.Caption
mediaURL, err = resolveMediaURL(msg.Video.ID, token, clog)
Expand Down Expand Up @@ -1091,6 +1102,7 @@ type wacMTPayload struct {
Image *wacMTMedia `json:"image,omitempty"`
Audio *wacMTMedia `json:"audio,omitempty"`
Video *wacMTMedia `json:"video,omitempty"`
Sticker *wacMTMedia `json:"sticker,omitempty"`

Interactive *wacInteractive `json:"interactive,omitempty"`

Expand Down Expand Up @@ -1226,7 +1238,10 @@ func (h *handler) sendCloudAPIWhatsappMsg(ctx context.Context, msg courier.Msg,

} else if i < len(msg.Attachments()) && (len(qrs) == 0 || len(qrs) > 3) {
attType, attURL := handlers.SplitAttachment(msg.Attachments()[i])
attType = strings.Split(attType, "/")[0]
splitedAttType := strings.Split(attType, "/")
attType = splitedAttType[0]
attFormat := splitedAttType[1]

if attType == "application" {
attType = "document"
}
Expand All @@ -1239,7 +1254,12 @@ func (h *handler) sendCloudAPIWhatsappMsg(ctx context.Context, msg courier.Msg,
}

if attType == "image" {
payload.Image = &media
if attFormat == "webp" {
payload.Type = "sticker"
payload.Sticker = &media
} else {
payload.Image = &media
}
} else if attType == "audio" {
payload.Audio = &media
} else if attType == "video" {
Expand Down
33 changes: 33 additions & 0 deletions handlers/facebookapp/facebookapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,21 @@ var testCasesWAC = []ChannelHandleTestCase{
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
PrepRequest: addValidSignature,
},
{
Label: "Receive Valid Sticker Message",
URL: wacReceiveURL,
Data: string(test.ReadFile("./testdata/wac/stickerWAC.json")),
ExpectedRespStatus: 200,
ExpectedBodyContains: "Handled",
NoQueueErrorCheck: true,
NoInvalidChannelCheck: true,
ExpectedMsgText: Sp(""),
ExpectedURN: "whatsapp:5678",
ExpectedExternalID: "external_id",
ExpectedAttachments: []string{"https://foo.bar/attachmentURL_Sticker"},
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
PrepRequest: addValidSignature,
},
{
Label: "Receive Valid Video Message",
URL: wacReceiveURL,
Expand Down Expand Up @@ -828,6 +843,11 @@ func TestHandler(t *testing.T) {
return
}

if strings.HasSuffix(r.URL.Path, "sticker") {
w.Write([]byte(`{"url": "https://foo.bar/attachmentURL_Sticker"}`))
return
}

// valid token
w.Write([]byte(`{"url": "https://foo.bar/attachmentURL"}`))

Expand Down Expand Up @@ -1311,6 +1331,19 @@ var SendTestCasesWAC = []ChannelSendTestCase{
ExpectedExternalID: "157b5e14568e8",
SendPrep: setSendURL,
},
{
Label: "Sticker Send",
MsgText: "sticker caption",
MsgURN: "whatsapp:250788123123",
MsgAttachments: []string{"image/webp:https://foo.bar/sticker.webp"},
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
MockResponseStatus: 201,
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"sticker","sticker":{"link":"https://foo.bar/sticker.webp","caption":"sticker caption"}}`,
ExpectedRequestPath: "/12345_ID/messages",
ExpectedMsgStatus: "W",
ExpectedExternalID: "157b5e14568e8",
SendPrep: setSendURL,
},
{
Label: "Video Send",
MsgText: "video caption",
Expand Down

0 comments on commit 7e20fe4

Please sign in to comment.