Skip to content

Commit

Permalink
Merge branch 'main' into shutdown-tolerance-time
Browse files Browse the repository at this point in the history
  • Loading branch information
rasoro committed Dec 4, 2024
2 parents 03827a1 + 43e8498 commit 88672b3
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 7 deletions.
5 changes: 5 additions & 0 deletions WENI-CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
1.43.0
----------
* feat: add buttons support to wpp broadcasts
* feat: add channel option to whatsapp broadcasts

1.42.0
----------
* Fix: handle new broadcast_type field
Expand Down
34 changes: 32 additions & 2 deletions core/models/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ func newOutgoingMsgWpp(rt *runtime.Runtime, org *Org, channel *Channel, contactI
metadata["interaction_type"] = msgWpp.InteractionType()
metadata["order_details_message"] = msgWpp.OrderDetailsMessage()
}
if len(msgWpp.Buttons()) > 0 {
metadata["buttons"] = msgWpp.Buttons()
}
if msgWpp.TextLanguage != "" {
metadata["text_language"] = msgWpp.TextLanguage
}
Expand Down Expand Up @@ -1459,6 +1462,7 @@ type WppBroadcastMessage struct {
FlowMessage flows.FlowMessage `json:"flow_message,omitempty"`
ListMessage flows.ListMessage `json:"list_message,omitempty"`
CTAMessage flows.CTAMessage `json:"cta_message,omitempty"`
Buttons []flows.ButtonComponent `json:"buttons,omitempty"`
}

type WppBroadcast struct {
Expand All @@ -1470,6 +1474,7 @@ type WppBroadcast struct {
OrgID OrgID `json:"org_id" db:"org_id"`
ParentID BroadcastID `json:"parent_id,omitempty" db:"parent_id"`
Msg WppBroadcastMessage `json:"msg"`
ChannelID ChannelID `json:"channel_id,omitempty"`
}
}

Expand All @@ -1479,18 +1484,20 @@ func (b *WppBroadcast) ContactIDs() []ContactID { return b.b.ContactIDs }
func (b *WppBroadcast) GroupIDs() []GroupID { return b.b.GroupIDs }
func (b *WppBroadcast) URNs() []urns.URN { return b.b.URNs }
func (b *WppBroadcast) Msg() WppBroadcastMessage { return b.b.Msg }
func (b *WppBroadcast) ChannelID() ChannelID { return b.b.ChannelID }

func (b *WppBroadcast) MarshalJSON() ([]byte, error) { return json.Marshal(b.b) }
func (b *WppBroadcast) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &b.b) }

func NewWppBroadcast(orgID OrgID, id BroadcastID, msg WppBroadcastMessage, urns []urns.URN, contactIDs []ContactID, groupIDs []GroupID) *WppBroadcast {
func NewWppBroadcast(orgID OrgID, id BroadcastID, msg WppBroadcastMessage, urns []urns.URN, contactIDs []ContactID, groupIDs []GroupID, channelID ChannelID) *WppBroadcast {
bcast := &WppBroadcast{}
bcast.b.OrgID = orgID
bcast.b.BroadcastID = id
bcast.b.Msg = msg
bcast.b.URNs = urns
bcast.b.ContactIDs = contactIDs
bcast.b.GroupIDs = groupIDs
bcast.b.ChannelID = channelID

return bcast
}
Expand All @@ -1500,6 +1507,7 @@ func (b *WppBroadcast) CreateBatch(contactIDs []ContactID) *WppBroadcastBatch {
batch.b.BroadcastID = b.b.BroadcastID
batch.b.Msg = b.b.Msg
batch.b.OrgID = b.b.OrgID
batch.b.ChannelID = b.b.ChannelID
batch.b.ContactIDs = contactIDs
return batch
}
Expand All @@ -1512,6 +1520,7 @@ type WppBroadcastBatch struct {
ContactIDs []ContactID `json:"contact_ids,omitempty"`
IsLast bool `json:"is_last"`
OrgID OrgID `json:"org_id"`
ChannelID ChannelID `json:"channel_id,omitempty"`
}
}

Expand All @@ -1521,6 +1530,7 @@ func (b *WppBroadcastBatch) URNs() map[ContactID]urns.URN { return b.b.UR
func (b *WppBroadcastBatch) SetURNs(urns map[ContactID]urns.URN) { b.b.URNs = urns }
func (b *WppBroadcastBatch) OrgID() OrgID { return b.b.OrgID }
func (b *WppBroadcastBatch) Msg() WppBroadcastMessage { return b.b.Msg }
func (b *WppBroadcastBatch) ChannelID() ChannelID { return b.b.ChannelID }

func (b *WppBroadcastBatch) IsLast() bool { return b.b.IsLast }
func (b *WppBroadcastBatch) SetIsLast(last bool) { b.b.IsLast = last }
Expand Down Expand Up @@ -1602,6 +1612,10 @@ func CreateWppBroadcastMessages(ctx context.Context, rt *runtime.Runtime, oa *Or
}
}

