Effects¶
An effect is an account that produces some sort of action as a result of a message from a cause.
Configuration¶
The configuration for an effect will have an actions field
whose value will be an array of objects. Each object in this array will have
an on field whose value will be a pattern, as well as
any other parameters that are needed to define what action the effect will take
when it encounters a message that matches the pattern.
Patterns¶
Patterns are used to match the messages that an effect should act on. A pattern matches a value depending on what the pattern is:
it is a string, integer, boolean, or
null, and the value is equal to the patternit is an array, and the value is an array of the same size, where each element in the pattern is another pattern that recursively matches the corresponding element in the value
it is an object where for all of the pattern’s fields:
if the field’s name does not start with an underscore, it is a pattern that recursively matches the corresponding field in the value.
if the field’s name starts with a double-underscore (
__), it is a pattern that recursively matches the field in the value with the same name, but with one underscore removed. For example, a pattern with a field of__foowould match against the_foofield in the value.if the field’s name begins with a single underscore, then the pattern matches depending on the field name:
_refs: then the field’s value is a list of patterns that match messages that references the current message. Each of the sub-patterns must contain an_event_idmatch (see below) at least once, which will match the event ID of the current message._refsis only valid in the top-level pattern (implemetations may support nested_refs, but are not required to do so), and matches the current message only if all of the sub-patterns match some messages. This allows effects to limit which messages from causes will trigger actions using :ref:filters <filter>._event_id: must be in a sub-pattern under a_refsarray, and matches the event ID of the parent message. Its behaviour is undefined if it is not under a_refsarray. The field’s is ignored, but is usually1by convention._any: matches any value. The field’s is ignored, but is usually1by convention._or: is an array of sub-patterns. The pattern matches if any of the sub-patterns matches._and: is an array of sub-patterns. The pattern matches if all of the sub-patterns match._not: matches if the value does not match the field’s value._regexp: matches if the value matches the regular expression given in the field’s value. Effects should use a Perl-compatible dialect of regular expressions._contains: matches if the value is an array that contains an element that matches the field’s value._<: matches if the value is less than the field’s value. Works if both values are numbers or both are strings. (Similarly for_>,_<=, and_>=.)_lt_n: matches if the value is less than the field’s value. Both values can be numbers or strings; if a value is a string, then it is parsed as a number. (Similarly for_gt_n,_lte_n,_gte_n, and_eq_n.)_capture: matches any value, and remembers the value using the name given. The effect may expose the captures for use in the configuration of the action. If multiple patterns use the samename, then the values must be the same. For example, the pattern[{"_capture": "x"}, {"_capture": "x"}]will match[1,1], but not[1,2]. Names beginning with two underscores are reserved and must not be used. Captures with the same name may be used in for matching in the main event and in_refs, but behaviour is undefined when using captures with the same name that only appears in different_refsand not in the main event.
Examples¶
The pattern
{
"sender": "@vcs:example.org",
"content": {
"ca.uhoreg.merovingian.vcs.commit": {
"branch": "main"
}
},
"_refs": [
{
"type": "m.reaction",
"sender": "@lint:example.org",
"content": {
"m.relationship": {
"rel_type": "m.annotation",
"event_id": {"_event_id": 1},
"key": "👍"
}
}
},
{
"type": "m.reaction",
"sender": "@test:example.org",
"content": {
"m.relationship": {
"rel_type": "m.annotation",
"event_id": {"_event_id": 1},
"key": "👍"
}
}
}
]
}
would match a message sent by @vcs:example.org with contents
@vcs:example.org¶{
"body": "Alice pushed commit abcdefg",
"msgtype": "m.notice",
"ca.uhoreg.merovingian.vcs.commit": {
"branch": "main",
"id": "abcdefg",
"author": "Alice",
"timestamp": 1234567890
}
}
if that message received a 👍 reaction from both @lint:example.org and
@test:example.org.
Interpreting events¶
Once an event has been matched, the effect performs an action based on the
event. FIXME: fix this paragraph. If the effect allows the user to control
the action using the configuration, and allows the user to select which part of
the message to use, then the effect should accept a string that indicates the
path within the object using “.” or “[...]” to indicate sub-fields. If
a field name includes a “.”, then it must be accessed using “[...]”.
Array elements are addressed using a zero-based index within the array. If the
property value is intended to be interpolated into a string, the path should be
enclosed by “{{...}}”.
For example, if we have an effect that can be configured to send an arbitrary message to the room by allowing the user to specify a message template, and we want it to send a message informing a user that their build passed, then we might action configuration:
{
"on": {
"_comment": "the pattern above"
},
"message":
"{{event.content[\"ca.uhoreg.merovingian.vcs.commit\"].author.name}}: your commit
({{event.content.[\"ca.uhoreg.merovingian.vcs.commit\"].id}}) was successfully built."
}
Given the above message, the effect would send a message that reads: “Alice: your commit (abcdefg) was successfully built.”