Triggers and Payloads
System triggers can generate a payload that gets passed to action
and condition
blocks along with the global payload. When defining a call to an action/condition block in the Flow Nodes, developers specify how to map a parameter from the payload to a parameter passed to the block.
This document:
- Lists the available triggers along with the payload generated by each of them.
- Lists the global payload parameters.
- Explains how the payload is mapped to actions/conditions blocks parameters.
- Explains the usage of the special
result
parameter passed to each condition and action.
Triggers
USER_MESSAGE
Triggered when the user sends a chat message to one of the bots. This trigger must contain params
with a person
key. For example:
trigger:
type: user_message
params:
person: keen
flowNode:
...
Generated payload:
userMessageText
: the text the user wrote to the bot.
GITHUB_PUSH
Triggered when the user push something to their repository
Generated payload:
githubPushHeadCommit
: the body of the relevant commit that was pushed.
GITHUB_PR_LIFECYCLE_STATUS
Triggered when the status of a PR opened by the user is changed.
Generated payload:
eventType:
the status of the PR. Equal to one of the following:github_pr_opened:
PR opened by the usergithub_pr_workflow_complete_success:
All PR checks passed successfullygithub_pr_workflow_complete_failure:
One of the PR checks failedgithub_pr_merged:
User merged the PR
githubPrNumber:
PR numbergithubRepository:
The name of the repository in which the PR was openedgithubWorkflowRunUrl
: Defined wheneventType
is one ofgithub_pr_workflow_complete_success
orgithub_pr_workflow_complete_failure
. Holds a URL of the workflow run.
Here’s an example of how to run the Github Actions and approve it once it all run successfully. Pay attention there’s an action to finish the step only when they merge the PR (that’s possible because the user can merge the PR only when you approve the PR)
trigger:
type: github_pr_lifecycle_status
flowNode:
switch:
key: "${eventType}"
cases:
github_pr_opened:
do:
...
github_pr_workflow_complete_success:
do:
- actionId: github_pr_approve
...
github_pr_workflow_complete_failure:
- actionId: github_pr_reject
...
github_pr_merged:
do:
- actionId: finish_step
GITHUB_ISSUE_CREATED
Triggered when the user creates an issue on their repository.
GITHUB_BRANCH_CREATED
Triggered when the user creates a remote branch on their repository.
GITHUB_DISCUSSION_CREATED
Triggered when the user creates a discussion on their repository.
Generated payload:
githubDiscussionNumber
: the discussion number of the created discussion
An example:
trigger:
type: github_discussion_created
flowNode:
do:
- actionId: github_reply_to_discussion
params:
discussionNumber: "${githubDiscussionNumber}"
body: "Message body"
PING
Triggered when a ping event happens in the user’s Anythink repo. No specific payload.
CHAT_OPENED
Triggered when the user opens Snack. No specific payload.
LOCAL_PAGE_LOAD
Triggered when the user opens a page in the Anythink frontend.
Payload:
path:
The URL of the opened page.
GITHUB_USER_CONNECTED
Triggered when the user accepts the invitation to his Github repo. No specific payload
NEWRELIC_EVENT_RECEIVED
Triggered when an event is received from the user’s New Relic account.
CHAT_FORM_SUBMITTED
Triggers when a a user submit a form on Snack.
Payload:
formSubmission
: The data submitted by the user. The type is different between form types -single_select_form
- a single stringmulti_select_form
- a list of strings
Params:
formId
: Used to subscribe to the desired form.
Usage example (for single select form):
trigger:
type: chat_form_submitted
params:
formId: your_single_select_form_id
flowNode:
if:
conditions:
- conditionId: text_contains_strings
params:
text: "${formSubmission}"
strings:
- accept
then:
do:
- actionId: your action here
else:
do:
- actionId: a different action here
USER_EVENT
Triggered when there’s a custom event called on the user, you can trigger it by calling https://engine.wilco.gg/users/${WILCO_USER_ID}/event
. You can find the user id in the .wilco
file in the user’s repository. This trigger must contain params
with a event
key that matches the event prop in the payload of the event that you’re sending. Params:
event
: the event type, passed in the event payload
Payload:
eventMetadata
: the metadata in the event payload
For example:
trigger:
type: user_event
params:
event: test
flowNode:
... // You can now user ${eventMetadata} here
And the equivalent event:
curl -X POST https://engine.wilco.gg/users/${WILCO_USER_ID}/event -d '{"event":"test", "metadata": {"prop": "value"}}' -H 'Content-Type: application/json'
Global Payload
In addition to specific payload passed by each trigger, a global payload is always available:
user
: The Wilco user object. Contains the following fields (partial list):firstName
User’s first namelastName
User’s last nameemail
User’s email addressgithubuser:
User’s Github usernamerepository:
User’s Github repo urlrepoName:
Name of the user’s Github repocompany
: Name of the user’s companyK8sBackendUrl:
url of the K8s backend appK8sFrontendUrl:
url of the K8s frontend appnewrelic:
User’s New Relic account informationaccountId
New Relic account idapiKey
New Relic API key
frameworks:
The backend and frontend frameworks chosen by the userbackend:
One of node/rails/pythonfrontend:
Currently only reactdatabase:
One of mongodb/postgresql
Usage example:
actionId: github_pr_approve params: message: Nailed it! Excellent job @**${user.githubuser}**! You can now merge the PR.
-
bots:
Info about the bots. A map from bot id to bot details.Available ids are:
keen
lucca
information for each bot:
displayName:
name of the bot. E.g, Ness or Navi
Usage example:
actionId: bot_message params: person: lucca messages: - text: Hey ${user.firstName}, delay: 2000 - text: I'm **${bots['lucca'].displayName}**, the lucca team leader. delay: 1500 - text: "**${bots['keen'].displayName}** asked me to help you out. Just write here your *GitHub username* (without the \\`@\\`, so Messenger doesn’t freak out), and we'll add you as a contributor to the company's repository." delay: 3500
-
nextQuestUrl:
url for the next quest.Equal to:
${CONFIG.ENVIRONMENT.WILCO_APP_URL}/home
Mapping payload to block params
-
All payload (trigger + global) parameters are passed as is to each block. This way, no additional configuration in the YAML is required for trivial cases.
A good example is Github blocks which usually require a pr number or repo name:
const isFileInPRContains = async ({ user, githubPrNumber, fileName, regex, }) => { const file = await getAddedFile(user, githubPrNumber, [fileName]); return !!file?.patch?.match(RegExp(regex)); };
In this example,
user
andgithubPrNumber
are available in the condition parameters without any further configuration. Calling thegithub_does_file_contain
can be configured in the YAML file, for example, in the following way (onlyregex
andfileName
are defined):if: conditions: - conditionId: github_does_file_contain params: regex: license_key paramsFramework: node: fileName: backend/newrelic.js rails: fileName: backend/config/newrelic.yml python: fileName: backend/newrelic.ini then: ...
-
In many cases, it is required to map the payload parameter to the block parameter. Referencing payload parameters is done using
${<payload_param>}
. Two such cases can be:-
The name of the block parameter is different from its name in the payload
An example of such a case is checking if chat message matches a regex:
if: conditions: - conditionId: text_match_regex params: text: "${userMessageText}" regex: ".*localhost.*@" then:
In this example, the param
userMessageText
is passed to the condition astext
-
It is required to pass the payload parameter after some manipulation or as part of a more complex string (or both).
An example for such a case:
do: - actionId: bot_message params: person: keen messages: - text: Ooohh, I didn’t expect you to do this so quickly! Even your username, ${path.slice(2)}, brings back memories. Strangely enough, they’re your memories, which I don’t know why I have. delay: 2000
We embed
path
param from the payload to the text sent tokeen
bot. The param here is embedded after applyingslice(2)
on its value. -
Result parameter
In addition to the payload parameters, a result
parameter is passed to all conditions and actions. Each block can decide if to use it or not. The result
parameter is used to pass information from the block to the next blocks.
- The result is unique for each block and they are not shared, which means that a block can’t override or change the result object of other blocks.
-
The result will be stored only if
name
was set for the block. In that case, the result of a block namedsome_name
will be stored in the global payload inpayload.outputs[some_name]
. If name is missing, the result won’t be stored and won’t be used.A more specific example:
conditions: - conditionId: k8s_backend_config_var_defined name: new_relic_license_key_config params: key: NEW_RELIC_LICENSE_KEY then: ...
In this example, we call an action with the id
k8s_backend_config_var_defined
and give it a name,new_relic_license_key_config.
This condition checks that a config var exists and sets its value on the result if it does.{ "value": "config_var_val" }
Then, the config var value can be used in next blocks. Foe example:
if: conditions: - conditionId: newrelic_license_key_valid params: licenseKey: '${outputs.new_relic_license_key_config.value}' then: ...
The config var is used as input to the
newrelic_license_key_valid
condition which checks that the value is a valid New-Relic license key.
A default result is initialized for all conditions and actions.
-
For actions, the result is initialized to:
{ "success": true "error": null }
-
For conditions, the result is initialized to:
{ "error": null }
There’s no need for
success
as conditions always return true/false andsuccess
is set according to the result. Meaning,output.condition_name
will containsuccess
as well.