Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include header images from template messages as attachments on preview message #1262

Merged
merged 2 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions flows/actions/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/nyaruka/goflow/assets"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/flows/events"
"github.com/nyaruka/goflow/utils"
)

func init() {
Expand Down Expand Up @@ -127,14 +128,16 @@ func (a *SendMsgAction) getTemplateMsg(run flows.Run, urn urns.URN, channelRef *
evaluatedVariables[i] = v
}

// cross-reference with asset to get variable types
// cross-reference with asset to get variable types and filter out invalid values
variables := make([]*flows.TemplatingVariable, len(translation.Variables()))
for i, v := range translation.Variables() {
// we pad out any missing variables with empty values
value := ""
if i < len(evaluatedVariables) {
variables[i] = &flows.TemplatingVariable{Type: v.Type(), Value: evaluatedVariables[i]}
} else {
variables[i] = &flows.TemplatingVariable{Type: v.Type(), Value: ""}
value = evaluatedVariables[i]
}

variables[i] = &flows.TemplatingVariable{Type: v.Type(), Value: value}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about having this ignore attachments that don't match the header type, e.g. ignore video/mp4:http://... if variable is type image... but the empty values will cause a send failure anyway and I think it will be more obvious to the user what the problem is if we just try to send the wrong attachment type and let WhatsApp complain about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I avoided the mismatch by using the attachment type in https://github.com/nyaruka/courier/pull/752/files should I keep using the parameter type instead?
Of course both approaches would fail to send if the parameter type is not the same as the one on the template

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your change is fine.. in the case that someone updates their template but doesn't update the flow using it, we'll send a param of the wrong type to whatsapp, and I assume they'll send back a fairly clear error message.

}

// create a list of components that have variables
Expand All @@ -150,27 +153,33 @@ func (a *SendMsgAction) getTemplateMsg(run flows.Run, urn urns.URN, channelRef *
}

// the message we return is an approximate preview of what the channel will send using the template
var previewParts []string
var previewText []string
var previewAttachments []utils.Attachment
var previewQRs []string

for _, comp := range translation.Components() {
previewContent := comp.Content()
for key, index := range comp.Variables() {
previewContent = strings.ReplaceAll(previewContent, fmt.Sprintf("{{%s}}", key), variables[index].Value)
variable := variables[index]

if variable.Type == "text" {
previewContent = strings.ReplaceAll(previewContent, fmt.Sprintf("{{%s}}", key), variable.Value)
} else if variable.Type == "image" || variable.Type == "video" || variable.Type == "document" {
previewAttachments = append(previewAttachments, utils.Attachment(variable.Value))
}
}

if previewContent != "" {
if comp.Type() == "header" || comp.Type() == "body" || comp.Type() == "footer" {
previewParts = append(previewParts, previewContent)
previewText = append(previewText, previewContent)
} else if strings.HasPrefix(comp.Type(), "button/") {
previewQRs = append(previewQRs, stringsx.TruncateEllipsis(previewContent, maxQuickReplyLength))
}
}
}

previewText := strings.Join(previewParts, "\n\n")
locale := translation.Locale()
templating := flows.NewMsgTemplating(a.Template, translation.Namespace(), components, variables)

return flows.NewMsgOut(urn, channelRef, previewText, nil, previewQRs, templating, flows.NilMsgTopic, locale, unsendableReason)
return flows.NewMsgOut(urn, channelRef, strings.Join(previewText, "\n\n"), previewAttachments, previewQRs, templating, flows.NilMsgTopic, locale, unsendableReason)
}
43 changes: 41 additions & 2 deletions flows/actions/testdata/_assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@
{
"type": "header",
"name": "header",
"content": "",
"content": "Update",
"variables": {}
},
{
Expand Down Expand Up @@ -384,7 +384,7 @@
{
"type": "header",
"name": "header",
"content": "",
"content": "Actualizar",
"variables": {}
},
{
Expand Down Expand Up @@ -424,6 +424,45 @@
]
}
]
},
{
"uuid": "be68beff-1a5b-424b-815e-023cc53c1ddc",
"name": "cat_fact",
"translations": [
{
"channel": {
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d",
"name": "My Android Phone"
},
"locale": "eng-US",
"components": [
{
"type": "header",
"name": "header",
"content": "",
"variables": {
"1": 0
}
},
{
"type": "body",
"name": "body",
"content": "{{1}}",
"variables": {
"1": 1
}
}
],
"variables": [
{
"type": "image"
},
{
"type": "text"
}
]
}
]
}
],
"topics": [
Expand Down
104 changes: 98 additions & 6 deletions flows/actions/testdata/send_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,6 @@
"type": "send_msg",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "Hey Ryan Lewis, your gender is saved as boy.",
"attachments": [
"http://example.com/red.jpg"
],
"quick_replies": [
"Yes",
"No"
Expand Down Expand Up @@ -833,7 +830,7 @@
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d",
"name": "My Android Phone"
},
"text": "Hola, Ryan Lewis, tu género está guardado como niño.",
"text": "Actualizar\n\nHola, Ryan Lewis, tu género está guardado como niño.",
"quick_replies": [
"Sip",
"No"
Expand Down Expand Up @@ -882,7 +879,6 @@
],
"templates": [
"Hey Ryan Lewis, your gender is saved as boy.",
"http://example.com/red.jpg",
"Yes",
"No",
"@contact.name",
Expand All @@ -896,7 +892,6 @@
],
"localizables": [
"Hey Ryan Lewis, your gender is saved as boy.",
"http://example.com/red.jpg",
"Yes",
"No",
"@contact.name",
Expand All @@ -917,5 +912,102 @@
"waiting_exits": [],
"parent_refs": []
}
},
{
"description": "Template with header image component",
"action": {
"type": "send_msg",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "The Maine Coone is the only native American long haired breed.",
"attachments": [
"image/jpeg:http://example.com/cat1.jpg"
],
"template": {
"uuid": "be68beff-1a5b-424b-815e-023cc53c1ddc",
"name": "cat_fact"
},
"template_variables": [
"image/jpeg:http://example.com/cat2.jpg",
"The first true cats came into existence about 12 million years ago and were the Proailurus."
]
},
"events": [
{
"type": "msg_created",
"created_on": "2018-10-18T14:20:30.000123456Z",
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c",
"msg": {
"uuid": "9688d21d-95aa-4bed-afc7-f31b35731a3d",
"urn": "tel:+12065551212?channel=57f1078f-88aa-46f4-a59a-948a5739c03d&id=123",
"channel": {
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d",
"name": "My Android Phone"
},
"text": "The first true cats came into existence about 12 million years ago and were the Proailurus.",
"attachments": [
"image/jpeg:http://example.com/cat2.jpg"
],
"templating": {
"template": {
"uuid": "be68beff-1a5b-424b-815e-023cc53c1ddc",
"name": "cat_fact"
},
"namespace": "",
"components": [
{
"type": "header",
"name": "header",
"variables": {
"1": 0
}
},
{
"type": "body",
"name": "body",
"variables": {
"1": 1
}
}
],
"variables": [
{
"type": "image",
"value": "image/jpeg:http://example.com/cat2.jpg"
},
{
"type": "text",
"value": "The first true cats came into existence about 12 million years ago and were the Proailurus."
}
]
},
"locale": "eng-US"
}
}
],
"templates": [
"The Maine Coone is the only native American long haired breed.",
"image/jpeg:http://example.com/cat1.jpg",
"image/jpeg:http://example.com/cat2.jpg",
"The first true cats came into existence about 12 million years ago and were the Proailurus."
],
"localizables": [
"The Maine Coone is the only native American long haired breed.",
"image/jpeg:http://example.com/cat1.jpg",
"image/jpeg:http://example.com/cat2.jpg",
"The first true cats came into existence about 12 million years ago and were the Proailurus."
],
"inspection": {
"dependencies": [
{
"uuid": "be68beff-1a5b-424b-815e-023cc53c1ddc",
"name": "cat_fact",
"type": "template"
}
],
"issues": [],
"results": [],
"waiting_exits": [],
"parent_refs": []
}
}
]
Loading