View Source Runbox.Scenario.UserAction (runbox v19.0.0)
Toolbox for working with scenario user actions.
User action is action created by scenario and fired by user (usually from UI). Scenario is usually also a receiver of fired action. Assumed workflow is following:
Scenario creates actions to be fired in the future and Altworx stores them.
UI displays available actions.
User fires selected action from UI.
UI pushes the action to raw Kafka topic (defined in action) with extra data attached (usually empty).
Normalizer pipeline receives the action and sends it to target scenario via a runtime topic.
Currently, user actions can be attached only to incidents. This can be done either
via the user_actions
field of Runbox.Scenario.OutputAction.Incident
and
Runbox.Scenario.OutputAction.IncidentPatch
or using Toolbox.Workflow
.
Normalized user actions
Fired output actions are normalized into a %Runbox.Message{}
with
%Runbox.Scenario.UserAction{}
in its body. For example:
%Runbox.Message{
from: "N6_rt_camera_user_actions",
type: "close_incident",
timestamp: 1750857766412,
body: %Runbox.Scenario.UserAction{
type: "close_incident",
details: %{
"submit_text" => "Close the incident",
"type" => "button"
"incident_id" => "6157565f-8c9e-3e66-a5f6-2c4d6211a9c1",
},
user: "joe",
data: %{}
},
origin: %{offset: 2, partition: 0, topic: "camera_user_actions"}
}
Summary
Functions
Unpacks the action and fetches access tags associated with it.
Unpacks action and makes it fired (prepared for sending to target topic).
Helper for UserAction forwarding to be used in normalizer.
Packs user action to JWT to be used (fired) later (from UI for example).
Parses string containing JSON to Runbox.Scenario.UserAction
.
Types
@type t() :: %Runbox.Scenario.UserAction{ data: any(), details: map(), type: String.t(), user: String.t() }
Fired user action.
When action is fired by the user, it should be pushed to raw topic
with current
timestamp to be correctly reordered by Normalizer
. Properties type
and details
should contain enough information for routing action to the target scenario. Property
user
is ID of user who fired the action, data
contains extra information attached
by environment where user fired the action (for example comment filled by the user on UI).
Functions
@spec fetch_access_tags(Joken.bearer_token()) :: {:ok, [String.t()]} | {:error, Joken.error_reason()}
Unpacks the action and fetches access tags associated with it.
Returns error if packed action (JWT) is not valid.
@spec fire(Joken.bearer_token(), String.t(), any()) :: {:ok, topic :: String.t(), String.t()} | {:error, Joken.error_reason()}
Unpacks action and makes it fired (prepared for sending to target topic).
Routing properties (type
, details
) are propagated from packed action, user
and data
properties are attached to fired action. Target topic
is also extracted from packed action.
Returns error if packed action (JWT) is not valid.
@spec normalizer_pipeline_step(Runbox.Message.t()) :: Runbox.Message.t()
Helper for UserAction forwarding to be used in normalizer.
If helper is used in normalizer pipeline configuration in config.ini
like
[pipelines.some_pipeline]
definition = Runbox.Scenario.UserAction.normalizer_pipeline_step
then Runbox.Message
body
will contain fired Runbox.Scenario.UserAction
.
@spec pack(String.t(), String.t(), map(), [{:access_tags, [String.t()]}]) :: {:ok, Joken.bearer_token()} | {:error, Joken.error_reason()}
Packs user action to JWT to be used (fired) later (from UI for example).
Parameter details
must be a map encodable to JSON. Because details
can be (and it is!)
encoded/decoded to/from JSON during its life-cycle, atom keys in details
are always converted
to string keys in fired action's details
.
details
must contain "type"
which is currently always "button"
and submit_text
which will be used as the user-facing label for the button. Other fields are up to you.
Optionally, access_tags
can be given inside opts
to control access to the action.
A user must have all of the specified access tags to be able to fire the action.
If access tags are not given, the default []
is used, which means that anyone can
fire the action.
Example
UserAction.pack("camera_user_actions", "close_incident", %{
"type" => "button",
"submit_text" => "Close the incident",
"incident_id" => "6157565f-8c9e-3e66-a5f6-2c4d6211a9c1"
}, access_tags: ["camera", "privileged"])
Parses string containing JSON to Runbox.Scenario.UserAction
.