Skip to content

Commit

Permalink
Merge pull request #1129 from nyaruka/unsendable_reason
Browse files Browse the repository at this point in the history
Add unsendable reason to `MsgOut` and set when contact status is not active
  • Loading branch information
rowanseymour authored Sep 12, 2022
2 parents 26738ae + fdef4a6 commit 566d601
Show file tree
Hide file tree
Showing 18 changed files with 210 additions and 23 deletions.
19 changes: 11 additions & 8 deletions flows/actions/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ func (a *SendMsgAction) Execute(run flows.Run, step flows.Step, logModifier flow
return nil
}

// a message to a non-active contact is unsendable but can still be created
unsendableReason := flows.NilUnsendableReason
if run.Contact().Status() != flows.ContactStatusActive {
unsendableReason = flows.UnsendableReasonContactStatus
}

evaluatedText, evaluatedAttachments, evaluatedQuickReplies := a.evaluateMessage(run, nil, a.Text, a.Attachments, a.QuickReplies, logEvent)

destinations := run.Contact().ResolveDestinations(a.AllURNs)
Expand All @@ -88,14 +94,11 @@ func (a *SendMsgAction) Execute(run flows.Run, step flows.Step, logModifier flow

// create a new message for each URN+channel destination
for _, dest := range destinations {
var channelRef *assets.ChannelReference
if dest.Channel != nil {
channelRef = assets.NewChannelReference(dest.Channel.UUID(), dest.Channel.Name())
}

var templating *flows.MsgTemplating
urn := dest.URN.URN()
channelRef := assets.NewChannelReference(dest.Channel.UUID(), dest.Channel.Name())

// do we have a template defined?
var templating *flows.MsgTemplating
if a.Templating != nil {
// looks for a translation in the contact locale or environment default
locales := []envs.Locale{
Expand All @@ -122,14 +125,14 @@ func (a *SendMsgAction) Execute(run flows.Run, step flows.Step, logModifier flow
}
}

msg := flows.NewMsgOut(dest.URN.URN(), channelRef, evaluatedText, evaluatedAttachments, evaluatedQuickReplies, templating, a.Topic)
msg := flows.NewMsgOut(urn, channelRef, evaluatedText, evaluatedAttachments, evaluatedQuickReplies, templating, a.Topic, unsendableReason)
logEvent(events.NewMsgCreated(msg))
}

// if we couldn't find a destination, create a msg without a URN or channel and it's up to the caller
// to handle that as they want
if len(destinations) == 0 {
msg := flows.NewMsgOut(urns.NilURN, nil, evaluatedText, evaluatedAttachments, evaluatedQuickReplies, nil, flows.NilMsgTopic)
msg := flows.NewMsgOut(urns.NilURN, nil, evaluatedText, evaluatedAttachments, evaluatedQuickReplies, nil, a.Topic, flows.UnsendableReasonNoDestination)
logEvent(events.NewMsgCreated(msg))
}

Expand Down
3 changes: 2 additions & 1 deletion flows/actions/testdata/send_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c",
"msg": {
"uuid": "9688d21d-95aa-4bed-afc7-f31b35731a3d",
"text": "Hi there"
"text": "Hi there",
"unsendable_reason": "no_destination"
}
}
]
Expand Down
69 changes: 63 additions & 6 deletions flows/events/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/nyaruka/goflow/flows/routers/waits/hints"
"github.com/nyaruka/goflow/services/webhooks"
"github.com/nyaruka/goflow/test"
"github.com/nyaruka/goflow/utils"
"github.com/shopspring/decimal"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -428,28 +429,84 @@ func TestEventMarshaling(t *testing.T) {
},
{
events.NewIVRCreated(
flows.NewIVRMsgOut(
urns.URN("tel:+12345678900"),
assets.NewChannelReference(assets.ChannelUUID("57f1078f-88aa-46f4-a59a-948a5739c03d"), "My Android Phone"),
"Hi there",
"eng",
"http://example.com/hi.mp3",
),
),
`{
"created_on": "2018-10-18T14:20:30.000123456Z",
"msg": {
"uuid": "20cc4181-48cf-4344-9751-99419796decd",
"urn": "tel:+12345678900",
"channel": {
"name": "My Android Phone",
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d"
},
"text": "Hi there",
"text_language": "eng",
"attachments": ["audio:http://example.com/hi.mp3"]
},
"type": "ivr_created"
}`,
},
{
events.NewMsgCreated(
flows.NewMsgOut(
urns.URN("tel:+12345678900"),
assets.NewChannelReference(assets.ChannelUUID("57f1078f-88aa-46f4-a59a-948a5739c03d"), "My Android Phone"),
"Hi there",
nil,
nil,
nil,
nil, nil, nil,
flows.NilMsgTopic,
flows.NilUnsendableReason,
),
),
`{
"created_on": "2018-10-18T14:20:30.000123456Z",
"msg": {
"uuid": "04e910a5-d2e3-448b-958a-630e35c62431",
"urn": "tel:+12345678900",
"channel": {
"name": "My Android Phone",
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d"
},
"text": "Hi there",
"text": "Hi there"
},
"type": "msg_created"
}`,
},
{
events.NewMsgCreated(
flows.NewMsgOut(
urns.URN("tel:+12345678900"),
assets.NewChannelReference(assets.ChannelUUID("57f1078f-88aa-46f4-a59a-948a5739c03d"), "My Android Phone"),
"Hi there",
[]utils.Attachment{"image/jpeg:http://s3.amazon.com/bucket/test.jpg"},
[]string{"yes", "no"},
nil,
flows.MsgTopicAgent,
flows.UnsendableReasonContactStatus,
),
),
`{
"created_on": "2018-10-18T14:20:30.000123456Z",
"msg": {
"uuid": "94f0e964-be11-4d7b-866b-323926b4c6a0",
"urn": "tel:+12345678900",
"uuid": "20cc4181-48cf-4344-9751-99419796decd"
"channel": {
"name": "My Android Phone",
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d"
},
"text": "Hi there",
"attachments": ["image/jpeg:http://s3.amazon.com/bucket/test.jpg"],
"quick_replies": ["yes", "no"],
"topic": "agent",
"unsendable_reason": "contact_status"
},
"type": "ivr_created"
"type": "msg_created"
}`,
},
{
Expand Down
29 changes: 21 additions & 8 deletions flows/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ func init() {
})
}

