Note: the following is not directly relevant to saidit, it is present for educational purposes. Source:

Converting to the new version

Disclaimer: This page is a brief description of how to manually convert your subreddit from using the old, external version of the bot to the new, built-into-reddit version. You do not need to do this, your subreddit will be converted automatically eventually without any work necessary. This page is intended only for people that are very confident writing AutoModerator rules already, and want to do the conversion themselves immediately.

Information about what has changed

The information below is intended for people already very familiar with writing AutoModerator rules and does not go into depth on much in particular, only brief explanations of what needs to be changed as part of converting. For more in-depth information, check the full documentation page.

General new changes

  • The new version uses the standard Python regular expressions library, instead of the "re2" library used by the old version. This means that some things that were unavailable in re2 like positive/negative look-behind and look-ahead are now available. However, re2 also supported checking for unicode character categories with \p{something}, and this is not supported by the Python regex library. So any rules using \p{ } type regex checks will not work.
  • The new version will also re-check things when they are edited, so you may see some comments or self-posts get acted on at a later time, if they're edited in a way that ends up triggering a condition. You can prevent re-checking on edit (so they will only be checked when first posted) by adding is_edited: false to any rule.
  • The new version will check things immediately when they are reported (old version checks reports every 5 minutes). Also, items of any age will now be checked when they're reported, whereas the previous version only looked at reported items from the last 24 hours.
  • The new version does not have the previous standard conditions for gawker network sites or gaming referral links. If you were using either of those standards and want to keep using it in the new version, copy the definition (and switch to the new modifiers syntax for gaming referral sites) from

Syntax changes


Modifiers are now part of the "name" of the check, in parentheses. For example, a rule that was previously written as:

url: '\.(jpe?g|png|gif)'
modifiers: [ends-with, regex]
action: remove

Must now be written:

url (ends-with, regex): '\.(jpe?g|png|gif)'
action: remove

In addition, the inverse modifier has been completely removed. To do an inverse check, it is now required to use the previously-optional syntax of starting the check name with a ~. So title: means "title must match", whereas ~title: is "title must NOT match".

General check changes

type: both is now type: any. There are also two new options for type:. In addition to type: comment and type: submission, you can now also use type: link submission and type: text submission, so you no longer need to check domain to see if something is or is not a self-post.

The user: check against username should now be done with author: Note that if you are doing anything except a simple "username must be one of" or "username must not be one of" (author: and ~author: respectively) check, you must do it as a name: check inside the author: group. Also, if you have any other checks against the author in addition to the name (karma, age, submitter/moderator/contributor), you must check the name inside the author group as well. So for example, if you are checking against specific usernames, you can write it as:

author: [trolly, trollerson, trolltastic]
action: remove

But if you even want to do a "starts with" check, you must write it as:

    name (starts-with): "troll"
action: remove

See the "Sub-checks / groups" section below for more info about the author: group.

body_max_length and body_min_length have been renamed to body_shorter_than and body_longer_than respectively. This should be more intuitive.

is_reply has been replaced with is_top_level (so it should have the opposite value of is_reply).

The author_is_submitter check is now is_submitter inside the author group (see "Sub-checks / groups" below).

General action changes

Setting flair is now done with the set_flair: directive, instead of separate lines for setting text and class. You can set this to either a string, or a list of two strings. A single string will set the flair text, or two strings will be used as the text and the class in that order. So a rule that was previously written as:

title: "[Announcement]"
link_flair_text: "Official Announcement"
link_flair_class: "announcement"

is now:

title: "[Announcement]"
set_flair: ["Official Announcement", "announcement"]

In addition, the automatic lowercase conversion of flair classes will no longer happen, the class will be set with exactly the same casing as defined in the rule.

To set user flair instead of link flair, use set_flair inside the author: group (see the section below about sub-checks).

The set_options action is now gone, replaced with individual lines for set_nsfw, set_contest_mode, and set_sticky. These can all take true or false values to set or unset the respective option on the link.

Sub-checks/actions or "groups"

Some checks and actions can now be "grouped" based on which item they are being applied to. So instead of having lots of confusing things with slightly different names like author_flair_text all valid in the base item to check against the item's author's flair, that is instead grouped into the author: check and always uses the same check named flair_text to check against something's flair text. For example, a rule like this would be applied to a comment, and checks against both the flair text of its parent link, as well as the flair text of the comment's author:

type: comment
    flair_text: "Restricted"
    ~flair_text: "Approved"
action: remove

author and parent_submission are the two currently available groups.

Note that it is also now possible to perform actions on a comment's parent submission now, because of this. For example, this rule will remove any submission if a user with the "trusted" flair class comments in it saying that it's a repost:

type: comment
body: "repost"
    flair_css_class: "trusted"
    action: remove
modmail: The above submission was removed because {{author}} said it was a repost.


user_conditions no longer exists, these checks are now a part of the author: group. You can still check against comment_karma, link_karma, combined_karma, and account_age the same as previously, with the enhancement that account_age now allows you to specify a time period (but it still defaults to days if you don't). So for example, you can now do a check like:

    account_age: < 6 hours
action: remove

Valid time periods are minutes, hours, days, weeks, months, and years.

the rank: check is gone, you can now use is_moderator: or is_contributor: instead, which should be set to true or false.

must_satisfy: any and must_satisfy: all are now satisfy_any_threshold:, which should be set to true if you want the condition to trigger if only one threshold is met (so satisfy_any_threshold: true is the same as old must_satisfy: any.


As with the name of the check, the {{user}} placeholder is now {{author}}, and {{media_user}} is now {{media_author}}.

You can now specify a particular check to take {{match-x}} replacements from. For example, if you have a rule like this:

title: [red, blue, yellow]
domain: [,]
modmail: The above post has {{match-1}} in its title.

Previously this would not have been reliable. {{match-1}} may have been substituted with either the title or the domain, so the {{match-x}} replacements could not really be used in any rule that contained multiple checks. Now, you are (optionally) able to include the name of the check you want to take the match from specifically, so in this case it would be {{match-title-1}}.

In addition, it is now no longer required to specify the match number if you want the "main" match (number 1). You can use placeholders like {{match}} or {{match-title}} instead, which would be behave exactly the same as {{match-1}} and {{match-title-1}} respectively.

revision by [deleted]— view source