(effect)= # Effects An effect is an account that produces some sort of action as a result of a message from a {ref}`cause `. (effect_config)= ## Configuration The {ref}`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 {ref}`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. (effect_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 pattern - it 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 `__foo` would match against the `_foo` field 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_id` match (see below) at least once, which will match the event ID of the current message. `_refs` is 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 `. - `_event_id`: must be in a sub-pattern under a `_refs` array, and matches the event ID of the parent message. Its behaviour is undefined if it is not under a `_refs` array. The field's is ignored, but is usually `1` by convention. - `_any`: matches any value. The field's is ignored, but is usually `1` by 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 same `name`, 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 `_refs` and not in the main event. #### Examples The pattern ```{code-block} json --- caption: 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 ```{code-block} json --- caption: "message from `@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: ```{code-block} json --- caption: pattern --- { "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."