Skip to content

Commit 1847a76

Browse files
committed
Support sending and receiving stickers for WAC and D3C
1 parent 40b54ee commit 1847a76

File tree

6 files changed

+197
-14
lines changed

6 files changed

+197
-14
lines changed

Diff for: handlers/dialog360/dialog360.go

+26-7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ type wacMedia struct {
9191
Mimetype string `json:"mime_type"`
9292
SHA256 string `json:"sha256"`
9393
}
94+
95+
type wacSticker struct {
96+
Animated bool `json:"animated"`
97+
ID string `json:"id"`
98+
Mimetype string `json:"mime_type"`
99+
SHA256 string `json:"sha256"`
100+
}
94101
type moPayload struct {
95102
Object string `json:"object"`
96103
Entry []struct {
@@ -124,11 +131,12 @@ type moPayload struct {
124131
Text struct {
125132
Body string `json:"body"`
126133
} `json:"text"`
127-
Image *wacMedia `json:"image"`
128-
Audio *wacMedia `json:"audio"`
129-
Video *wacMedia `json:"video"`
130-
Document *wacMedia `json:"document"`
131-
Voice *wacMedia `json:"voice"`
134+
Image *wacMedia `json:"image"`
135+
Audio *wacMedia `json:"audio"`
136+
Video *wacMedia `json:"video"`
137+
Document *wacMedia `json:"document"`
138+
Voice *wacMedia `json:"voice"`
139+
Sticker *wacSticker `json:"sticker"`
132140
Location *struct {
133141
Latitude float64 `json:"latitude"`
134142
Longitude float64 `json:"longitude"`
@@ -267,6 +275,8 @@ func (h *handler) processCloudWhatsAppPayload(ctx context.Context, channel couri
267275
} else if msg.Type == "image" && msg.Image != nil {
268276
text = msg.Image.Caption
269277
mediaURL, err = resolveMediaURL(channel, msg.Image.ID, clog)
278+
} else if msg.Type == "sticker" && msg.Sticker != nil {
279+
mediaURL, err = resolveMediaURL(channel, msg.Sticker.ID, clog)
270280
} else if msg.Type == "video" && msg.Video != nil {
271281
text = msg.Video.Caption
272282
mediaURL, err = resolveMediaURL(channel, msg.Video.ID, clog)
@@ -475,6 +485,7 @@ type wacMTPayload struct {
475485
Image *wacMTMedia `json:"image,omitempty"`
476486
Audio *wacMTMedia `json:"audio,omitempty"`
477487
Video *wacMTMedia `json:"video,omitempty"`
488+
Sticker *wacMTMedia `json:"sticker,omitempty"`
478489

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

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

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

636649
if attType == "image" {
637-
payload.Image = &media
650+
if attFormat == "webp" {
651+
payload.Type = "sticker"
652+
payload.Sticker = &media
653+
} else {
654+
payload.Image = &media
655+
}
656+
638657
} else if attType == "audio" {
639658
payload.Audio = &media
640659
} else if attType == "video" {

Diff for: handlers/dialog360/dialog360_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,20 @@ var testCasesD3C = []ChannelHandleTestCase{
112112
ExpectedAttachments: []string{"https://waba-v2.360dialog.io/whatsapp_business/attachments/?mid=id_image"},
113113
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
114114
},
115+
{
116+
Label: "Receive Valid Sticker Message",
117+
URL: d3CReceiveURL,
118+
Data: string(test.ReadFile("./testdata/wac/stickerWAC.json")),
119+
ExpectedRespStatus: 200,
120+
ExpectedBodyContains: "Handled",
121+
NoQueueErrorCheck: true,
122+
NoInvalidChannelCheck: true,
123+
ExpectedMsgText: Sp(""),
124+
ExpectedURN: "whatsapp:5678",
125+
ExpectedExternalID: "external_id",
126+
ExpectedAttachments: []string{"https://waba-v2.360dialog.io/whatsapp_business/attachments/?mid=id_sticker"},
127+
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
128+
},
115129
{
116130
Label: "Receive Valid Video Message",
117131
URL: d3CReceiveURL,
@@ -347,6 +361,19 @@ var SendTestCasesD3C = []ChannelSendTestCase{
347361
ExpectedExternalID: "157b5e14568e8",
348362
SendPrep: setSendURL,
349363
},
364+
{
365+
Label: "Sticker Send",
366+
MsgText: "sticker caption",
367+
MsgURN: "whatsapp:250788123123",
368+
MsgAttachments: []string{"image/webp:https://foo.bar/sticker.webp"},
369+
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
370+
MockResponseStatus: 201,
371+
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"sticker","sticker":{"link":"https://foo.bar/sticker.webp","caption":"sticker caption"}}`,
372+
ExpectedRequestPath: "/messages",
373+
ExpectedMsgStatus: "W",
374+
ExpectedExternalID: "157b5e14568e8",
375+
SendPrep: setSendURL,
376+
},
350377
{
351378
Label: "Video Send",
352379
MsgText: "video caption",

Diff for: handlers/dialog360/testdata/wac/stickerWAC.json

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"object": "whatsapp_business_account",
3+
"entry": [
4+
{
5+
"id": "8856996819413533",
6+
"changes": [
7+
{
8+
"value": {
9+
"messaging_product": "whatsapp",
10+
"metadata": {
11+
"display_phone_number": "+250 788 123 200",
12+
"phone_number_id": "12345"
13+
},
14+
"contacts": [
15+
{
16+
"profile": {
17+
"name": "Kerry Fisher"
18+
},
19+
"wa_id": "5678"
20+
}
21+
],
22+
"messages": [
23+
{
24+
"from": "5678",
25+
"id": "external_id",
26+
"sticker": {
27+
"file": "/usr/local/wamedia/shared/b1cf38-8734-4ad3-b4a1-ef0c10d0d683",
28+
"id": "id_sticker",
29+
"mime_type": "image/webp",
30+
"sha256": "29ed500fa64eb55fc19dc4124acb300e5dcc54a0f822a301ae99944db"
31+
},
32+
"timestamp": "1454119029",
33+
"type": "sticker"
34+
}
35+
]
36+
},
37+
"field": "messages"
38+
}
39+
]
40+
}
41+
]
42+
}

Diff for: handlers/facebookapp/facebookapp.go

+27-7
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ type wacMedia struct {
127127
Mimetype string `json:"mime_type"`
128128
SHA256 string `json:"sha256"`
129129
}
130+
131+
type wacSticker struct {
132+
Animated bool `json:"animated"`
133+
ID string `json:"id"`
134+
Mimetype string `json:"mime_type"`
135+
SHA256 string `json:"sha256"`
136+
}
137+
130138
type moPayload struct {
131139
Object string `json:"object"`
132140
Entry []struct {
@@ -160,11 +168,12 @@ type moPayload struct {
160168
Text struct {
161169
Body string `json:"body"`
162170
} `json:"text"`
163-
Image *wacMedia `json:"image"`
164-
Audio *wacMedia `json:"audio"`
165-
Video *wacMedia `json:"video"`
166-
Document *wacMedia `json:"document"`
167-
Voice *wacMedia `json:"voice"`
171+
Image *wacMedia `json:"image"`
172+
Audio *wacMedia `json:"audio"`
173+
Video *wacMedia `json:"video"`
174+
Document *wacMedia `json:"document"`
175+
Voice *wacMedia `json:"voice"`
176+
Sticker *wacSticker `json:"sticker"`
168177
Location *struct {
169178
Latitude float64 `json:"latitude"`
170179
Longitude float64 `json:"longitude"`
@@ -464,6 +473,8 @@ func (h *handler) processCloudWhatsAppPayload(ctx context.Context, channel couri
464473
} else if msg.Type == "image" && msg.Image != nil {
465474
text = msg.Image.Caption
466475
mediaURL, err = resolveMediaURL(msg.Image.ID, token, clog)
476+
} else if msg.Type == "sticker" && msg.Sticker != nil {
477+
mediaURL, err = resolveMediaURL(msg.Sticker.ID, token, clog)
467478
} else if msg.Type == "video" && msg.Video != nil {
468479
text = msg.Video.Caption
469480
mediaURL, err = resolveMediaURL(msg.Video.ID, token, clog)
@@ -1091,6 +1102,7 @@ type wacMTPayload struct {
10911102
Image *wacMTMedia `json:"image,omitempty"`
10921103
Audio *wacMTMedia `json:"audio,omitempty"`
10931104
Video *wacMTMedia `json:"video,omitempty"`
1105+
Sticker *wacMTMedia `json:"sticker,omitempty"`
10941106

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

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

12271239
} else if i < len(msg.Attachments()) && (len(qrs) == 0 || len(qrs) > 3) {
12281240
attType, attURL := handlers.SplitAttachment(msg.Attachments()[i])
1229-
attType = strings.Split(attType, "/")[0]
1241+
splitedAttType := strings.Split(attType, "/")
1242+
attType = splitedAttType[0]
1243+
attFormat := splitedAttType[1]
1244+
12301245
if attType == "application" {
12311246
attType = "document"
12321247
}
@@ -1239,7 +1254,12 @@ func (h *handler) sendCloudAPIWhatsappMsg(ctx context.Context, msg courier.Msg,
12391254
}
12401255

12411256
if attType == "image" {
1242-
payload.Image = &media
1257+
if attFormat == "webp" {
1258+
payload.Type = "sticker"
1259+
payload.Sticker = &media
1260+
} else {
1261+
payload.Image = &media
1262+
}
12431263
} else if attType == "audio" {
12441264
payload.Audio = &media
12451265
} else if attType == "video" {

Diff for: handlers/facebookapp/facebookapp_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,21 @@ var testCasesWAC = []ChannelHandleTestCase{
627627
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
628628
PrepRequest: addValidSignature,
629629
},
630+
{
631+
Label: "Receive Valid Sticker Message",
632+
URL: wacReceiveURL,
633+
Data: string(test.ReadFile("./testdata/wac/stickerWAC.json")),
634+
ExpectedRespStatus: 200,
635+
ExpectedBodyContains: "Handled",
636+
NoQueueErrorCheck: true,
637+
NoInvalidChannelCheck: true,
638+
ExpectedMsgText: Sp(""),
639+
ExpectedURN: "whatsapp:5678",
640+
ExpectedExternalID: "external_id",
641+
ExpectedAttachments: []string{"https://foo.bar/attachmentURL_Sticker"},
642+
ExpectedDate: time.Date(2016, 1, 30, 1, 57, 9, 0, time.UTC),
643+
PrepRequest: addValidSignature,
644+
},
630645
{
631646
Label: "Receive Valid Video Message",
632647
URL: wacReceiveURL,
@@ -828,6 +843,11 @@ func TestHandler(t *testing.T) {
828843
return
829844
}
830845

846+
if strings.HasSuffix(r.URL.Path, "sticker") {
847+
w.Write([]byte(`{"url": "https://foo.bar/attachmentURL_Sticker"}`))
848+
return
849+
}
850+
831851
// valid token
832852
w.Write([]byte(`{"url": "https://foo.bar/attachmentURL"}`))
833853

@@ -1311,6 +1331,19 @@ var SendTestCasesWAC = []ChannelSendTestCase{
13111331
ExpectedExternalID: "157b5e14568e8",
13121332
SendPrep: setSendURL,
13131333
},
1334+
{
1335+
Label: "Sticker Send",
1336+
MsgText: "sticker caption",
1337+
MsgURN: "whatsapp:250788123123",
1338+
MsgAttachments: []string{"image/webp:https://foo.bar/sticker.webp"},
1339+
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
1340+
MockResponseStatus: 201,
1341+
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"sticker","sticker":{"link":"https://foo.bar/sticker.webp","caption":"sticker caption"}}`,
1342+
ExpectedRequestPath: "/12345_ID/messages",
1343+
ExpectedMsgStatus: "W",
1344+
ExpectedExternalID: "157b5e14568e8",
1345+
SendPrep: setSendURL,
1346+
},
13141347
{
13151348
Label: "Video Send",
13161349
MsgText: "video caption",

Diff for: handlers/facebookapp/testdata/wac/stickerWAC.json

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"object": "whatsapp_business_account",
3+
"entry": [
4+
{
5+
"id": "8856996819413533",
6+
"changes": [
7+
{
8+
"value": {
9+
"messaging_product": "whatsapp",
10+
"metadata": {
11+
"display_phone_number": "+250 788 123 200",
12+
"phone_number_id": "12345"
13+
},
14+
"contacts": [
15+
{
16+
"profile": {
17+
"name": "Kerry Fisher"
18+
},
19+
"wa_id": "5678"
20+
}
21+
],
22+
"messages": [
23+
{
24+
"from": "5678",
25+
"id": "external_id",
26+
"sticker": {
27+
"file": "/usr/local/wamedia/shared/b1cf38-8734-4ad3-b4a1-ef0c10d0d683",
28+
"id": "id_sticker",
29+
"mime_type": "image/webp",
30+
"sha256": "29ed500fa64eb55fc19dc4124acb300e5dcc54a0f822a301ae99944db"
31+
},
32+
"timestamp": "1454119029",
33+
"type": "sticker"
34+
}
35+
]
36+
},
37+
"field": "messages"
38+
}
39+
]
40+
}
41+
]
42+
}

0 commit comments

Comments
 (0)