Skip to content

Commit

Permalink
Prep for support for more WA templates components
Browse files Browse the repository at this point in the history
  • Loading branch information
norkans7 committed Nov 29, 2023
1 parent 503a4a9 commit 03d5765
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 224 deletions.
147 changes: 71 additions & 76 deletions handlers/dialog360/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,28 +324,83 @@ func (h *handler) Send(ctx context.Context, msg courier.MsgOut, clog *courier.Ch
for i := 0; i < len(msgParts)+len(msg.Attachments()); i++ {
payload := whatsapp.SendRequest{MessagingProduct: "whatsapp", RecipientType: "individual", To: msg.URN().Path()}

if len(msg.Attachments()) == 0 {
// do we have a template?
templating, err := whatsapp.GetTemplating(msg)
if err != nil {
return nil, errors.Wrapf(err, "unable to decode template: %s for channel: %s", string(msg.Metadata()), msg.Channel().UUID())
}
if templating != nil {
// do we have a template?
templating, err := whatsapp.GetTemplating(msg)
if err != nil {
return nil, errors.Wrapf(err, "unable to decode template: %s for channel: %s", string(msg.Metadata()), msg.Channel().UUID())
}

Check warning on line 331 in handlers/dialog360/handler.go

View check run for this annotation

Codecov / codecov/patch

handlers/dialog360/handler.go#L330-L331

Added lines #L330 - L331 were not covered by tests
if templating != nil {

payload.Type = "template"
payload.Type = "template"

template := whatsapp.Template{Name: templating.Template.Name, Language: &whatsapp.Language{Policy: "deterministic", Code: lang}}
payload.Template = &template
template := whatsapp.Template{Name: templating.Template.Name, Language: &whatsapp.Language{Policy: "deterministic", Code: lang}}
payload.Template = &template

component := &whatsapp.Component{Type: "body"}
for _, v := range templating.Components {
template.Components = append(payload.Template.Components, &v)
}

for _, v := range templating.Variables {
component.Params = append(component.Params, &whatsapp.Param{Type: "text", Text: v})
} else if len(msg.Attachments()) == 0 {
if i < (len(msgParts) + len(msg.Attachments()) - 1) {
// this is still a msg part
text := &whatsapp.Text{PreviewURL: false}
payload.Type = "text"
if strings.Contains(msgParts[i-len(msg.Attachments())], "https://") || strings.Contains(msgParts[i-len(msg.Attachments())], "http://") {
text.PreviewURL = true

Check warning on line 349 in handlers/dialog360/handler.go

View check run for this annotation

Codecov / codecov/patch

handlers/dialog360/handler.go#L345-L349

Added lines #L345 - L349 were not covered by tests
}
template.Components = append(payload.Template.Components, component)

text.Body = msgParts[i-len(msg.Attachments())]
payload.Text = text

Check warning on line 352 in handlers/dialog360/handler.go

View check run for this annotation

Codecov / codecov/patch

handlers/dialog360/handler.go#L351-L352

Added lines #L351 - L352 were not covered by tests
} else {
if i < (len(msgParts) + len(msg.Attachments()) - 1) {
if len(qrs) > 0 {
payload.Type = "interactive"
// We can use buttons
if len(qrs) <= 3 {
interactive := whatsapp.Interactive{Type: "button", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

btns := make([]whatsapp.Button, len(qrs))
for i, qr := range qrs {
btns[i] = whatsapp.Button{
Type: "reply",
}
btns[i].Reply.ID = fmt.Sprint(i)
btns[i].Reply.Title = qr
}
interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Buttons: btns}
payload.Interactive = &interactive
} else if len(qrs) <= 10 {
interactive := whatsapp.Interactive{Type: "list", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

section := whatsapp.Section{
Rows: make([]whatsapp.SectionRow, len(qrs)),
}
for i, qr := range qrs {
section.Rows[i] = whatsapp.SectionRow{
ID: fmt.Sprint(i),
Title: qr,
}
}

interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Button: menuButton, Sections: []whatsapp.Section{
section,
}}

payload.Interactive = &interactive
} else {
return nil, fmt.Errorf("too many quick replies WAC supports only up to 10 quick replies")
}

Check warning on line 402 in handlers/dialog360/handler.go

View check run for this annotation

Codecov / codecov/patch

handlers/dialog360/handler.go#L400-L402

Added lines #L400 - L402 were not covered by tests
} else {
// this is still a msg part
text := &whatsapp.Text{PreviewURL: false}
payload.Type = "text"
Expand All @@ -354,66 +409,6 @@ func (h *handler) Send(ctx context.Context, msg courier.MsgOut, clog *courier.Ch
}
text.Body = msgParts[i-len(msg.Attachments())]
payload.Text = text
} else {
if len(qrs) > 0 {
payload.Type = "interactive"
// We can use buttons
if len(qrs) <= 3 {
interactive := whatsapp.Interactive{Type: "button", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

btns := make([]whatsapp.Button, len(qrs))
for i, qr := range qrs {
btns[i] = whatsapp.Button{
Type: "reply",
}
btns[i].Reply.ID = fmt.Sprint(i)
btns[i].Reply.Title = qr
}
interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Buttons: btns}
payload.Interactive = &interactive
} else if len(qrs) <= 10 {
interactive := whatsapp.Interactive{Type: "list", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

section := whatsapp.Section{
Rows: make([]whatsapp.SectionRow, len(qrs)),
}
for i, qr := range qrs {
section.Rows[i] = whatsapp.SectionRow{
ID: fmt.Sprint(i),
Title: qr,
}
}

interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Button: menuButton, Sections: []whatsapp.Section{
section,
}}

payload.Interactive = &interactive
} else {
return nil, fmt.Errorf("too many quick replies WAC supports only up to 10 quick replies")
}
} else {
// this is still a msg part
text := &whatsapp.Text{PreviewURL: false}
payload.Type = "text"
if strings.Contains(msgParts[i-len(msg.Attachments())], "https://") || strings.Contains(msgParts[i-len(msg.Attachments())], "http://") {
text.PreviewURL = true
}
text.Body = msgParts[i-len(msg.Attachments())]
payload.Text = text
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions handlers/dialog360/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ var SendTestCasesD3C = []OutgoingTestCase{
MsgText: "templated message",
MsgURN: "whatsapp:250788123123",
MsgLocale: "eng",
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "variables": ["Chef", "tomorrow"]}}`),
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type": "body","text": "Hi {{1}}, are you still experiencing problems with {{2}}?","parameters": [{"type": "text", "text": "Chef"},{"type": "text", "text": "tomorrow"}],"example": {"body_text": [["Bob","Product_A"]]}}]}}`),
ExpectedMsgStatus: "W",
ExpectedExternalID: "157b5e14568e8",
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
Expand All @@ -422,7 +422,7 @@ var SendTestCasesD3C = []OutgoingTestCase{
MsgText: "templated message",
MsgURN: "whatsapp:250788123123",
MsgLocale: "eng-US",
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "variables": ["Chef", "tomorrow"]}}`),
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type": "body","text": "Hi {{1}}, are you still experiencing problems with {{2}}?","parameters": [{"type": "text", "text": "Chef"},{"type": "text", "text": "tomorrow"}],"example": {"body_text": [["Bob","Product_A"]]}}]}}`),
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
MockResponseStatus: 200,
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"template","template":{"name":"revive_issue","language":{"policy":"deterministic","code":"en_US"},"components":[{"type":"body","sub_type":"","index":"","parameters":[{"type":"text","text":"Chef"},{"type":"text","text":"tomorrow"}]}]}}`,
Expand All @@ -435,7 +435,7 @@ var SendTestCasesD3C = []OutgoingTestCase{
MsgText: "templated message",
MsgURN: "whatsapp:250788123123",
MsgLocale: "bnt",
MsgMetadata: json.RawMessage(`{"templating": { "template": { "name": "revive_issue", "uuid": "8ca114b4-bee2-4d3b-aaf1-9aa6b48d41e8" }, "variables": ["Chef", "tomorrow"]}}`),
MsgMetadata: json.RawMessage(`{"templating": { "template": { "name": "revive_issue", "uuid": "8ca114b4-bee2-4d3b-aaf1-9aa6b48d41e8" }, "components": [{"type": "body","text": "Hi {{1}}, are you still experiencing problems with {{2}}?","parameters": [{"type": "text", "text": "Chef"},{"type": "text", "text": "tomorrow"}],"example": {"body_text": [["Bob","Product_A"]]}}]}}`),
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
MockResponseStatus: 200,
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"template","template":{"name":"revive_issue","language":{"policy":"deterministic","code":"en"},"components":[{"type":"body","sub_type":"","index":"","parameters":[{"type":"text","text":"Chef"},{"type":"text","text":"tomorrow"}]}]}}`,
Expand Down
150 changes: 73 additions & 77 deletions handlers/meta/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,28 +814,84 @@ func (h *handler) sendWhatsAppMsg(ctx context.Context, msg courier.MsgOut, clog
for i := 0; i < len(msgParts)+len(msg.Attachments()); i++ {
payload := whatsapp.SendRequest{MessagingProduct: "whatsapp", RecipientType: "individual", To: msg.URN().Path()}

if len(msg.Attachments()) == 0 {
// do we have a template?
templating, err := whatsapp.GetTemplating(msg)
if err != nil {
return nil, errors.Wrapf(err, "unable to decode template: %s for channel: %s", string(msg.Metadata()), msg.Channel().UUID())
}
if templating != nil {
// do we have a template?
templating, err := whatsapp.GetTemplating(msg)
if err != nil {
return nil, errors.Wrapf(err, "unable to decode template: %s for channel: %s", string(msg.Metadata()), msg.Channel().UUID())
}

Check warning on line 821 in handlers/meta/handlers.go

View check run for this annotation

Codecov / codecov/patch

handlers/meta/handlers.go#L820-L821

Added lines #L820 - L821 were not covered by tests
if templating != nil {

payload.Type = "template"
payload.Type = "template"

template := whatsapp.Template{Name: templating.Template.Name, Language: &whatsapp.Language{Policy: "deterministic", Code: lang}}
payload.Template = &template
template := whatsapp.Template{Name: templating.Template.Name, Language: &whatsapp.Language{Policy: "deterministic", Code: lang}}
payload.Template = &template

component := &whatsapp.Component{Type: "body"}
for _, v := range templating.Components {
template.Components = append(payload.Template.Components, &v)
}

for _, v := range templating.Variables {
component.Params = append(component.Params, &whatsapp.Param{Type: "text", Text: v})
}
template.Components = append(payload.Template.Components, component)
} else if len(msg.Attachments()) == 0 {

if i < (len(msgParts) + len(msg.Attachments()) - 1) {
// this is still a msg part
text := &whatsapp.Text{PreviewURL: false}
payload.Type = "text"
if strings.Contains(msgParts[i-len(msg.Attachments())], "https://") || strings.Contains(msgParts[i-len(msg.Attachments())], "http://") {
text.PreviewURL = true
}
text.Body = msgParts[i-len(msg.Attachments())]
payload.Text = text

Check warning on line 843 in handlers/meta/handlers.go

View check run for this annotation

Codecov / codecov/patch

handlers/meta/handlers.go#L836-L843

Added lines #L836 - L843 were not covered by tests
} else {
if i < (len(msgParts) + len(msg.Attachments()) - 1) {
if len(qrs) > 0 {
payload.Type = "interactive"
// We can use buttons
if len(qrs) <= 3 {
interactive := whatsapp.Interactive{Type: "button", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

btns := make([]whatsapp.Button, len(qrs))
for i, qr := range qrs {
btns[i] = whatsapp.Button{
Type: "reply",
}
btns[i].Reply.ID = fmt.Sprint(i)
btns[i].Reply.Title = qr
}
interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Buttons: btns}
payload.Interactive = &interactive
} else if len(qrs) <= 10 {
interactive := whatsapp.Interactive{Type: "list", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

section := whatsapp.Section{
Rows: make([]whatsapp.SectionRow, len(qrs)),
}
for i, qr := range qrs {
section.Rows[i] = whatsapp.SectionRow{
ID: fmt.Sprint(i),
Title: qr,
}
}

interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Button: menuButton, Sections: []whatsapp.Section{
section,
}}

payload.Interactive = &interactive
} else {
return nil, fmt.Errorf("too many quick replies WAC supports only up to 10 quick replies")
}

Check warning on line 893 in handlers/meta/handlers.go

View check run for this annotation

Codecov / codecov/patch

handlers/meta/handlers.go#L891-L893

Added lines #L891 - L893 were not covered by tests
} else {
// this is still a msg part
text := &whatsapp.Text{PreviewURL: false}
payload.Type = "text"
Expand All @@ -844,66 +900,6 @@ func (h *handler) sendWhatsAppMsg(ctx context.Context, msg courier.MsgOut, clog
}
text.Body = msgParts[i-len(msg.Attachments())]
payload.Text = text
} else {
if len(qrs) > 0 {
payload.Type = "interactive"
// We can use buttons
if len(qrs) <= 3 {
interactive := whatsapp.Interactive{Type: "button", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

btns := make([]whatsapp.Button, len(qrs))
for i, qr := range qrs {
btns[i] = whatsapp.Button{
Type: "reply",
}
btns[i].Reply.ID = fmt.Sprint(i)
btns[i].Reply.Title = qr
}
interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Buttons: btns}
payload.Interactive = &interactive
} else if len(qrs) <= 10 {
interactive := whatsapp.Interactive{Type: "list", Body: struct {
Text string "json:\"text\""
}{Text: msgParts[i-len(msg.Attachments())]}}

section := whatsapp.Section{
Rows: make([]whatsapp.SectionRow, len(qrs)),
}
for i, qr := range qrs {
section.Rows[i] = whatsapp.SectionRow{
ID: fmt.Sprint(i),
Title: qr,
}
}

interactive.Action = &struct {
Button string "json:\"button,omitempty\""
Sections []whatsapp.Section "json:\"sections,omitempty\""
Buttons []whatsapp.Button "json:\"buttons,omitempty\""
}{Button: menuButton, Sections: []whatsapp.Section{
section,
}}

payload.Interactive = &interactive
} else {
return nil, fmt.Errorf("too many quick replies WAC supports only up to 10 quick replies")
}
} else {
// this is still a msg part
text := &whatsapp.Text{PreviewURL: false}
payload.Type = "text"
if strings.Contains(msgParts[i-len(msg.Attachments())], "https://") || strings.Contains(msgParts[i-len(msg.Attachments())], "http://") {
text.PreviewURL = true
}
text.Body = msgParts[i-len(msg.Attachments())]
payload.Text = text
}
}
}

Expand Down Expand Up @@ -1066,7 +1062,7 @@ func (h *handler) sendWhatsAppMsg(ctx context.Context, msg courier.MsgOut, clog
zeroIndex = true
}

err := h.requestWAC(payload, accessToken, status, wacPhoneURL, zeroIndex, clog)
err = h.requestWAC(payload, accessToken, status, wacPhoneURL, zeroIndex, clog)
if err != nil {
return status, err
}
Expand Down
6 changes: 3 additions & 3 deletions handlers/meta/whataspp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ var whatsappOutgoingTests = []OutgoingTestCase{
MsgText: "templated message",
MsgURN: "whatsapp:250788123123",
MsgLocale: "eng",
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "variables": ["Chef", "tomorrow"]}}`),
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type": "body","text": "Hi {{1}}, are you still experiencing problems with {{2}}?","parameters": [{"type": "text", "text": "Chef"},{"type": "text", "text": "tomorrow"}],"example": {"body_text": [["Bob","Product_A"]]}}]}}`),
ExpectedMsgStatus: "W",
ExpectedExternalID: "157b5e14568e8",
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
Expand All @@ -386,7 +386,7 @@ var whatsappOutgoingTests = []OutgoingTestCase{
MsgText: "templated message",
MsgURN: "whatsapp:250788123123",
MsgLocale: "eng-US",
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "variables": ["Chef", "tomorrow"]}}`),
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type": "body","text": "Hi {{1}}, are you still experiencing problems with {{2}}?","parameters": [{"type": "text", "text": "Chef"},{"type": "text", "text": "tomorrow"}],"example": {"body_text": [["Bob","Product_A"]]}}]}}`),
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
MockResponseStatus: 200,
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"template","template":{"name":"revive_issue","language":{"policy":"deterministic","code":"en_US"},"components":[{"type":"body","sub_type":"","index":"","parameters":[{"type":"text","text":"Chef"},{"type":"text","text":"tomorrow"}]}]}}`,
Expand All @@ -399,7 +399,7 @@ var whatsappOutgoingTests = []OutgoingTestCase{
MsgText: "templated message",
MsgURN: "whatsapp:250788123123",
MsgLocale: "bnt",
MsgMetadata: json.RawMessage(`{"templating": { "template": { "name": "revive_issue", "uuid": "8ca114b4-bee2-4d3b-aaf1-9aa6b48d41e8" }, "variables": ["Chef", "tomorrow"]}}`),
MsgMetadata: json.RawMessage(`{"templating": { "template": { "name": "revive_issue", "uuid": "8ca114b4-bee2-4d3b-aaf1-9aa6b48d41e8" }, "components": [{"type": "body","text": "Hi {{1}}, are you still experiencing problems with {{2}}?","parameters": [{"type": "text", "text": "Chef"},{"type": "text", "text": "tomorrow"}],"example": {"body_text": [["Bob","Product_A"]]}}]}}`),
MockResponseBody: `{ "messages": [{"id": "157b5e14568e8"}] }`,
MockResponseStatus: 200,
ExpectedRequestBody: `{"messaging_product":"whatsapp","recipient_type":"individual","to":"250788123123","type":"template","template":{"name":"revive_issue","language":{"policy":"deterministic","code":"en"},"components":[{"type":"body","sub_type":"","index":"","parameters":[{"type":"text","text":"Chef"},{"type":"text","text":"tomorrow"}]}]}}`,
Expand Down
Loading

0 comments on commit 03d5765

Please sign in to comment.