Skip to content

Commit 5123aff

Browse files
committed
Read templating from new msg field instead of metadata
1 parent a081fe6 commit 5123aff

File tree

12 files changed

+128
-237
lines changed

12 files changed

+128
-237
lines changed

Diff for: backends/rapidpro/msg.go

+20-18
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,20 @@ const (
4747

4848
// Msg is our base struct to represent msgs both in our JSON and db representations
4949
type Msg struct {
50-
OrgID_ OrgID `json:"org_id" db:"org_id"`
51-
ID_ courier.MsgID `json:"id" db:"id"`
52-
UUID_ courier.MsgUUID `json:"uuid" db:"uuid"`
53-
Direction_ MsgDirection ` db:"direction"`
54-
Status_ courier.MsgStatus ` db:"status"`
55-
Visibility_ MsgVisibility ` db:"visibility"`
56-
HighPriority_ bool `json:"high_priority" db:"high_priority"`
57-
Text_ string `json:"text" db:"text"`
58-
Attachments_ pq.StringArray `json:"attachments" db:"attachments"`
59-
QuickReplies_ pq.StringArray `json:"quick_replies" db:"quick_replies"`
60-
Locale_ null.String `json:"locale" db:"locale"`
61-
ExternalID_ null.String ` db:"external_id"`
62-
Metadata_ json.RawMessage `json:"metadata" db:"metadata"`
50+
OrgID_ OrgID `json:"org_id" db:"org_id"`
51+
ID_ courier.MsgID `json:"id" db:"id"`
52+
UUID_ courier.MsgUUID `json:"uuid" db:"uuid"`
53+
Direction_ MsgDirection ` db:"direction"`
54+
Status_ courier.MsgStatus ` db:"status"`
55+
Visibility_ MsgVisibility ` db:"visibility"`
56+
HighPriority_ bool `json:"high_priority" db:"high_priority"`
57+
Text_ string `json:"text" db:"text"`
58+
Attachments_ pq.StringArray `json:"attachments" db:"attachments"`
59+
QuickReplies_ pq.StringArray `json:"quick_replies" db:"quick_replies"`
60+
Locale_ null.String `json:"locale" db:"locale"`
61+
Templating_ *courier.Templating `json:"templating" db:"templating"`
62+
ExternalID_ null.String ` db:"external_id"`
63+
Metadata_ json.RawMessage `json:"metadata" db:"metadata"`
6364

6465
ChannelID_ courier.ChannelID ` db:"channel_id"`
6566
ContactID_ ContactID `json:"contact_id" db:"contact_id"`
@@ -142,11 +143,12 @@ func (m *Msg) URN() urns.URN { return m.URN_ }
142143
func (m *Msg) Channel() courier.Channel { return m.channel }
143144

144145
// outgoing specific
145-
func (m *Msg) QuickReplies() []string { return m.QuickReplies_ }
146-
func (m *Msg) Locale() i18n.Locale { return i18n.Locale(string(m.Locale_)) }
147-
func (m *Msg) URNAuth() string { return m.URNAuth_ }
148-
func (m *Msg) Origin() courier.MsgOrigin { return m.Origin_ }
149-
func (m *Msg) ContactLastSeenOn() *time.Time { return m.ContactLastSeenOn_ }
146+
func (m *Msg) QuickReplies() []string { return m.QuickReplies_ }
147+
func (m *Msg) Locale() i18n.Locale { return i18n.Locale(string(m.Locale_)) }
148+
func (m *Msg) Templating() *courier.Templating { return m.Templating_ }
149+
func (m *Msg) URNAuth() string { return m.URNAuth_ }
150+
func (m *Msg) Origin() courier.MsgOrigin { return m.Origin_ }
151+
func (m *Msg) ContactLastSeenOn() *time.Time { return m.ContactLastSeenOn_ }
150152
func (m *Msg) Topic() string {
151153
if m.Metadata_ == nil {
152154
return ""

Diff for: handlers/dialog360/handler.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/nyaruka/courier/utils"
1919
"github.com/nyaruka/gocommon/jsonx"
2020
"github.com/nyaruka/gocommon/urns"
21-
"github.com/pkg/errors"
2221
)
2322

2423
const (
@@ -317,13 +316,9 @@ func (h *handler) Send(ctx context.Context, msg courier.MsgOut, res *courier.Sen
317316

318317
if len(msg.Attachments()) == 0 {
319318
// do we have a template?
320-
templating, err := whatsapp.GetTemplating(msg)
321-
if err != nil {
322-
return errors.Wrapf(err, "unable to decode template: %s for channel: %s", string(msg.Metadata()), msg.Channel().UUID())
323-
}
324-
if templating != nil {
319+
if msg.Templating() != nil {
325320
payload.Type = "template"
326-
payload.Template = whatsapp.GetTemplatePayload(templating)
321+
payload.Template = whatsapp.GetTemplatePayload(msg.Templating())
327322
} else {
328323
if i < (len(msgParts) + len(msg.Attachments()) - 1) {
329324
// this is still a msg part

Diff for: handlers/dialog360/handler_test.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package dialog360
22

33
import (
44
"context"
5-
"encoding/json"
65
"fmt"
76
"net/http"
87
"net/http/httptest"
@@ -421,11 +420,11 @@ var SendTestCasesD3C = []OutgoingTestCase{
421420
ExpectedExtIDs: []string{"157b5e14568e8"},
422421
},
423422
{
424-
Label: "Template Send",
425-
MsgText: "templated message",
426-
MsgURN: "whatsapp:250788123123",
427-
MsgLocale: "eng",
428-
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type": "body", "params": [{"type":"text", "value":"Chef"}, {"type": "text" , "value": "tomorrow"}]}], "language": "en_US"}}`),
423+
Label: "Template Send",
424+
MsgText: "templated message",
425+
MsgURN: "whatsapp:250788123123",
426+
MsgLocale: "eng",
427+
MsgTemplating: `{"template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type": "body", "params": [{"type":"text", "value":"Chef"}, {"type": "text" , "value": "tomorrow"}]}], "language": "en_US"}`,
429428
MockResponses: map[string][]*httpx.MockResponse{
430429
"https://waba-v2.360dialog.io/messages": {
431430
httpx.NewMockResponse(200, nil, []byte(`{ "messages": [{"id": "157b5e14568e8"}] }`)),

Diff for: handlers/meta/handlers.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -805,13 +805,9 @@ func (h *handler) sendWhatsAppMsg(ctx context.Context, msg courier.MsgOut, res *
805805

806806
if len(msg.Attachments()) == 0 {
807807
// do we have a template?
808-
templating, err := whatsapp.GetTemplating(msg)
809-
if err != nil {
810-
return errors.Wrapf(err, "unable to decode template: %s for channel: %s", string(msg.Metadata()), msg.Channel().UUID())
811-
}
812-
if templating != nil {
808+
if msg.Templating() != nil {
813809
payload.Type = "template"
814-
payload.Template = whatsapp.GetTemplatePayload(templating)
810+
payload.Template = whatsapp.GetTemplatePayload(msg.Templating())
815811

816812
} else {
817813
if i < (len(msgParts) + len(msg.Attachments()) - 1) {

Diff for: handlers/meta/whataspp_test.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package meta
22

33
import (
44
"context"
5-
"encoding/json"
65
"testing"
76
"time"
87

@@ -390,11 +389,11 @@ var whatsappOutgoingTests = []OutgoingTestCase{
390389
ExpectedExtIDs: []string{"157b5e14568e8"},
391390
},
392391
{
393-
Label: "Template Send",
394-
MsgText: "templated message",
395-
MsgURN: "whatsapp:250788123123",
396-
MsgLocale: "eng",
397-
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type":"body", "params": [{"type":"text", "value":"Chef"}, {"type": "text" , "value": "tomorrow"}]}], "language": "en_US"}}`),
392+
Label: "Template Send",
393+
MsgText: "templated message",
394+
MsgURN: "whatsapp:250788123123",
395+
MsgLocale: "eng",
396+
MsgTemplating: `{"template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [{"type":"body", "params": [{"type":"text", "value":"Chef"}, {"type": "text" , "value": "tomorrow"}]}], "language": "en_US"}`,
398397
MockResponses: map[string][]*httpx.MockResponse{
399398
"*/12345_ID/messages": {
400399
httpx.NewMockResponse(201, nil, []byte(`{ "messages": [{"id": "157b5e14568e8"}] }`)),
@@ -406,11 +405,11 @@ var whatsappOutgoingTests = []OutgoingTestCase{
406405
ExpectedExtIDs: []string{"157b5e14568e8"},
407406
},
408407
{
409-
Label: "Template Send, no variables",
410-
MsgText: "templated message",
411-
MsgURN: "whatsapp:250788123123",
412-
MsgLocale: "eng",
413-
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [], "variables": [], "language": "en_US"}}`),
408+
Label: "Template Send, no variables",
409+
MsgText: "templated message",
410+
MsgURN: "whatsapp:250788123123",
411+
MsgLocale: "eng",
412+
MsgTemplating: `{"template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" }, "components": [], "variables": [], "language": "en_US"}`,
414413
MockResponses: map[string][]*httpx.MockResponse{
415414
"*/12345_ID/messages": {
416415
httpx.NewMockResponse(200, nil, []byte(`{ "messages": [{"id": "157b5e14568e8"}] }`)),
@@ -426,7 +425,8 @@ var whatsappOutgoingTests = []OutgoingTestCase{
426425
MsgText: "templated message",
427426
MsgURN: "whatsapp:250788123123",
428427
MsgLocale: "eng",
429-
MsgMetadata: json.RawMessage(`{ "templating": { "template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" },"components": [
428+
MsgTemplating: `{"template": { "name": "revive_issue", "uuid": "171f8a4d-f725-46d7-85a6-11aceff0bfe3" },
429+
"components": [
430430
{
431431
"type": "body",
432432
"name": "body",
@@ -461,7 +461,7 @@ var whatsappOutgoingTests = []OutgoingTestCase{
461461
}
462462
]
463463
}
464-
], "language": "en_US"}}`),
464+
], "language": "en_US"}`,
465465
MockResponses: map[string][]*httpx.MockResponse{
466466
"*/12345_ID/messages": {
467467
httpx.NewMockResponse(201, nil, []byte(`{ "messages": [{"id": "157b5e14568e8"}] }`)),

Diff for: handlers/meta/whatsapp/templates.go

+1-44
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,12 @@
11
package whatsapp
22

33
import (
4-
"encoding/json"
54
"strings"
65

76
"github.com/nyaruka/courier"
8-
"github.com/nyaruka/courier/utils"
9-
"github.com/pkg/errors"
107
)
118

12-
type MsgTemplating struct {
13-
Template struct {
14-
Name string `json:"name" validate:"required"`
15-
UUID string `json:"uuid" validate:"required"`
16-
} `json:"template" validate:"required,dive"`
17-
Namespace string `json:"namespace"`
18-
Components []struct {
19-
Type string `json:"type"`
20-
Name string `json:"name"`
21-
Params []struct {
22-
Type string `json:"type"`
23-
Value string `json:"value"`
24-
} `json:"params"`
25-
} `json:"components"`
26-
Language string `json:"language"`
27-
}
28-
29-
func GetTemplating(msg courier.MsgOut) (*MsgTemplating, error) {
30-
if len(msg.Metadata()) == 0 {
31-
return nil, nil
32-
}
33-
34-
metadata := &struct {
35-
Templating *MsgTemplating `json:"templating"`
36-
}{}
37-
if err := json.Unmarshal(msg.Metadata(), metadata); err != nil {
38-
return nil, err
39-
}
40-
41-
if metadata.Templating == nil {
42-
return nil, nil
43-
}
44-
45-
if err := utils.Validate(metadata.Templating); err != nil {
46-
return nil, errors.Wrapf(err, "invalid templating definition")
47-
}
48-
49-
return metadata.Templating, nil
50-
}
51-
52-
func GetTemplatePayload(templating *MsgTemplating) *Template {
9+
func GetTemplatePayload(templating *courier.Templating) *Template {
5310
template := &Template{
5411
Name: templating.Template.Name,
5512
Language: &Language{Policy: "deterministic", Code: templating.Language},

Diff for: handlers/meta/whatsapp/templates_test.go

+6-39
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,15 @@
11
package whatsapp_test
22

33
import (
4-
"encoding/json"
5-
"fmt"
64
"testing"
75

6+
"github.com/nyaruka/courier"
87
"github.com/nyaruka/courier/handlers/meta/whatsapp"
98
"github.com/nyaruka/courier/test"
9+
"github.com/nyaruka/gocommon/jsonx"
1010
"github.com/stretchr/testify/assert"
11-
"github.com/stretchr/testify/require"
1211
)
1312

14-
func TestGetTemplating(t *testing.T) {
15-
msg := test.NewMockMsg(1, "87995844-2017-4ba0-bc73-f3da75b32f9b", nil, "tel:+1234567890", "hi", nil)
16-
17-
// no metadata, no templating
18-
tpl, err := whatsapp.GetTemplating(msg)
19-
assert.NoError(t, err)
20-
assert.Nil(t, tpl)
21-
22-
msg.WithMetadata(json.RawMessage(`{}`))
23-
24-
// no templating in metadata, no templating
25-
tpl, err = whatsapp.GetTemplating(msg)
26-
assert.NoError(t, err)
27-
assert.Nil(t, tpl)
28-
29-
msg.WithMetadata(json.RawMessage(`{"templating": {"foo": "bar"}}`))
30-
31-
// invalid templating in metadata, error
32-
tpl, err = whatsapp.GetTemplating(msg)
33-
assert.Error(t, err, "x")
34-
assert.Nil(t, tpl)
35-
36-
msg.WithMetadata(json.RawMessage(`{"templating": {"template": {"uuid": "4ed5000f-5c94-4143-9697-b7cbd230a381", "name": "Update"}}}`))
37-
38-
// valid templating, no error
39-
tpl, err = whatsapp.GetTemplating(msg)
40-
assert.NoError(t, err)
41-
assert.Equal(t, "4ed5000f-5c94-4143-9697-b7cbd230a381", tpl.Template.UUID)
42-
assert.Equal(t, "Update", tpl.Template.Name)
43-
}
44-
4513
func TestGetTemplatePayload(t *testing.T) {
4614
tcs := []struct {
4715
templating string
@@ -121,12 +89,11 @@ func TestGetTemplatePayload(t *testing.T) {
12189
}
12290

12391
for _, tc := range tcs {
124-
metadata := json.RawMessage(fmt.Sprintf(`{"templating": %s}`, tc.templating))
125-
msg := test.NewMockMsg(1, "87995844-2017-4ba0-bc73-f3da75b32f9b", nil, "tel:+1234567890", "hi", nil).WithMetadata(metadata)
126-
templating, err := whatsapp.GetTemplating(msg)
127-
require.NoError(t, err)
92+
templating := &courier.Templating{}
93+
jsonx.MustUnmarshal([]byte(tc.templating), templating)
12894

129-
actual := whatsapp.GetTemplatePayload(templating)
95+
msg := test.NewMockMsg(1, "87995844-2017-4ba0-bc73-f3da75b32f9b", nil, "tel:+1234567890", "hi", nil).WithTemplating(templating)
96+
actual := whatsapp.GetTemplatePayload(msg.Templating())
13097

13198
assert.Equal(t, tc.expected, actual)
13299
}

Diff for: handlers/test.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package handlers
33
import (
44
"bytes"
55
"context"
6-
"encoding/json"
76
"fmt"
87
"io"
98
"log"
@@ -21,6 +20,7 @@ import (
2120
"github.com/nyaruka/courier/test"
2221
"github.com/nyaruka/gocommon/httpx"
2322
"github.com/nyaruka/gocommon/i18n"
23+
"github.com/nyaruka/gocommon/jsonx"
2424
"github.com/nyaruka/gocommon/urns"
2525
"github.com/stretchr/testify/assert"
2626
"github.com/stretchr/testify/require"
@@ -301,9 +301,9 @@ type OutgoingTestCase struct {
301301
MsgQuickReplies []string
302302
MsgLocale i18n.Locale
303303
MsgTopic string
304+
MsgTemplating string
304305
MsgHighPriority bool
305306
MsgResponseToExternalID string
306-
MsgMetadata json.RawMessage
307307
MsgFlow *courier.FlowReference
308308
MsgOptIn *courier.OptInReference
309309
MsgUserID courier.UserID
@@ -337,8 +337,10 @@ func (tc *OutgoingTestCase) Msg(mb *test.MockBackend, ch courier.Channel) courie
337337
if tc.MsgURNAuth != "" {
338338
m.WithURNAuth(tc.MsgURNAuth)
339339
}
340-
if len(tc.MsgMetadata) > 0 {
341-
m.WithMetadata(tc.MsgMetadata)
340+
if tc.MsgTemplating != "" {
341+
templating := &courier.Templating{}
342+
jsonx.MustUnmarshal([]byte(tc.MsgTemplating), templating)
343+
m.WithTemplating(templating)
342344
}
343345
if tc.MsgFlow != nil {
344346
m.WithFlow(tc.MsgFlow)

0 commit comments

Comments
 (0)