Powerful automation engine.
MIT License
A Flarum extension.
The idea is simple: When X, if Y, do Z.
Let's define some key terms:
Code-wise, these are represented by "Drivers", implementing one of TriggerDriverInterface
, MetricDriverInterface
, etc.
Requirement and Action drivers take a list of "settings", which they specify validation rules for. This means you can build a UserEmailMatchesRegex : RequirementDriverInterface
, or a AddUserToGroup : ActionDriverInterface
, and then create multiple instances of the drivers with any regex or group ID.
All these are tied together by Rules. Rules are stored as [A DATABASE TABLE OR A SETTING, IDK], and specify:
Trigger drivers specify a list of "subject models", e.g. the author and post in a post created event. These determine which metrics, requirements, and actions are available when defining a rule for some trigger, since "running" a metric, requirement, or action always requires some subject (e.g. which user are we calculating num likes received for, which post are we auto-flagging, etc)
Whenever any event that has rules attached via triggers runs, we "evaluate" all valid rules, and if all the rule's metrics and requirements are satisfied, the rule's actions will run.
A rule is invalid if (1) it has requirements or actions where settings don't pass validation, (2) any of it's components depend on an extension that isn't currently enabled, or (3) any of it's components reference drivers that don't currently exist.
This makes for an extremely powerful extension. Since extensions can add their own metrics, requirements, and actions, this extension can automate away a lot of moderation. Beyond the examples listed below, some things that could be possible are:
Because this system is so generic, we can separate testing the framework for (validating, evaluating, running) rules, from each of the drivers.
Testing drivers is super easy, which makes it cheap and easy to add any drivers we want. See this extension's test suite for examples.
Rule
as JSON, so that rules could be easily shared between forums?
Rule
class, including the core validation and evaluation logic for rules
Any metric driver could be implemented as a requirement driver, since requirements are more powerful. But if your requirements are about numerical conditions, metric drivers are better because:
Criteria: Users that receive 50 or more likes and have started at least 10 discussions should placed in the "Active" group.
Here, the metrics are "received 50 or more likes" and "have started at least 10 discussions". Unsurprisingly, they come with the triggers (PostWasLiked
, PostWasUnliked
) and (Discussion\Started
) respectively.
The actions are:
Criteria: If a user gets 15 warnings or more and is not an admin, suspend them.
Here, the metrics are "gets 15 warnings or more" and the requirements are "is not an admin". The triggers would be a new warning for the metric. The requirement has no triggers.
The actions are:
Criteria: If a user's email matches a regex, activate their email.
The requirement is "a user's email matches a regex". The triggers are saving a user.
The actions are:
Criteria: Add a user to a group
There are no metrics or requirements, so this will be applied to all users on login.
The actions are:
This extension is extremely flexible. It can be considered a framework for automoderation actions.
Extensions can use the Askvortsov\AutoModerator\Extend\AutoModerator
extender to add:
You should look at the source code of the default drivers for examples. They're fairly exhaustive of what's offered.
If your extension adds action or requirement drivers that consume settings, you have 2 options:
availableSettings
method. This is very easy, but also very restrictive. You can only use strings, and can't add any restrictions or UI.js/src/admin/components/SuspendSelector
for an example. The component should take a settings stream as this.attrs.settings
. The contents of the stream should be an object that maps setting keys to values. The component is responsible for updating the stream on input. You can register a form component by adding its class to app.autoModeratorForms[DRIVER CATEGORY][TYPE]
, where DRIVER CATEGORY
is "action"
or "requirement"
, and TYPE
is the type string you registered your driver with in extend.php
. See js/src/admin/index.js
for the underlying data structure and examples.Contributions and PRs are welcome! Any PRs adding new drivers should come with unit tests (like with all existing drivers).
Compatible starting with Flarum 1.0.
composer require askvortsov/flarum-automod:*
composer update askvortsov/flarum-automod