type UnsendableReason string

const (
NilUnsendableReason UnsendableReason = ""
UnsendableReasonNoDestination UnsendableReason = "no_destination" // no sendable channel+URN pair
UnsendableReasonContactStatus UnsendableReason = "contact_status" // contact is blocked or stopped or archived
)

// MsgTopic is the topic, as required by some channel types
type MsgTopic string

Expand Down Expand Up @@ -51,10 +59,11 @@ type MsgIn struct {
type MsgOut struct {
BaseMsg

QuickReplies_ []string `json:"quick_replies,omitempty"`
Templating_ *MsgTemplating `json:"templating,omitempty"`
Topic_ MsgTopic `json:"topic,omitempty"`
TextLanguage envs.Language `json:"text_language,omitempty"`
QuickReplies_ []string `json:"quick_replies,omitempty"`
Templating_ *MsgTemplating `json:"templating,omitempty"`
Topic_ MsgTopic `json:"topic,omitempty"`
TextLanguage envs.Language `json:"text_language,omitempty"`
UnsendableReason_ UnsendableReason `json:"unsendable_reason,omitempty"`
}

// NewMsgIn creates a new incoming message
Expand All @@ -71,7 +80,7 @@ func NewMsgIn(uuid MsgUUID, urn urns.URN, channel *assets.ChannelReference, text
}

// NewMsgOut creates a new outgoing message
func NewMsgOut(urn urns.URN, channel *assets.ChannelReference, text string, attachments []utils.Attachment, quickReplies []string, templating *MsgTemplating, topic MsgTopic) *MsgOut {
func NewMsgOut(urn urns.URN, channel *assets.ChannelReference, text string, attachments []utils.Attachment, quickReplies []string, templating *MsgTemplating, topic MsgTopic, reason UnsendableReason) *MsgOut {
return &MsgOut{
BaseMsg: BaseMsg{
UUID_: MsgUUID(uuids.New()),
Expand All @@ -80,9 +89,10 @@ func NewMsgOut(urn urns.URN, channel *assets.ChannelReference, text string, atta
Text_: text,
Attachments_: attachments,
},
QuickReplies_: quickReplies,
Templating_: templating,
Topic_: topic,
QuickReplies_: quickReplies,
Templating_: templating,
Topic_: topic,
UnsendableReason_: reason,
}
}

Expand Down Expand Up @@ -147,6 +157,9 @@ func (m *MsgOut) Templating() *MsgTemplating { return m.Templating_ }
// Topic returns the topic to use to send this message (if any)
func (m *MsgOut) Topic() MsgTopic { return m.Topic_ }

// UnsendableReason returns the reason this message can't be sent (if any)
func (m *MsgOut) UnsendableReason() UnsendableReason { return m.UnsendableReason_ }

// MsgTemplating represents any substituted message template that should be applied when sending this message
type MsgTemplating struct {
Template_ *assets.TemplateReference `json:"template"`
Expand Down
1 change: 1 addition & 0 deletions flows/msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func TestMsgOut(t *testing.T) {
nil,
nil,
flows.MsgTopicAgent,
flows.NilUnsendableReason,
)

// test marshaling our msg
Expand Down
19 changes: 19 additions & 0 deletions test/testdata/runner/enter_flow_loop.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"created_on": "2018-07-06T12:30:02.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb"
},
"step_uuid": "8720f157-ca1c-432f-9c0b-2014ddc77094",
Expand Down Expand Up @@ -65,6 +66,7 @@
"created_on": "2018-07-06T12:30:02.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb"
},
"step_uuid": "8720f157-ca1c-432f-9c0b-2014ddc77094",
Expand Down Expand Up @@ -178,6 +180,7 @@
"created_on": "2018-07-06T12:30:24.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "a4d15ed4-5b24-407f-b86e-4b881f09a186"
},
"step_uuid": "312d3af0-a565-4c96-ba00-bd7f0d08e671",
Expand All @@ -204,6 +207,7 @@
"created_on": "2018-07-06T12:30:38.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "688e64f9-2456-4b42-afcb-91a2073e5459"
},
"step_uuid": "44fe8d72-00ed-4736-acca-bbca70987315",
Expand Down Expand Up @@ -292,6 +296,7 @@
"created_on": "2018-07-06T12:30:02.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb"
},
"step_uuid": "8720f157-ca1c-432f-9c0b-2014ddc77094",
Expand Down Expand Up @@ -379,6 +384,7 @@
"created_on": "2018-07-06T12:30:24.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "a4d15ed4-5b24-407f-b86e-4b881f09a186"
},
"step_uuid": "312d3af0-a565-4c96-ba00-bd7f0d08e671",
Expand Down Expand Up @@ -438,6 +444,7 @@
"created_on": "2018-07-06T12:30:38.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "688e64f9-2456-4b42-afcb-91a2073e5459"
},
"step_uuid": "44fe8d72-00ed-4736-acca-bbca70987315",
Expand Down Expand Up @@ -552,6 +559,7 @@
"created_on": "2018-07-06T12:31:02.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "f5e0f002-41fc-4565-8d9f-e51d30290005"
},
"step_uuid": "b504fe9e-d8a8-47fd-af9c-ff2f1faac4db",
Expand All @@ -572,6 +580,7 @@
"created_on": "2018-07-06T12:31:16.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "f3cbd795-9bb3-4331-ba82-c15b24dd577f"
},
"step_uuid": "457e423f-85de-46f3-97a3-ae27459a6be4",
Expand Down Expand Up @@ -660,6 +669,7 @@
"created_on": "2018-07-06T12:30:02.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb"
},
"step_uuid": "8720f157-ca1c-432f-9c0b-2014ddc77094",
Expand Down Expand Up @@ -747,6 +757,7 @@
"created_on": "2018-07-06T12:30:24.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "a4d15ed4-5b24-407f-b86e-4b881f09a186"
},
"step_uuid": "312d3af0-a565-4c96-ba00-bd7f0d08e671",
Expand Down Expand Up @@ -806,6 +817,7 @@
"created_on": "2018-07-06T12:30:38.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "688e64f9-2456-4b42-afcb-91a2073e5459"
},
"step_uuid": "44fe8d72-00ed-4736-acca-bbca70987315",
Expand Down Expand Up @@ -894,6 +906,7 @@
"created_on": "2018-07-06T12:31:02.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "f5e0f002-41fc-4565-8d9f-e51d30290005"
},
"step_uuid": "b504fe9e-d8a8-47fd-af9c-ff2f1faac4db",
Expand Down Expand Up @@ -947,6 +960,7 @@
"created_on": "2018-07-06T12:31:16.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "f3cbd795-9bb3-4331-ba82-c15b24dd577f"
},
"step_uuid": "457e423f-85de-46f3-97a3-ae27459a6be4",
Expand Down Expand Up @@ -1093,6 +1107,7 @@
"created_on": "2018-07-06T12:30:02.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb"
},
"step_uuid": "8720f157-ca1c-432f-9c0b-2014ddc77094",
Expand Down Expand Up @@ -1180,6 +1195,7 @@
"created_on": "2018-07-06T12:30:24.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "a4d15ed4-5b24-407f-b86e-4b881f09a186"
},
"step_uuid": "312d3af0-a565-4c96-ba00-bd7f0d08e671",
Expand Down Expand Up @@ -1239,6 +1255,7 @@
"created_on": "2018-07-06T12:30:38.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "688e64f9-2456-4b42-afcb-91a2073e5459"
},
"step_uuid": "44fe8d72-00ed-4736-acca-bbca70987315",
Expand Down Expand Up @@ -1327,6 +1344,7 @@
"created_on": "2018-07-06T12:31:02.123456789Z",
"msg": {
"text": "Clearing name",
"unsendable_reason": "no_destination",
"uuid": "f5e0f002-41fc-4565-8d9f-e51d30290005"
},
"step_uuid": "b504fe9e-d8a8-47fd-af9c-ff2f1faac4db",
Expand Down Expand Up @@ -1380,6 +1398,7 @@
"created_on": "2018-07-06T12:31:16.123456789Z",
"msg": {
"text": "Enter command: name or exit",
"unsendable_reason": "no_destination",
"uuid": "f3cbd795-9bb3-4331-ba82-c15b24dd577f"
},
"step_uuid": "457e423f-85de-46f3-97a3-ae27459a6be4",
Expand Down
Loading

0 comments on commit 566d601

Please sign in to comment.