-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new triger_session action to replace start_session
- Loading branch information
1 parent
f5d91b4
commit 6b43aa0
Showing
9 changed files
with
282 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
[ | ||
{ | ||
"description": "Error event and NOOP if flow missing", | ||
"action": { | ||
"type": "trigger_session", | ||
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912", | ||
"flow": { | ||
"uuid": "dede1e50-db55-4b50-8929-2116bfc56148", | ||
"name": "Missing" | ||
}, | ||
"contact": { | ||
"uuid": "945493e3-933f-4668-9761-ce990fae5e5c", | ||
"name": "Stavros" | ||
}, | ||
"interrupt": true | ||
}, | ||
"events": [ | ||
{ | ||
"type": "error", | ||
"created_on": "2018-10-18T14:20:30.000123456Z", | ||
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c", | ||
"text": "missing dependency: flow[uuid=dede1e50-db55-4b50-8929-2116bfc56148,name=Missing]" | ||
} | ||
], | ||
"inspection": { | ||
"dependencies": [ | ||
{ | ||
"uuid": "dede1e50-db55-4b50-8929-2116bfc56148", | ||
"name": "Missing", | ||
"type": "flow", | ||
"missing": true | ||
}, | ||
{ | ||
"uuid": "945493e3-933f-4668-9761-ce990fae5e5c", | ||
"name": "Stavros", | ||
"type": "contact" | ||
} | ||
], | ||
"issues": [ | ||
{ | ||
"type": "missing_dependency", | ||
"node_uuid": "72a1f5df-49f9-45df-94c9-d86f7ea064e5", | ||
"action_uuid": "ad154980-7bf7-4ab8-8728-545fd6378912", | ||
"description": "missing flow dependency 'dede1e50-db55-4b50-8929-2116bfc56148'", | ||
"dependency": { | ||
"uuid": "dede1e50-db55-4b50-8929-2116bfc56148", | ||
"name": "Missing", | ||
"type": "flow" | ||
} | ||
} | ||
], | ||
"results": [], | ||
"waiting_exits": [], | ||
"parent_refs": [] | ||
} | ||
}, | ||
{ | ||
"description": "Session triggered event with concrete contact reference", | ||
"action": { | ||
"type": "trigger_session", | ||
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912", | ||
"flow": { | ||
"uuid": "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d", | ||
"name": "Collect Age" | ||
}, | ||
"contact": { | ||
"uuid": "945493e3-933f-4668-9761-ce990fae5e5c", | ||
"name": "Stavros" | ||
}, | ||
"interrupt": true | ||
}, | ||
"events": [ | ||
{ | ||
"type": "session_triggered", | ||
"created_on": "2018-10-18T14:20:30.000123456Z", | ||
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c", | ||
"flow": { | ||
"uuid": "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d", | ||
"name": "Collect Age" | ||
}, | ||
"contact": { | ||
"uuid": "945493e3-933f-4668-9761-ce990fae5e5c", | ||
"name": "Stavros" | ||
}, | ||
"interrupt": true, | ||
"exclusions": {}, | ||
"run_summary": { | ||
"uuid": "e7187099-7d38-4f60-955c-325957214c42", | ||
"flow": { | ||
"uuid": "bead76f5-dac4-4c9d-996c-c62b326e8c0a", | ||
"name": "Action Tester", | ||
"revision": 123 | ||
}, | ||
"contact": { | ||
"uuid": "5d76d86b-3bb9-4d5a-b822-c9d86f5d8e4f", | ||
"name": "Ryan Lewis", | ||
"language": "eng", | ||
"last_seen_on": "2018-10-18T14:20:30.000123456Z", | ||
"status": "active", | ||
"timezone": "America/Guayaquil", | ||
"created_on": "2018-06-20T11:40:30.123456789Z", | ||
"urns": [ | ||
"tel:+12065551212?channel=57f1078f-88aa-46f4-a59a-948a5739c03d&id=123", | ||
"twitterid:54784326227#nyaruka" | ||
], | ||
"groups": [ | ||
{ | ||
"uuid": "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d", | ||
"name": "Testers" | ||
}, | ||
{ | ||
"uuid": "0ec97956-c451-48a0-a180-1ce766623e31", | ||
"name": "Males" | ||
} | ||
], | ||
"fields": { | ||
"gender": { | ||
"text": "Male" | ||
} | ||
} | ||
}, | ||
"status": "active", | ||
"results": {} | ||
}, | ||
"history": { | ||
"parent_uuid": "1ae96956-4b34-433e-8d1a-f05fe6923d6d", | ||
"ancestors": 1, | ||
"ancestors_since_input": 0 | ||
} | ||
} | ||
] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package actions | ||
|
||
import ( | ||
"github.com/nyaruka/gocommon/jsonx" | ||
"github.com/nyaruka/gocommon/urns" | ||
"github.com/nyaruka/goflow/assets" | ||
"github.com/nyaruka/goflow/flows" | ||
"github.com/nyaruka/goflow/flows/events" | ||
"github.com/nyaruka/goflow/utils" | ||
) | ||
|
||
// max number of times a session can trigger another session without there being input from the contact | ||
const maxAncestorsSinceInput = 5 | ||
|
||
func init() { | ||
registerType(TypeTriggerSession, func() flows.Action { return &TriggerSessionAction{} }) | ||
} | ||
|
||
// TypeTriggerSession is the type for the trigger session action | ||
const TypeTriggerSession string = "trigger_session" | ||
|
||
// TriggerSessionAction can be used to trigger sessions for another contact. A [event:session_triggered] event will be | ||
// created and it's the responsibility of the caller to act on that by initiating a new session with the flow engine. | ||
// The contact can be specified via a concrete reference or as a URN via the scheme and path fields. In the latter case | ||
// the contact will be created if they don't exist. | ||
// | ||
// { | ||
// "uuid": "8eebd020-1af5-431c-b943-aa670fc74da9", | ||
// "type": "trigger_session", | ||
// "flow": {"uuid": "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d", "name": "Registration"}, | ||
// "contact": {"uuid": "1e1ce1e1-9288-4504-869e-022d1003c72a", "name": "Bob"}, | ||
// "interrupt": true | ||
// } | ||
// | ||
// @action start_session | ||
type TriggerSessionAction struct { | ||
baseAction | ||
onlineAction | ||
|
||
Flow *assets.FlowReference `json:"flow" validate:"required"` | ||
Contact *flows.ContactReference `json:"contact" validate:"required"` | ||
Interrupt bool `json:"interrupt"` | ||
} | ||
|
||
// NewTriggerSession creates a new trigger session action | ||
func NewTriggerSession(uuid flows.ActionUUID, flow *assets.FlowReference, contact *flows.ContactReference, interrupt bool) *TriggerSessionAction { | ||
return &TriggerSessionAction{ | ||
baseAction: newBaseAction(TypeTriggerSession, uuid), | ||
Flow: flow, | ||
Contact: contact, | ||
Interrupt: interrupt, | ||
} | ||
} | ||
|
||
// Execute runs our action | ||
func (a *TriggerSessionAction) Execute(run flows.Run, step flows.Step, logModifier flows.ModifierCallback, logEvent flows.EventCallback) error { | ||
contact := a.resolveContact(run, logEvent) | ||
if contact == nil { | ||
logEvent(events.NewDependencyError(a.Contact)) | ||
return nil | ||
} | ||
|
||
// check that flow exists - error event if not | ||
flow, err := run.Session().Assets().Flows().Get(a.Flow.UUID) | ||
if err != nil { | ||
logEvent(events.NewDependencyError(a.Flow)) | ||
return nil | ||
} | ||
|
||
// loop footgun prevention | ||
ref := run.Session().History() | ||
if ref.AncestorsSinceInput >= maxAncestorsSinceInput { | ||
logEvent(events.NewErrorf("too many sessions have been spawned since the last time input was received")) | ||
return nil | ||
} | ||
|
||
runSnapshot, err := jsonx.Marshal(run.Snapshot()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
history := flows.NewChildHistory(run.Session()) | ||
|
||
logEvent(events.NewSessionTriggered(flow.Reference(false), contact, a.Interrupt, runSnapshot, history)) | ||
return nil | ||
} | ||
|
||
func (a *TriggerSessionAction) resolveContact(run flows.Run, logEvent flows.EventCallback) *flows.ContactReference { | ||
// if this is a concrete reference, return as is | ||
if !a.Contact.Variable() { | ||
return a.Contact | ||
} | ||
|
||
// otherwise this is a variable reference so evaluate it | ||
evaluatedURN, ok := run.EvaluateTemplate(a.Contact.URNMatch, logEvent) | ||
if !ok { | ||
return nil | ||
} | ||
|
||
// if we have a valid URN now, return it | ||
urn := urns.URN(evaluatedURN) | ||
if urn.Validate() == nil { | ||
return &flows.ContactReference{URNMatch: string(urn.Normalize())} | ||
} | ||
|
||
// otherwise try to parse as phone number | ||
parsedTel := utils.ParsePhoneNumber(evaluatedURN, run.Session().MergedEnvironment().DefaultCountry()) | ||
if parsedTel != "" { | ||
urn, _ := urns.New(urns.Phone, parsedTel) | ||
return &flows.ContactReference{URNMatch: string(urn.Normalize())} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters