diff --git a/core/models/broadcasts.go b/core/models/broadcasts.go index 8b422d0d1..991a16895 100644 --- a/core/models/broadcasts.go +++ b/core/models/broadcasts.go @@ -277,12 +277,11 @@ func (b *BroadcastBatch) createMessage(rt *runtime.Runtime, oa *OrgAssets, c *Co return nil, fmt.Errorf("error creating flow contact for broadcast message: %w", err) } - trans, locale := b.Translations.ForContact(oa.Env(), contact, b.BaseLanguage) - text := trans.Text - attachments := trans.Attachments - quickReplies := trans.QuickReplies + content, locale := b.Translations.ForContact(oa.Env(), contact, b.BaseLanguage) if b.Expressions { + ev := goflow.Engine(rt).Evaluator() + // build up the minimum viable context for templates templateCtx := types.NewXObject(map[string]types.XValue{ "contact": flows.Context(oa.Env(), contact), @@ -291,25 +290,24 @@ func (b *BroadcastBatch) createMessage(rt *runtime.Runtime, oa *OrgAssets, c *Co "urns": flows.ContextFunc(oa.Env(), contact.URNs().MapContext), }) - ev := goflow.Engine(rt).Evaluator() - text, _, _ = ev.Template(oa.Env(), templateCtx, text, nil) + content.Text, _, _ = ev.Template(oa.Env(), templateCtx, content.Text, nil) - for i := range attachments { - evaluated, _, _ := ev.Template(oa.Env(), templateCtx, string(attachments[i]), nil) - attachments[i] = utils.Attachment(evaluated) + for i := range content.Attachments { + evaluated, _, _ := ev.Template(oa.Env(), templateCtx, string(content.Attachments[i]), nil) + content.Attachments[i] = utils.Attachment(evaluated) } - for i := range quickReplies { - quickReplies[i], _, _ = ev.Template(oa.Env(), templateCtx, quickReplies[i], nil) + for i := range content.QuickReplies { + content.QuickReplies[i], _, _ = ev.Template(oa.Env(), templateCtx, content.QuickReplies[i], nil) } } // don't create a message if we have no content - if text == "" && len(attachments) == 0 && len(trans.QuickReplies) == 0 { + if content.Empty() { return nil, nil } // create our outgoing message - out, ch := NewMsgOut(oa, contact, text, attachments, quickReplies, locale) + out, ch := NewMsgOut(oa, contact, content, nil, locale) msg, err := NewOutgoingBroadcastMsg(rt, oa.Org(), ch, contact, out, b) if err != nil { diff --git a/core/models/msgs.go b/core/models/msgs.go index 858992d7a..ef3d34b35 100644 --- a/core/models/msgs.go +++ b/core/models/msgs.go @@ -770,7 +770,7 @@ func FailChannelMessages(ctx context.Context, db *sql.DB, orgID OrgID, channelID return nil } -func NewMsgOut(oa *OrgAssets, c *flows.Contact, text string, atts []utils.Attachment, qrs []string, locale i18n.Locale) (*flows.MsgOut, *Channel) { +func NewMsgOut(oa *OrgAssets, c *flows.Contact, content *flows.MsgContent, templating *flows.MsgTemplating, locale i18n.Locale) (*flows.MsgOut, *Channel) { // resolve URN + channel for this contact urn := urns.NilURN var channel *Channel @@ -790,7 +790,7 @@ func NewMsgOut(oa *OrgAssets, c *flows.Contact, text string, atts []utils.Attach unsendableReason = flows.UnsendableReasonNoDestination } - return flows.NewMsgOut(urn, channelRef, text, atts, qrs, nil, flows.NilMsgTopic, locale, unsendableReason), channel + return flows.NewMsgOut(urn, channelRef, content, templating, flows.NilMsgTopic, locale, unsendableReason), channel } const sqlUpdateMsgDeletedBySender = ` diff --git a/core/models/msgs_test.go b/core/models/msgs_test.go index b8d3f22e2..f2da8f1b3 100644 --- a/core/models/msgs_test.go +++ b/core/models/msgs_test.go @@ -35,14 +35,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { tcs := []struct { Channel *testdata.Channel - Text string Contact *testdata.Contact URN urns.URN URNID models.URNID - Attachments []utils.Attachment - QuickReplies []string - Locale i18n.Locale + Content *flows.MsgContent Templating *flows.MsgTemplating + Locale i18n.Locale Topic flows.MsgTopic Unsendable flows.UnsendableReason Flow *testdata.Flow @@ -55,12 +53,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { ExpectedMsgCount int ExpectedPriority bool }{ - { // 0 + { // 0: missing URN ID Channel: testdata.TwilioChannel, - Text: "missing urn id", Contact: testdata.Cathy, URN: urns.URN("tel:+250700000001"), URNID: models.URNID(0), + Content: &flows.MsgContent{Text: "hello"}, Flow: testdata.Favorites, ResponseTo: models.MsgID(123425), ExpectedStatus: models.MsgStatusQueued, @@ -70,18 +68,17 @@ func TestNewOutgoingFlowMsg(t *testing.T) { ExpectedPriority: true, }, { // 1 - Channel: testdata.TwilioChannel, - Text: "test outgoing", - Contact: testdata.Cathy, - URN: urns.URN(fmt.Sprintf("tel:+250700000001?id=%d", testdata.Cathy.URNID)), - URNID: testdata.Cathy.URNID, - QuickReplies: []string{"yes", "no"}, - Locale: "eng-US", + Channel: testdata.TwilioChannel, + Contact: testdata.Cathy, + URN: urns.URN(fmt.Sprintf("tel:+250700000001?id=%d", testdata.Cathy.URNID)), + URNID: testdata.Cathy.URNID, + Content: &flows.MsgContent{Text: "test outgoing", QuickReplies: []string{"yes", "no"}}, Templating: flows.NewMsgTemplating( assets.NewTemplateReference("9c22b594-fcab-4b29-9bcb-ce4404894a80", "revive_issue"), []*flows.TemplatingComponent{{Type: "body", Name: "body", Variables: map[string]int{"1": 0}}}, []*flows.TemplatingVariable{{Type: "text", Value: "name"}}, ), + Locale: "eng-US", Topic: flows.MsgTopicPurchase, Flow: testdata.SingleMessage, ExpectedStatus: models.MsgStatusQueued, @@ -90,13 +87,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { ExpectedMsgCount: 1, ExpectedPriority: false, }, - { + { // 2 Channel: testdata.TwilioChannel, - Text: "test outgoing", Contact: testdata.Cathy, URN: urns.URN(fmt.Sprintf("tel:+250700000001?id=%d", testdata.Cathy.URNID)), URNID: testdata.Cathy.URNID, - Attachments: []utils.Attachment{utils.Attachment("image/jpeg:https://dl-foo.com/image.jpg")}, + Content: &flows.MsgContent{Text: "test outgoing", Attachments: []utils.Attachment{utils.Attachment("image/jpeg:https://dl-foo.com/image.jpg")}}, Flow: testdata.Favorites, ExpectedStatus: models.MsgStatusQueued, ExpectedFailedReason: models.NilMsgFailedReason, @@ -104,12 +100,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { ExpectedMsgCount: 2, ExpectedPriority: false, }, - { + { // 3: suspended org Channel: testdata.TwilioChannel, - Text: "suspended org", Contact: testdata.Cathy, URN: urns.URN(fmt.Sprintf("tel:+250700000001?id=%d", testdata.Cathy.URNID)), URNID: testdata.Cathy.URNID, + Content: &flows.MsgContent{Text: "hello"}, Flow: testdata.Favorites, SuspendedOrg: true, ExpectedStatus: models.MsgStatusFailed, @@ -118,12 +114,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { ExpectedMsgCount: 1, ExpectedPriority: false, }, - { + { // 4: no destination Channel: nil, - Text: "no destination", Contact: testdata.Cathy, URN: urns.NilURN, URNID: models.URNID(0), + Content: &flows.MsgContent{Text: "hello"}, Unsendable: flows.UnsendableReasonNoDestination, Flow: testdata.Favorites, ExpectedStatus: models.MsgStatusFailed, @@ -132,12 +128,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { ExpectedMsgCount: 1, ExpectedPriority: false, }, - { + { // 5: blocked contact Channel: testdata.TwilioChannel, - Text: "blocked contact", Contact: blake, URN: urns.URN(fmt.Sprintf("tel:+250700000007?id=%d", blakeURNID)), URNID: blakeURNID, + Content: &flows.MsgContent{Text: "hello"}, Unsendable: flows.UnsendableReasonContactStatus, Flow: testdata.Favorites, ExpectedStatus: models.MsgStatusFailed, @@ -172,12 +168,12 @@ func TestNewOutgoingFlowMsg(t *testing.T) { session.SetIncomingMsg(tc.ResponseTo, null.NullString) } - flowMsg := flows.NewMsgOut(tc.URN, chRef, tc.Text, tc.Attachments, tc.QuickReplies, tc.Templating, tc.Topic, tc.Locale, tc.Unsendable) + flowMsg := flows.NewMsgOut(tc.URN, chRef, tc.Content, tc.Templating, tc.Topic, tc.Locale, tc.Unsendable) msg, err := models.NewOutgoingFlowMsg(rt, oa.Org(), ch, session, flow, flowMsg, dates.Now()) assert.NoError(t, err) - expectedAttachments := tc.Attachments + expectedAttachments := tc.Content.Attachments if expectedAttachments == nil { expectedAttachments = []utils.Attachment{} } @@ -185,10 +181,10 @@ func TestNewOutgoingFlowMsg(t *testing.T) { err = models.InsertMessages(ctx, rt.DB, []*models.Msg{msg}) assert.NoError(t, err) assert.Equal(t, oa.OrgID(), msg.OrgID()) - assert.Equal(t, tc.Text, msg.Text(), "%d: text mismatch", i) + assert.Equal(t, tc.Content.Text, msg.Text(), "%d: text mismatch", i) assert.Equal(t, models.MsgTypeText, msg.Type(), "%d: type mismatch", i) assert.Equal(t, expectedAttachments, msg.Attachments(), "%d: attachments mismatch", i) - assert.Equal(t, tc.QuickReplies, msg.QuickReplies(), "%d: quick replies mismatch", i) + assert.Equal(t, tc.Content.QuickReplies, msg.QuickReplies(), "%d: quick replies mismatch", i) assert.Equal(t, tc.Locale, msg.Locale(), "%d: locale mismatch", i) if tc.Templating != nil { @@ -230,7 +226,8 @@ func TestNewOutgoingFlowMsg(t *testing.T) { // check that msg loop detection triggers after 20 repeats of the same text newOutgoing := func(text string) *models.Msg { - flowMsg := flows.NewMsgOut(urns.URN(fmt.Sprintf("tel:+250700000001?id=%d", testdata.Cathy.URNID)), assets.NewChannelReference(testdata.TwilioChannel.UUID, "Twilio"), text, nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + content := &flows.MsgContent{Text: text} + flowMsg := flows.NewMsgOut(urns.URN(fmt.Sprintf("tel:+250700000001?id=%d", testdata.Cathy.URNID)), assets.NewChannelReference(testdata.TwilioChannel.UUID, "Twilio"), content, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) msg, err := models.NewOutgoingFlowMsg(rt, oa.Org(), channel, session, flow, flowMsg, dates.Now()) require.NoError(t, err) return msg @@ -397,10 +394,10 @@ func TestGetMsgRepetitions(t *testing.T) { _, cathy, _ := testdata.Cathy.Load(rt, oa) _, george, _ := testdata.George.Load(rt, oa) - msg1 := flows.NewMsgOut(testdata.Cathy.URN, nil, "foo", nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) - msg2 := flows.NewMsgOut(testdata.Cathy.URN, nil, "FOO", nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) - msg3 := flows.NewMsgOut(testdata.Cathy.URN, nil, "bar", nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) - msg4 := flows.NewMsgOut(testdata.George.URN, nil, "foo", nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + msg1 := flows.NewMsgOut(testdata.Cathy.URN, nil, &flows.MsgContent{Text: "foo"}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + msg2 := flows.NewMsgOut(testdata.Cathy.URN, nil, &flows.MsgContent{Text: "FOO"}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + msg3 := flows.NewMsgOut(testdata.Cathy.URN, nil, &flows.MsgContent{Text: "bar"}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + msg4 := flows.NewMsgOut(testdata.George.URN, nil, &flows.MsgContent{Text: "foo"}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) assertRepetitions := func(contact *flows.Contact, m *flows.MsgOut, expected int) { count, err := models.GetMsgRepetitions(rt.RP, contact, m) @@ -525,7 +522,7 @@ func TestNewMsgOut(t *testing.T) { _, cathy, _ := testdata.Cathy.Load(rt, oa) - out, ch := models.NewMsgOut(oa, cathy, "hello", nil, nil, `eng-US`) + out, ch := models.NewMsgOut(oa, cathy, &flows.MsgContent{Text: "hello"}, nil, `eng-US`) assert.Equal(t, "hello", out.Text()) assert.Equal(t, urns.URN("tel:+16055741111?id=10000"), out.URN()) assert.Equal(t, assets.NewChannelReference("74729f45-7f29-4868-9dc4-90e491e3c7d8", "Twilio"), out.Channel()) @@ -534,7 +531,7 @@ func TestNewMsgOut(t *testing.T) { cathy.SetStatus(flows.ContactStatusBlocked) - out, ch = models.NewMsgOut(oa, cathy, "hello", nil, nil, `eng-US`) + out, ch = models.NewMsgOut(oa, cathy, &flows.MsgContent{Text: "hello"}, nil, `eng-US`) assert.Equal(t, urns.URN("tel:+16055741111?id=10000"), out.URN()) assert.Equal(t, assets.NewChannelReference("74729f45-7f29-4868-9dc4-90e491e3c7d8", "Twilio"), out.Channel()) assert.Equal(t, "Twilio", ch.Name()) @@ -543,7 +540,7 @@ func TestNewMsgOut(t *testing.T) { cathy.SetStatus(flows.ContactStatusActive) cathy.ClearURNs() - out, ch = models.NewMsgOut(oa, cathy, "hello", nil, nil, `eng-US`) + out, ch = models.NewMsgOut(oa, cathy, &flows.MsgContent{Text: "hello"}, nil, `eng-US`) assert.Equal(t, urns.NilURN, out.URN()) assert.Nil(t, out.Channel()) assert.Nil(t, ch) @@ -568,12 +565,12 @@ func TestMsgTemplating(t *testing.T) { ) // create a message with templating - out1 := flows.NewMsgOut(testdata.Cathy.URN, chRef, "Hello", nil, nil, templating1, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + out1 := flows.NewMsgOut(testdata.Cathy.URN, chRef, &flows.MsgContent{Text: "Hello"}, templating1, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) msg1, err := models.NewOutgoingFlowMsg(rt, oa.Org(), channel, session, flow, out1, dates.Now()) require.NoError(t, err) // create a message without templating - out2 := flows.NewMsgOut(testdata.Cathy.URN, chRef, "Hello", nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + out2 := flows.NewMsgOut(testdata.Cathy.URN, chRef, &flows.MsgContent{Text: "Hello"}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) msg2, err := models.NewOutgoingFlowMsg(rt, oa.Org(), channel, session, flow, out2, dates.Now()) require.NoError(t, err) diff --git a/core/msgio/courier_test.go b/core/msgio/courier_test.go index b293efb3d..6a7ef206a 100644 --- a/core/msgio/courier_test.go +++ b/core/msgio/courier_test.go @@ -48,9 +48,11 @@ func TestNewCourierMsg(t *testing.T) { flowMsg1 := flows.NewMsgOut( cathyURN, assets.NewChannelReference(testdata.TwilioChannel.UUID, "Test Channel"), - "Hi there", - []utils.Attachment{utils.Attachment("image/jpeg:https://dl-foo.com/image.jpg")}, - []string{"yes", "no"}, + &flows.MsgContent{ + Text: "Hi there", + Attachments: []utils.Attachment{utils.Attachment("image/jpeg:https://dl-foo.com/image.jpg")}, + QuickReplies: []string{"yes", "no"}, + }, flows.NewMsgTemplating( assets.NewTemplateReference("9c22b594-fcab-4b29-9bcb-ce4404894a80", "revive_issue"), []*flows.TemplatingComponent{{Type: "body", Name: "body", Variables: map[string]int{"1": 0}}}, @@ -113,8 +115,8 @@ func TestNewCourierMsg(t *testing.T) { flowMsg2 := flows.NewMsgOut( cathyURN, assets.NewChannelReference(testdata.TwilioChannel.UUID, "Test Channel"), - "Hi there", - nil, nil, nil, + &flows.MsgContent{Text: "Hi there"}, + nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason, @@ -149,7 +151,7 @@ func TestNewCourierMsg(t *testing.T) { // try a broadcast message which won't have session and flow fields set and won't be high priority bcastID := testdata.InsertBroadcast(rt, testdata.Org1, `eng`, map[i18n.Language]string{`eng`: "Blast"}, nil, models.NilScheduleID, []*testdata.Contact{testFred}, nil) - bcastMsg1 := flows.NewMsgOut(fredURN, assets.NewChannelReference(testdata.TwilioChannel.UUID, "Test Channel"), "Blast", nil, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + bcastMsg1 := flows.NewMsgOut(fredURN, assets.NewChannelReference(testdata.TwilioChannel.UUID, "Test Channel"), &flows.MsgContent{Text: "Blast"}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) msg3, err := models.NewOutgoingBroadcastMsg(rt, oa.Org(), channel, fred, bcastMsg1, &models.BroadcastBatch{BroadcastID: bcastID, OptInID: optInID, CreatedByID: testdata.Admin.ID}) require.NoError(t, err) diff --git a/go.mod b/go.mod index 9c82cac3e..1be42cf36 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( firebase.google.com/go/v4 v4.14.1 github.com/Masterminds/semver v1.5.0 github.com/appleboy/go-fcm v1.2.1 - github.com/aws/aws-sdk-go v1.54.12 + github.com/aws/aws-sdk-go v1.54.14 github.com/buger/jsonparser v1.1.1 github.com/elastic/go-elasticsearch/v8 v8.14.0 github.com/getsentry/sentry-go v0.28.1 @@ -20,7 +20,7 @@ require ( github.com/lib/pq v1.10.9 github.com/nyaruka/ezconf v0.3.0 github.com/nyaruka/gocommon v1.55.7 - github.com/nyaruka/goflow v0.218.1 + github.com/nyaruka/goflow v0.218.3 github.com/nyaruka/null/v3 v3.0.0 github.com/nyaruka/redisx v0.8.1 github.com/nyaruka/rp-indexer/v9 v9.1.9 diff --git a/go.sum b/go.sum index 11bcce58b..4ebcac794 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYW github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/appleboy/go-fcm v1.2.1 h1:NhpACabtRuAplYg6bTNfSr3LBwsSuutP55HsphzLU/g= github.com/appleboy/go-fcm v1.2.1/go.mod h1:5FzMN+9J2sxnkoys9h3y48GQH8HnI637Q/ro/uP2Qsk= -github.com/aws/aws-sdk-go v1.54.12 h1:xPDB+GSBZq0rJbmDZF+EyfMbnWRyfEPcn7PZ7bJjXSw= -github.com/aws/aws-sdk-go v1.54.12/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.54.14 h1:llJ60MzLzovyDE/rEDbUjS1cICh7krk1PwQwNlKRoeQ= +github.com/aws/aws-sdk-go v1.54.14/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= @@ -156,8 +156,8 @@ github.com/nyaruka/ezconf v0.3.0 h1:kGvJqVN8AHowb4HdaHAviJ0Z3yI5Pyekp1WqibFEaGk= github.com/nyaruka/ezconf v0.3.0/go.mod h1:89GUW6EPRNLIxT7lC4LWnjWTgZeQwRoX7lBmc8ralAU= github.com/nyaruka/gocommon v1.55.7 h1:TXXQQFvbHcLqpIH6IGABMX3WMDbZFaqDKtGeUL9hn+0= github.com/nyaruka/gocommon v1.55.7/go.mod h1:L201WJTeL5RtfAxVn58gGu3P8l0jETjzyGN5fjbLhlQ= -github.com/nyaruka/goflow v0.218.1 h1:xsKUVsMU0xPnFfRSB4WeF6uWkoX6dBToeufM2XNMiUA= -github.com/nyaruka/goflow v0.218.1/go.mod h1:lcdYSHmtkYzdI6VsXKpxD7ZISEHlU+6f49JKtcMJlMU= +github.com/nyaruka/goflow v0.218.3 h1:mhnhTyNj1WcKo++DqR+HANIT94kVt85N0IvMyA8tHr4= +github.com/nyaruka/goflow v0.218.3/go.mod h1:lcdYSHmtkYzdI6VsXKpxD7ZISEHlU+6f49JKtcMJlMU= github.com/nyaruka/librato v1.1.1 h1:0nTYtJLl3Sn7lX3CuHsLf+nXy1k/tGV0OjVxLy3Et4s= github.com/nyaruka/librato v1.1.1/go.mod h1:fme1Fu1PT2qvkaBZyw8WW+SrnFe2qeeCWpvqmAaKAKE= github.com/nyaruka/null/v2 v2.0.3 h1:rdmMRQyVzrOF3Jff/gpU/7BDR9mQX0lcLl4yImsA3kw= diff --git a/testsuite/testdata/msgs.go b/testsuite/testdata/msgs.go index 996a5084b..65b5bccdc 100644 --- a/testsuite/testdata/msgs.go +++ b/testsuite/testdata/msgs.go @@ -87,7 +87,7 @@ func insertOutgoingMsg(rt *runtime.Runtime, org *Org, channel *Channel, contact sentOn = &t } - fm := flows.NewMsgOut(contact.URN, channelRef, text, attachments, nil, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) + fm := flows.NewMsgOut(contact.URN, channelRef, &flows.MsgContent{text, attachments, nil}, nil, flows.NilMsgTopic, i18n.NilLocale, flows.NilUnsendableReason) var id models.MsgID must(rt.DB.Get(&id, diff --git a/web/msg/send.go b/web/msg/send.go index ee2af76bc..fc0442fc8 100644 --- a/web/msg/send.go +++ b/web/msg/send.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" + "github.com/nyaruka/goflow/flows" "github.com/nyaruka/goflow/utils" "github.com/nyaruka/mailroom/core/models" "github.com/nyaruka/mailroom/core/msgio" @@ -52,7 +53,9 @@ func handleSend(ctx context.Context, rt *runtime.Runtime, r *sendRequest) (any, return nil, 0, fmt.Errorf("error creating flow contact: %w", err) } - out, ch := models.NewMsgOut(oa, contact, r.Text, r.Attachments, nil, contact.Locale(oa.Env())) + content := &flows.MsgContent{Text: r.Text, Attachments: r.Attachments} + + out, ch := models.NewMsgOut(oa, contact, content, nil, contact.Locale(oa.Env())) var msg *models.Msg if r.TicketID != models.NilTicketID {