if bcast.ChannelID() != NilChannelID {
channel = oa.ChannelByID(bcast.ChannelID())
}

// no urn and channel? move on
if channel == nil {
return nil, nil
Expand Down Expand Up @@ -1685,13 +1699,29 @@ func CreateWppBroadcastMessages(ctx context.Context, rt *runtime.Runtime, oa *Or
}
}

// evaluate our buttons
buttons := make([]flows.ButtonComponent, 0)
for _, button := range bcast.Msg().Buttons {
var newButton flows.ButtonComponent
newButton.SubType, _ = excellent.EvaluateTemplate(oa.Env(), evaluationCtx, button.SubType, nil)

for _, param := range button.Parameters {
var newParam flows.ButtonParam
newParam.Type, _ = excellent.EvaluateTemplate(oa.Env(), evaluationCtx, param.Type, nil)
newParam.Text, _ = excellent.EvaluateTemplate(oa.Env(), evaluationCtx, param.Text, nil)
newButton.Parameters = append(newButton.Parameters, newParam)
}

buttons = append(buttons, newButton)
}

// don't do anything if we have no text or attachments
if text == "" && len(attachments) == 0 {
return nil, nil
}

// create our outgoing message
out := flows.NewMsgWppOut(urn, channel.ChannelReference(), bcast.Msg().InteractionType, headerType, headerText, text, footerText, ctaMessage, listMessage, flowMessage, orderDetails, attachments, quickReplies, templating, flows.NilMsgTopic)
out := flows.NewMsgWppOut(urn, channel.ChannelReference(), bcast.Msg().InteractionType, headerType, headerText, text, footerText, ctaMessage, listMessage, flowMessage, orderDetails, attachments, quickReplies, buttons, templating, flows.NilMsgTopic)
msg, err := NewOutgoingWppBroadcastMsg(rt, oa.Org(), channel, c.ID(), out, time.Now(), bcast.BroadcastID())
if err != nil {
return nil, errors.Wrapf(err, "error creating outgoing message")
Expand Down
65 changes: 63 additions & 2 deletions core/tasks/msgs/send_wpp_broadcast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestWppBroadcastTask(t *testing.T) {
// add an extra URN for cathy
testdata.InsertContactURN(db, testdata.Org1, testdata.Cathy, urns.URN("tel:+12065551212"), 1001)

// change alexandrias URN to a twitter URN and set her language to eng so that a template gets used for her
// change alexandrias URN to a whatsapp URN and set her language to eng so that a template gets used for her
db.MustExec(`UPDATE contacts_contacturn SET identity = 'whatsapp:559899999999', path='559899999999', scheme='whatsapp' WHERE contact_id = $1`, testdata.Alexandria.ID)
db.MustExec(`UPDATE contacts_contact SET language='eng' WHERE id = $1`, testdata.Alexandria.ID)

Expand Down Expand Up @@ -139,6 +139,21 @@ func TestWppBroadcastTask(t *testing.T) {
},
}

buttonsMsg := models.WppBroadcastMessage{
Text: "hello @contact.name",
Buttons: []flows.ButtonComponent{
{
SubType: "url",
Parameters: []flows.ButtonParam{
{
Type: "text",
Text: "button param text",
},
},
},
},
}

tcs := []struct {
BroadcastID models.BroadcastID
URNs []urns.URN
Expand All @@ -149,6 +164,7 @@ func TestWppBroadcastTask(t *testing.T) {
MsgCount int
Msg models.WppBroadcastMessage
MsgText string
ChannelID models.ChannelID
}{
{
models.NilBroadcastID,
Expand All @@ -160,6 +176,7 @@ func TestWppBroadcastTask(t *testing.T) {
121,
baseMsg,
"hello world",
models.NilChannelID,
},
{
existingID,
Expand All @@ -171,6 +188,7 @@ func TestWppBroadcastTask(t *testing.T) {
1,
evaluationMsg,
"hello Cathy",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -182,6 +200,19 @@ func TestWppBroadcastTask(t *testing.T) {
1,
evaluationMsg,
"hello Cathy",
testdata.WhatsAppCloudChannel.ID,
},
{
models.NilBroadcastID,
nil,
cathyOnly,
nil,
queue.HandlerQueue,
1,
1,
evaluationMsg,
"hello Cathy",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -193,6 +224,7 @@ func TestWppBroadcastTask(t *testing.T) {
1,
replyMsg,
"hello Cathy, how are you doing today?",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -204,6 +236,7 @@ func TestWppBroadcastTask(t *testing.T) {
1,
listMsg,
"hello Cathy",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -215,6 +248,7 @@ func TestWppBroadcastTask(t *testing.T) {
1,
ctaMsg,
"hello Cathy",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -226,6 +260,7 @@ func TestWppBroadcastTask(t *testing.T) {
1,
flowMsg,
"hello Cathy",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -237,6 +272,7 @@ func TestWppBroadcastTask(t *testing.T) {
1,
orderDetailsMsg,
"hello Cathy",
models.NilChannelID,
},
{
models.NilBroadcastID,
Expand All @@ -250,6 +286,19 @@ func TestWppBroadcastTask(t *testing.T) {
1,
templateMsg,
"Welcome Alexandia!",
models.NilChannelID,
},
{
models.NilBroadcastID,
nil,
cathyOnly,
nil,
queue.HandlerQueue,
1,
1,
buttonsMsg,
"hello Cathy",
models.NilChannelID,
},
}

Expand All @@ -258,7 +307,7 @@ func TestWppBroadcastTask(t *testing.T) {

for i, tc := range tcs {
// handle our start task
bcast := models.NewWppBroadcast(oa.OrgID(), tc.BroadcastID, tc.Msg, tc.URNs, tc.ContactIDs, tc.GroupIDs)
bcast := models.NewWppBroadcast(oa.OrgID(), tc.BroadcastID, tc.Msg, tc.URNs, tc.ContactIDs, tc.GroupIDs, tc.ChannelID)
err = msgs.CreateWppBroadcastBatches(ctx, rt, bcast)
assert.NoError(t, err)

Expand Down Expand Up @@ -337,6 +386,12 @@ func TestWppBroadcastTask(t *testing.T) {
Returns(1, "%d: unexpected order details message count", i)
}

// assert our buttons are being sent
if len(tc.Msg.Buttons) > 0 {
testsuite.AssertQuery(t, db, `SELECT count(*) FROM msgs_msg WHERE org_id = 1 AND created_on > $1 AND text = $2 AND metadata LIKE '%' || 'buttons' || '%'`, lastNow, tc.MsgText).
Returns(1, "%d: unexpected buttons count", i)
}

// assert our template is being sent
if tc.Msg.Template.UUID != "" {
testsuite.AssertQuery(t, db, `SELECT count(*) FROM msgs_msg WHERE org_id = 1 AND created_on > $1 AND text = $2 AND metadata = $3`,
Expand All @@ -346,6 +401,12 @@ func TestWppBroadcastTask(t *testing.T) {
).Returns(1, "%d: unexpected template count", i)
}

// assert our channel is being set
if tc.ChannelID != models.NilChannelID {
testsuite.AssertQuery(t, db, `SELECT count(*) FROM msgs_msg WHERE org_id = 1 AND created_on > $1 AND text = $2 AND channel_id = $3`, lastNow, tc.MsgText, tc.ChannelID).
Returns(1, "%d: unexpected channel count", i)
}

// make sure our broadcast is marked as sent
if tc.BroadcastID != models.NilBroadcastID {
testsuite.AssertQuery(t, db, `SELECT count(*) FROM msgs_broadcast WHERE id = $1 AND status = 'S'`, tc.BroadcastID).
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ go 1.17

replace github.com/nyaruka/gocommon => github.com/Ilhasoft/gocommon v1.16.2-weni

replace github.com/nyaruka/goflow => github.com/weni-ai/goflow v1.5.4
replace github.com/nyaruka/goflow => github.com/weni-ai/goflow v1.5.5
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLD
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/weni-ai/goflow v1.5.4 h1:8s4pwLcOv2mkceWLjcvQn52iOFvAvlssUVxVxezlzSY=
github.com/weni-ai/goflow v1.5.4/go.mod h1:o0xaVWP9qNcauBSlcNLa79Fm2oCPV+BDpheFRa/D40c=
github.com/weni-ai/goflow v1.5.5 h1:nXF70PsHq1+vMWMYtn51NKZbCWyCALrrQR/ofFAqS+0=
github.com/weni-ai/goflow v1.5.5/go.mod h1:o0xaVWP9qNcauBSlcNLa79Fm2oCPV+BDpheFRa/D40c=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down

0 comments on commit 88672b3

Please sign in to comment.