Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
baracudda committed Mar 27, 2024
2 parents ca00b46 + 26d5cb6 commit 61487e2
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
23 changes: 22 additions & 1 deletion flows/actions/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/nyaruka/goflow/envs"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/flows/events"
"math/rand"
)

func init() {
Expand Down Expand Up @@ -83,7 +84,27 @@ func (a *SendMsgAction) Execute(run flows.Run, step flows.Step, logModifier flow

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

destinations := run.Contact().ResolveDestinations(a.AllURNs)
var destinations []flows.Destination
flowChannels := run.Flow().Channels()
if len(flowChannels) > 0 {
//<*((==<
destinations = run.Contact().ResolveURNDestinations(a.AllURNs, flowChannels)
if len(destinations) == 0 {
theRandomChannelUUID := run.Flow().ChannelUUIDs()[rand.Intn(len(flowChannels))]
//pick URN from contact based on channel we have
if theURN, theChannel := run.Contact().ResolveURN(theRandomChannelUUID); theURN != nil && theChannel != nil {
destinations = append(destinations, flows.Destination{URN: theURN, Channel: theChannel})
} else {
logEvent(events.NewErrorf("no matching URN for contact [%s] with channel [%s]",
run.Contact().UUID(),
theRandomChannelUUID,
))
return nil
}
}
} else {
destinations = run.Contact().ResolveDestinations(a.AllURNs)
}

sa := run.Session().Assets()

Expand Down
28 changes: 28 additions & 0 deletions flows/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,34 @@ func (c *Contact) ResolveDestinations(all bool) []Destination {
return destinations
}

// ResolveURNDestinations resolves possible URN/channel destinations //<*((==<
func (c *Contact) ResolveURNDestinations(all bool, flowChannels map[assets.ChannelUUID]*assets.ChannelReference) []Destination {
var destinations []Destination
for _, u := range c.urns {
channel := c.assets.Channels().GetForURN(u, assets.ChannelRoleSend)
if channel != nil {
if _, found := flowChannels[channel.UUID()]; found {
destinations = append(destinations, Destination{URN: u, Channel: channel})
if !all {
break
}
}
}
}
return destinations
}

// ResolveURN resolves possible URN given channel to use //<*((==<
func (c *Contact) ResolveURN(aChannelID assets.ChannelUUID) (*ContactURN, *Channel) {
for _, u := range c.urns {
channel := c.assets.Channels().Get(aChannelID)
if channel != nil && channel.SupportsScheme(u.URN().Scheme()) {
return u, channel
}
}
return nil, nil
}

// PreferredURN gets the preferred URN for this contact, i.e. the URN we would use for sending
func (c *Contact) PreferredURN() *ContactURN {
destinations := c.ResolveDestinations(false)
Expand Down
16 changes: 14 additions & 2 deletions flows/definition/flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type flow struct {
expireAfterMinutes int
localization flows.Localization
nodes []flows.Node
channels []assets.ChannelUUID //<*((==<
channelMap map[assets.ChannelUUID]*assets.ChannelReference //<*((==<

// optional properties not used by engine itself
ui json.RawMessage
Expand All @@ -50,7 +52,7 @@ type flow struct {
}

// NewFlow creates a new flow
func NewFlow(uuid assets.FlowUUID, name string, language envs.Language, flowType flows.FlowType, revision int, expireAfterMinutes int, localization flows.Localization, nodes []flows.Node, ui json.RawMessage, a assets.Flow) (flows.Flow, error) {
func NewFlow(uuid assets.FlowUUID, name string, language envs.Language, flowType flows.FlowType, revision int, expireAfterMinutes int, localization flows.Localization, nodes []flows.Node, ui json.RawMessage, a assets.Flow, channels []assets.ChannelUUID) (flows.Flow, error) {
f := &flow{
uuid: uuid,
name: name,
Expand All @@ -64,11 +66,17 @@ func NewFlow(uuid assets.FlowUUID, name string, language envs.Language, flowType
nodeMap: make(map[flows.NodeUUID]flows.Node, len(nodes)),
ui: ui,
asset: a,
channels: channels,
}

for _, node := range f.nodes {
f.nodeMap[node.UUID()] = node
}
//<*((==<
f.channelMap = make(map[assets.ChannelUUID]*assets.ChannelReference, len(f.channels))
for i := range f.channels {
f.channelMap[f.channels[i]] = assets.NewChannelReference(f.channels[i], string("Name Of: "+f.channels[i]))
}

if err := f.validate(); err != nil {
return nil, err
Expand All @@ -88,6 +96,8 @@ func (f *flow) Nodes() []flows.Node { return f.nodes }
func (f *flow) Localization() flows.Localization { return f.localization }
func (f *flow) UI() json.RawMessage { return f.ui }
func (f *flow) GetNode(uuid flows.NodeUUID) flows.Node { return f.nodeMap[uuid] }
func (f *flow) ChannelUUIDs() []assets.ChannelUUID { return f.channels } //<*((==<
func (f *flow) Channels() map[assets.ChannelUUID]*assets.ChannelReference { return f.channelMap } //<*((==<

func (f *flow) validate() error {
// track UUIDs used by nodes and actions to ensure that they are unique
Expand Down Expand Up @@ -315,6 +325,8 @@ type flowEnvelope struct {
Localization localization `json:"localization"`
Nodes []*node `json:"nodes"`
UI json.RawMessage `json:"_ui,omitempty"`
//<*((==<
ChannelUUIDs []assets.ChannelUUID `json:"channels,omitempty"`
}

// ReadFlow reads a flow definition from the passed in byte array, migrating it to the spec version of the engine if necessary
Expand Down Expand Up @@ -355,7 +367,7 @@ func readFlow(data json.RawMessage, mc *migrations.Config, a assets.Flow) (flows
e.Localization = make(localization)
}

return NewFlow(e.UUID, e.Name, e.Language, e.Type, e.Revision, e.ExpireAfterMinutes, e.Localization, nodes, e.UI, a)
return NewFlow(e.UUID, e.Name, e.Language, e.Type, e.Revision, e.ExpireAfterMinutes, e.Localization, nodes, e.UI, a, e.ChannelUUIDs)
}

// MarshalJSON marshals this flow into JSON
Expand Down
1 change: 1 addition & 0 deletions flows/definition/flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ func TestNewFlow(t *testing.T) {
},
nil, // no UI
nil, // no asset
nil,
)
require.NoError(t, err)

Expand Down
2 changes: 2 additions & 0 deletions flows/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ type Flow interface {
UI() json.RawMessage
Nodes() []Node
GetNode(uuid NodeUUID) Node
ChannelUUIDs() []assets.ChannelUUID //<*((==<
Channels() map[assets.ChannelUUID]*assets.ChannelReference //<*((==<

Asset() assets.Flow
Reference() *assets.FlowReference
Expand Down

0 comments on commit 61487e2

Please sign in to comment.