Subreddit Configuration
High level overviews, important features of, and example usage for significant components in a subreddit’s configuration are found here.
This list is not exhaustive. For complete documentation on a subreddit’s configuration consult the schema.
Table of Contents
- Runs
- Checks
- Rules
- Rule Sets
- Actions
- Filters
- Common Patterns
- Subreddit-Level Configuration
- Best Practices
- Subreddit-ready examples
Runs
A Run is made up of a set of Checks that represent a group of related behaviors the bot should check for or perform. Checks within a Run are processed in the order they are listed. Refer to the How It Works section to see how Runs fit into CM’s lifecycle.
Runs are the largest unit of behavior in a subreddit’s configuration and are defined at the top level of the configuration like so:
runs:
# the first run of the config
- name: MyFirstRun
checks:
...
- name: MySecondRun
checks:
...
An example of Runs:
- A group of Checks that look for missing flairs on a user or a new submission and flair accordingly
- A group of Checks that detect spam or self-promotion and then remove those activities
Both group of Checks are independent of each other (don’t have any patterns or actions in common).
However, Checks processed prior to a Run can determine if a Run is processed or not depending on the flow control configured in those Checks.
Flow Control Defaults Using Runs
Checks in a Run that do not specify their own Flow Control can have their defaults configured at the Run level:
runs:
- name: MyFirstRun
postFail: nextRun
postTrigger: next
checks:
...
Runs may also have these flow control defaults specified at the subreddit or bot level.
Filter Defaults Using Runs
Checks in a Run may have their Filters merged or replaced by run-level filter defaults:
runs:
- name: MyFirstRun
filterCriteriaDefaults:
authorIs:
- isMod: false
Runs may also have these filter behavior defaults specified at the subreddit or bot level.
Checks
A Check is a set of:
- Zero or more Rules that define what conditions should trigger this Check.
- Zero or more Actions that define what the bot should do once the Check is triggered.
Refer to the How It Works section to see how Checks fit into CM’s lifecycle.
- If a Check has no Rules and passes any Filters it is automatically triggered
- If a Check is triggered and has no Actions it is only recorded
- Checks must have explicitly defined:
- name
- kind – what type of Activity (
submission
orcomment
) it should process
runs:
- name: MyFirstRun
checks:
# a minimal check
- name: MyMinimalCheck
kind: submission
# a normal check
- name: MyNormalCheck
kind: submission
rules:
...
actions:
...
# a kitchen-sink check
- name: KitchenSink
kind: submission
description: A friendly description
itemIs:
- approved: false
authorIs:
- verified: true
rules:
...
actions:
...
postTrigger: stop
postFail: next
Testing Rules
The Rules specified in a Check are processed in the order they were written in.
A Check determines when it has been triggered by setting a condition
to evaluate Rules and Rule Sets with. When this condition is:
AND
– all Rules in the Check must be triggered for the Check to be triggeredOR
– any Rule in the Check that is triggered will trigger the Check
- name: MyCheck
kind: submission
condition: AND # Rule1 AND Rule2 must be triggered to trigger MyCheck
rules:
- name: Rule1
...
- name: Rule2
...
- name: MyCheck
kind: submission
condition: OR # Rule1 OR Rule2 must both be triggered to trigger MyCheck
rules:
- name: Rule1
...
- name: Rule2
...
Specifying Flow Control
When a Check is finished processing it can have one of two states: triggered or not triggered. The behavior of CM after a Check is finished processing 1) depends on what state the Check is in and 2) is dictated by the Check itself using a property for each type of state:
postFail
– for not triggeredpostTrigger
– for triggered
This enables a user to arbitrarily configure how CM responds to the triggering (or not triggering) of a Check.
Each Check will always have these properties defined – either explicitly or passed down as defaults from a Run, Subreddit, or Operator configuration.
Refer to the main Flow Control documentation for an in-depth explanation and all possible options.
Recording Options
postFail
and postTrigger
also enable specifying if/how an Event is recorded. Valid options for recording:
false
– do not record this Eventtrue
– record Event to all available outputsdatabase
– record Event to the databaseinflux
– record Event to InfluxDB (not implemented)list of: database, influx
– a list of outputs to record to
The default recording options for flow control properties are:
postFail
–false
(do not record)postTrigger
–true
(record to all)
Recording options can be explicitly defined by providing a PostBehaviorOptionConfig object to one/both of the flow control properties EX:
- name: MyCheck
kind: submission
postTrigger:
recordTo: database
postFail:
recordTo: false
When an Activity has finished being processed CM will aggregate all Recording Options and output to all specified. Any “positive” outputs override a false
output IE to prevent an Event from being recorded all recordTo
values must be false
.
recordTo
values can also be specified in flow control defaults for a Run, Subreddit, or Operator configuration.
Rules
A Rule is some set of criteria (conditions) that are tested against an Activity, a User, or a User’s history. A Rule is considered triggered when the criteria for that rule are found to be true for whatever is being tested against.
Rules must have a kind
that identifies what kind of Rule they are.
Optionally, they may have Filters.
Named Rules
Rules may be given a name
. If a Rule is named it can re-used anywhere in the configuration regardless of location. This is done by:
- specifying a name on a Rule once EX:
name: MyNamedRule
- using the Rule’s name in place of a Rule object in your Checks or Rule Sets.
runs:
- name: MyFirstRun
checks:
- name: MyFirstCheck
kind: submission
rules:
- name: AnonymousRule1
kind: regex
...
# use the name of the Rule instead of writing an entire Rule object
- NamedRule1
- name: AnonymousRule2
kind: recent
...
actions:
...
- name: MySecondCheck
kind: submission
rules:
# named rule
- name: NamedRule1
kind: history
...
Named Rules are essential building blocks of a readable and effective configuration. If you find yourself repeating the same Rule many times it’s a sign you should give it a name and replace it’s usage with references to it.
List of Rules
Attribution
The Attribution rule will aggregate an Author’s content Attributions (youtube channels, twitter, website domains, etc.) and can check on their totals or percentages of all Activities over a time period:
- Total # of attributions
- As percentage of all Activity or only Submissions
- Look at all domains or only media (youtube, vimeo, etc.)
- Include self posts (by reddit domain) or not
Recent Activity
Given a list subreddit criteria, the Recent Activity rule finds Activities matching those criteria in the Author’s history over window and then allows for comparing different facets of the results:
- number of activities found
- aggregated karma from activities
- number of distinct subreddits found
The above can also be expressed as a percentage of all activities found, instead of number.
The search can also be modified in a number of ways:
- Filter found activities using an Item Filter
- Only return activities that match the Activity from the Event being processed
- Using image detection (pixel or perceptual hash matching)
- Only return certain types of activities (only submission or only comments)
Repeat Activity
The Repeat Activity rule will check for patterns of repetition in an Author’s Activity history over a window. When comparing submissions it checks a composite of the submissions’ title and content.
To determine sameness it uses an average of Dice’s Coefficient, Cosine Similarity, and Levenshtein Distance weighted by the length of the content being compared (more weight for longer content).
Some of the ways the rule can be modified:
- Only return repeated activities that match the Activity from the Event being processed
- Specify the sameness percentage used to classify a repeat (default must be 85% similar)
- Include/exclude activities from a list of subreddit criteria
- Specify gap size allowed between non-repeats
History
The History rule can check an Author’s submission/comment statistics over a time period:
- Submission total or percentage of All Activity
- Comment total or percentage of all Activity
- Comments made as OP (commented in their own Submission) total or percentage of all Comments
Author
The Author rule behaves the same as the Author Filter. It can be used when you want to test Author state alongside other rules to create more complex behavior than would be possible by only applying to individual Rules or an entire check.
Regex
The Regex rule matches on text content from an Activity in the same way automod uses regex. However, it can also be used to match on content from the Author’s Activity history over a window.
Repost
The Repost rule is used to find reposts for both Submissions and Comments, depending on what type of Check it is used on.
This rule is for searching all of Reddit for reposts, as opposed to just the history of the Author of the Activity being checked. If you only want to check for reposts by the Author of the Activity being checked you should use the Repeat Activity rule.
Sentiment Analysis
The Sentiment Rule is used to determine the overall emotional intent (negative, neutral, positive) of a Submission or Comment by analyzing the actual text content of the Activity.
ModerateHateSpeech.com Predictions
ContextMod integrates with moderatehatespeech.com (MHS) toxic content machine learning model through their API. This rule sends an Activity’s content (title or body) to MHS which returns a prediction on whether the content is toxic and actionable by a moderator. Their model is specifically trained for reddit content.
Rule Sets
The rules
list on a Check
can contain both Rule
objects and RuleSet
objects.
A Rule Set is a “nested” set of Rule
objects with a condition
specified. These allow you to create more complex trigger behavior by combining multiple rules that a Check only sees as “one” Rule to use with its condition.
runs:
- name: MyFirstRun
checks:
- name: ComplexCheck
kind: submission
# all "top level" rules must be triggered
# -- TopLevelRule1 AND TopLevelRule2 and the Rule Set
condition: AND
rules:
- name: TopLevelRule1
kind: regex
...
- name: TopLevelRule2
kind: history
...
# a Rule Set
- condition: OR # if any Rule in this Rule Set is triggered the Check sees the Rule Set as "triggered"
rules:
- name: NestedRule1
kind: recent
...
- name: NestedRule2
kind: recent
...
Actions
An Action is some action the bot can take against the checked Activity (comment/submission) or Author of the Activity as well as some “meta” actions used for controlling how CM handles Events.
CM has Actions for most things a normal reddit user or moderator can do.
Actions are performed in the order they are listed in the Check.
Named Actions
Named Actions work the same as Named Rules and Named Filters:
Actions may be given a name
. If an Action is named it can re-used anywhere in the configuration regardless of location. This is done by:
- specifying a name on an Action once EX:
name: MyNamedAction
- using the Action’s name in place of a Action object in your Checks
runs:
- name: MyFirstRun
checks:
- name: MyFirstCheck
kind: submission
rules:
...
actions:
- kind: remove
- MyNamedAction # use the name of the Action instead of writing an entire Action object
- name: MySecondCheck
kind: submission
rules:
...
actions:
- name: MyNamedAction
kind: comment
content: 'This is a test comment the bot will make'
Templating
Actions that can submit text (Report, Comment, UserNote) will have their content
values run through a Mustache Template. This means you can insert data generated by Rules into your text before the Action is performed.
Action Templating Documentation
List of Actions
Approve
Approve an Activity. Schema Documentation
Optionally, may specify a list of targets to approve:
self
– approve Activity being processedparent
– if Activity being processed is a Comment then approve the Submission it comes from
actions:
- kind: approve
target: ['self'] # or both with ['self', 'parent']
Ban
Ban the Author of the Activity being processed. Schema Documentation
message
can be templated and use URL Tokens
actions:
- kind: ban
message: string # required, the ban message the user receives
note: string # mod note
reason: string # reason shown for ban
# number of days to ban user. Min 1 Max 999
#
# leaving 'duration' unspecified will ban user permanently
duration: number
Comment
Reply to an Activity with a comment. Schema Documentation
- If the Activity is a Submission the comment is a top-level reply
- If the Activity is a Comment the comment is a child reply
Templating
content
can be templated and use URL Tokens
Targets
Optionally, specify the Activity CM should reply to. When not specified CM replies to the Activity being processed using self
Valid values: self
, parent
, or a Reddit permalink.
self
and parent
are special targets that are relative to the Activity being processed:
- When the Activity being processed is a Submission =>
parent
logs a warning and does nothing - When the Activity being processed is a Comment
self
=> reply to Commentparent
=> make a top-level Comment in the Submission the Comment belong to
If target is not self/parent then CM assumes the value is a reddit permalink and will attempt to make a Comment to that Activity
actions:
- kind: comment
content: string # required, the content of the comment
distinguish: boolean # distinguish as a mod
sticky: boolean # sticky comment
lock: boolean # lock the comment after creation
targets: string # 'self' or 'parent' or 'https://reddit.com/r/someSubreddit/21nfdi....'
Comment As Subreddit
ContextMod can comment as the subreddit using the /u/subreddit-ModTeam
account with some restrictions:
- The activity being replied to must ALREADY BE REMOVED.
- You can use the Remove Action beforehand to ensure this is the case.
- The created comment will always be stickied and distinguished
Usage:
actions:
- kind: comment
asModTeam: true
content: string # required, the content of the comment
lock: boolean # lock the comment after creation
targets: string # 'self' or 'parent' or 'https://reddit.com/r/someSubreddit/21nfdi....'
Submission
Create a Submission Schema Documentation
The Submission type, Link or Self-Post, is determined based on the presence of url
in the action’s configuration.
actions:
- kind: submission
title: string # required, the title of the submission. can be templated.
content: string # the body of the submission. can be templated
url: string # if specified the submission will be a Link Submission. can be templated
distinguish: boolean # distinguish as a mod
sticky: boolean # sticky comment
lock: boolean # lock the comment after creation
nsfw: boolean # mark submission as NSFW
spoiler: boolean # mark submission as a spoiler
flairId: string # flair template id for submission
flairText: string # flair text for submission
targets: string # 'self' or a subreddit name IE mealtimevideos
Templating
content
,url
, and title
can be templated and use URL Tokens
TIP: To create a Link Submission pointing to the Activity currently being processed use
actions:
- kind: submission
url:
# ...
Targets
Optionally, specify the Subreddit the Submission should be made in. When not specified CM uses self
Valid values: self
or Subreddit Name
self
=> (Default) Create Submission in the same Subreddit of the Activity being processed- Subreddit Name => Create Submission in given subreddit IE
mealtimevideos
- Your bot must be able to access and be able to post in the given subreddit
Example:
actions:
- kind: comment
targets: mealtimevideos
To post to multiple subreddits use a list:
actions:
- kind: comment
targets:
- self
- mealtimevideos
- anotherSubreddit
Contributor
Add or Remove the Author of the Activity being processed as an Approved Contributor to the subreddit. Schema Documentation
actions:
- kind: comment
action: 'add or remove' # required, add or remove contributor
Dispatch
Create a new Event, from the currently processing Activity or its Parent, for CM to process. Schema Documentation
Optionally, may specify a list of targets to dispatch:
self
– create new Event from Activity being processedparent
– if Activity being processed is a Comment then create a new Event from the Submission it comes from
Additionally, may specify a duration of time to delay processing by.
actions:
- kind: dispatch
target: ['self']
delay: '10 minutes'
identifier: 'myDispatch'
TODO in-depth documentation on dispatch
Cancel Dispatch
Cancel a Dispatch Action that has been delayed using:
- the target of the action (
self
orparent
) AND/OR - an identifier used for the initial Dispatch Action
actions:
- kind: cancelDispatch
target: ['self']
identifier: 'myDispatch'
Flair
User Flair
Set the flair for the Author of the Activity being processed. Schema Documentation
actions:
- kind: userflair
flair_template_id: string # optional, flair template to use. Will override all other properties
css: string # optional, css value to use
text: string # optional, css class name to use
If the userflair
action is used but no properties are specified then the action removes any user flair.
Submission Flair
Set the flair for the Submission being processed Schema Documentation
actions:
- kind: flair
flair_template_id: string # optional, flair template to use. Will override all other properties
css: string # optional, css value to use
text: string # optional, css class name to use
If the flair
action is used but no properties are specified then the action removes any submission flair.
Lock
Lock the Activity being processed. Schema Documentation
actions:
- kind: lock
Message
Send a private message. Schema Documentation
Must specify these properties:
asSubreddit: boolean
– send the message as the subreddit or notcontent: string
– the content of the message to send
Some other things to note:
- If the
to
property is not specified then the message is sent to the Author of the Activity being processedto
may be a User (u/aUser) or a Subreddit (r/aSubreddit)to
cannot be a Subreddit whenasSubreddit: true
– IE cannot send subreddit-to-subreddit messages- TIP:
to
can be templated – to send a message to the subreddit the Activity being processed is in use'r/'
content
andtitle
can be templated and use URL Tokens
actions:
- kind: message
asSubreddit: true
content: 'A message sent as the subreddit' # can be templated
title: 'Title of the message' # can be templated
to: 'u/aUser' # do not specify 'to' in order default to sending to Author of Activity being processed. Can also be templated
Remove
Remove the Activity being processed. Schema Documentation
If neither note nor reasonId are included then no removal reason is added.
actions:
- kind: remove
spam: false # optional, mark as spam on removal
note: 'a moderator-readable note' # optional, a note only visible to moderators (new reddit only)
reasonId: '2n0f4674-365e-46d2-8fc7-a337d85d5340' # optional, the ID of a removal reason to add to the removal action (new reddit only)
Report
Report the Activity being processed. Schema Documentation
content
is required. It can be templated and use URL Tokens
actions:
- kind: report
content: 'This is what will show up in the report'
UserNote
Add a Toolbox User Note to the Author of the Activity. Schema Documentation
Your subreddit must have Toolbox UserNotes enabled for this action to work.
type
is requiredcontent
can be templated and use URL Tokens
actions:
- kind: usernote
type: spamwarn
content: 'Usernote message'
existingNoteCheck: boolean # if true (default) then the usernote will not be added if the same note appears for this activity
Mod Note
Add a Mod Note for the Author of the Activity.
type
must be one of the valid note labels:- BOT_BAN
- PERMA_BAN
- BAN
- ABUSE_WARNING
- SPAM_WARNING
- SPAM_WATCH
- SOLID_CONTRIBUTOR
- HELPFUL_USER
actions:
- kind: modnote
type: SPAM_WATCH
content: 'a note only mods can see message' # optional
referenceActivity: boolean # if true the Note will be linked to the Activity being processed
existingNoteCheck: boolean # if true (default) then the note will not be added if the same note appears for this activity
Filters
Filters are an additional channel for determining if an Event should be processed by ContextMod. They differ from Rules in several key ways:
- Runs, Checks, Rules, and Actions can all have Filters
- Filters test against the current state of the Activity (or it’s Author) being processed, rather than looking at history/context/etc…
- CM supports filters for:
- Author - age, verified email, profile description, flair…
- Item (Submission/Comment) - sticked, # of reports, removed, flair, score…
- Subreddit - name, nsfw, quarantined…
- Toolbox Usernotes
- Mod Notes
- CM supports filters for:
- Filter test results only determine if the Run, Check, Rule, or Action should run – rather than triggering it
- When the filter test passes the thing being tested continues to process as usual
- When the filter test fails the thing being tested fails.
Refer to the full Filter documentation for more
Common Patterns
Conditions
ContextMod uses AND/OR operands in many places to allow you to determine how a set of conditions is evaluated.
A condition is a statement that can be determined to be true or false. A set of conditions:
- an orange is orange
- the sky is blue
- the sun is black
These conditions can be combined together to evaluate to either true or false using AND or OR operands.
AND
All statements in the set must be true for the condition to be true
- an orange is orange => TRUE
- the sky is blue => TRUE
- the sun is black => FALSE
=> Condition evaluates to FALSE
OR
Any statement in the set must be true for the condition to be true
- an orange is orange => TRUE
- the sky is blue => TRUE
- the sun is black => FALSE
=> Condition evaluates to TRUE because the first two were true
Activities window
Most Rules have a window
property somewhere within their configuration. This property defines the range of Activities (submission and/or comments) that should be retrieved for checking the criteria of the Rule.
Full Activities window
documentation
URL Tokens
A field that can use URL Tokens can use a special prefix at the beginning of the string to tell ContextMod to fetch content from a URL instead of using the field as-is for content. If the field is also templated then the content is run through templating after being retrieved.
If value starts with wiki:
then the proceeding value will be used to get a wiki page from the current subreddit EX
wiki:botconfig/mybot
tries to get https://reddit.com/r/currentSubreddit/wiki/botconfig/mybot
If the value starts with wiki:
and ends with |someValue
then someValue
will be used as the base subreddit for the wiki page EX
EX wiki:replytemplates/test|ContextModBot
tries to get https://reddit.com/r/ContextModBot/wiki/replytemplates/test
If the value starts with url:
then the value is fetched as an external url and expects raw text returned EX
EX url:https://pastebin.com/raw/38qfL7mL
tries to get the text response of https://pastebin.com/raw/38qfL7mL
If none of the above is used the value is used as-is.
Thresholds and Comparisons
Most rules/filters have criteria that require you to define a specific condition to test against. This can be anything from repeats of activities to account age.
In all of these scenarios the condition is defined using a subset of comparison operators (very similar to how automoderator does things).
Available operators:
<
– less than =>5 < 6
=> 5 is less than 6>
– greater than =>6 > 5
=> 6 is greater than 5<=
– less than or equal to =>5 <= 5
=> 5 is less than or equal to 5>=
– greater than or equal to =>5 >= 5
=> 5 is greater than or equal to 5
In the context of a rule/filter comparison you provide the comparison omitting the value that is being tested. An example…
The RepeatActivity rule has a threshold
comparison to test against the number of repeat activities it finds
- You want the rule to trigger if it finds 4 or more repeat activities
- The rule would be configured like this
"threshold": ">= 4"
Essentially what this is telling the rule is threshold: "x >= 4"
where x
is the largest repeat of activities it finds.
Percentages
Some criteria accept an optional percentage to compare against:
"threshold": "> 20%"
Refer to the individual rule/criteria schema to see what this percentage is comparing against.
Durations
Some criteria accept an optional duration to compare against:
"threshold": "< 1 month"
The duration value compares a time range from now to duration value
time in the past.
Refer to duration values in activity window documentation as well as the individual rule/criteria schema to see what this duration is comparing against.
Filter Defaults
Filters can have default values specified at the bot level, subreddit level, and run level.
Each level is “more specific” than the previous and will override more specific levels below it until, eventually, the defaults are applied to a Check.
IE Bot Defaults -> Subreddit Defaults (overiddes Bot) -> Run Defaults (overrides Subreddit) -> Apply to Check
Applying Default Behavior
The defaults object also specifies how it applies itself to the Filters on a Check using authorIsBehavior
and itemIsBehavior
.
Both behavior properties have these options:
merge
– will add any Filter Criteria in the defaults to the Filters, leaving any explicitly specified in the Check untouched.replace
– If the Check has any explicitly specified Filters the default’s Filter Criteria are ignored.
Filter Defaults Defaults
If no Filter Defaults are specified at any level then all Checks will have this default applied:
authorIs:
exclude:
- isMod: true
authorIsBehavior: merge
In other words – Checks will not run if the Author of the Activity being processed is a Moderator.
Flow Control Defaults
See Flow Control Documentation
Subreddit-Level Configuration
Other than configuration specific to processing Events there are many subreddit-level defaults and settings that can be controlled from the top-level of your configuration.
See Filter Defaults and Flow Control Defaults for links to those defaults for a subreddit.
Polling
Polling is how ContextMod creates Events from new Activities in a Subreddit. CM monitors one or more polling sources and processes any new Activities it discovers.
Polling Sources
There are four valid polling sources:
unmoderated
Activities that have yet to be approved/removed by a mod. This includes all modqueue (reports/spam) and new submissions.
Use this if you want the bot to act like a regular moderator and act on anything that can be seen from mod tools.
This is the default polling source.
modqueue
Activities requiring moderator review, such as reported things and items caught by the spam filter.
Use this if you only want the Bot to process reported/filtered Activities.
newSub
Get only Submissions that show up in /r/mySubreddit/new
Use this if you want the bot to process Submissions only when:
- they are not initially filtered by Automoderator or
- after they have been manually approved from modqueue
newComm
Get only new Comments
Use this if you want the bot to process Comments only when:
- they are not initially filtered by Automoderator or
- after they have been manually approved from modqueue
Configuring Polling Sources
Polling can be configured by specifying the top level polling
property in your subreddit’s configuration:
polling:
...
runs:
...
polling
must be a list comprised of either polling source names:
polling:
- unmoderated
- modqueue
and/or a polling source objects:
# using names and objects
polling:
# using a name
- unmoderated
# using an object
- pollOn: newComm
delayUntil: 30
Best Practices
Order of Operations
Check Order
Checks are run in the order they appear in your configuration, therefore you should place your highest requirement/severe action checks at the top and lowest requirement/moderate actions at the bottom.
This is so that if an Activity warrants a more serious reaction that Check is triggered first rather than having a lower requirement check with less severe actions triggered and causing all subsequent Checks to be skipped.
- Attribution >50% AND Repeat Activity 8x AND Recent Activity in 2 subs => remove submission + ban
- Attribution >20% AND Repeat Activity 4x AND Recent Activity in 5 subs => remove submission + flair user restricted
- Attribution >20% AND Repeat Activity 2x => remove submission
- Attribution >20% AND History comments <30% => remove submission
- Attribution >15% => report
- Repeat Activity 2x => report
- Recent Activity in 3 subs => report
- Author not vetted => flair new user submission
This behavior can be arbitrarily controlled using Flow Control but, in order to keep complexity low, the above approach is a good rule-of-thumb.
Rule Order
The ordering of your Rules within a Check/RuleSet can have an impact on Check performance (speed) as well as API usage.
Consider these three rules:
- Rule A – Recent Activity => 3 subreddits => last 15 submissions
- Rule B – Repeat Activity => last 3 days
- Rule C – Attribution => >10% => last 90 days or 300 submissions
The first two rules are lightweight in their requirements – Rule A can be completed in 1 API call, Rule B potentially completed in 1 Api call.
However, depending on how active the Author is, Rule C will take at least 3 API calls just to get all activities (Reddit limit 100 items per call).
If the Check is using AND
condition for its rules (default) then if either Rule A or Rule B fail then Rule C will never run. This means 3 API calls never made plus the time waiting for each to return.
It is therefore advantageous to list your lightweight Rules first in each Check.
Configuration Re-use and Caching
ContextMod implements caching functionality for:
- author history (
window
criteria in rules) authorIs
anditemIs
resultscontent
that uses wiki pages (on Comment/Report/Ban Actions)- User Notes
- Rule results
All of these use api requests so caching them reduces api usage.
Cached results can be re-used if the criteria in configuration is identical to a previously cached result or by using Named Rules/Actions/Filters. So…
- author history cache results are re-used if
window
criteria on a Rule is identical to thewindow
on another Rule IE always use 7 Days or always use 50 Items for absolute counts. authorIs
criteria is identical to anotherauthorIs
elsewhere in configuration..- etc…
Re-use will result in less API calls and faster Check times.
PROTIP: You can monitor the re-use of cache in the Cache
section of your subreddit on the web interface. See the tooltips in that section for a better breakdown of cache statistics.
Learn more about how Caching works
Partial Configurations
ContextMod supports fetching parts of a configuration (a Fragment) from an external source. Fragments are an advanced feature and should only be used by users who are familiar with CM’s configuration syntax and understand the risks/downsides associates with fragmenting a configuration.
Fragments are supported for:
Should You Use Partial Configurations?
- PROS
- Consolidate shared configuration for many subreddits into one location
- Shared configuration can be updated independently of subreddits
- Allows sharing access to configuration outside of moderators of a specific subreddit or even reddit
- CONS
- Editor does not currently support viewing, editing, or updating Fragments. Only the Fragment URL is visible in a Subreddit’s configuration
- No editor support for viewing obscures “complete view” of configuration and makes editor less useful for validation
- Currently, editor cannot validate individual Fragments. They must be copy-pasted “in place” within a normal configuration.
- Using external (non-wiki) sources means you are responsible for the security/access to the fragment
- Editor does not currently support viewing, editing, or updating Fragments. Only the Fragment URL is visible in a Subreddit’s configuration
In general, Fragments should only be used to offload small, well-tested pieces of a configuration that can be shared between many subreddits. Examples:
- A regex Rule for spam links
- A Recent Activity Rule for reporting users from freekarma subreddits
Usage
A Fragment may be either a special string or a Fragment object. The fetched Fragment can be either an object or an array of objects of the type of Fragment being replaced.
String
If value starts with wiki:
then the proceeding value will be used to get a wiki page from the current subreddit
- EX
wiki:botconfig/myFragment
tries to gethttps://reddit.com/r/currentSubreddit/wiki/botconfig/myFragment
If the value starts with wiki:
and ends with |someValue
then someValue
will be used as the base subreddit for the wiki page
- EX
wiki:myFragment/test|ContextModBot
tries to gethttps://reddit.com/r/ContextModBot/wiki/myFragment/test
If the value starts with url:
then the value is fetched as an external url and expects raw text returned
- EX
url:https://pastebin.com/raw/38qfL7mL
tries to get the text response ofhttps://pastebin.com/raw/38qfL7mL
Object
The object contains:
path
– REQUIRED string following rules abovettl
– OPTIONAL, number of seconds to cache the URL result. Defaults toWikiTTL
Sharing Full Configs as Runs
If the Fragment fetched by CM is a “full config” (including runs
, polling
, etc…) that could be used as a valid config for another subreddit then CM will extract and use the Runs from that config.
However, the config must also explicitly allow access for use as a Fragment. This is to prevent subreddits that share a Bot account from accidentally (or intentionally) gaining access to another subreddit’s config with permissions.
Sharing
The config that will be shared (accessed at wiki:botconfig/contextbot|SharingSubreddit
) must have the sharing
property defined at its top-level. If sharing
is not defined access will be denied for all subreddits.
sharing: false # deny access to all subreddits (default when sharing is not defined)
polling:
- newComm
runs:
# ...
sharing: true # any subreddit can use this config (reddit account must also be able to access wiki page)
# when a list is given all subreddit names that match any from the list are ALLOWED to access the config
# list can be regular expressions or case-insensitive strings
sharing:
- mealtimevideos
- videos
- '/Ask.*/i'
# if `exclude` is used then any subreddit name that is NOT on this list can access the config
# list can be regular expressions or case-insensitive strings
sharing:
exclude:
- mealtimevideos
- videos
- '/Ask.*/i'
Examples
Replacing A Rule with a URL Fragment
runs:
- checks:
- name: Free Karma Alert
description: Check if author has posted in 'freekarma' subreddits
kind: submission
rules:
- 'url:https://gist.githubusercontent.com/FoxxMD/0e1ee1ab950ff4d1f0cd26172bae7f8f/raw/0ebfaca903e4a651827effac5775c8718fb6e1f2/fragmentRule.yaml'
- name: badSub
kind: recentActivity
useSubmissionAsReference: false
thresholds:
# if the number of activities (sub/comment) found CUMULATIVELY in the subreddits listed is
# equal to or greater than 1 then the rule is triggered
- threshold: '>= 1'
subreddits:
- MyBadSubreddit
window: 7 days
actions:
- kind: report
content: 'uses freekarma subreddits and bad subreddits'
Replacing A Rule with a URL Fragment (Multiple)
runs:
- checks:
- name: Free Karma Alert
description: Check if author has posted in 'freekarma' subreddits
kind: submission
rules:
- 'url:https://gist.githubusercontent.com/FoxxMD/0e1ee1ab950ff4d1f0cd26172bae7f8f/raw/0ebfaca903e4a651827effac5775c8718fb6e1f2/fragmentRuleArray.yaml'
actions:
- kind: report
content: 'uses freekarma subreddits and bad subreddits'
Replacing A Rule with a Wiki Fragment
runs:
- checks:
- name: Free Karma Alert
description: Check if author has posted in 'freekarma' subreddits
kind: submission
rules:
- 'wiki:freeKarmaFrag'
actions:
- kind: report
content: 'uses freekarma subreddits'
Using Another Subreddit’s Config
runs:
- `wiki:botconfig/contextbot|SharingSubreddit`
- name: MySubredditSpecificRun
checks:
- name: Free Karma Alert
description: Check if author has posted in 'freekarma' subreddits
kind: submission
rules:
- 'wiki:freeKarmaFrag'
actions:
- kind: report
content: 'uses freekarma subreddits'
In r/SharingSubreddit
:
sharing: true
runs:
- name: ARun
# ...
Subreddit-Ready Examples
Refer to the Subreddit Cookbook Examples section to find ready-to-use configurations for common scenarios (spam, freekarma blocking, etc…). This is also a good place to familiarize yourself with what complete configurations look like.