mirror of
https://github.com/FoxxMD/context-mod.git
synced 2026-01-14 07:57:57 -05:00
Compare commits
59 Commits
redisCache
...
regexList
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eee2a8e856 | ||
|
|
e79779d980 | ||
|
|
b094b72d4a | ||
|
|
d90e88360d | ||
|
|
9031f7fec8 | ||
|
|
0a2b13e4c4 | ||
|
|
5183747219 | ||
|
|
718f81b921 | ||
|
|
154603328c | ||
|
|
4041ea5bb5 | ||
|
|
981591a5fa | ||
|
|
999329c6ce | ||
|
|
d7cf15dcc1 | ||
|
|
f58430c615 | ||
|
|
8e18afbda9 | ||
|
|
b3b0d92f2a | ||
|
|
34ee5da082 | ||
|
|
ba8ad100bc | ||
|
|
4b6f66499a | ||
|
|
9a08df1990 | ||
|
|
1f3aa8e732 | ||
|
|
ec98d8f629 | ||
|
|
2d8b7f7b86 | ||
|
|
b9f85814d4 | ||
|
|
e11a1d2a52 | ||
|
|
43bfa3ca51 | ||
|
|
0127cbfd0f | ||
|
|
59d31bde84 | ||
|
|
17ae7fa295 | ||
|
|
bf074487ff | ||
|
|
85e786d248 | ||
|
|
641a7fbd63 | ||
|
|
0278a4d673 | ||
|
|
d318286507 | ||
|
|
36221705fa | ||
|
|
fdc0ccf4c8 | ||
|
|
a949a4ed10 | ||
|
|
d67283a923 | ||
|
|
21b2182ef0 | ||
|
|
fcfb037d6c | ||
|
|
8c3601a4cf | ||
|
|
cfc96b6c82 | ||
|
|
239d173ffd | ||
|
|
fda6090ddd | ||
|
|
d23f87ba60 | ||
|
|
2941386955 | ||
|
|
b2b924c01d | ||
|
|
ee20ba786b | ||
|
|
f71933b9b9 | ||
|
|
e6246188ad | ||
|
|
bfd5ba7816 | ||
|
|
fd5488376a | ||
|
|
6c8ea66fcc | ||
|
|
acbb9a8626 | ||
|
|
122d5fb2af | ||
|
|
cd8ccffa20 | ||
|
|
8695058064 | ||
|
|
1271eee4c5 | ||
|
|
59f935ce46 |
@@ -1,7 +1,10 @@
|
||||
.git
|
||||
logs
|
||||
.github
|
||||
docs
|
||||
_site
|
||||
.bundle
|
||||
vendor
|
||||
docs/.jekyll-cache
|
||||
node_modules
|
||||
coverage
|
||||
.nyc_output
|
||||
@@ -22,3 +25,5 @@ coverage
|
||||
!.mocharc.json
|
||||
!tsconfig.json
|
||||
!package*.json
|
||||
!docker/config/**
|
||||
!_config.yml
|
||||
|
||||
53
.github/workflows/pages.yml
vendored
Normal file
53
.github/workflows/pages.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
|
||||
name: Deploy Jekyll site to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["master"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow one concurrent deployment
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: '3.0' # Not needed with a .ruby-version file
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
cache-version: 0 # Increment this number if you need to re-download cached gems
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v1
|
||||
- run: bundle exec jekyll build --baseurl ${{ steps.pages.outputs.base_path }} # defaults output to '/_site'
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v1 # This will automatically upload an artifact from the '/_site' directory
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -381,6 +381,17 @@ dist
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# Copied from https://github.com/github/gitignore/blob/main/Jekyll.gitignore
|
||||
# Ignore metadata generated by Jekyll
|
||||
_site/
|
||||
.sass-cache/
|
||||
.jekyll-cache/
|
||||
.jekyll-metadata
|
||||
|
||||
# Ignore folders generated by Bundler
|
||||
.bundle/
|
||||
vendor/
|
||||
|
||||
**/src/**/*.js
|
||||
**/tests/**/*.js
|
||||
**/tests/**/*.map
|
||||
@@ -396,3 +407,4 @@ dist
|
||||
!docs/**/*.json5
|
||||
!docs/**/*.yaml
|
||||
!docs/**/*.json
|
||||
!docker/config/**
|
||||
|
||||
3
.idea/redditcontextbot.iml
generated
3
.idea/redditcontextbot.iml
generated
@@ -9,6 +9,9 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/logs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.nyc_output" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/_site" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/docs/.jekyll-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor" />
|
||||
</content>
|
||||
<content url="file://$MODULE_DIR$/node_modules" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
||||
15
Dockerfile
15
Dockerfile
@@ -96,11 +96,26 @@ WORKDIR /app
|
||||
|
||||
FROM base as build
|
||||
|
||||
# copy NPM dependencies and install
|
||||
COPY --chown=abc:abc package*.json ./
|
||||
COPY --chown=abc:abc tsconfig.json .
|
||||
|
||||
RUN npm install
|
||||
|
||||
# copy bundle/jekyll dependencies and docs folder
|
||||
COPY --chown=abc:abc Gemfile Gemfile.lock _config.yml ./
|
||||
COPY --chown=abc:abc docs ./docs/
|
||||
|
||||
# sassc (a jekll dependency) is very slow to compile bc there are no alpine binaries
|
||||
# https://github.com/sass/sassc-ruby/issues/189#issuecomment-629758948
|
||||
# so for now sync used jekyll version with prebuilt binary available in alpine repo
|
||||
RUN apk add --no-cache --virtual .build-deps \
|
||||
ruby-jekyll \
|
||||
&& bundle install \
|
||||
&& jekyll build -b /docs \
|
||||
&& apk del .build-deps \
|
||||
&& rm -rf docs
|
||||
|
||||
COPY --chown=abc:abc . /app
|
||||
|
||||
RUN npm run build && rm -rf node_modules
|
||||
|
||||
19
Gemfile
Normal file
19
Gemfile
Normal file
@@ -0,0 +1,19 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# sassc (a jekll dependency) is very slow to compile bc there are no alpine binaries
|
||||
# https://github.com/sass/sassc-ruby/issues/189#issuecomment-629758948
|
||||
# so for now sync used jekyll version with prebuilt binary available in alpine repo
|
||||
gem "jekyll", "4.2.2" # installed by `gem jekyll`
|
||||
# gem "webrick" # required when using Ruby >= 3 and Jekyll <= 4.2.2
|
||||
|
||||
gem "just-the-docs", "0.4.0.rc3" # currently the latest pre-release
|
||||
# gem "just-the-docs" # the latest release - currently 0.3.3
|
||||
|
||||
gem "jekyll-readme-index"
|
||||
gem 'jekyll-default-layout'
|
||||
gem 'jekyll-titles-from-headings'
|
||||
gem 'jekyll-relative-links'
|
||||
|
||||
group :jekyll_plugins do
|
||||
gem 'jekyll-optional-front-matter'
|
||||
end
|
||||
90
Gemfile.lock
Normal file
90
Gemfile.lock
Normal file
@@ -0,0 +1,90 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
colorator (1.1.0)
|
||||
concurrent-ruby (1.1.10)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
eventmachine (1.2.7)
|
||||
ffi (1.15.5)
|
||||
forwardable-extended (2.6.0)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (4.2.2)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (~> 1.0)
|
||||
jekyll-sass-converter (~> 2.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (~> 2.3)
|
||||
kramdown-parser-gfm (~> 1.0)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.4.0)
|
||||
pathutil (~> 0.9)
|
||||
rouge (~> 3.0)
|
||||
safe_yaml (~> 1.0)
|
||||
terminal-table (~> 2.0)
|
||||
jekyll-default-layout (0.1.5)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-sass-converter (2.2.0)
|
||||
sassc (> 2.0.1, < 3.0)
|
||||
jekyll-seo-tag (2.8.0)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-titles-from-headings (0.5.3)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
just-the-docs (0.4.0.rc3)
|
||||
jekyll (>= 3.8.5)
|
||||
jekyll-seo-tag (>= 2.0)
|
||||
rake (>= 12.3.1)
|
||||
kramdown (2.4.0)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.7.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.4.0)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (5.0.0)
|
||||
rake (13.0.6)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.5)
|
||||
rouge (3.30.0)
|
||||
safe_yaml (1.0.5)
|
||||
sassc (2.4.0)
|
||||
ffi (~> 1.9)
|
||||
terminal-table (2.0.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
unicode-display_width (1.8.0)
|
||||
|
||||
PLATFORMS
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
jekyll (= 4.2.2)
|
||||
jekyll-default-layout
|
||||
jekyll-optional-front-matter
|
||||
jekyll-readme-index
|
||||
jekyll-relative-links
|
||||
jekyll-titles-from-headings
|
||||
just-the-docs (= 0.4.0.rc3)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.25
|
||||
46
README.md
46
README.md
@@ -1,9 +1,13 @@
|
||||
---
|
||||
title: Home
|
||||
nav_order: 1
|
||||
---
|
||||
# ContextMod [](https://github.com/FoxxMD/context-mod/releases) [](https://opensource.org/licenses/MIT) [](https://hub.docker.com/r/foxxmd/context-mod)
|
||||
|
||||
<img src="/docs/logo.png" align="right"
|
||||
alt="ContextMod logo" width="180" height="176">
|
||||
|
||||
**Context Mod** (CM) is an event-based, [reddit](https://reddit.com) moderation bot built on top of [snoowrap](https://github.com/not-an-aardvark/snoowrap) and written in [typescript](https://www.typescriptlang.org/).
|
||||
[**Context Mod**](https://contextmod.dev/) (CM) is an event-based, [reddit](https://reddit.com) moderation bot built on top of [snoowrap](https://github.com/not-an-aardvark/snoowrap) and written in [typescript](https://www.typescriptlang.org/).
|
||||
|
||||
It is designed to help fill in the gaps for [automoderator](https://www.reddit.com/wiki/automoderator/full-documentation) in regard to more complex behavior with a focus on **user-history based moderation.**
|
||||
|
||||
@@ -16,27 +20,27 @@ An example of the above that Context Bot can do:
|
||||
|
||||
Feature Highlights for **Moderators:**
|
||||
|
||||
* Complete bot **autonomy**. YAML config is [stored in your subreddit's wiki](/docs/subreddit/gettingStarted.md#setup-wiki-page) (like automoderator)
|
||||
* Complete bot **autonomy**. YAML config is [stored in your subreddit's wiki](/docs/moderators/gettingStarted.md#setup-wiki-page) (like automoderator)
|
||||
* Simple rule-action behavior can be combined to create **complex behavior detection**
|
||||
* Support Activity filtering based on:
|
||||
* [Author criteria](/docs/subreddit/components/README.md#author-filter) (name, css flair/text, age, karma, moderator status, [Toolbox User Notes](https://www.reddit.com/r/toolbox/wiki/docs/usernotes), and more!)
|
||||
* [Activity state](/docs/subreddit/components/README.md#item-filter) (removed, locked, distinguished, etc...)
|
||||
* State of Subreddit Activity is in [Subreddit](/docs/subreddit/components/README.md#subreddit-filter) (nsfw, name, profile, etc...)
|
||||
* Rules and Actions support [named references](/docs/subreddit/components/README.md#named-rules) -- **write once, reference anywhere**
|
||||
* Powerful [logic control](/docs/subreddit/components/advancedConcepts/flowControl.md) (if, then, goto)
|
||||
* [Delay/re-process activities](/docs/subreddit/components/README.md#dispatch) using arbitrary rules
|
||||
* [**Image Comparisons**](/docs/imageComparison.md) via fingerprinting and/or pixel differences
|
||||
* [**Repost detection**](/docs/subreddit/components/repost) with support for external services (youtube, etc...)
|
||||
* [Author criteria](docs/subreddit-configuration/in-depth/filters/README.md#author-filter) (name, css flair/text, age, karma, moderator status, [Toolbox User Notes](https://www.reddit.com/r/toolbox/wiki/docs/usernotes), and more!)
|
||||
* [Activity state](docs/subreddit-configuration/in-depth/filters/README.md#item-filter) (removed, locked, distinguished, etc...)
|
||||
* State of Subreddit Activity is in [Subreddit](docs/subreddit-configuration/in-depth/filters/README.md#subreddit-filter) (nsfw, name, profile, etc...)
|
||||
* Rules and Actions support [named references](docs/subreddit-configuration/README.md#named-rules) -- **write once, reference anywhere**
|
||||
* Powerful [logic control](docs/subreddit-configuration/advancedConcepts/flowControl.md) (if, then, goto)
|
||||
* [Delay/re-process activities](docs/subreddit-configuration/README.md#dispatch) using arbitrary rules
|
||||
* [**Image Comparisons**](docs/subreddit-configuration/imageComparison.md) via fingerprinting and/or pixel differences
|
||||
* [**Repost detection**](docs/subreddit-configuration/in-depth/repost) with support for external services (youtube, etc...)
|
||||
* Event notification via Discord
|
||||
* [**Web interface**](#web-ui-and-screenshots) for monitoring, administration, and oauth bot authentication
|
||||
* [**Placeholders**](/docs/subreddit/actionTemplating.md) (like automoderator) can be configured via a wiki page or raw text and supports [mustache](https://mustache.github.io) templating
|
||||
* [**Partial Configurations**](/docs/subreddit/components/README.md#partial-configurations) -- offload parts of your configuration to shared locations to consolidate logic between multiple subreddits
|
||||
* [Guest Access](/docs/subreddit/README.md#guest-access) enables collaboration and easier setup by allowing temporary access
|
||||
* [Toxic content prediction](/docs/subreddit/components/README.md#moderatehatespeechcom-predictions) using [moderatehatespeech.com](https://moderatehatespeech.com) machine learning model
|
||||
* [**Placeholders**](docs/subreddit-configuration/actionTemplating.md) (like automoderator) can be configured via a wiki page or raw text and supports [mustache](https://mustache.github.io) templating
|
||||
* [**Partial Configurations**](docs/subreddit-configuration/README.md#partial-configurations) -- offload parts of your configuration to shared locations to consolidate logic between multiple subreddits
|
||||
* [Guest Access](docs/moderators/README.md#guest-access) enables collaboration and easier setup by allowing temporary access
|
||||
* [Toxic content prediction](docs/subreddit-configuration/README.md#moderatehatespeechcom-predictions) using [moderatehatespeech.com](https://moderatehatespeech.com) machine learning model
|
||||
|
||||
Feature highlights for **Developers and Hosting (Operators):**
|
||||
|
||||
* [Server/client architecture](/docs/serverClientArchitecture.md)
|
||||
* [Server/client architecture](/docs/operator/serverClientArchitecture.md)
|
||||
* Default/no configuration runs "All In One" behavior
|
||||
* Additional configuration allows web interface to connect to multiple servers
|
||||
* Each server instance can run multiple reddit accounts as bots
|
||||
@@ -44,7 +48,7 @@ Feature highlights for **Developers and Hosting (Operators):**
|
||||
* [Database Persistence](/docs/operator/database.md) using SQLite, MySql, or Postgres
|
||||
* Audit trails for bot activity
|
||||
* Historical statistics
|
||||
* [Docker container support](/docs/operator/installation.md#docker-recommended)
|
||||
* [Docker container](/docs/operator/installation.md#docker-recommended) and [docker-compose](/docs/operator/installation.md#docker-compose) support
|
||||
* Easy, UI-based [OAuth authentication](/docs/operator/addingBot.md) for adding Bots and moderator dashboard
|
||||
* Integration with [InfluxDB](https://www.influxdata.com) for detailed [time-series metrics](/docs/operator/database.md#influx) and a pre-built [Grafana](https://grafana.com) [dashboard](/docs/operator/database.md#grafana)
|
||||
|
||||
@@ -59,7 +63,7 @@ Feature highlights for **Developers and Hosting (Operators):**
|
||||
|
||||
Each subreddit using the RCB bot configures its behavior via their own wiki page.
|
||||
|
||||
When a monitored **Activity** (new comment/submission, new modqueue item, etc.) is detected the bot runs through a list of [**Checks**](/docs/subreddit/components/README.md#checks) to determine what to do with the **Activity** from that Event. Each **Check** consists of :
|
||||
When a monitored **Activity** (new comment/submission, new modqueue item, etc.) is detected the bot runs through a list of [**Checks**](docs/subreddit-configuration/README.md#checks) to determine what to do with the **Activity** from that Event. Each **Check** consists of :
|
||||
|
||||
#### Kind
|
||||
|
||||
@@ -67,11 +71,11 @@ Is this check for a submission or comment?
|
||||
|
||||
#### Rules
|
||||
|
||||
A list of [**Rules**](/docs/subreddit/components/README.md#rules) to run against the **Activity**. Triggered Rules can cause the whole Check to trigger and run its **Actions**
|
||||
A list of [**Rules**](docs/subreddit-configuration/README.md#rules) to run against the **Activity**. Triggered Rules can cause the whole Check to trigger and run its **Actions**
|
||||
|
||||
#### Actions
|
||||
|
||||
A list of [**Actions**](/docs/subreddit/components/README.md#actions) that describe what the bot should do with the **Activity** or **Author** of the activity (comment, remove, approve, etc.). The bot will run **all** Actions in this list.
|
||||
A list of [**Actions**](docs/subreddit-configuration/README.md#actions) that describe what the bot should do with the **Activity** or **Author** of the activity (comment, remove, approve, etc.). The bot will run **all** Actions in this list.
|
||||
|
||||
___
|
||||
|
||||
@@ -95,14 +99,14 @@ See the [Operator's Getting Started Guide](/docs/operator/gettingStarted.md)
|
||||
|
||||
This guide is for **reddit moderators** who want to configure an existing CM bot to run on their subreddit.
|
||||
|
||||
See the [Moderator's Getting Started Guide](/docs/subreddit/gettingStarted.md)
|
||||
See the [Moderator's Getting Started Guide](/docs/moderators/gettingStarted.md)
|
||||
|
||||
## Configuration and Documentation
|
||||
|
||||
Context Bot's configuration can be written in YAML (like automoderator) or [JSON5](https://json5.org/). Its schema conforms to [JSON Schema Draft 7](https://json-schema.org/). Additionally, many **operator** settings can be passed via command line or environmental variables.
|
||||
|
||||
* For **operators** (running the bot instance) see the [Operator Configuration](/docs/operator/configuration.md) guide
|
||||
* For **moderators** consult the [app schema and examples folder](/docs/README.md#configuration-and-usage)
|
||||
* For **moderators** consult the [Subreddit Configuration Docs](/docs/subreddit-configuration/README.md)
|
||||
|
||||
[**Check the full docs for in-depth explanations of all concepts and examples**](/docs)
|
||||
|
||||
|
||||
45
_config.yml
Normal file
45
_config.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
title: ContextMod
|
||||
description: Documentation for ContextMod
|
||||
theme: just-the-docs
|
||||
|
||||
source: docs
|
||||
|
||||
url: https://contextmod.dev
|
||||
|
||||
color_scheme: dark
|
||||
|
||||
mermaid:
|
||||
version: "9.1.3"
|
||||
|
||||
aux_links:
|
||||
Github: https://github.com/foxxmd/context-mod
|
||||
|
||||
plugins:
|
||||
- jekyll-readme-index
|
||||
- jekyll-default-layout
|
||||
- jekyll-titles-from-headings
|
||||
- jekyll-optional-front-matter
|
||||
- jekyll-relative-links
|
||||
|
||||
titles_from_headings:
|
||||
enabled: true
|
||||
strip_title: false
|
||||
collections: false
|
||||
|
||||
readme_index:
|
||||
enabled: true
|
||||
remove_originals: true
|
||||
with_frontmatter: true
|
||||
|
||||
optional_front_matter:
|
||||
remove_originals: true
|
||||
|
||||
defaults:
|
||||
- scope:
|
||||
path: ""
|
||||
values:
|
||||
has_toc: false
|
||||
- scope:
|
||||
path: "images"
|
||||
values:
|
||||
image: true
|
||||
62
docker-compose.yml
Normal file
62
docker-compose.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
app:
|
||||
image: foxxmd/context-mod:latest
|
||||
# use the settings below, instead of 'image', if running context-mod from the repository (developing local changes)
|
||||
# build:
|
||||
# context: .
|
||||
volumes:
|
||||
# Location of config file to use with CM
|
||||
# The path BEFORE the colon (:) is the path on the host machine
|
||||
# which defaults to a folder named 'data' in the same directory this file is run in.
|
||||
- './data:/config'
|
||||
# For a new installation you should use the config from the repository included for use with docker-compose
|
||||
# https://github.com/FoxxMD/context-mod/blob/master/docker/config/docker-compose/config.yaml
|
||||
# Copy config.yaml to /(this directory)/data/config.yaml and then modify to match any changed settings below (see comments on config.yaml)
|
||||
ports:
|
||||
- "${CM_WEB-8085}:8085"
|
||||
environment:
|
||||
IS_DOCKER: true
|
||||
# If using a linux host, uncomment these and set them accordingly https://github.com/FoxxMD/context-mod/blob/master/docs/operator/installation.md#linux-host
|
||||
# PUID: 1000
|
||||
# PGID: 1000
|
||||
|
||||
cache:
|
||||
image: 'redis:7-alpine'
|
||||
volumes:
|
||||
# on linux will need to make sure this directory has correct permissions for container to access
|
||||
- './data/cache:/data'
|
||||
|
||||
database:
|
||||
image: 'mariadb:10.9.3'
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: CHANGE_THIS
|
||||
MYSQL_USER: cmuser
|
||||
# this should match the password set in config.yaml
|
||||
MYSQL_PASSWORD: CHANGE_THIS
|
||||
MYSQL_DATABASE: ContextMod
|
||||
volumes:
|
||||
- './data/db:/var/lib/mysql'
|
||||
|
||||
influx:
|
||||
image: 'influxdb:latest'
|
||||
volumes:
|
||||
- './data/influx:/var/lib/influxdb2'
|
||||
ports:
|
||||
- "${INFLUX_WEB:-8086}:8086"
|
||||
profiles:
|
||||
- full
|
||||
|
||||
grafana:
|
||||
image: 'grafana/grafana'
|
||||
volumes:
|
||||
- './data/grafana:/var/lib/grafana'
|
||||
ports:
|
||||
- "${GRAFANA_WEB:-3000}:3000"
|
||||
environment:
|
||||
GF_SECURITY_ADMIN_PASSWORD: CHANGE_THIS
|
||||
depends_on:
|
||||
- influx
|
||||
profiles:
|
||||
- full
|
||||
43
docker/config/docker-compose/config.yaml
Normal file
43
docker/config/docker-compose/config.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
operator:
|
||||
name: CHANGE_THIS #YOUR REDDIT USERNAME HERE
|
||||
logging:
|
||||
# default level for all transports
|
||||
level: debug
|
||||
file:
|
||||
# override default level
|
||||
level: warn
|
||||
# true -> log folder at projectDir/log
|
||||
dirname: true
|
||||
caching:
|
||||
provider:
|
||||
store: redis
|
||||
host: cache
|
||||
port: 6379
|
||||
prefix: prod
|
||||
databaseConfig:
|
||||
migrations:
|
||||
continueOnAutomatedBackup: true
|
||||
#force: true # uncomment this to make cm run new migrations without confirmation
|
||||
#logging: ['query', 'error', 'warn', 'log'] # uncomment this to get typeorm to log EVERYTHING
|
||||
connection:
|
||||
type: 'mariadb'
|
||||
host: 'database'
|
||||
username: 'cmuser'
|
||||
# This should match the password set in docker-compose.yaml
|
||||
password: 'CHANGE_THIS'
|
||||
database: 'ContextMod'
|
||||
web:
|
||||
credentials:
|
||||
redirectUri: 'http://localhost:8085/callback'
|
||||
session:
|
||||
storage: cache
|
||||
port: 8085
|
||||
#
|
||||
# Influx/Grafana requires additional configuration. See https://github.com/FoxxMD/context-mod/blob/master/docs/operator/database.md#influx
|
||||
#
|
||||
#influxConfig:
|
||||
# credentials:
|
||||
# url: 'http://influx:8086'
|
||||
# token: 'YourInfluxToken'
|
||||
# org: YourInfluxOrg
|
||||
# bucket: contextmod
|
||||
@@ -1,4 +1,8 @@
|
||||
# Documentation
|
||||
---
|
||||
title: Overview
|
||||
permalink: /overview.html
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Table of Contents
|
||||
|
||||
@@ -22,8 +26,8 @@
|
||||
|
||||
Review **at least** the **How It Works** and **Concepts** below, then:
|
||||
|
||||
* For **Operators** (running a bot instance) refer to [**Operator Getting Started**](/docs/operator/gettingStarted.md) guide
|
||||
* For **Moderators** (configuring an existing bot for your subreddit) refer to the [**Moderator Getting Started**](/docs/subreddit/gettingStarted.md) guide
|
||||
* For **Operators** (running a bot instance) refer to [**Operator Getting Started**](operator/gettingStarted.md) guide
|
||||
* For **Moderators** (configuring an existing bot for your subreddit) refer to the [**Moderator Getting Started**](moderators/gettingStarted.md) guide
|
||||
|
||||
## How It Works
|
||||
|
||||
@@ -33,10 +37,10 @@ Where possible Context Mod (CM) uses the same terminology as, and emulates the b
|
||||
|
||||
Expand the section below for a simplified flow diagram of how CM processes an incoming Activity. Then refer the text description of the diagram below as well as [Concepts](#Concepts) for descriptions of individual components.
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
<summary>Diagram</summary>
|
||||
|
||||

|
||||

|
||||
|
||||
</details>
|
||||
|
||||
@@ -92,7 +96,7 @@ An example of Runs:
|
||||
|
||||
Both group of Checks are independent of each other (don't have any patterns or actions in common).
|
||||
|
||||
[Full Documentation for Runs](/docs/subreddit/components/README.md#runs)
|
||||
[Full Documentation for Runs](subreddit-configuration/README.md#runs)
|
||||
|
||||
### Checks
|
||||
|
||||
@@ -105,7 +109,7 @@ A Run can be made up of one or more **Checks** that are processed **in the order
|
||||
|
||||
Once a Check is **triggered** (its Rules are satisfied and Actions performed) all subsequent Checks are skipped.
|
||||
|
||||
[Full Documentation for Checks](/docs/subreddit/components/README.md#checks)
|
||||
[Full Documentation for Checks](subreddit-configuration/README.md#checks)
|
||||
|
||||
### Rule
|
||||
|
||||
@@ -113,11 +117,11 @@ A **Rule** is some set of **criteria** (conditions) that are tested against an A
|
||||
|
||||
CM has different **Rules** that can test against different types of behavior and aspects of a User, their history, and the Activity (submission/common) being checked.
|
||||
|
||||
[Full Documentation for Rules](/docs/subreddit/components/README.md#rules)
|
||||
[Full Documentation for Rules](subreddit-configuration/README.md#rules)
|
||||
|
||||
#### Available Rules
|
||||
|
||||
All available rules can be found in the [components documentation](/docs/subreddit/components/README.md#rules)
|
||||
All available rules can be found in the [components documentation](subreddit-configuration/README.md#rules)
|
||||
|
||||
### Rule Set
|
||||
|
||||
@@ -127,7 +131,7 @@ Rule Sets can be used interchangeably with other **Rules** and **Rule Sets** in
|
||||
|
||||
They allow you to create more complex trigger behavior by combining multiple rules into one "parent rule".
|
||||
|
||||
[Rule Sets Documentation](/docs/subreddit/components/README.md#rule-sets)
|
||||
[Rule Sets Documentation](subreddit-configuration/README.md#rule-sets)
|
||||
|
||||
### Action
|
||||
|
||||
@@ -135,7 +139,7 @@ An **Action** is some action the bot can take against the checked Activity (comm
|
||||
|
||||
#### Available Actions
|
||||
|
||||
[Available Actions Documentation](/docs/subreddit/components/README.md#list-of-actions)
|
||||
[Available Actions Documentation](subreddit-configuration/README.md#list-of-actions)
|
||||
|
||||
### Filters
|
||||
|
||||
@@ -146,14 +150,14 @@ An **Action** is some action the bot can take against the checked Activity (comm
|
||||
* When the filter test **passes** the thing being tested continues to process as usual
|
||||
* When the filter test **fails** the thing being tested **fails**.
|
||||
|
||||
[Full Documentation for Filters](/docs/subreddit/components/README.md#filters)
|
||||
[Full Documentation for Filters](subreddit-configuration/README.md#filters)
|
||||
|
||||
## Configuration And Usage
|
||||
|
||||
* For **Operator/Bot maintainers** see **[Operation Guide](/docs/operator/README.md)**
|
||||
* For **Operator/Bot maintainers** see **[Operation Guide](operator/README.md)**
|
||||
* For **Moderators**
|
||||
* Start with the [Subreddit/Moderator docs](/docs/subreddit/README.md) or [Moderator Getting Started guide](/docs/subreddit/gettingStarted.md)
|
||||
* Refer to the [Subreddit Components Documentation](/docs/subreddit/components) or the [subreddit-ready examples](/docs/subreddit/components/subredditReady)
|
||||
* Start with the [Subreddit/Moderator docs](moderators/README.md) or [Moderator Getting Started guide](moderators/gettingStarted.md)
|
||||
* Refer to the [Subreddit Components Documentation](subreddit-configuration) or the [subreddit-ready examples](subreddit-configuration/cookbook)
|
||||
* as well as the [schema](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FApp.json) which has
|
||||
* fully annotated configuration data/structure
|
||||
* generated examples in json/yaml
|
||||
|
||||
@@ -1,12 +1,36 @@
|
||||
TODO add more development sections...
|
||||
---
|
||||
nav_order: 7
|
||||
---
|
||||
|
||||
# Development
|
||||
|
||||
# Serving Docs Locally
|
||||
|
||||
Requirements:
|
||||
|
||||
* [Jeykll](https://jekyllrb.com/) installed
|
||||
* Ruby 2.5.0 or higher and [RubyGems](https://rubygems.org/pages/download) (usually bundled)
|
||||
* [Bundler](https://bundler.io/) installed
|
||||
|
||||
## Install Doc Dependencies
|
||||
|
||||
```bash
|
||||
npm run docs-install
|
||||
```
|
||||
|
||||
## Serve Docs
|
||||
|
||||
```bash
|
||||
npm run docs-start
|
||||
```
|
||||
|
||||
# Developing/Testing Github Actions
|
||||
|
||||
Use [act](https://github.com/nektos/act) to run Github actions locally.
|
||||
|
||||
An example secrets file can be found in the project working directory at [act.env.example](act.env.example)
|
||||
An example secrets file can be found in the project working directory at [act.env.example](../act.env.example)
|
||||
|
||||
Modify [push-hook-sample.json](.github/push-hook-sample.json) to point to the local branch you want to run a `push` event trigger on, then run this command from the project working directory:
|
||||
Modify [push-hook-sample.json](../.github/push-hook-sample.json) to point to the local branch you want to run a `push` event trigger on, then run this command from the project working directory:
|
||||
|
||||
```bash
|
||||
act -e .github/push-hook-sample.json --secret-file act.env
|
||||
@@ -28,7 +52,7 @@ Map port `1080:1080` -- acts as both the proxy port and the UI endpoint with the
|
||||
http(s)://localhost:1080/mockserver/dashboard
|
||||
```
|
||||
|
||||
In your [operator configuration](/docs/operator/operatorConfiguration.md) define a proxy for snoowrap at the top-level:
|
||||
In your [operator configuration](operator/configuration.md) define a proxy for snoowrap at the top-level:
|
||||
|
||||
```yaml
|
||||
snoowrap:
|
||||
@@ -59,7 +83,7 @@ Content-Length: 155
|
||||
--data-raw '{
|
||||
"httpRequest": {},
|
||||
"priority": 0,
|
||||
"httpForward": {
|
||||
"httpForward": {
|
||||
"host": "oauth.reddit.com",
|
||||
"port": 443,
|
||||
"scheme": "HTTPS"
|
||||
@@ -95,7 +119,7 @@ The lifecycle of a mock call I do:
|
||||
Content-Type: application/json
|
||||
Content-Length: 1757
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
@@ -178,7 +202,7 @@ Content-Length: 1757
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
#### All Responses Timeout
|
||||
|
||||
<details markdown="block">
|
||||
@@ -260,7 +284,7 @@ curl --location --request PUT 'http://localhost:8010/mockserver/expectation' \
|
||||
### Clearing Behavior
|
||||
|
||||
|
||||
```HTTP
|
||||
```HTTP
|
||||
PUT /mockserver/clear?type=EXPECTATIONS HTTP/1.1
|
||||
Host: localhost:8010
|
||||
Content-Type: application/json
|
||||
@@ -287,7 +311,7 @@ Content-Length: 251
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
<summary>CURL</summary>
|
||||
|
||||
```bash
|
||||
@@ -313,7 +337,7 @@ curl --location --request PUT 'http://localhost:8010/mockserver/expectation' \
|
||||
|
||||
#### All Responses Drop After Delay (Connection Closed by Server)
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
<summary>HTTP</summary>
|
||||
|
||||
```HTTP
|
||||
@@ -340,7 +364,7 @@ Content-Length: 234
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
<summary>CURL</summary>
|
||||
|
||||
```bash
|
||||
@@ -378,7 +402,7 @@ Content-Length: 26
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
<summary>CURL</summary>
|
||||
|
||||
```bash
|
||||
|
||||
BIN
docs/favicon.ico
Normal file
BIN
docs/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
169
docs/index.md
Normal file
169
docs/index.md
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
title: Home
|
||||
nav_order: 1
|
||||
---
|
||||
# ContextMod [](https://github.com/FoxxMD/context-mod/releases) [](https://opensource.org/licenses/MIT) [](https://hub.docker.com/r/foxxmd/context-mod)
|
||||
|
||||
<img src="/logo.png" align="right"
|
||||
alt="ContextMod logo" width="180" height="176">
|
||||
|
||||
[**Context Mod**](https://contextmod.dev/) (CM) is an event-based, [reddit](https://reddit.com) moderation bot built on top of [snoowrap](https://github.com/not-an-aardvark/snoowrap) and written in [typescript](https://www.typescriptlang.org/).
|
||||
|
||||
It is designed to help fill in the gaps for [automoderator](https://www.reddit.com/wiki/automoderator/full-documentation) in regard to more complex behavior with a focus on **user-history based moderation.**
|
||||
|
||||
An example of the above that Context Bot can do:
|
||||
|
||||
> * On a new submission, check if the user has also posted the same link in **N** number of other subreddits within a timeframe/# of posts
|
||||
> * On a new submission or comment, check if the user has had any activity (sub/comment) in **N** set of subreddits within a timeframe/# of posts
|
||||
>
|
||||
>In either instance Context Bot can then perform any action a moderator can (comment, report, remove, lock, etc...) against that user, comment, or submission.
|
||||
|
||||
Feature Highlights for **Moderators:**
|
||||
|
||||
* Complete bot **autonomy**. YAML config is [stored in your subreddit's wiki](moderators/gettingStarted.md#setup-wiki-page) (like automoderator)
|
||||
* Simple rule-action behavior can be combined to create **complex behavior detection**
|
||||
* Support Activity filtering based on:
|
||||
* [Author criteria](subreddit-configuration/in-depth/filters/README.md#author-filter) (name, css flair/text, age, karma, moderator status, [Toolbox User Notes](https://www.reddit.com/r/toolbox/wiki/usernotes), and more!)
|
||||
* [Activity state](subreddit-configuration/in-depth/filters/README.md#item-filter) (removed, locked, distinguished, etc...)
|
||||
* State of Subreddit Activity is in [Subreddit](subreddit-configuration/in-depth/filters/README.md#subreddit-filter) (nsfw, name, profile, etc...)
|
||||
* Rules and Actions support [named references](subreddit-configuration/README.md#named-rules) -- **write once, reference anywhere**
|
||||
* Powerful [logic control](subreddit-configuration/advancedConcepts/flowControl.md) (if, then, goto)
|
||||
* [Delay/re-process activities](subreddit-configuration/README.md#dispatch) using arbitrary rules
|
||||
* [**Image Comparisons**](subreddit-configuration/imageComparison.md) via fingerprinting and/or pixel differences
|
||||
* [**Repost detection**](subreddit-configuration/in-depth/repost) with support for external services (youtube, etc...)
|
||||
* Event notification via Discord
|
||||
* [**Web interface**](#web-ui-and-screenshots) for monitoring, administration, and oauth bot authentication
|
||||
* [**Placeholders**](subreddit-configuration/actionTemplating.md) (like automoderator) can be configured via a wiki page or raw text and supports [mustache](https://mustache.github.io) templating
|
||||
* [**Partial Configurations**](subreddit-configuration/README.md#partial-configurations) -- offload parts of your configuration to shared locations to consolidate logic between multiple subreddits
|
||||
* [Guest Access](moderators/README.md#guest-access) enables collaboration and easier setup by allowing temporary access
|
||||
* [Toxic content prediction](subreddit-configuration/README.md#moderatehatespeechcom-predictions) using [moderatehatespeech.com](https://moderatehatespeech.com) machine learning model
|
||||
|
||||
Feature highlights for **Developers and Hosting (Operators):**
|
||||
|
||||
* [Server/client architecture](operator/serverClientArchitecture.md)
|
||||
* Default/no configuration runs "All In One" behavior
|
||||
* Additional configuration allows web interface to connect to multiple servers
|
||||
* Each server instance can run multiple reddit accounts as bots
|
||||
* Global/subreddit-level [**caching**](operator/caching.md) of Reddit APIs responses and CM results
|
||||
* [Database Persistence](operator/database.md) using SQLite, MySql, or Postgres
|
||||
* Audit trails for bot activity
|
||||
* Historical statistics
|
||||
* [Docker container](operator/installation.md#docker-recommended) and [docker-compose](operator/installation.md#docker-compose) support
|
||||
* Easy, UI-based [OAuth authentication](operator/addingBot.md) for adding Bots and moderator dashboard
|
||||
* Integration with [InfluxDB](https://www.influxdata.com) for detailed [time-series metrics](operator/database.md#influx) and a pre-built [Grafana](https://grafana.com) [dashboard](operator/database.md#grafana)
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [How It Works](#how-it-works)
|
||||
* [Getting Started](#getting-started)
|
||||
* [Configuration And Documentation](#configuration-and-documentation)
|
||||
* [Web UI and Screenshots](#web-ui-and-screenshots)
|
||||
|
||||
### How It Works
|
||||
|
||||
Each subreddit using the RCB bot configures its behavior via their own wiki page.
|
||||
|
||||
When a monitored **Activity** (new comment/submission, new modqueue item, etc.) is detected the bot runs through a list of [**Checks**](subreddit-configuration/README.md#checks) to determine what to do with the **Activity** from that Event. Each **Check** consists of :
|
||||
|
||||
#### Kind
|
||||
|
||||
Is this check for a submission or comment?
|
||||
|
||||
#### Rules
|
||||
|
||||
A list of [**Rules**](subreddit-configuration/README.md#rules) to run against the **Activity**. Triggered Rules can cause the whole Check to trigger and run its **Actions**
|
||||
|
||||
#### Actions
|
||||
|
||||
A list of [**Actions**](subreddit-configuration/README.md#actions) that describe what the bot should do with the **Activity** or **Author** of the activity (comment, remove, approve, etc.). The bot will run **all** Actions in this list.
|
||||
|
||||
___
|
||||
|
||||
The **Checks** for a subreddit are split up into **Submission Checks** and **Comment Checks** based on their **kind**. Each list of checks is run independently based on when events happen (submission or comment).
|
||||
|
||||
When an Event occurs all Checks of that type are run in the order they were listed in the configuration. When one check is triggered (an Action is performed) the remaining checks will not be run.
|
||||
|
||||
___
|
||||
|
||||
[Learn more about the RCB lifecycle and core concepts in the docs.](/README.md#how-it-works)
|
||||
|
||||
## Getting Started
|
||||
|
||||
#### Operators
|
||||
|
||||
This guide is for users who want to **run their own bot on a ContextMod instance.**
|
||||
|
||||
See the [Operator's Getting Started Guide](operator/gettingStarted.md)
|
||||
|
||||
#### Moderators
|
||||
|
||||
This guide is for **reddit moderators** who want to configure an existing CM bot to run on their subreddit.
|
||||
|
||||
See the [Moderator's Getting Started Guide](moderators/gettingStarted.md)
|
||||
|
||||
## Configuration and Documentation
|
||||
|
||||
Context Bot's configuration can be written in YAML (like automoderator) or [JSON5](https://json5.org/). Its schema conforms to [JSON Schema Draft 7](https://json-schema.org/). Additionally, many **operator** settings can be passed via command line or environmental variables.
|
||||
|
||||
* For **operators** (running the bot instance) see the [Operator Configuration](operator/configuration.md) guide
|
||||
* For **moderators** consult the [Subreddit Configuration Docs](subreddit-configuration/README.md)
|
||||
|
||||
[**Check the full docs for in-depth explanations of all concepts and examples**](/docs)
|
||||
|
||||
## Web UI and Screenshots
|
||||
|
||||
### Dashboard
|
||||
|
||||
CM comes equipped with a dashboard designed for use by both moderators and bot operators.
|
||||
|
||||
* Authentication via Reddit OAuth -- only accessible if you are the bot operator or a moderator of a subreddit the bot moderates
|
||||
* Connect to multiple ContextMod instances (specified in configuration)
|
||||
* Monitor API usage/rates
|
||||
* Monitoring and administration **per subreddit:**
|
||||
* Start/stop/pause various bot components
|
||||
* View statistics on bot usage (# of events, checks run, actions performed) and cache usage
|
||||
* View various parts of your subreddit's configuration and manually update configuration
|
||||
* View **real-time logs** of what the bot is doing on your subreddit
|
||||
* **Run bot on any permalink**
|
||||
|
||||

|
||||
|
||||
### Bot Setup/Authentication
|
||||
|
||||
A bot oauth helper allows operators to define oauth credentials/permissions and then generate unique, one-time invite links that allow moderators to authenticate their own bots without operator assistance. [Learn more about using the oauth helper.](operator/addingBot.md#cm-oauth-helper-recommended)
|
||||
|
||||
Operator view/invite link generation:
|
||||
|
||||

|
||||
|
||||
Moderator view/invite and authorization:
|
||||
|
||||

|
||||
|
||||
A similar helper and invitation experience is available for adding **subreddits to an existing bot.**
|
||||
|
||||

|
||||
|
||||
### Configuration Editor
|
||||
|
||||
A built-in editor using [monaco-editor](https://microsoft.github.io/monaco-editor/) makes editing configurations easy:
|
||||
|
||||
* Automatic JSON or YAML syntax validation and formatting
|
||||
* Automatic Schema (subreddit or operator) validation
|
||||
* All properties are annotated via hover popups
|
||||
* Unauthenticated view via `yourdomain.com/config`
|
||||
* Authenticated view loads subreddit configurations by simple link found on the subreddit dashboard
|
||||
* Switch schemas to edit either subreddit or operator configurations
|
||||
|
||||

|
||||
|
||||
### [Grafana Dashboard](operator/database.md#grafana)
|
||||
|
||||
* Overall stats (active bots/subreddits, api calls, per second/hour/minute activity ingest)
|
||||
* Over time graphs for events, per subreddit, and for individual rules/check/actions
|
||||
|
||||

|
||||
|
||||
## License
|
||||
|
||||
[MIT](/LICENSE)
|
||||
@@ -1,6 +1,12 @@
|
||||
---
|
||||
has_children: true
|
||||
title: Moderators
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
This section is for **reddit moderators**. It covers how to use a CM bot for your subreddit.
|
||||
|
||||
If you are trying to run a ContextMod instance (the actual software) please refer to the [operator section](/docs/operator/README.md).
|
||||
If you are trying to run a ContextMod instance (the actual software) please refer to the [operator section](../operator/README.md).
|
||||
|
||||
# Table of Contents
|
||||
|
||||
@@ -18,7 +24,7 @@ If you are trying to run a ContextMod instance (the actual software) please refe
|
||||
|
||||
The Context Mod **software** can manage multiple **bots** (reddit accounts used as bots, like `/u/MyCMBot`). Each bot can manage (run) multiple **subreddits** which is determined by the subreddits the account is a moderator of.
|
||||
|
||||
You, the moderator of a subreddit a CM bot runs in, can access/manage the Bot using the CM software's [web interface](/docs/images/subredditStatus.jpg) and control its behavior using the [web editor.](/docs/images/editor.jpg)
|
||||
You, the moderator of a subreddit a CM bot runs in, can access/manage the Bot using the CM software's [web interface](../images/subredditStatus.jpg) and control its behavior using the [web editor.](../images/editor.jpg)
|
||||
|
||||
## Your Relationship to CM
|
||||
|
||||
@@ -42,7 +48,7 @@ Unlike reddit, though, there is a greater level of trust required between you an
|
||||
Your bot is like an **invite-only version of Automoderator**:
|
||||
|
||||
* Unlike automoderator, you **must** interact with the Operator in order to get the bot working. It is not public for anyone to use.
|
||||
* Like automoderator, you **must** create a [configuration](/docs/subreddit/components/README.md) for it do anything.
|
||||
* Like automoderator, you **must** create a [configuration](../subreddit-configuration/README.md) for it do anything.
|
||||
* The bot does not come pre-configured for you. It is a blank slate and requires user input to be useful.
|
||||
* Also like automoderator, you are **entirely in control of the bot.**
|
||||
* You can start, stop, and edit its behavior at any time without needing to communicate with the Operator.
|
||||
@@ -51,11 +57,11 @@ Your bot is like an **invite-only version of Automoderator**:
|
||||
|
||||
# Getting Started
|
||||
|
||||
The [Getting Started](/docs/subreddit/gettingStarted.md) guide lays out the steps needed to go from nothing to a working Bot. If you are a moderator new to Context Mod this is where you want to begin.
|
||||
The [Getting Started](gettingStarted.md) guide lays out the steps needed to go from nothing to a working Bot. If you are a moderator new to Context Mod this is where you want to begin.
|
||||
|
||||
# Accessing The Bot
|
||||
|
||||
All bot management and editing is done through the [web interface.](/docs/images/subredditStatus.jpg) The URL used for accessing this interface is given to you by the **Operator** once they have agreed to host your bot/subreddit.
|
||||
All bot management and editing is done through the [web interface.](/../images/subredditStatus.jpg) The URL used for accessing this interface is given to you by the **Operator** once they have agreed to host your bot/subreddit.
|
||||
|
||||
NOTE: This interface is **only access to moderators of your subreddit** and [guests.](#guest-access) You must login to the web interface **with your moderator account** in order to access it.
|
||||
|
||||
@@ -63,9 +69,9 @@ A **guided tour** that helps show how to manage the bot at a high-level is avail
|
||||
|
||||
## Editing The Bot
|
||||
|
||||
Find the [editor in the web interface](/docs/webInterface.md#editingupdating-your-config) to access the built-in editor for the bot.
|
||||
Find the [editor in the web interface](../webInterface.md#editingupdating-your-config) to access the built-in editor for the bot.
|
||||
|
||||
[The editor](/docs/images/editor.jpg) should be your all-in-one location for viewing and editing your bot's behavior. **It is equivalent to Automoderator's editor page.**
|
||||
[The editor](../images/editor.jpg) should be your all-in-one location for viewing and editing your bot's behavior. **It is equivalent to Automoderator's editor page.**
|
||||
|
||||
The editor features:
|
||||
|
||||
@@ -76,11 +82,11 @@ The editor features:
|
||||
|
||||
# Configuration
|
||||
|
||||
Use the [Configuration Reference](/docs/subreddit/components/README.md) to learn about all the different components available for building a CM configuration.
|
||||
Use the [Configuration Reference](../subreddit-configuration/README.md) to learn about all the different components available for building a CM configuration.
|
||||
|
||||
Additionally, refer to [How It Works](/docs/README.md#how-it-works) and [Core Concepts](/docs/README.md#concepts) to learn the basic of CM configuration.
|
||||
Additionally, refer to [How It Works](../README.md#how-it-works) and [Core Concepts](../README.md#concepts) to learn the basic of CM configuration.
|
||||
|
||||
After you have the basics under your belt you could use the [subreddit-reddit example configurations](/docs/subreddit/components/subredditReady) to familiarize yourself with a complete configuration and ways to use CM.
|
||||
After you have the basics under your belt you could use the [subreddit configurations cookbook](../subreddit-configuration/cookbook) to familiarize yourself with a complete configuration and ways to use CM.
|
||||
|
||||
# Guest Access
|
||||
|
||||
@@ -92,4 +98,4 @@ Guests can do everything a regular mod can except view/add/remove Guest. They ca
|
||||
|
||||
**Guests are helpful if you are new to CM and know reddit users that can help you get started.**
|
||||
|
||||
[Add guests from the Subreddit tab in the main interface.](/docs/images/guests.jpg)
|
||||
[Add guests from the Subreddit tab in the main interface.](../images/guests.jpg)
|
||||
@@ -1,5 +1,12 @@
|
||||
---
|
||||
parent: Moderators
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
This getting started guide is for **reddit moderators** -- that is, someone who wants **an existing ContextMod bot to run on their subreddit.** If you are trying to run a ContextMod
|
||||
instance (software) please refer to the [operator getting started](/docs/operator/gettingStarted.md) guide.
|
||||
instance (software) please refer to the [operator getting started](../operator/gettingStarted.md) guide.
|
||||
|
||||
# Table of Contents
|
||||
|
||||
@@ -14,8 +21,8 @@ instance (software) please refer to the [operator getting started](/docs/operato
|
||||
|
||||
Before continuing with this guide you should first make sure you understand how a ContextMod works. Please review this documentation:
|
||||
|
||||
* [How It Works](/docs/README.md#how-it-works)
|
||||
* [Core Concepts](/docs/README.md#concepts)
|
||||
* [How It Works](../README.md#how-it-works)
|
||||
* [Core Concepts](../README.md#concepts)
|
||||
|
||||
# Choose A Bot
|
||||
|
||||
@@ -81,11 +88,11 @@ The default location for this page is at `https://old.reddit.com/r/YOURSUBERDDIT
|
||||
|
||||
The bot automatically tries to create its configuration wiki page. You can find the result of this in the log for your subreddit in the web interface.
|
||||
|
||||
If this fails for some reason you can create the wiki page through the web interface by navigating to your subreddit's tab, opening the [built-in editor (click **View**)](/docs/images/configBox.png), and following the directions in **Create configuration for...** link found there.
|
||||
If this fails for some reason you can create the wiki page through the web interface by navigating to your subreddit's tab, opening the [built-in editor (click **View**)](../images/configBox.png), and following the directions in **Create configuration for...** link found there.
|
||||
|
||||
If neither of the above approaches work, or you do not wish to use the web interface, expand the section below for directions on how to manually setup the wiki page:
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
* Visit the wiki page of the subreddit you want the bot to moderate
|
||||
* The default location the bot checks for a configuration is at `https://old.reddit.com/r/YOURSUBERDDIT/wiki/botconfig/contextbot`
|
||||
@@ -104,11 +111,11 @@ If you already have a configuration you may skip the below step and go directly
|
||||
|
||||
### Using an Example Config
|
||||
|
||||
Visit the [Examples](https://github.com/FoxxMD/context-mod/tree/master/docs/examples) folder to find various examples of individual rules or see the [subreddit-ready examples.](/docs/subreddit/components/subredditReady)
|
||||
Visit the [Examples](https://github.com/FoxxMD/context-mod/tree/master../examples) folder to find various examples of individual rules or see the [subreddit cookbook examples.](../subreddit-configuration/cookbook)
|
||||
|
||||
After you have found a configuration to use as a starting point:
|
||||
|
||||
* Copy the URL for the configuration file EX `https://github.com/FoxxMD/context-mod/blob/master/docs/examples/subredditReady/freekarma.json5` and either:
|
||||
* Copy the URL for the configuration file EX `https://github.com/FoxxMD/context-mod/blob/master../examples/subredditReady/freekarma.json5` and either:
|
||||
* (Easiest) **Load** it into your [subreddit's built-in editor](#using-the-built-in-editor) and **Save**
|
||||
* or on the file's page, click the **Raw** button, select all and copy to your clipboard, and [manually save to your wiki page](#manually-saving)
|
||||
|
||||
@@ -136,13 +143,13 @@ PROTIP: Find an [example config](#using-an-example-config) to use as a starting
|
||||
In the web interface each subreddit's tab has access to the built-in editor. Use this built-in editor to automatically create, load, or save the configuration for that subreddit's wiki.
|
||||
|
||||
* Visit the tab for the subreddit you want to edit the configuration of
|
||||
* Open the [built-in editor by click **View**](/docs/images/configBox.png)
|
||||
* Open the [built-in editor by click **View**](../images/configBox.png)
|
||||
* Edit your configuration
|
||||
* Follow the directions on the **Save to r/..** link found at the top of the editor to automatically save your configuration
|
||||
|
||||
### Manually Saving
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
* Open the wiki page you created in the [wiki setup step](#setup-wiki-page) and click **edit**
|
||||
* Copy-paste your configuration into the wiki text box
|
||||
@@ -1,4 +1,9 @@
|
||||
# Operator Guide
|
||||
---
|
||||
has_children: true
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Operator
|
||||
|
||||
An **Operator** is the user **running the ContextMod software.**
|
||||
|
||||
@@ -6,18 +11,18 @@ They are responsible for configuring the software at a high-level and managing a
|
||||
|
||||
* Creating cache/database servers and configuring their connections in CM
|
||||
* Provisioning the [Reddit Clients](#provisioning-a-reddit-client) needed to run bots and the CM UI
|
||||
* Providing [global-level configuration](/docs/operator/configuration.md) that affects general bot/subreddit behavior
|
||||
* Providing [global-level configuration](configuration.md) that affects general bot/subreddit behavior
|
||||
* Onboarding new bots/subreddits
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Client-Server Architecture](/docs/serverClientArchitecture.md)
|
||||
* [Getting Started](/docs/operator/gettingStarted.md)
|
||||
* [Installation](/docs/operator/installation.md)
|
||||
* [Client-Server Architecture](serverClientArchitecture.md)
|
||||
* [Getting Started](gettingStarted.md)
|
||||
* [Installation](installation.md)
|
||||
* [Provisioning a Reddit Client](#provisioning-a-reddit-client)
|
||||
* [Configuration](/docs/operator/configuration.md)
|
||||
* [Adding A Bot](/docs/operator/addingBot.md)
|
||||
* [Configuration](configuration.md)
|
||||
* [Adding A Bot](addingBot.md)
|
||||
|
||||
# Overview
|
||||
|
||||
@@ -28,13 +33,13 @@ CM is composed of two applications that operate independently but are packaged t
|
||||
|
||||
Both applications authenticate, and are primarily operated, by using [Reddit's API through OAuth.](https://github.com/reddit-archive/reddit/wiki/OAuth2) The **Client** uses OAuth to verify the identity of moderators logging into the web interface. The **Server** uses oauth tokens to interact with Reddit's API and operate all the configured bots.
|
||||
|
||||
In its default mode of operation CM takes care of all the interaction between **Server** and **Client** for you so that you can effectively treat it as a monolithic application. Learn more about CM's architecture and other operation modes in the [Server-Client Architecture documentation.](/docs/serverClientArchitecture.md)
|
||||
In its default mode of operation CM takes care of all the interaction between **Server** and **Client** for you so that you can effectively treat it as a monolithic application. Learn more about CM's architecture and other operation modes in the [Server-Client Architecture documentation.](../serverClientArchitecture.md)
|
||||
|
||||
# [Getting Started](/docs/operator/gettingStarted.md)
|
||||
# [Getting Started](gettingStarted.md)
|
||||
|
||||
The [Getting Started](/docs/operator/gettingStarted.md) guide serves as a straight-forward "how-to" for standing up a CM server from scratch with minimal explanation.
|
||||
The [Getting Started](gettingStarted.md) guide serves as a straight-forward "how-to" for standing up a CM server from scratch with minimal explanation.
|
||||
|
||||
# [Installation](/docs/operator/installation.md)
|
||||
# [Installation](installation.md)
|
||||
|
||||
CM has many installation options:
|
||||
|
||||
@@ -42,7 +47,7 @@ CM has many installation options:
|
||||
* Built/pulled from a Docker image hosted on Dockerhub
|
||||
* Deployed to Heroku with a Quick Deploy template (experimental)
|
||||
|
||||
Refer to the [Installation](/docs/operator/installation.md) docs for more information.
|
||||
Refer to the [Installation](installation.md) docs for more information.
|
||||
|
||||
# Provisioning A Reddit Client
|
||||
|
||||
@@ -60,18 +65,18 @@ Click **create app**.
|
||||
|
||||
Then write down your **Client ID, Client Secret, and Redirect Uri** somewhere
|
||||
|
||||
# [Configuration](/docs/operator/configuration.md)
|
||||
# [Configuration](configuration.md)
|
||||
|
||||
The [Configuration](/docs/operator/configuration.md) documentation covers:
|
||||
The [Configuration](configuration.md) documentation covers:
|
||||
|
||||
* How CM's configuration can be defined
|
||||
* How to create and define location for a config file
|
||||
* Running CM from the command line
|
||||
* Documentation for configuration on Bots, the web client, API, and more...
|
||||
|
||||
# [Adding A Bot](/docs/operator/addingBot.md)
|
||||
# [Adding A Bot](addingBot.md)
|
||||
|
||||
The [Adding A Bot](/docs/operator/addingBot.md) documentation covers:
|
||||
The [Adding A Bot](addingBot.md) documentation covers:
|
||||
|
||||
* What is a Bot?
|
||||
* What is needed to add a Bot to CM?
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
parent: Operator
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Adding A Bot
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [What is a Bot?](#what-is-a-bot)
|
||||
@@ -19,7 +26,7 @@ There is nothing special about the account! What's special is how its used -- th
|
||||
|
||||
These things need to be done before a Bot can be added to CM:
|
||||
|
||||
* [Provisioned a Reddit Client](/docs/operator/README.md#provisioning-a-reddit-client)
|
||||
* [Provisioned a Reddit Client](README.md#provisioning-a-reddit-client)
|
||||
* You or the person who controls the Bot account must have account credentials (username/password). Logging in to reddit is part of the setup process.
|
||||
* If the bot does not exist **create a reddit account for it.**
|
||||
* If the bot does exist make sure you are in communication with the owner of the account.
|
||||
@@ -38,7 +45,7 @@ This method will use CM's built in oauth flow. It is recommended because:
|
||||
If this is your **first time adding a bot** you must make sure you have
|
||||
|
||||
* done the [prerequisites](#prerequisites)
|
||||
* created a [minimum operator configuration](/docs/operator/configuration.md#minimum-config)
|
||||
* created a [minimum operator configuration](configuration.md#minimum-config)
|
||||
* that specifies the client id/secret from provisioning your reddit client
|
||||
* specified **Operator Name** in the configuration
|
||||
|
||||
@@ -56,14 +63,14 @@ Follow the directions in the helper to create a **Bot Invite Link.**
|
||||
|
||||
Visit the **Bot Invite Link** while **logged in to reddit as the bot account** to begin the onboarding process. Refer to the [Onboarding Your Bot]() subreddit documentation for more information on this process.
|
||||
|
||||
At the end of the onboarding process the bot should be automatically added to your operator configuration. If there is an issue with automatically adding it then the oauth credentials will be displayed at the end of onboarding and can be [manually added to the configuration.](/docs/operator/configuration.md#manually-adding-a-bot)
|
||||
At the end of the onboarding process the bot should be automatically added to your operator configuration. If there is an issue with automatically adding it then the oauth credentials will be displayed at the end of onboarding and can be [manually added to the configuration.](configuration.md#manually-adding-a-bot)
|
||||
|
||||
## Aardvark OAuth Helper
|
||||
|
||||
This method should only be used if you cannot use the [CM OAuth Helper method.](#cm-oauth-helper-recommended)
|
||||
|
||||
* Visit [https://not-an-aardvark.github.io/reddit-oauth-helper/](https://not-an-aardvark.github.io/reddit-oauth-helper/) and follow the instructions given.
|
||||
* **Note:** You will need to update the **redirect uri** you set when [provisioning your reddit client.](/docs/operator/README.md#provisioning-a-reddit-client)
|
||||
* **Note:** You will need to update the **redirect uri** you set when [provisioning your reddit client.](README.md#provisioning-a-reddit-client)
|
||||
* Input your **Client ID** and **Client Secret** in the text boxes with those names.
|
||||
* Choose scopes. **It is very important you check everything on this list or CM may not work correctly**
|
||||
* edit
|
||||
@@ -82,5 +89,5 @@ This method should only be used if you cannot use the [CM OAuth Helper method.](
|
||||
* wikiread
|
||||
* wikiedit (if you are using Toolbox User Notes)
|
||||
* Click **Generate tokens**, you will get a popup asking you to approve access (or login) -- **the account you approve access with is the account that Bot will control.**
|
||||
* After approving an **Access Token** and **Refresh Token** will be shown at the bottom of the page. Use these to [manually add a bot to your operator configuration.](/docs/operator/configuration.md#manually-adding-a-bot)
|
||||
* After approving an **Access Token** and **Refresh Token** will be shown at the bottom of the page. Use these to [manually add a bot to your operator configuration.](configuration.md#manually-adding-a-bot)
|
||||
* After adding the bot you will need to restart CM.
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
parent: Operator
|
||||
---
|
||||
|
||||
# Caching
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
parent: Operator
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Configuration
|
||||
|
||||
The **Operator** configuration refers to configuration used configure to the actual application/bot. This is different
|
||||
from the **Subreddit** configuration that is defined in each Subreddit's wiki and determines the rules/actions for
|
||||
activities the Bot runs on.
|
||||
@@ -36,7 +43,7 @@ configuration.
|
||||
Using a file has many benefits over using ARG or ENV:
|
||||
|
||||
* CM can automatically update your configuration
|
||||
* CM can automatically add bots via the [CM OAuth Helper](/docs/operator/addingBot.md#cm-oauth-helper-recommended)
|
||||
* CM can automatically add bots via the [CM OAuth Helper](addingBot.md#cm-oauth-helper-recommended)
|
||||
* CM has a built-in configuration editor that can help you build and validate your configuration file
|
||||
* File config is **required** if adding multiple bots to CM
|
||||
|
||||
@@ -44,8 +51,8 @@ Using a file has many benefits over using ARG or ENV:
|
||||
|
||||
By default CM will look for `config.yaml` or `config.json` in the `DATA_DIR` directory:
|
||||
|
||||
* [Local installation](/docs/operator/installation.md#locally) -- `DATA_DIR` is the root of your installation directory (same folder as `package.json`)
|
||||
* [Docker](/docs/operator/installation.md#docker-recommended) -- `DATA_DIR` is at `/config` in the container
|
||||
* [Local installation](installation.md#locally) -- `DATA_DIR` is the root of your installation directory (same folder as `package.json`)
|
||||
* [Docker](installation.md#docker-recommended) -- `DATA_DIR` is at `/config` in the container
|
||||
|
||||
The `DATA_DIR` directory can be changed by passing `DATA_DIR` as an environmental variable EX `DATA_DIR=/path/to/directory`
|
||||
|
||||
@@ -65,7 +72,7 @@ One ContextMod instance can
|
||||
|
||||
However, the default configuration (using **ENV/ARG**) assumes your intention is to run one bot (one reddit account) on one CM instance without these additional features. This is to make this mode of operation easier for users with this intention.
|
||||
|
||||
To take advantage of this additional features you **must** use a **FILE** configuration. Learn about how this works and how to configure this scenario in the [Architecture Documentation.](/docs/serverClientArchitecture.md)
|
||||
To take advantage of this additional features you **must** use a **FILE** configuration. Learn about how this works and how to configure this scenario in the [Architecture Documentation.](serverClientArchitecture.md)
|
||||
|
||||
## CLI Usage
|
||||
|
||||
@@ -79,7 +86,7 @@ node src/index.js run
|
||||
|
||||
Run `node src/index.js run help` to get a list of available command line options (denoted by **ARG** above):
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
```
|
||||
Usage: index [options] [command]
|
||||
@@ -124,11 +131,11 @@ Options:
|
||||
|
||||
# Minimum Configuration
|
||||
|
||||
The minimum configuration required to run CM assumes you have no bots and want to use CM to [add your first bot.](/docs/operator/addingBot.md#cm-oauth-helper-recommended)
|
||||
The minimum configuration required to run CM assumes you have no bots and want to use CM to [add your first bot.](addingBot.md#cm-oauth-helper-recommended)
|
||||
|
||||
You will need have this information available:
|
||||
|
||||
* From [provision a reddit client](/docs/operator/README.md#provisioning-a-reddit-client)
|
||||
* From [provision a reddit client](README.md#provisioning-a-reddit-client)
|
||||
* Client ID
|
||||
* Client Secret
|
||||
* Redirect URI (if different from default `http://localhost:8085/callback`)
|
||||
@@ -153,7 +160,7 @@ Configured using the `bots` top-level property. Bot configuration can override a
|
||||
|
||||
## Adding A Bot
|
||||
|
||||
If you use the [CM OAuth Helper](/docs/operator/addingBot.md#cm-oauth-helper-recommended) and it works successfully then the configuration for the Bot will be automatically added.
|
||||
If you use the [CM OAuth Helper](addingBot.md#cm-oauth-helper-recommended) and it works successfully then the configuration for the Bot will be automatically added.
|
||||
|
||||
### Manually Adding a Bot
|
||||
|
||||
@@ -166,7 +173,7 @@ Minimum information required for a valid bot:
|
||||
* Refresh Token
|
||||
* Access Token
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
<summary>Example</summary>
|
||||
|
||||
```yaml
|
||||
@@ -211,7 +218,7 @@ Below are examples of the minimum required config to run the application using a
|
||||
|
||||
Using **FILE**
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
See [Specify File Location](#specify-file-location) for where this file would be located.
|
||||
|
||||
@@ -248,7 +255,7 @@ JSON (`config.json5`)
|
||||
|
||||
Using **ENV** (`.env`)
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
```
|
||||
OPERATOR=YourRedditUsername
|
||||
@@ -261,7 +268,7 @@ REDIRECT_URI=http://localhost:8085/callback
|
||||
|
||||
Using **ARG**
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
```
|
||||
node src/index.js run --clientId=f4b4df1c7b2 --clientSecret=34v5q1c56ub --redirectUri=http://localhost:8085/callback
|
||||
@@ -275,7 +282,7 @@ An example of using multiple configuration levels together IE all are provided t
|
||||
|
||||
**FILE**
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -296,7 +303,7 @@ logging:
|
||||
|
||||
**ENV** (`.env`)
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
```
|
||||
CLIENT_SECRET=34v5q1c56ub
|
||||
@@ -308,7 +315,7 @@ PORT=9008
|
||||
|
||||
**ARG**
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
```
|
||||
node src/index.js run --subreddits=sub1 --clientId=34v5q1c56ub
|
||||
@@ -328,9 +335,9 @@ log level: debug
|
||||
|
||||
## Configuring Client for Many Instances
|
||||
|
||||
See the [Architecture Docs](/docs/serverClientArchitecture.md) for more information.
|
||||
See the [Architecture Docs](erverClientArchitecture.md) for more information.
|
||||
|
||||
<details>
|
||||
<details markdown="block">
|
||||
|
||||
YAML
|
||||
|
||||
@@ -401,8 +408,8 @@ JSON
|
||||
|
||||
# Cache Configuration
|
||||
|
||||
See the [Cache Configuration](/docs/operator/caching.md) documentation.
|
||||
See the [Cache Configuration](caching.md) documentation.
|
||||
|
||||
# Database Configuration
|
||||
|
||||
See the [Database Configuration](/docs/operator/database.md) documentation.
|
||||
See the [Database Configuration](database.md) documentation.
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
parent: Operator
|
||||
---
|
||||
|
||||
# Database
|
||||
|
||||
# Overview
|
||||
|
||||
CM uses a database to store three types of data:
|
||||
@@ -31,16 +37,16 @@ databaseConfig:
|
||||
|
||||
## SQLite
|
||||
|
||||
When using a [local installation](/docs/installation.md#locally) the default database is `sqljs`, which requires no binary dependencies. When using [docker](/docs/operator/installation.md#docker-recommended) the default is `better-sqlite3`.
|
||||
When using a [local installation](installation.md#locally) the default database is `sqljs`, which requires no binary dependencies. When using [docker](installation.md#docker-recommended) the default is `better-sqlite3`.
|
||||
|
||||
**NOTE:** It is **NOT RECOMMENDED** to use `sqljs` in a production environment for performance reasons. You should at least switch to `better-sqlite3` or preferably MySql/Postgres.
|
||||
|
||||
* [`sqljs` connection options](https://typeorm.io/data-source-options#sqljs-data-source-options)
|
||||
* [`better-sqlite3` connection options](https://typeorm.io/data-source-options#better-sqlite3-data-source-options)
|
||||
|
||||
For both sqlite types, if no database/location is specified, it will be created in the [`DATA_DIR` directory.](/docs/operator/configuration.md#specify-file-location)
|
||||
For both sqlite types, if no database/location is specified, it will be created in the [`DATA_DIR` directory.](configuration.md#specify-file-location)
|
||||
|
||||
If CM detects it cannot **read and write** to the database files, or directory if no files exist, it will fallback to using an in-memory database that will be lost when CM restarts. If you have trouble with r/w permissions and are using docker make sure [file permissions are correct for your mounted volume.](/docs/operator/installation.md#linux-host)
|
||||
If CM detects it cannot **read and write** to the database files, or directory if no files exist, it will fallback to using an in-memory database that will be lost when CM restarts. If you have trouble with r/w permissions and are using docker make sure [file permissions are correct for your mounted volume.](installation.md#linux-host)
|
||||
|
||||
## MySQL/MariaDB
|
||||
|
||||
@@ -95,7 +101,7 @@ The Retention Policy can be specified at operator level, bot, subreddit *overrid
|
||||
operator:
|
||||
name: u/MyRedditAccount
|
||||
databaseConfig:
|
||||
retention: '3 months' # each subreddit will retain 3 more of recorded events
|
||||
retention: '3 months' # each subreddit will retain 3 months of recorded events
|
||||
bots:
|
||||
# all subreddits this bot moderates will have 3 month retention
|
||||
- name: u/OneBotAccount
|
||||
@@ -172,7 +178,7 @@ influxConfig:
|
||||
|
||||
A pre-built dashboard for [Grafana](https://grafana.com) can be imported to display overall metrics/stats using InfluxDB data.
|
||||
|
||||

|
||||

|
||||
|
||||
* Create a new Data Source using **InfluxDB** type
|
||||
* Choose **Flux** for the **Query Language**
|
||||
@@ -181,7 +187,7 @@ A pre-built dashboard for [Grafana](https://grafana.com) can be imported to disp
|
||||
* Click **Save and test**
|
||||
* Import Dashboard
|
||||
* **Browse** the Dashboard pane
|
||||
* Click **Import** and **upload** the [grafana dashboard json file](/docs/operator/grafana.json)
|
||||
* Click **Import** and **upload** the [grafana dashboard json file](grafana.json)
|
||||
* Chose the data source you created from the **InfluxDB CM** dropdown
|
||||
* Click **Import**
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
This getting started guide is for **Operators** -- that is, someone who wants to run the actual software for a ContentMod bot. If you are a **Moderator** check out the [moderator getting started](/docs/subreddit/gettingStarted.md) guide instead.
|
||||
---
|
||||
parent: Operator
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
This getting started guide is for **Operators** -- that is, someone who wants to run the actual software for a ContentMod bot. If you are a **Moderator** check out the [moderator getting started](/docs/moderators/gettingStarted.md) guide instead.
|
||||
|
||||
# Table of Contents
|
||||
|
||||
@@ -11,11 +18,11 @@ This getting started guide is for **Operators** -- that is, someone who wants to
|
||||
|
||||
# Installation
|
||||
|
||||
Follow the [installation](/docs/operator/installation.md) documentation. It is recommended to use **Docker** since it is self-contained.
|
||||
Follow the [installation](installation.md) documentation. It is recommended to use **Docker** since it is self-contained.
|
||||
|
||||
# Create a Reddit Client
|
||||
|
||||
[Create a reddit client](/docs/operator/README.md#provisioning-a-reddit-client)
|
||||
[Create a reddit client](README.md#provisioning-a-reddit-client)
|
||||
|
||||
# Start ContextMod
|
||||
|
||||
@@ -27,11 +34,11 @@ The First Time Setup page will ask you to input:
|
||||
* Client Secret (from [Create a Reddit Client](#create-a-reddit-client))
|
||||
* Operator -- this is the username of your main Reddit account.
|
||||
|
||||
**Write Config** and then restart CM. You have now created the [minimum configuration](/docs/operator/configuration.md#minimum-configuration) required to run CM.
|
||||
**Write Config** and then restart CM. You have now created the [minimum configuration](configuration.md#minimum-configuration) required to run CM.
|
||||
|
||||
# Add A Bot to CM
|
||||
|
||||
You should automatically be directed to the [Bot Invite Helper](/docs/operator/addingBot.md#cm-oauth-helper-recommended) used to authorize and add a Bot to your CM instance.
|
||||
You should automatically be directed to the [Bot Invite Helper](addingBot.md#cm-oauth-helper-recommended) used to authorize and add a Bot to your CM instance.
|
||||
|
||||
Follow the directions here and **create an Authorization Invite** at the bottom of the page.
|
||||
|
||||
@@ -47,8 +54,8 @@ To monitor the behavior of bots running on your instance visit http://localhost:
|
||||
|
||||
# What's Next?
|
||||
|
||||
As an operator you should familiarize yourself with how the [operator configuration](/docs/operator/configuration.md) you made works. This will help you understand how to get the most of your CM instance by leveraging the [Cache](/docs/oeprator/caching.md) and [Database](/docs/operator/database.md) effectively as well as provide you will all possible options for configuring CM using the [schema.](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FOperatorConfig.json)
|
||||
As an operator you should familiarize yourself with how the [operator configuration](configuration.md) you made works. This will help you understand how to get the most of your CM instance by leveraging the [Cache](caching.md) and [Database](database.md) effectively as well as provide you will all possible options for configuring CM using the [schema.](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FOperatorConfig.json)
|
||||
|
||||
If you are also the moderator of the subreddit the bot will be running you should check out the [moderator getting started guide.](/docs/subreddit/gettingStarted.md#setup-wiki-page)
|
||||
If you are also the moderator of the subreddit the bot will be running you should check out the [moderator getting started guide.](../moderators/gettingStarted.md#setup-wiki-page)
|
||||
|
||||
You might also be interested in these [quick tips for using the web interface](/docs/webInterface.md). Additionally, on the dashboard click the **Help** button at the top of the page to get a guided tour of the dashboard.
|
||||
You might also be interested in these [quick tips for using the web interface](../webInterface.md). Additionally, on the dashboard click the **Help** button at the top of the page to get a guided tour of the dashboard.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
parent: Operator
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
In order to run a ContextMod instance you must first you must install it somewhere.
|
||||
@@ -13,7 +18,7 @@ Images available from these registeries:
|
||||
* [Dockerhub](https://hub.docker.com/r/foxxmd/context-mod) - `docker.io/foxxmd/context-mod`
|
||||
* [GHCR](https://github.com/foxxmd/context-mod/pkgs/container/context-mod) - `ghcr.io/foxxmd/context-mod`
|
||||
|
||||
An example of starting the container using the [minimum configuration](/docs/operator/configuration.md#minimum-config):
|
||||
An example of starting the container using the [minimum configuration](configuration.md#minimum-config):
|
||||
|
||||
* Bind the directory where your config file, logs, and database are located on your host machine into the container's default `DATA_DIR` by using `-v /host/path/folder:/config`
|
||||
* Note: **You must do this** or else your configuration will be lost next time your container is updated.
|
||||
@@ -40,6 +45,34 @@ To get the UID and GID for the current user run these commands from a terminal:
|
||||
docker run -d -v /host/path/folder:/config -p 8085:8085 -e PUID=1000 -e PGID=1000 ghcr.io/foxxmd/context-mod:latest
|
||||
```
|
||||
|
||||
### Docker-Compose
|
||||
|
||||
The included [`docker-compose.yml`](/docker-compose.yml) provides production-ready dependencies for CM to use:
|
||||
|
||||
* [Redis](https://redis.io/) for caching
|
||||
* [MariaDB](https://mariadb.org/) for database
|
||||
* Optionally, [Influx/Grafana](database.md#influx) instances
|
||||
|
||||
#### Setup
|
||||
|
||||
The included `docker-compose.yml` file is written for **Docker Compose v2.**
|
||||
|
||||
For new installations copy [`config.yaml`](/docker/config/docker-compose/config.yaml) into a folder named `data` in the same folder `docker-compose.yml` will be run from. For users migrating their existing CM instances to docker-compose, copy your existing `config.yaml` into the same `data` folder.
|
||||
|
||||
Read through the comments in both `docker-compose.yml` and `config.yaml` and makes changes to any relevant settings (passwords, usernames, etc...). Ensure that any settings used in both files (EX mariaDB passwords) match.
|
||||
|
||||
To build and start CM:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
To include Grafana/Influx dependencies run:
|
||||
|
||||
```bash
|
||||
docker compose --profile full up -d
|
||||
```
|
||||
|
||||
## Locally
|
||||
|
||||
Requirements:
|
||||
@@ -57,7 +90,7 @@ npm install
|
||||
tsc -p .
|
||||
```
|
||||
|
||||
An example of running CM using the [minimum configuration](/docs/operator/configuration.md#minimum-config) with a [configuration file](/docs/operator/configuration.md#file-configuration-recommended):
|
||||
An example of running CM using the [minimum configuration](configuration.md#minimum-config) with a [configuration file](configuration.md#file-configuration-recommended):
|
||||
|
||||
```bash
|
||||
node src/index.js run
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
parent: Operator
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
# Overview
|
||||
|
||||
ContextMod's high-level functionality is separated into two **independently run** applications.
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
has_children: true
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
# 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.](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fmaster%2Fsrc%2FSchema%2FApp.json)
|
||||
@@ -45,13 +52,6 @@ This list is not exhaustive. [For complete documentation on a subreddit's config
|
||||
* [Toolbox UserNote](#usernote)
|
||||
* [Mod Note](#mod-note)
|
||||
* [Filters](#filters)
|
||||
* [Filter Types](#filter-types)
|
||||
* [Author Filter](#author-filter)
|
||||
* [Mod Notes/Actions](#mod-actionsnotes-filter)
|
||||
* [Toolbox UserNotes](#toolbox-usernotes-filter)
|
||||
* [Item Filter](#item-filter)
|
||||
* [Subreddit Filter](#subreddit-filter)
|
||||
* [Named Filters](#named-filters)
|
||||
* [Common Patterns](#common-patterns)
|
||||
* [Conditions](#conditions)
|
||||
* [Activities `window`](#activities-window)
|
||||
@@ -70,11 +70,12 @@ This list is not exhaustive. [For complete documentation on a subreddit's config
|
||||
* [Rule Order](#rule-order)
|
||||
* [Configuration Re-use and Caching](#configuration-re-use-and-caching)
|
||||
* [Partial Configurations](#partial-configurations)
|
||||
* [Sharing Configs Between Subreddits](#sharing-full-configs-as-runs)
|
||||
* [Subreddit-ready examples](#subreddit-ready-examples)
|
||||
|
||||
# Runs
|
||||
|
||||
A **Run** is made up of a set of [**Checks**](#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](/docs/README.md#how-it-works) section to see how Runs fit into CM's lifecycle.
|
||||
A **Run** is made up of a set of [**Checks**](#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](../README.md#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:
|
||||
|
||||
@@ -134,13 +135,13 @@ A **Check** is a set of:
|
||||
* Zero or more [**Rules**](#rules) that define what conditions should **trigger** this Check.
|
||||
* Zero or more [**Actions**](#actions) that define what the bot should do once the Check is **triggered**.
|
||||
|
||||
Refer to the [How It Works](/docs/README.md#how-it-works) section to see how Checks fit into CM's lifecycle.
|
||||
Refer to the [How It Works](../README.md#how-it-works) section to see how Checks fit into CM's lifecycle.
|
||||
|
||||
* If a Check has no Rules and passes any [Filters](#filters) it is automatically triggered
|
||||
* If a Check is triggered and has no Actions it is only [recorded](#recording-options)
|
||||
* **Checks must have explicitly defined:**
|
||||
* **name**
|
||||
* **kind** -- what type of [Activity](/docs/README.md#activity) (`submission` or `comment`) it should process
|
||||
* **kind** -- what type of [Activity](../README.md#activity) (`submission` or `comment`) it should process
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
@@ -216,11 +217,11 @@ This enables a user to arbitrarily configure how CM responds to the triggering (
|
||||
|
||||
Each Check will **always** have these properties defined -- either explicitly or passed down as defaults from a [Run](#flow-control-defaults-using-runs), [Subreddit](#filter-defaults), or Operator configuration.
|
||||
|
||||
Refer to the main [**Flow Control** documentation](/docs/subreddit/components/advancedConcepts/flowControl.md) for an in-depth explanation and all possible options.
|
||||
Refer to the main [**Flow Control** documentation](advancedConcepts/flowControl.md) for an in-depth explanation and all possible options.
|
||||
|
||||
## Recording Options
|
||||
|
||||
`postFail` and `postTrigger` also enable specifying if/how an [Event](/docs/README.md#event) is recorded. Valid options for recording:
|
||||
`postFail` and `postTrigger` also enable specifying if/how an [Event](../README.md#event) is recorded. Valid options for recording:
|
||||
|
||||
* `false` -- do not record this Event
|
||||
* `true` -- record Event to all available outputs
|
||||
@@ -250,7 +251,7 @@ When an Activity has finished being processed CM will aggregate all Recording Op
|
||||
|
||||
# Rules
|
||||
|
||||
A **Rule** is some set of **criteria** (conditions) that are tested against an [Activity](/docs/README.md#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.
|
||||
A **Rule** is some set of **criteria** (conditions) that are tested against an [Activity](../README.md#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.
|
||||
|
||||
@@ -293,13 +294,13 @@ runs:
|
||||
|
||||
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.
|
||||
|
||||
See **Rule Name Reuse Examples [YAML](/docs/subreddit/components/advancedConcepts/ruleNameReuse.yaml) | [JSON](/docs/subreddit/components/advancedConcepts/ruleNameReuse.json5)**
|
||||
See **Rule Name Reuse Examples [YAML](advancedConcepts/ruleNameReuse.yaml) | [JSON](advancedConcepts/ruleNameReuse.json5)**
|
||||
|
||||
## List of Rules
|
||||
|
||||
### Attribution
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/attribution)
|
||||
[**Full Documentation**](in-depth/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:
|
||||
|
||||
@@ -310,7 +311,7 @@ The **Attribution** rule will aggregate an Author's content Attributions (youtub
|
||||
|
||||
### Recent Activity
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/recentActivity)
|
||||
[**Full Documentation**](in-depth/recentActivity)
|
||||
|
||||
Given a list subreddit criteria, the **Recent Activity** rule finds Activities matching those criteria in the Author's history over [window](#activities-window) and then allows for comparing different facets of the results:
|
||||
|
||||
@@ -322,14 +323,14 @@ The above can also be expressed as a percentage of all activities found, instead
|
||||
|
||||
The search can also be modified in a number of ways:
|
||||
|
||||
* Filter found activities using an [Item Filter](#item-filter)
|
||||
* Filter found activities using an [Item Filter](in-depth/filters#item-filter)
|
||||
* Only return activities that match the Activity from the Event being processed
|
||||
* Using [image detection](/docs/imageComparison.md) (pixel or perceptual hash matching)
|
||||
* Using [image detection](imageComparison.md) (pixel or perceptual hash matching)
|
||||
* Only return certain types of activities (only submission or only comments)
|
||||
|
||||
### Repeat Activity
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/repeatActivity)
|
||||
[**Full Documentation**](in-depth/repeatActivity)
|
||||
|
||||
The **Repeat Activity** rule will check for patterns of repetition in an Author's Activity history over a [window](#activities-window). When comparing submissions it checks a composite of the submissions' title and content.
|
||||
|
||||
@@ -344,7 +345,7 @@ Some of the ways the rule can be modified:
|
||||
|
||||
### History
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/history)
|
||||
[**Full Documentation**](in-depth/history)
|
||||
|
||||
The **History** rule can check an Author's submission/comment statistics over a time period:
|
||||
|
||||
@@ -354,33 +355,33 @@ The **History** rule can check an Author's submission/comment statistics over a
|
||||
|
||||
### Author
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/author)
|
||||
[**Full Documentation**](in-depth/author)
|
||||
|
||||
The **Author** rule behaves the same as the [Author Filter](#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.
|
||||
The **Author** rule behaves the same as the [Author Filter](in-depth/filters#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
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/regex)
|
||||
[**Full Documentation**](in-depth/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](#activities-window).
|
||||
|
||||
### Repost
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/repost)
|
||||
[**Full Documentation**](in-depth/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](/docs/subreddit/components/repeatActivity) rule.
|
||||
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](repeatActivity) rule.
|
||||
|
||||
### Sentiment Analysis
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/sentiment)
|
||||
[**Full Documentation**](in-depth/sentiment)
|
||||
|
||||
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
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/mhs)
|
||||
[**Full Documentation**](in-depth/mhs)
|
||||
|
||||
ContextMod integrates with [moderatehatespeech.com](https://moderatehatespeech.com/) (MHS) [toxic content machine learning model](https://moderatehatespeech.com/framework/) 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.](https://www.reddit.com/r/redditdev/comments/xdscbo/updated_bot_backed_by_moderationoriented_ml_for/)
|
||||
|
||||
@@ -419,7 +420,7 @@ runs:
|
||||
...
|
||||
```
|
||||
|
||||
See **ruleSets [YAML](/docs/subreddit/components/advancedConcepts/ruleSets.yaml) | [JSON](/docs/subreddit/components/advancedConcepts/ruleSets.json5)** for a complete example as well as consulting the [schema](https://json-schema.app/view/%23%2Fdefinitions%2FRuleSetJson?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FApp.json).
|
||||
See **ruleSets [YAML](advancedConcepts/ruleSets.yaml) | [JSON](advancedConcepts/ruleSets.json5)** for a complete example as well as consulting the [schema](https://json-schema.app/view/%23%2Fdefinitions%2FRuleSetJson?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FApp.json).
|
||||
|
||||
# Actions
|
||||
|
||||
@@ -431,7 +432,7 @@ Actions are performed in the order they are listed in the **Check.**
|
||||
|
||||
## Named Actions
|
||||
|
||||
**Named Actions** work the same as [**Named Rules**](#named-rules) and [**Named Filters:**](#named-filters)
|
||||
**Named Actions** work the same as [**Named Rules**](#named-rules) and [**Named Filters:**](in-depth/filters#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:
|
||||
|
||||
@@ -463,7 +464,7 @@ runs:
|
||||
|
||||
Actions that can submit text (Report, Comment, UserNote) will have their `content` values run through a [Mustache Template](https://mustache.github.io/). This means you can insert data generated by Rules into your text before the Action is performed.
|
||||
|
||||
[**Action Templating Documentation**](/docs/subreddit/actionTemplating.md)
|
||||
[**Action Templating Documentation**](actionTemplating.md)
|
||||
|
||||
## List of Actions
|
||||
|
||||
@@ -536,6 +537,25 @@ actions:
|
||||
targets: string # 'self' or 'parent' or 'https://reddit.com/r/someSubreddit/21nfdi....'
|
||||
```
|
||||
|
||||
### Comment As Subreddit
|
||||
|
||||
ContextMod can comment [as the subreddit](https://www.reddit.com/r/modnews/comments/wpy5c8/announcing_remove_as_a_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](#remove) beforehand to ensure this is the case.
|
||||
* The created comment will always be stickied and distinguished
|
||||
|
||||
Usage:
|
||||
|
||||
```yaml
|
||||
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](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubmissionCheckJson/%23%2Fdefinitions%2FSubmissionActionJson?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fmaster%2Fsrc%2FSchema%2FApp.json)
|
||||
@@ -716,7 +736,7 @@ actions:
|
||||
Remove the Activity being processed. [Schema Documentation](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubmissionCheckJson/%23%2Fdefinitions%2FRemoveActionJson?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
|
||||
* **note** can be [templated](#templating)
|
||||
* **reasonId** IDs can be found in the [editor](/docs/webInterface.md) using the **Removal Reasons** popup
|
||||
* **reasonId** IDs can be found in the [editor](../../webInterface.md) using the **Removal Reasons** popup
|
||||
|
||||
If neither note nor reasonId are included then no removal reason is added.
|
||||
|
||||
@@ -744,7 +764,7 @@ actions:
|
||||
|
||||
Add a Toolbox User Note to the Author of the Activity. [Schema Documentation](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubmissionCheckJson/%23%2Fdefinitions%2FUserNoteActionJson?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
|
||||
Your subreddit must have [Toolbox UserNotes](/docs/subreddit/components/userNotes) enabled for this action to work.
|
||||
Your subreddit must have [Toolbox UserNotes](in-depth/userNotes) enabled for this action to work.
|
||||
|
||||
* `type` is required
|
||||
* `content` can be [templated](#templating) and use [URL Tokens](#url-tokens)
|
||||
@@ -754,12 +774,12 @@ actions:
|
||||
- kind: usernote
|
||||
type: spamwarn
|
||||
content: 'Usernote message'
|
||||
allowDuplicate: boolean # if false then the usernote will not be added if the same note appears for this activity
|
||||
existingNoteCheck: boolean # if true (default) then the usernote will not be added if the same note appears for this activity
|
||||
```
|
||||
|
||||
### Mod Note
|
||||
|
||||
[**Full Documentation**](/docs/subreddit/components/modActions/README.md#mod-note-action)
|
||||
[**Full Documentation**](in-depth/modActions/README.md#mod-note-action)
|
||||
|
||||
Add a [Mod Note](https://www.reddit.com/r/modnews/comments/t8vafc/announcing_mod_notes/) for the Author of the Activity.
|
||||
|
||||
@@ -779,6 +799,7 @@ actions:
|
||||
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
|
||||
@@ -787,133 +808,17 @@ actions:
|
||||
|
||||
* **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](in-depth/filters#author-filter) - age, verified email, profile description, flair...
|
||||
* [Item (Submission/Comment)](in-depth/filters#item-filter) - sticked, # of reports, removed, flair, score...
|
||||
* [Subreddit](in-depth/filters#subreddit-filter) - name, nsfw, quarantined...
|
||||
* [Toolbox Usernotes](in-depth/filters#toolbox-usernotes-filter)
|
||||
* [Mod Notes](in-depth/filters#mod-actionsnotes-filter)
|
||||
* 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**.
|
||||
|
||||
A Filter has these properties:
|
||||
|
||||
* `include` -- An optional list of Filter Criteria. If **any** passes the filter passes.
|
||||
* `exclude` -- An optional list of Filter Criteria. All **must NOT** pass for the filter to pass. Ignored if `include` is present.
|
||||
* `excludeCondition` -- A [condition](#conditions) that determines how the list of Filter Criteria are tested together
|
||||
|
||||
## Filter Criteria
|
||||
|
||||
A **criteria** is some property of a thing can be tested, and what the expected outcome is EX
|
||||
|
||||
`age: '> 2 months'` => Author is older than 2 months
|
||||
|
||||
**Filter Criteria** is one of more **criteria** combined together to form a set of criteria that must all be true together for the Filter Criteria to be true EX
|
||||
|
||||
```yaml
|
||||
age: '> 2 months'
|
||||
verified: true
|
||||
```
|
||||
|
||||
The above Filter Criteria is true if the Author's account is older than 2 months AND they have a verified email
|
||||
|
||||
### Filter Shapes
|
||||
|
||||
Generically, a "full" Filter looks like this:
|
||||
|
||||
```yaml
|
||||
include: #optional
|
||||
- name: AFilterCriteria
|
||||
criteria:
|
||||
...
|
||||
... #one or more filter criteria
|
||||
|
||||
exclude: #optional
|
||||
... # one or more filter criteria
|
||||
|
||||
excludeCondition: OR or AND
|
||||
```
|
||||
|
||||
But for convenience a Filter's shape can be simplified with a few assumptions
|
||||
|
||||
#### Simple Object
|
||||
|
||||
When a Filter is an object, the object is assumed to be a Filter Criteria which is used in `include`
|
||||
|
||||
```yaml
|
||||
itemIs:
|
||||
approved: false
|
||||
```
|
||||
|
||||
#### Simple List
|
||||
|
||||
When a Filter is a list, the list is assumed to be a list of Filter Criteria and used in `include`
|
||||
|
||||
```yaml
|
||||
itemIs:
|
||||
- approved: false
|
||||
filtered: false
|
||||
- is_self: true
|
||||
```
|
||||
|
||||
## Filter Types
|
||||
|
||||
There are two types of Filter. Both types have the same "shape" in the configuration with the differences between them being:
|
||||
|
||||
* what they are testing on
|
||||
* what criteria are available to test
|
||||
|
||||
### Author Filter
|
||||
|
||||
Test the Author of an Activity. See [Schema documentation](https://json-schema.app/view/%23%2Fdefinitions%2FAuthorCriteria?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json) for all possible Author Criteria
|
||||
|
||||
#### Mod Actions/Notes Filter
|
||||
|
||||
See [Mod Actions/Notes](/docs/subreddit/components/modActions/README.md#mod-action-filter) documentation.
|
||||
|
||||
#### Toolbox UserNotes Filter
|
||||
|
||||
See [UserNotes](/docs/subreddit/components/userNotes/README.md) documentation
|
||||
|
||||
### Item Filter
|
||||
|
||||
Test for properties of an Activity:
|
||||
|
||||
* [Comment Criteria](https://json-schema.app/view/%23%2Fdefinitions%2FCommentState?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
* [Submission Criteria](https://json-schema.app/view/%23%2Fdefinitions%2FSubmissionState?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
|
||||
### Subreddit Filter
|
||||
|
||||
Test for properties of the Subreddit an Activity belongs to. See [Schema documentation](https://json-schema.app/view/%23%2Fdefinitions%2FSubredditCriteria?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
|
||||
## Named Filters
|
||||
|
||||
**Named Filters** work the same as [**Named Rules**](#named-rules) and [**Named Actions:**](#named-actions)
|
||||
|
||||
**Filter Criteria** may be given a `name`. A named **Filter Criteria** can **re-used anywhere in the configuration regardless of location.** This is done by:
|
||||
|
||||
* specifying a name on a **Filter Criteria** **once** EX: `name: MyFitlerCriteria`
|
||||
* using the Filter Criteria's name in place of a Filter Criteria object
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyFirstRun
|
||||
checks:
|
||||
- name: MyFirstCheck
|
||||
kind: submission
|
||||
itemIs:
|
||||
- MyFilterCriteria
|
||||
rules:
|
||||
...
|
||||
actions:
|
||||
...
|
||||
- name: MySecondCheck
|
||||
kind: submission
|
||||
itemIs:
|
||||
include:
|
||||
- name: MyFilterCriteria
|
||||
criteria:
|
||||
approved: false
|
||||
rules:
|
||||
...
|
||||
actions:
|
||||
...
|
||||
```
|
||||
[**Refer to the full Filter documentation for more**](in-depth/filters)
|
||||
|
||||
# Common Patterns
|
||||
|
||||
@@ -953,7 +858,7 @@ These conditions can be combined together to evaluate to either true or false us
|
||||
|
||||
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](/docs/subreddit/activitiesWindow.md)
|
||||
[Full Activities `window` documentation](activitiesWindow.md)
|
||||
|
||||
## URL Tokens
|
||||
|
||||
@@ -1015,7 +920,7 @@ Some criteria accept an optional **duration** to compare against:
|
||||
|
||||
The duration value compares a time range from **now** to `duration value` time in the past.
|
||||
|
||||
Refer to [duration values in activity window documentation](/docs/subreddit/activitiesWindow.md#duration-values) as well as the individual rule/criteria schema to see what this duration is comparing against.
|
||||
Refer to [duration values in activity window documentation](activitiesWindow.md#duration) as well as the individual rule/criteria schema to see what this duration is comparing against.
|
||||
|
||||
## Filter Defaults
|
||||
|
||||
@@ -1049,7 +954,7 @@ In other words -- Checks will not run if the Author of the Activity being proces
|
||||
|
||||
## Flow Control Defaults
|
||||
|
||||
See [Flow Control Documentation](/docs/subreddit/components/advancedConcepts/flowControl.md#default-behaviors)
|
||||
See [Flow Control Documentation](advancedConcepts/flowControl.md#default-behaviors)
|
||||
|
||||
# Subreddit-Level Configuration
|
||||
|
||||
@@ -1059,7 +964,7 @@ See [Filter Defaults](#filter-defaults) and [Flow Control Defaults](#flow-contro
|
||||
|
||||
## Polling
|
||||
|
||||
**Polling** is how ContextMod creates [Events](/docs/README.md#event) from new Activities in a Subreddit. CM monitors one or more polling sources and processes any new Activities it discovers.
|
||||
**Polling** is how ContextMod creates [Events](../README.md#event) from new Activities in a Subreddit. CM monitors one or more polling sources and processes any new Activities it discovers.
|
||||
|
||||
### Polling Sources
|
||||
|
||||
@@ -1191,7 +1096,7 @@ 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](/docs/operator/caching.md)
|
||||
[Learn more about how Caching works](../operator/caching.md)
|
||||
|
||||
## Partial Configurations
|
||||
|
||||
@@ -1246,6 +1151,49 @@ The object contains:
|
||||
* `path` -- REQUIRED string following rules above
|
||||
* `ttl` -- OPTIONAL, number of seconds to cache the URL result. Defaults to `WikiTTL`
|
||||
|
||||
### 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.
|
||||
|
||||
```yaml
|
||||
sharing: false # deny access to all subreddits (default when sharing is not defined)
|
||||
|
||||
polling:
|
||||
- newComm
|
||||
|
||||
runs:
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml
|
||||
sharing: true # any subreddit can use this config (reddit account must also be able to access wiki page)
|
||||
```
|
||||
|
||||
```yaml
|
||||
# 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'
|
||||
```
|
||||
|
||||
```yaml
|
||||
# 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**
|
||||
@@ -1268,7 +1216,7 @@ runs:
|
||||
subreddits:
|
||||
- MyBadSubreddit
|
||||
window: 7 days
|
||||
actions:
|
||||
actions:
|
||||
- kind: report
|
||||
content: 'uses freekarma subreddits and bad subreddits'
|
||||
```
|
||||
@@ -1303,6 +1251,33 @@ runs:
|
||||
content: 'uses freekarma subreddits'
|
||||
```
|
||||
|
||||
**Using Another Subreddit's Config**
|
||||
|
||||
```yaml
|
||||
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`:
|
||||
|
||||
```yaml
|
||||
sharing: true
|
||||
|
||||
runs:
|
||||
- name: ARun
|
||||
# ...
|
||||
```
|
||||
|
||||
# Subreddit-Ready Examples
|
||||
|
||||
Refer to the [Subreddit-Ready Examples](/docs/subreddit/components/subredditReady) 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.
|
||||
Refer to the [Subreddit Cookbook Examples](cookbook) 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.
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
parent: Subreddit Configuration
|
||||
---
|
||||
|
||||
# Action Templating
|
||||
|
||||
Actions that can submit text (Report, Comment, UserNote, Message, Ban, Submission) will have their `content` values run through a [Mustache Template](https://mustache.github.io/). This means you can insert data generated by Rules into your text before the Action is performed.
|
||||
|
||||
See here for a [cheatsheet](https://gist.github.com/FoxxMD/d365707cf99fdb526a504b8b833a5b78) and [here](https://www.tsmean.com/articles/mustache/the-ultimate-mustache-tutorial/) for a more thorough tutorial.
|
||||
@@ -51,6 +57,29 @@ All Actions with `content` have access to this data:
|
||||
| `title` | As comments => the body of the comment. As Submission => title | Test post please ignore |
|
||||
| `shortTitle` | The same as `title` but truncated to 15 characters | test post pleas... |
|
||||
|
||||
#### Common Author
|
||||
|
||||
Additionally, `author` has these properties accessible:
|
||||
|
||||
| Name | Description | Example |
|
||||
|----------------|-------------------------------------|----------|
|
||||
| `age` | (Approximate) Age of account | 3 months |
|
||||
| `linkKarma` | Amount of link karma | 10 |
|
||||
| `commentKarma` | Amount of comment karma | 3 |
|
||||
| `totalKarma` | Combined link+comment karma | 13 |
|
||||
| `verified` | Does account have a verified email? | true |
|
||||
|
||||
NOTE: Accessing these properties may require an additional API call so use sparingly on high-volume comments
|
||||
|
||||
##### Example Usage
|
||||
|
||||
```
|
||||
The user {{item.author}} has been a redditor for {{item.author.age}}
|
||||
```
|
||||
Produces:
|
||||
|
||||
> The user FoxxMD has been a redditor for 3 months
|
||||
|
||||
### Submissions
|
||||
|
||||
If the **Activity** is a Submission these additional properties are accessible:
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
parent: Subreddit Configuration
|
||||
---
|
||||
|
||||
# Activities `window`
|
||||
|
||||
# Table Of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
@@ -24,13 +30,13 @@
|
||||
|
||||
# Overview
|
||||
|
||||
An **Activity Window** (`window`) is a group of properties that describe a **range** of [**Activities**](/docs/README.md#activity) to retrieve from Reddit and how to **filter** them.
|
||||
An **Activity Window** (`window`) is a group of properties that describe a **range** of [**Activities**](../README.md#activity) to retrieve from Reddit and how to **filter** them.
|
||||
|
||||
The main components of an Activity Window:
|
||||
|
||||
* **Range** -- How many Activities ([`count`](#count)) or what time period ([`duration`](#duration)) of Activities to fetch
|
||||
* **Type of Activities** -- When **fetching** from an Author's history, should it return overview (any Activities), just Submissions, or just Comments?
|
||||
* **Filters** -- How the retrieved Activities should be [filtered](/docs/subreddit/components/README.md#filters) before returning them to a Rule
|
||||
* **Filters** -- How the retrieved Activities should be [filtered](README.md#filters) before returning them to a Rule
|
||||
|
||||
|
||||
As an example, if you want to run a **Recent Activity Rule** to check if a user has had activity in /r/mealtimevideos you also need to define what range of activities you want to look at from that user's history.
|
||||
@@ -214,7 +220,7 @@ window:
|
||||
|
||||
# Filters
|
||||
|
||||
Activity Window can also specify [Item and Subreddit Filters](/docs/subreddit/components/README.md#filters) to filter the Activities retrieved from Reddit before they are returned to a Rule.
|
||||
Activity Window can also specify [Item and Subreddit Filters](README.md#filters) to filter the Activities retrieved from Reddit before they are returned to a Rule.
|
||||
|
||||
Activities can be filtered **during** (`pre`) retrieval or **after** (`post`) retrieval. **When**, during the window **lifecycle**, the Activities are filtered can change the set of Activities returned to a Rule drastically.
|
||||
|
||||
@@ -222,10 +228,10 @@ Activities can be filtered **during** (`pre`) retrieval or **after** (`post`) re
|
||||
|
||||
Regardless of when you are filtering Activities the shape of the filter is the same. Filter properties:
|
||||
|
||||
* `subreddits` -- A [Filter Shape](/docs/subreddit/components/README.md#filter-shapes) for filtering by the [Subreddit Criteria](/docs/subreddit/components/README.md#subreddit-filter) of each Activity
|
||||
* `submissionState` -- A [Filter Shape](/docs/subreddit/components/README.md#filter-shapes) for [Submission Criteria](/docs/subreddit/components/README.md#item-filter). Will run only if filtering a Submission.
|
||||
* `commentState` -- A [Filter Shape](/docs/subreddit/components/README.md#filter-shapes) for [Comment Criteria](/docs/subreddit/components/README.md#item-filter). Will run only if filtering a Comment.
|
||||
* `activityState` -- A [Filter Shape](/docs/subreddit/components/README.md#filter-shapes) for either [Submission or Comment Criteria](/docs/subreddit/components/README.md#item-filter). Will run only if `submissionState` or `commentState` is not defined for their respective Activity types.
|
||||
* `subreddits` -- A [Filter Shape](README.md#filter-shapes) for filtering by the [Subreddit Criteria](README.md#subreddit-filter) of each Activity
|
||||
* `submissionState` -- A [Filter Shape](README.md#filter-shapes) for [Submission Criteria](README.md#item-filter). Will run only if filtering a Submission.
|
||||
* `commentState` -- A [Filter Shape](README.md#filter-shapes) for [Comment Criteria](README.md#item-filter). Will run only if filtering a Comment.
|
||||
* `activityState` -- A [Filter Shape](README.md#filter-shapes) for either [Submission or Comment Criteria](README.md#item-filter). Will run only if `submissionState` or `commentState` is not defined for their respective Activity types.
|
||||
|
||||
In this example the filter only returns Activities:
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
parent: Subreddit Configuration
|
||||
has_toc: false
|
||||
---
|
||||
|
||||
# Flow Control
|
||||
|
||||
Context Mod's behavior after a **Check** has been processed can be configured by a user. This allows a subreddit to control exactly what Runs/Checks will be processed based on the outcome (triggered or not) of a Check.
|
||||
|
||||
# Table of Contents
|
||||
@@ -21,7 +28,7 @@ Context Mod's behavior after a **Check** has been processed can be configured by
|
||||
When a Check is finished processing it can be in one of two states:
|
||||
|
||||
* **Triggered** -- The **Rules** defined in the Check were **triggered** which caused the **Actions** for the Check to be run
|
||||
* **Failure** -- The **Rules** defined in the check were **not triggered**, based on the conditions that were set (either from the [Check condition](/docs/README.md#Checks) or [Rule Sets](/docs/subreddit/components/advancedConcepts/README.md#Rule-Sets)), and no **Actions** were run
|
||||
* **Failure** -- The **Rules** defined in the check were **not triggered**, based on the conditions that were set (either from the [Check condition](../README.md#Checks) or Rule Sets, and no **Actions** were run
|
||||
|
||||
The behavior CM follows is based on which state it is in. The behavior can be specified **by one or both** of these **state properties** on the Check configuration:
|
||||
|
||||
205
docs/subreddit-configuration/cookbook/README.md
Normal file
205
docs/subreddit-configuration/cookbook/README.md
Normal file
@@ -0,0 +1,205 @@
|
||||
---
|
||||
parent: Subreddit Configuration
|
||||
---
|
||||
|
||||
# Cookbook
|
||||
|
||||
Here you will find useful configs for CM that provide real-world functionality. This is where you should look first for **"how do i..."** questions.
|
||||
|
||||
## How To Use
|
||||
|
||||
Each recipe includes what type of config piece it is (Rule, Check, Action, Run, etc...). Keep this in mind before copy-pasting to make sure it goes in the right place in your config.
|
||||
|
||||
### Copy-Pasting
|
||||
|
||||
If the type is **Check** or **Run** the recipe contents will have instructions in the comments on how to use it as a **full subreddit config** OR **by itself (default).** If not Check/Run then when copy-pasting you will need to ensure it is placed in the correct spot in your config.
|
||||
|
||||
|
||||
### As Config Fragment
|
||||
|
||||
**Checks, Runs, Actions, and Rule** recipes can be referenced in your config without copy-pasting by using them as [Config Fragments.](../README.md#partial-configurations) These need to be placed in the correct spot in your config, just like copy-pasting, but only require the URL of the recipe instead of all the code.
|
||||
|
||||
To use a recipe as a fragment **copy** the URL of the config and insert into your config like this:
|
||||
|
||||
```yaml
|
||||
- 'url:https://URL_TO_CONFIG'
|
||||
```
|
||||
|
||||
EXAMPLE: Using the **Config** link from the [Free Karma](#remove-submissions-from-users-who-have-used-freekarma-subs-to-bypass-karma-checks) check below -- copy the **Config** link and insert it into a full subreddit config like this:
|
||||
|
||||
<details markdown="block">
|
||||
<summary>Config</summary>
|
||||
|
||||
```yaml
|
||||
polling:
|
||||
- newSub
|
||||
runs:
|
||||
- name: MyFirstRun
|
||||
checks:
|
||||
# freekarma check
|
||||
- 'url:https://github.com/FoxxMD/context-mod/blob/master/docs/subreddit/components/cookbook/freekarma.yaml'
|
||||
- name: MyRegularCheck
|
||||
kind: submission
|
||||
# ...
|
||||
```
|
||||
</details>
|
||||
|
||||
# Recipes
|
||||
|
||||
## Spam Prevention
|
||||
|
||||
### Remove submissions from users who have used 'freekarma' subs to bypass karma checks
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](freekarma.yaml)
|
||||
|
||||
If the user has any activity (comment/submission) in known freekarma subreddits in the past (100 activities) then remove the submission.
|
||||
|
||||
### Remove submissions that are consecutively spammed by the author
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](crosspostSpam.yaml)
|
||||
|
||||
If the user has crossposted the same submission in the past (100 activities) 4 or more times in a row then remove the submission.
|
||||
|
||||
### Remove submissions if users is flooding new
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](floodingNewSubmissions.yaml)
|
||||
|
||||
If the user has made more than 4 submissions in your subreddit in the last 24 hours than new submissions are removed and user is tagged with a modnote.
|
||||
|
||||
### Remove submissions posted in diametrically-opposed subreddit
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](diametricSpam.yaml)
|
||||
|
||||
If the user makes the same submission to another subreddit(s) that are "thematically" opposed to your subreddit it is probably spam. This check removes it. Detects all types of submissions (including images).
|
||||
|
||||
### Remove comments that are consecutively spammed by the author
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](commentSpam.yaml)
|
||||
|
||||
If the user made the same comment (with some fuzzy matching) 4 or more times in a row in the past (100 activities or 6 months) then remove the comment.
|
||||
|
||||
### Remove comment if it is a chat invite link spam
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](chatSpam.yaml)
|
||||
|
||||
This rule goes a step further than automod can by being more discretionary about how it handles this type of spam.
|
||||
|
||||
* Remove the comment if:
|
||||
* Comment being checked contains **only** a chat link (no other text) OR
|
||||
* Chat links appear **anywhere** in three or more of the last 100 comments the Author has made
|
||||
|
||||
This way ContextMod can more easily distinguish between these use cases for a user commenting with a chat link:
|
||||
|
||||
* actual spammers who only spam a chat link
|
||||
* users who may comment with a link but have context for it either in the current comment or in their history
|
||||
* users who many comment with a link but it's a one-off event (no other links historically)
|
||||
|
||||
## Repost Detection
|
||||
|
||||
### Remove comments reposted from youtube video submissions
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](youtubeCommentRepost.yaml)
|
||||
|
||||
**Requires bot has an API Key for Youtube.**
|
||||
|
||||
Removes comment on reddit if the same comment is found on the youtube video the submission is for.
|
||||
|
||||
### Remove comments reposted from reddit submissions
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](commentRepost.yaml)
|
||||
|
||||
Checks top-level comments on submissions younger than 30 minutes:
|
||||
* Finds other reddit submissions based on crosspost/duplicates/title/URL, takes top 10 submissions based # of upvotes
|
||||
* If this comment matches any top comments from those other submissions with at least 85% sameness then it is considered a repost and removed
|
||||
|
||||
### Remove reposted reddit submission
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](submissionRepost.yaml)
|
||||
|
||||
Checks reddit for top posts with a **Title** that is 90% or more similar to the submission being checked and removes it, if found.
|
||||
|
||||
## Self Promotion
|
||||
|
||||
### Remove link submissions where the user's history is comprised of 10% or more of the same link
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](selfPromo.yaml)
|
||||
|
||||
If the link origin (youtube author, twitter author, etc. or regular domain for non-media links)
|
||||
|
||||
* comprises 10% or more of the users **entire** history in the past (100 activities or 6 months)
|
||||
* or comprises 10% or more of the users **submission** history in the past (100 activities or 6 months) and the user has low engagement (<50% of history is comments or 40%> of comment are as OP)
|
||||
|
||||
then remove the submission
|
||||
|
||||
### Remove submissions posted in 'newtube' subreddits
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](newtube.yaml)
|
||||
|
||||
If the user makes the same submission to a 'newtube' or self-promotional subreddit it is removed and a modnote is added.
|
||||
|
||||
## Safety
|
||||
|
||||
### Remove comments on brigaded submissions when user has no history
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](brigadingNoHistory.yaml)
|
||||
|
||||
The users of comments on a brigaded submission (based on a special submission flair) have their comment history checked -- if they have no participation in your subreddit then the comment is removed.
|
||||
|
||||
### Remove submissions from users with a history of sex solicitation
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](sexSolicitationHistory.yaml)
|
||||
|
||||
If the author of a submission has submissions in their history that match common reddit "sex solicitation" tags (MFA, R4F, M4F, etc...) the submission is removed and a modnote added.
|
||||
|
||||
This is particularly useful for subreddits with underage audiences or mentally/emotionally vulnerable groups.
|
||||
|
||||
The check can be modified to removed comments by changing `kind: submission` to `kind: comment`
|
||||
|
||||
## Verification
|
||||
|
||||
### Verify users from r/TranscribersOfReddit
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](transcribersOfReddit.yaml)
|
||||
|
||||
[r/TranscribersOfReddit](https://www.reddit.com/r/transcribersofreddit) is a community of volunteers transcribing images and videos, across reddit, into plain text.
|
||||
|
||||
This Check detects their standard transcription template and also checks they have a history in r/transcribersofreddit -- then approves the comment and flairs the user with **Transcriber ✍️**
|
||||
|
||||
### Require submission authors have prior subreddit participation
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](requireNonOPParticipation.yaml)
|
||||
|
||||
Submission is removed if the author has **less than 5 non-OP comments** in your subreddit prior to making the submission.
|
||||
|
||||
### Require submission authors make a top-level comment with 15 minutes of posting
|
||||
|
||||
* Type: **Check**
|
||||
* [Config](requireNonOPParticipation.yaml)
|
||||
|
||||
After making a submission the author must make a top-level comment with a regex-checkable pattern within X minutes. If the comment is not made the submission is removed.
|
||||
|
||||
# Monitoring
|
||||
|
||||
### Sticky a comment on popular submissions
|
||||
|
||||
* Type: **Run**
|
||||
* [Config](popularSubmissionMonitoring.yaml)
|
||||
|
||||
This **Run** should come after any other Runs you have that may remove a Submission.
|
||||
|
||||
The Run will cause CM to check new submissions for 3 hours at a 10 minute interval. The bot will then make a comment and sticky it WHEN it detects the number of upvotes is abnormal for how long the Submission has been "alive".
|
||||
@@ -0,0 +1,44 @@
|
||||
#polling:
|
||||
# - newComm
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Report comments from users with no history in the subreddit IF the submission is flaired as being brigaded
|
||||
# optionally, remove comment
|
||||
#
|
||||
- name: Brigading No History
|
||||
kind: comment
|
||||
# only runs on comments in a submission with a link flair css class of 'brigaded'
|
||||
itemIs:
|
||||
- submissionState:
|
||||
# can use any or all of these to detect brigaded submission
|
||||
- link_flair_css: brigaded
|
||||
#flairTemplate: 123-1234
|
||||
#link_flair_text: Restricted
|
||||
rules:
|
||||
- name: noHistory
|
||||
kind: recentActivity
|
||||
# check last 100 activities that have not been removed
|
||||
window:
|
||||
count: 100
|
||||
filterOn:
|
||||
post:
|
||||
commentState:
|
||||
include:
|
||||
- removed: false
|
||||
thresholds:
|
||||
# triggers if user has only one activity (this one) in your subreddit
|
||||
- subreddits:
|
||||
- MYSUBREDDIT
|
||||
threshold: '<= 1'
|
||||
actions:
|
||||
- kind: report
|
||||
enable: true
|
||||
content: User has no history in subreddit
|
||||
|
||||
- kind: remove
|
||||
enable: false
|
||||
note: User has no history in subreddit
|
||||
@@ -1,9 +1,18 @@
|
||||
polling:
|
||||
- newComm
|
||||
runs:
|
||||
- checks:
|
||||
- name: ban discord only spammer
|
||||
description: ban a user who spams only a discord link many times historically
|
||||
#polling:
|
||||
# - newComm
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Remove comments from users who spam discord and telegram links
|
||||
# -- differs from just using automod:
|
||||
# 1) removes comment if it is ONLY discord/telegram link
|
||||
# 2) if not *only* link then checks user's history to see if link is spammed many times and only removes if it is
|
||||
#
|
||||
- name: ban chat only spammer
|
||||
description: ban a user who spams only a chat link many times historically
|
||||
kind: comment
|
||||
condition: AND
|
||||
rules:
|
||||
@@ -13,9 +22,9 @@ runs:
|
||||
- kind: remove
|
||||
- kind: ban
|
||||
content: spamming discord links
|
||||
- name: remove discord spam
|
||||
- name: remove chat spam
|
||||
description: >-
|
||||
remove comments from users who only link to discord or mention discord
|
||||
remove comments from users who only link to chat or mention chat
|
||||
link many times historically
|
||||
kind: comment
|
||||
condition: OR
|
||||
@@ -24,8 +33,9 @@ runs:
|
||||
kind: regex
|
||||
criteria:
|
||||
- name: only link
|
||||
# https://regexr.com/70j9m
|
||||
# single quotes are required to escape special characters
|
||||
regex: '/^.*(discord\.gg\/[\w\d]+)$/i'
|
||||
regex: '/^\s*((?:discord\.gg|t\.me|telegram\.me|telegr\.im)\/[\w\d]+)\s*$/i'
|
||||
- condition: AND
|
||||
rules:
|
||||
- name: linkAnywhereSpam
|
||||
@@ -33,15 +43,16 @@ runs:
|
||||
criteria:
|
||||
- name: contains link anywhere
|
||||
# single quotes are required to escape special characters
|
||||
regex: '/^.*(discord\.gg\/[\w\d]+).*$/i'
|
||||
regex: '/((?:discord\.gg|t\.me|telegram\.me|telegr\.im)\/[\w\d]+)/i'
|
||||
- name: linkAnywhereHistoricalSpam
|
||||
kind: regex
|
||||
criteria:
|
||||
- name: contains links anywhere historically
|
||||
# single quotes are required to escape special characters
|
||||
regex: '/^.*(discord\.gg\/[\w\d]+).*$/i'
|
||||
regex: '/((?:discord\.gg|t\.me|telegram\.me|telegr\.im)\/[\w\d]+)/i'
|
||||
totalMatchThreshold: '>= 3'
|
||||
lookAt: comments
|
||||
window: 10
|
||||
window: 100
|
||||
actions:
|
||||
- kind: remove
|
||||
note: Chat spam link
|
||||
@@ -0,0 +1,71 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
# - newComm
|
||||
#runs:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a series of RUNS
|
||||
- name: approvals
|
||||
checks:
|
||||
- name: approveSubmissionOnComment
|
||||
description: Approve an unapproved submission when OP comments with the magic words
|
||||
kind: comment
|
||||
itemIs:
|
||||
# only check comment if submission is not approved and this comment is by OP
|
||||
- submissionState:
|
||||
- approved: false
|
||||
op: true
|
||||
rules:
|
||||
- name: OPMagic
|
||||
kind: regex
|
||||
criteria:
|
||||
# YOU NEED TO EDIT THIS REGEX TO MATCH THE PATTERN THE OP'S COMMENT SHOULD HAVE IN ORDER TO VERIFY THE SUBMISSION
|
||||
- regex: '/Say Please/i'
|
||||
actions:
|
||||
- kind: approve
|
||||
targets:
|
||||
- parent
|
||||
- self
|
||||
# cancel any delayed dispatched actions
|
||||
- kind: cancelDispatch
|
||||
# tell action to look for delayed items matched parent (submission)
|
||||
target: parent
|
||||
# submission must have 'subVerification' identifier
|
||||
identifier: subVerification
|
||||
|
||||
- name: verification
|
||||
checks:
|
||||
- name: waitForVerification
|
||||
description: Delay processing this submission for 15 minutes
|
||||
kind: submission
|
||||
itemIs:
|
||||
# only dispatch if this is the first time we are seeing this submission
|
||||
- source:
|
||||
- "poll:newSub"
|
||||
- user
|
||||
actions:
|
||||
- kind: dispatch
|
||||
target: self
|
||||
# unique identifier which is a nice hint in the UI and also allows targeting this item while it is delayed
|
||||
identifier: subVerification
|
||||
delay: "15 minutes"
|
||||
# when it is reprocessed go directly to the 'verification' run, skipping everything else
|
||||
goto: verification
|
||||
|
||||
- name: removeNoVerification
|
||||
description: Remove submission if it is not verified after delay
|
||||
kind: submission
|
||||
itemIs:
|
||||
# only process this submission if it comes dispatch with 'subVerification' identifier and is NOT approved after 15 minutes
|
||||
- source: "dispatch:subVerification"
|
||||
approved: false
|
||||
actions:
|
||||
# if this submission is being processed it has been 5 minutes and was not cancelled by OF comment
|
||||
- kind: remove
|
||||
enable: true
|
||||
|
||||
- kind: comment
|
||||
enable: true
|
||||
lock: true
|
||||
distinguish: true
|
||||
content: 'Your submission has been removed because you did not follow verification instructions within 15 minutes of posting.'
|
||||
54
docs/subreddit-configuration/cookbook/commentRepost.yaml
Normal file
54
docs/subreddit-configuration/cookbook/commentRepost.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
#polling:
|
||||
# - newComm
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Checks top-level comments on submissions younger than 30 minutes:
|
||||
# * Finds other reddit submissions based on crosspost/duplicates/title/URL, takes top 10 submissions based # of upvotes
|
||||
# * If this comment matches any comments from those other submissions with at least 85% sameness then it is considered repost
|
||||
#
|
||||
# optionally, bans user if they have more than one modnote for comment reposts
|
||||
#
|
||||
- name: commRepost
|
||||
description: Check if comment has been reposted from youtube
|
||||
kind: comment
|
||||
itemIs:
|
||||
- removed: false
|
||||
approved: false
|
||||
op: false
|
||||
# top level comments only
|
||||
depth: '< 1'
|
||||
submissionState:
|
||||
- age: '< 30 minutes'
|
||||
condition: AND
|
||||
rules:
|
||||
- name: commRepost
|
||||
kind: repost
|
||||
criteria:
|
||||
- searchOn:
|
||||
- external
|
||||
actions:
|
||||
- kind: remove
|
||||
spam: true
|
||||
note: 'reposted comment from reddit with {{rules.commrepost.closestSameness}}% sameness'
|
||||
|
||||
- kind: ban
|
||||
authorIs:
|
||||
# if the author has more than one spamwatch usernote then just ban em
|
||||
include:
|
||||
- modActions:
|
||||
- noteType: SPAM_WATCH
|
||||
note: "/comment repost.*/i"
|
||||
search: total
|
||||
count: "> 1"
|
||||
message: You have been banned for repeated spammy behavior including reposting reddit comments
|
||||
note: reddit comment repost + spammy behavior
|
||||
reason: reddit comment repost + spammy behavior
|
||||
|
||||
- name: commRepostModNote
|
||||
kind: modnote
|
||||
content: 'YT comment repost with {{rules.commrepost.closestSameness}}% sameness'
|
||||
type: SPAM_WATCH
|
||||
@@ -1,14 +1,18 @@
|
||||
polling:
|
||||
- newComm
|
||||
runs:
|
||||
- checks:
|
||||
# Stop users who spam the same comment many times
|
||||
#polling:
|
||||
# - newComm
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Remove comments by users who spam the same comment many times
|
||||
#
|
||||
- name: low xp comment spam
|
||||
description: X-posted comment >=4x
|
||||
kind: comment
|
||||
condition: AND
|
||||
rules:
|
||||
- name: xPostLow
|
||||
- name: xPostLowComm
|
||||
kind: repeatActivity
|
||||
# number of "non-repeat" comments allowed between "repeat comments"
|
||||
gapAllowance: 2
|
||||
@@ -16,11 +20,13 @@ runs:
|
||||
threshold: '>= 4'
|
||||
# retrieve either last 50 comments or 6 months' of history, whichever is less
|
||||
window:
|
||||
count: 50
|
||||
count: 100
|
||||
duration: 6 months
|
||||
actions:
|
||||
- kind: report
|
||||
enable: true
|
||||
content: 'Remove => Posted same comment {{rules.xpostlow.largestRepeat}}x times'
|
||||
enable: false
|
||||
content: 'Remove => Posted same comment {{rules.xpostlowcomm.largestRepeat}}x times'
|
||||
|
||||
- kind: remove
|
||||
enable: true
|
||||
note: 'Posted same comment {{rules.xpostlowcomm.largestRepeat}}x times'
|
||||
@@ -1,7 +1,11 @@
|
||||
polling:
|
||||
- unmoderated
|
||||
runs:
|
||||
- checks:
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# stop users who post low-effort, crossposted spam submissions
|
||||
#
|
||||
# Remove a SUBMISSION if the user has crossposted it at least 4 times in recent history AND
|
||||
@@ -18,7 +22,7 @@ runs:
|
||||
gapAllowance: 2
|
||||
threshold: '>= 4'
|
||||
window:
|
||||
count: 50
|
||||
count: 100
|
||||
duration: 6 months
|
||||
- name: lowOrOpComm
|
||||
kind: history
|
||||
@@ -34,12 +38,15 @@ runs:
|
||||
comment: '> 40% OP'
|
||||
actions:
|
||||
- kind: report
|
||||
enable: true
|
||||
enable: false
|
||||
content: >-
|
||||
Remove=>{{rules.xpostlow.largestRepeat}} X-P =>
|
||||
{{rules.loworopcomm.thresholdSummary}}
|
||||
|
||||
- kind: remove
|
||||
enable: true
|
||||
note: 'Repeated submission {{rules.xpostlow.largestRepeat}}x and low comment engagement'
|
||||
|
||||
- kind: comment
|
||||
enable: true
|
||||
content: >-
|
||||
34
docs/subreddit-configuration/cookbook/diametricSpam.yaml
Normal file
34
docs/subreddit-configuration/cookbook/diametricSpam.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
- name: diametricSpam
|
||||
description: Check if author has posted the same image in opposite subs
|
||||
kind: submission
|
||||
rules:
|
||||
- name: recent
|
||||
kind: recentActivity
|
||||
useSubmissionAsReference: true
|
||||
# requires your subreddit to be running on a CM instance that supports image processing
|
||||
imageDetection:
|
||||
enable: true
|
||||
threshold: 5
|
||||
lookAt: submissions
|
||||
window: 30
|
||||
thresholds:
|
||||
- threshold: ">= 1"
|
||||
subreddits:
|
||||
- AnotherSubreddit
|
||||
actions:
|
||||
- kind: remove
|
||||
enable: true
|
||||
content: "Posted same image in {{rules.recent.subSummary}}"
|
||||
|
||||
- kind: comment
|
||||
distinguish: true
|
||||
sticky: true
|
||||
lock: true
|
||||
content: 'You have posted the same image in another subreddit ({{rules.recent.subSummary}}) that does not make sense given the theme of this subreddit. We consider this spam and it has been removed.'
|
||||
@@ -0,0 +1,34 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Add a mote note to users who are making more than 4 submissions a day
|
||||
# and optionally remove new submissions by them
|
||||
#
|
||||
- name: Flooding New
|
||||
description: Detect users make more than 4 submission in 24 hours
|
||||
kind: submission
|
||||
rules:
|
||||
- name: Recent In Sub
|
||||
kind: recentActivity
|
||||
useSubmissionAsReference: false
|
||||
window:
|
||||
duration: 24 hours
|
||||
fetch: submissions
|
||||
thresholds:
|
||||
- subreddits:
|
||||
# change this to your subreddit
|
||||
- MYSUBREDDIT
|
||||
threshold: "> 4"
|
||||
actions:
|
||||
- kind: modnote
|
||||
type: SPAM_WATCH
|
||||
content: '{{rules.recentinsub.totalCount}} submissions in the last 24 hours'
|
||||
|
||||
- kind: remove
|
||||
enable: false
|
||||
note: '{{rules.recentinsub.totalCount}} submissions in the last 24 hours'
|
||||
45
docs/subreddit-configuration/cookbook/freekarma.yaml
Normal file
45
docs/subreddit-configuration/cookbook/freekarma.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Remove submissions from users who have recent activity in freekarma subs in the last 100 activities
|
||||
#
|
||||
- name: freekarma removal
|
||||
description: Remove submission if user has used freekarma sub recently
|
||||
kind: submission
|
||||
rules:
|
||||
- name: freekarma
|
||||
kind: recentActivity
|
||||
window: 100
|
||||
useSubmissionAsReference: false
|
||||
thresholds:
|
||||
- subreddits:
|
||||
- FreeKarma4U
|
||||
- FreeKarma4You
|
||||
- freekarmaforyou
|
||||
- KarmaFarming4Pros
|
||||
- KarmaStore
|
||||
- upvote
|
||||
- promote
|
||||
- shamelessplug
|
||||
- upvote
|
||||
- FreeUpVotes
|
||||
- GiveMeKarma
|
||||
- nsfwkarma
|
||||
- GetFreeKarmaAnyTime
|
||||
- freekarma2021
|
||||
- FreeKarma2022
|
||||
- KarmaRocket
|
||||
- FREEKARMA4PORN
|
||||
actions:
|
||||
- kind: report
|
||||
enable: false
|
||||
content: 'Remove => {{rules.freekarma.totalCount}} activities in freekarma subs'
|
||||
|
||||
- kind: remove
|
||||
enable: true
|
||||
note: '{{rules.freekarma.totalCount}} activities in freekarma subs'
|
||||
55
docs/subreddit-configuration/cookbook/newtube.yaml
Normal file
55
docs/subreddit-configuration/cookbook/newtube.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Add a mote note to users who make a submission that is also posted to a 'newtube' subreddit
|
||||
# and optionally remove new submission
|
||||
#
|
||||
- name: Newtube Submission
|
||||
description: Tag user if submission was posted in 'newtube' subreddit
|
||||
kind: submission
|
||||
rules:
|
||||
- name: newTube
|
||||
kind: recentActivity
|
||||
window:
|
||||
count: 100
|
||||
fetch: submissions
|
||||
thresholds:
|
||||
- subreddits:
|
||||
- AdvertiseYourVideos
|
||||
- BrandNewTube
|
||||
- FreeKarma4U
|
||||
- FreeKarma4You
|
||||
- KarmaStore
|
||||
- GetMoreSubsYT
|
||||
- GetMoreViewsYT
|
||||
- NewTubers
|
||||
- promote
|
||||
- PromoteGamingVideos
|
||||
- shamelessplug
|
||||
- SelfPromotionYouTube
|
||||
- SmallYTChannel
|
||||
- SmallYoutubers
|
||||
- upvote
|
||||
- youtubestartups
|
||||
- YouTube_startups
|
||||
- YoutubeSelfPromotions
|
||||
- YoutubeSelfPromotion
|
||||
- YouTubeSubscribeBoost
|
||||
- youtubepromotion
|
||||
- YTPromo
|
||||
- Youtubeviews
|
||||
- YouTube_startups
|
||||
actions:
|
||||
- name: newtubeModTag
|
||||
kind: modnote
|
||||
type: SPAM_WATCH
|
||||
content: 'New Tube => {{rules.newtube.subSummary}}{{rules.newtubeall.subSummary}}'
|
||||
|
||||
- kind: remove
|
||||
enable: false
|
||||
note: 'New Tube => {{rules.newtube.subSummary}}{{rules.newtubeall.subSummary}}'
|
||||
@@ -0,0 +1,89 @@
|
||||
polling:
|
||||
- newSub
|
||||
|
||||
runs:
|
||||
- name: MyRegularRun
|
||||
itemIs:
|
||||
# regular run/checks should only run on new activities or if from dashboard
|
||||
- source:
|
||||
- 'poll:newSub'
|
||||
- 'poll:newComm'
|
||||
- 'user'
|
||||
checks:
|
||||
- name: RuleBreakingCheck1
|
||||
kind: submission
|
||||
# ...
|
||||
#
|
||||
# your regular checks go here
|
||||
#
|
||||
# assuming if a Submission makes it through all of your Checks then it is "OK"
|
||||
# to be Approved or generally will be visible in the subreddit (valid for monitoring for r/All)
|
||||
# -- at the end of the Run add a Dispath action
|
||||
- name: Dispatch For Popular Monitoring
|
||||
kind: submission
|
||||
actions:
|
||||
- kind: dispatch
|
||||
identifier: 'popular'
|
||||
# CM will wait 5 minutes before processing this submission again
|
||||
delay: '5 minutes'
|
||||
target: 'self'
|
||||
|
||||
# a separate run that only processes Submissions from dispatch:popular
|
||||
- name: PopularWatch
|
||||
itemIs:
|
||||
- source: 'dispatch:popular'
|
||||
checks:
|
||||
# each check here looks at submission age and tests upvotes against what you think is probably r/All number of votes
|
||||
# in descending age (oldest first)
|
||||
# NOTE: You should change the 'age' and 'score' tests to fit the traffic volume for your subreddit!
|
||||
- name: Two Hour Check
|
||||
kind: submission
|
||||
itemIs:
|
||||
- age: '>= 2 hours'
|
||||
score: '> 100'
|
||||
actions:
|
||||
- kind: comment
|
||||
name: popularComment
|
||||
content: 'Looks like this thread is getting a lot of attention. Greetings r/All! Please keep it civil.'
|
||||
sticky: true
|
||||
distinguish: true
|
||||
lock: true
|
||||
|
||||
- name: One Hour Check
|
||||
kind: submission
|
||||
itemIs:
|
||||
- age: '>= 1 hours'
|
||||
score: '> 50'
|
||||
actions:
|
||||
- popularComment
|
||||
|
||||
- name: Thirty Minute Check
|
||||
kind: submission
|
||||
itemIs:
|
||||
- age: '>= 30 minutes'
|
||||
score: '> 25'
|
||||
actions:
|
||||
- popularComment
|
||||
|
||||
- name: Ten Minute Check
|
||||
kind: submission
|
||||
itemIs:
|
||||
- age: '>= 10 minutes'
|
||||
score: '> 10'
|
||||
actions:
|
||||
- popularComment
|
||||
|
||||
# finally, if none of the popular checks passed re-dispatch submission to be checked in another 10 minutes
|
||||
- name: Delay Popular Check
|
||||
kind: submission
|
||||
postTrigger:
|
||||
# don't need to add this Actioned Events
|
||||
recordTo: false
|
||||
itemIs:
|
||||
# only monitor until submission is 3 hours old
|
||||
- age: '<= 3 hours'
|
||||
actions:
|
||||
- kind: dispatch
|
||||
identifier: 'popular'
|
||||
delay: '10 minutes'
|
||||
target: 'self'
|
||||
@@ -0,0 +1,51 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Report submissions by users with less than 5 non-OP comments in our subreddit
|
||||
# and optionally remove the submission
|
||||
#
|
||||
- name: RequireEngagement
|
||||
description: Remove submission if author has less than X non-op comments in our subreddit
|
||||
kind: submission
|
||||
rules:
|
||||
- name: LittleEngagement
|
||||
kind: recentActivity
|
||||
lookAt: comments
|
||||
useSubmissionAsReference: false
|
||||
# bot will check the last 100 NON-OP comments from user's history
|
||||
window:
|
||||
count: 100
|
||||
fetch: comments
|
||||
filterOn:
|
||||
post:
|
||||
commentState:
|
||||
- op: false
|
||||
thresholds:
|
||||
subreddits:
|
||||
- MYSUBREDDIT
|
||||
# rule is "triggered" if there are LESS THAN 5 comments in our subreddit in the window specified (currently 100 non-op comments)
|
||||
threshold: '< 5'
|
||||
|
||||
actions:
|
||||
|
||||
- kind: report # report the submission
|
||||
enable: true
|
||||
# the text of the report
|
||||
content: 'User has <5 non-OP comments in last 100 comments'
|
||||
|
||||
- kind: remove # remove the submission
|
||||
enable: false
|
||||
note: 'User has <5 non-OP comments in last 100 comments'
|
||||
|
||||
- kind: comment # reply to submission with a comment
|
||||
enable: false
|
||||
# contents of the comment
|
||||
content: We require users to have a minimum level of engagement (>5 comments on other people's posts) in our subreddit before making submissions. Your submission has been automatically removed.
|
||||
sticky: true
|
||||
distinguish: true
|
||||
lock: true
|
||||
@@ -1,7 +1,10 @@
|
||||
polling:
|
||||
- unmoderated
|
||||
runs:
|
||||
- checks:
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Stop users who make link submissions with a self-promotional agenda (with reddit's suggested 10% rule)
|
||||
# https://www.reddit.com/wiki/selfpromotion#wiki_guidelines_for_self-promotion_on_reddit
|
||||
@@ -58,8 +61,11 @@ runs:
|
||||
({{rules.attr.window}}{{rules.attrsub.window}}){{#rules.loworopcomm.thresholdSummary}}
|
||||
=>
|
||||
{{rules.loworopcomm.thresholdSummary}}{{/rules.loworopcomm.thresholdSummary}}
|
||||
|
||||
- kind: remove
|
||||
enable: false
|
||||
enable: true
|
||||
note: '>10% of author's history is content from this creator'
|
||||
|
||||
- kind: comment
|
||||
enable: true
|
||||
content: >-
|
||||
@@ -69,4 +75,3 @@ runs:
|
||||
is against [reddit's self promotional
|
||||
guidelines.](https://www.reddit.com/wiki/selfpromotion#wiki_guidelines_for_self-promotion_on_reddit)
|
||||
distinguish: true
|
||||
dryRun: true
|
||||
@@ -0,0 +1,33 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Remove submission if user has any "redditor for [sex]..." submissions in their history
|
||||
# and optionally bans user
|
||||
#
|
||||
- name: sexSpamHistory
|
||||
description: Detect sex spam language in recent history and ban if found (most likely a bot)
|
||||
kind: submission
|
||||
rules:
|
||||
- kind: regex
|
||||
name: redditorFor
|
||||
criteria:
|
||||
# matches if text has common "looking for" acronym like F4M R4A etc...
|
||||
- regex: '/[RFM]4[a-zA-Z\s0-9]/i'
|
||||
totalMatchThreshold: "> 1"
|
||||
window: 100
|
||||
testOn:
|
||||
- body
|
||||
- title
|
||||
actions:
|
||||
- kind: remove
|
||||
enable: true
|
||||
note: 'Has sex solicitation submission history: {{rules.redditorfor.matchSample}}'
|
||||
|
||||
- kind: modnote
|
||||
type: ABUSE_WARNING
|
||||
content: 'Has sex solicitation submission history: {{rules.redditorfor.matchSample}}'
|
||||
31
docs/subreddit-configuration/cookbook/submissionRepost.yaml
Normal file
31
docs/subreddit-configuration/cookbook/submissionRepost.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
#polling:
|
||||
# - newSub
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
- name: BotRepost
|
||||
description: Remove submission if it is likely a repost
|
||||
kind: submission
|
||||
rules:
|
||||
# search reddit for similar submissions to see if it is a repost
|
||||
- name: subRepost
|
||||
kind: repost
|
||||
criteria:
|
||||
- searchOn:
|
||||
# match found Submissions sameness using title against title of Submission being checked
|
||||
- kind: title
|
||||
# sameness (confidence) % of a title required to consider Submission being checked as a repost
|
||||
matchScore: 90
|
||||
|
||||
actions:
|
||||
# report the submission
|
||||
- kind: report
|
||||
enable: true
|
||||
content: '{{rules.subrepost.closestSameness}} confidence this is a repost.'
|
||||
|
||||
# remove the submission
|
||||
- kind: remove
|
||||
enable: false
|
||||
note: '{{rules.subrepost.closestSameness}} confidence this is a repost.'
|
||||
@@ -0,0 +1,41 @@
|
||||
#polling:
|
||||
# - newComm
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# Detect top-level comments by users from r/transcribersofreddit
|
||||
# and approve/flair the user
|
||||
#
|
||||
- name: transcriber comment
|
||||
description: approve/flair transcribed video comment
|
||||
kind: comment
|
||||
itemIs:
|
||||
# top-level comments
|
||||
depth: '< 1'
|
||||
condition: AND
|
||||
rules:
|
||||
- name: transcribedVideoFormat
|
||||
kind: regex
|
||||
criteria:
|
||||
- regex: '/^[\n\r\s]*\*Video Transcription\*[\n\r]+---[\S\s]+---/gim'
|
||||
- name: transcribersActivity
|
||||
kind: recentActivity
|
||||
window:
|
||||
count: 100
|
||||
duration: 1 week
|
||||
useSubmissionAsReference: false
|
||||
thresholds:
|
||||
- subreddits:
|
||||
- transcribersofreddit
|
||||
actions:
|
||||
- kind: approve
|
||||
- name: flairTranscriber
|
||||
kind: flair
|
||||
authorIs:
|
||||
exclude:
|
||||
- flairText:
|
||||
- Transcriber ✍️
|
||||
text: Transcriber ✍️
|
||||
@@ -0,0 +1,47 @@
|
||||
#polling:
|
||||
# - newComm
|
||||
#runs:
|
||||
# - checks:
|
||||
#### Uncomment the code above to use this as a FULL subreddit config
|
||||
####
|
||||
#### Otherwise copy-paste the code below to use as a CHECK
|
||||
#
|
||||
# If submission type is a youtube video CM will check top comments on the video and remove comment if it at least 85% the same
|
||||
# optionally, bans user if they have more than one modnote for comment reposts
|
||||
#
|
||||
- name: commRepostYT
|
||||
description: Check if comment has been reposted from youtube
|
||||
kind: comment
|
||||
itemIs:
|
||||
- removed: false
|
||||
approved: false
|
||||
op: false
|
||||
condition: AND
|
||||
rules:
|
||||
- name: commRepost
|
||||
kind: repost
|
||||
criteria:
|
||||
- searchOn:
|
||||
- external
|
||||
actions:
|
||||
- kind: remove
|
||||
spam: true
|
||||
note: 'reposted comment from youtube with {{rules.commrepostyt.closestSameness}}% sameness'
|
||||
|
||||
- kind: ban
|
||||
authorIs:
|
||||
# if the author has more than one spamwatch usernote then just ban em
|
||||
include:
|
||||
- modActions:
|
||||
- noteType: SPAM_WATCH
|
||||
note: "/comment repost.*/i"
|
||||
search: total
|
||||
count: "> 1"
|
||||
message: You have been banned for repeated spammy behavior including reposting youtube comments
|
||||
note: yt comment repost + spammy behavior
|
||||
reason: yt comment repost + spammy behavior
|
||||
|
||||
- name: commRepostYTModNote
|
||||
kind: modnote
|
||||
content: 'YT comment repost with {{rules.commrepostyt.closestSameness}}% sameness'
|
||||
type: SPAM_WATCH
|
||||
@@ -1,8 +1,13 @@
|
||||
---
|
||||
title: Image Comparison
|
||||
parent: Subreddit Configuration
|
||||
---
|
||||
|
||||
# Overview
|
||||
|
||||
ContextMod supports comparing image content, for the purpose of detecting duplicates, with two different but complimentary systems. Image comparison behavior is available for the following rules:
|
||||
|
||||
* [Recent Activity](/docs/subreddit/components/recentActivity)
|
||||
* [Recent Activity](in-depth/recentActivity)
|
||||
* Repeat Activity (In-progress)
|
||||
|
||||
To enable comparisons reference the example below (at the top-level of your rule) and configure as needed:
|
||||
@@ -39,6 +44,7 @@ YAML
|
||||
```yaml
|
||||
name: ruleWithImageDetection
|
||||
kind: recentActivity
|
||||
imageDetection:
|
||||
enable: true
|
||||
threshold: 5
|
||||
fetchBehavior: extension
|
||||
9
docs/subreddit-configuration/in-depth/README.md
Normal file
9
docs/subreddit-configuration/in-depth/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
parent: Subreddit Configuration
|
||||
has_children: true
|
||||
has_toc: true
|
||||
---
|
||||
|
||||
# In Depth
|
||||
|
||||
Further details and examples for CM components.
|
||||
36
docs/subreddit-configuration/in-depth/attribution/README.md
Normal file
36
docs/subreddit-configuration/in-depth/attribution/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# Attribution Rule
|
||||
|
||||
The **Attribution** rule will aggregate an Author's content Attribution (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
|
||||
|
||||
Consult the [schema](https://json-schema.app/view/%23/%23%2Fdefinitions%2FCheckJson/%23%2Fdefinitions%2FAttributionJSONConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FApp.json) for a complete reference of the rule's properties.
|
||||
|
||||
# [Template Variables](../../actionTemplating.md)
|
||||
|
||||
| Name | Description | Example |
|
||||
|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------|
|
||||
| `result` | Summary of rule results (also found in Actioned Events) | 1 Attribution(s) met the threshold of >= 20%, with 6 (40%) of 15 Total -- window: 3 years |
|
||||
| `triggeredDomainCount` | Number of domains that met the threshold | 1 |
|
||||
| `window` | Number or duration of Activities considered from window | 3 years |
|
||||
| `largestCount` | The count from the largest aggregated domain | 6 |
|
||||
| `largestPercentage` | The percentage of Activities the largest aggregated domain comprises | 40% |
|
||||
| `smallestCount` | The count from the smallest aggregated domain | 1 |
|
||||
| `smallestPercentage` | The percentage of Activities the smallest aggregated domain comprises | 6% |
|
||||
| `countRange` | A convenience string displaying "smallestCount - largestCount" or just one number if both are the same | 5 |
|
||||
| `percentRange` | A convenience string displaying "smallestPercentage - largestPercentage" or just one percentage if both are the same | 34% |
|
||||
| `domainsDelim` | A comma-delimited list of all the domain URLs that met the threshold | youtube.com/example1, youtube.com/example2, rueters.com |
|
||||
| `titlesDelim` | A comma-delimited list of friendly-names of the domain if one is present, otherwise the URL (IE youtube.com/c/34ldfa343 => "My Youtube Channel Title") | My Channel A, My Channel B, reuters.com |
|
||||
| `threshold` | The threshold you configured for this Rule to trigger | `>= 20%` |
|
||||
|
||||
# Examples
|
||||
|
||||
* Self Promotion as percentage of all Activities [YAML](redditSelfPromoAll.yaml) | [JSON](redditSelfPromoAll.json5) - Check if Author is submitting much more than they comment.
|
||||
* Self Promotion as percentage of Submissions [YAML](redditSelfPromoSubmissionsOnly.yaml) | [JSON](redditSelfPromoSubmissionsOnly.json5) - Check if any of Author's aggregated submission origins are >10% of their submissions
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# Author
|
||||
|
||||
## Rule
|
||||
@@ -9,7 +14,7 @@ The **Author** rule triggers if any [AuthorCriteria](https://json-schema.app/vie
|
||||
* author's subreddit flair text
|
||||
* author's subreddit flair css
|
||||
* author's subreddit mod status
|
||||
* [Toolbox User Notes](/docs/subreddit/componentscomponents/userNotes)
|
||||
* [Toolbox User Notes](../userNotes)
|
||||
|
||||
The Author **Rule** is best used in conjunction with other Rules to short-circuit a Check based on who the Author is. It is easier to use a Rule to do this then to write **author filters** for every Rule (and makes Rules more re-useable).
|
||||
|
||||
@@ -18,10 +23,10 @@ Consult the [schema](https://json-schema.app/view/%23%2Fdefinitions%2FAuthorRule
|
||||
### Examples
|
||||
|
||||
* Basic examples
|
||||
* Flair new user Submission [YAML](/docs/subreddit/componentscomponents/author/flairNewUserSubmission.yaml) | [JSON](/docs/subreddit/componentscomponents/author/flairNewUserSubmission.json5) - If the Author does not have the `vet` flair then flair the Submission with `New User`
|
||||
* Flair vetted user Submission [YAML](/docs/subreddit/componentscomponents/author/flairNewUserSubmission.yaml) | [JSON](/docs/subreddit/componentscomponents/author/flairNewUserSubmission.json5) - If the Author does have the `vet` flair then flair the Submission with `Vetted`
|
||||
* Flair new user Submission [YAML](flairNewUserSubmission.yaml) | [JSON](flairNewUserSubmission.json5) - If the Author does not have the `vet` flair then flair the Submission with `New User`
|
||||
* Flair vetted user Submission [YAML](flairNewUserSubmission.yaml) | [JSON](flairNewUserSubmission.json5) - If the Author does have the `vet` flair then flair the Submission with `Vetted`
|
||||
* Used with other Rules
|
||||
* Ignore vetted user [YAML](/docs/subreddit/componentscomponents/author/flairNewUserSubmission.yaml) | [JSON](/docs/subreddit/componentscomponents/author/flairNewUserSubmission.json5) - Short-circuit the Check if the Author has the `vet` flair
|
||||
* Ignore vetted user [YAML](flairNewUserSubmission.yaml) | [JSON](flairNewUserSubmission.json5) - Short-circuit the Check if the Author has the `vet` flair
|
||||
|
||||
## Filter
|
||||
|
||||
@@ -35,7 +40,7 @@ All **Rules** and **Checks** have an optional `authorIs` property that takes an
|
||||
|
||||
### Examples
|
||||
|
||||
* Skip recent activity check based on author [YAML](/docs/subreddit/componentscomponents/author/authorFilter.yaml) | [JSON](/docs/subreddit/componentscomponents/author/authorFilter.json5) - Skip a Recent Activity check for a set of subreddits if the Author of the Submission has any set of flairs.
|
||||
* Skip recent activity check based on author [YAML](authorFilter.yaml) | [JSON](authorFilter.json5) - Skip a Recent Activity check for a set of subreddits if the Author of the Submission has any set of flairs.
|
||||
|
||||
## Flair users and submissions
|
||||
|
||||
@@ -45,4 +50,4 @@ Consult [User Flair schema](https://json-schema.app/view/%23%2Fdefinitions%2FUse
|
||||
|
||||
### Examples
|
||||
|
||||
* OnlyFans submissions [YAML](/docs/subreddit/componentscomponents/author/onlyfansFlair.yaml) | [JSON](/docs/subreddit/componentscomponents/author/onlyfansFlair.json5) - Check whether submitter has typical OF keywords in their profile and flair both author + submission accordingly.
|
||||
* OnlyFans submissions [YAML](onlyfansFlair.yaml) | [JSON](onlyfansFlair.json5) - Check whether submitter has typical OF keywords in their profile and flair both author + submission accordingly.
|
||||
457
docs/subreddit-configuration/in-depth/filters/README.md
Normal file
457
docs/subreddit-configuration/in-depth/filters/README.md
Normal file
@@ -0,0 +1,457 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
title: Filters
|
||||
---
|
||||
# Table of Contents
|
||||
|
||||
* [Filters](#filters)
|
||||
* [Criteria](#criteria)
|
||||
* [Filter Shapes](#filter-shapes)
|
||||
* [Simple Object](#simple-object)
|
||||
* [Simple List](#simple-list)
|
||||
* [Filter Types](#filter-types)
|
||||
* [Author Filter](#author-filter)
|
||||
* [Mod Actions/Notes Filter](#mod-actionsnotes-filter)
|
||||
* [Toolbox UserNotes Filter](#toolbox-usernotes-filter)
|
||||
* [Item Filter](#item-filter)
|
||||
* [Subreddit Filter](#subreddit-filter)
|
||||
* [Named Filters](#named-filters)
|
||||
* [Examples](#examples)
|
||||
* [General Usage](#general-usage)
|
||||
* [Usage in a Run](#usage-in-a-run)
|
||||
* [Usage in a Check](#usage-in-a-check)
|
||||
* [Usage in a Rule](#usage-in-a-rule)
|
||||
* [Usage in an Action](#usage-in-an-action)
|
||||
* [Using Author and Item Filter](#using-author-and-item-filter)
|
||||
* [Filter Shapes Usage](#filter-shapes-usage)
|
||||
* [Using a Simple Object](#using-a-simple-object)
|
||||
* [Using a Simple List](#using-a-simple-list)
|
||||
* [Using a Full Anonymous Filter](#using-a-full-anonymous-filter)
|
||||
* [Using a Full Anonymous Filter with Exclude](#using-a-full-anonymous-filter-with-exclude)
|
||||
* [Using a Full Named Filter](#using-a-full-named-filter)
|
||||
* [Author Filter Examples](#author-filter-examples)
|
||||
* [New User](#new-user)
|
||||
* [New User with pattern in Name](#new-user-with-pattern-in-name)
|
||||
* [User has pattern in their profile description](#user-has-pattern-in-their-profile-description)
|
||||
* [Exclude moderators AND users by name](#exclude-moderators-and-users-by-name)
|
||||
* [Item Filter Examples](#item-filter-examples)
|
||||
* [Unmoderated comment by non-op](#unmoderated-comment-by-non-op)
|
||||
* [Submission is self post with no flair](#submission-is-self-post-with-no-flair)
|
||||
|
||||
# Filters
|
||||
|
||||
**Filters** are an additional channel for determining if an Event should be processed by ContextMod. They differ from [**Rules**](../../README.md#rules) in several key ways:
|
||||
|
||||
* **Runs, Checks, Rules, and Actions** can **all** have Filters
|
||||
* Filters test against the **current state** of the Activity (or its Author) being processed, rather than looking at history/context/etc...
|
||||
* 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**.
|
||||
|
||||
A Filter has these properties:
|
||||
|
||||
* `include` -- An optional list of Filter Criteria. If **any** passes the filter passes.
|
||||
* `exclude` -- An optional list of Filter Criteria. All **must NOT** pass for the filter to pass. Ignored if `include` is present.
|
||||
* `excludeCondition` -- A [condition](../../README.md#conditions) that determines how the list of Filter Criteria are tested together
|
||||
|
||||
## Criteria
|
||||
|
||||
A **criteria** is some property of a thing (Activity or Author) can be tested, and what the expected outcome is EX:
|
||||
|
||||
`age: '> 2 months'` => Author is older than 2 months
|
||||
|
||||
**Filter Criteria** is one of more **criteria** combined together to form a set of conditions that must all be true together for the Filter Criteria to be true EX
|
||||
|
||||
```yaml
|
||||
age: '> 2 months'
|
||||
verified: true
|
||||
```
|
||||
|
||||
The above Filter Criteria is true if:
|
||||
|
||||
* the Author's account is older than 2 months AND
|
||||
* they have a verified email
|
||||
|
||||
## Filter Shapes
|
||||
|
||||
Generically, a "full" Filter looks like this:
|
||||
|
||||
```yaml
|
||||
include: #optional
|
||||
- name: AFilterCriteria
|
||||
criteria:
|
||||
#...
|
||||
#...one or more Filter Criteria
|
||||
|
||||
exclude: #optional
|
||||
#...one or more Filter Criteria
|
||||
|
||||
excludeCondition: OR or AND
|
||||
```
|
||||
|
||||
But for convenience a Filter's shape can be simplified with a few assumptions:
|
||||
|
||||
### Simple Object
|
||||
|
||||
When a Filter is an object, the object is assumed to be a [Filter Criteria](#criteria) which is used in `include`
|
||||
|
||||
```yaml
|
||||
itemIs:
|
||||
approved: false
|
||||
```
|
||||
|
||||
### Simple List
|
||||
|
||||
When a Filter is a list, the list is assumed to be a list of [Filter Criteria](#criteria) and used in `include`
|
||||
|
||||
```yaml
|
||||
itemIs:
|
||||
- approved: false
|
||||
filtered: false
|
||||
- is_self: true
|
||||
```
|
||||
|
||||
## Filter Types
|
||||
|
||||
There are two types of Filter. Both types have the same "shape" in the configuration with the differences between them being:
|
||||
|
||||
* what they are testing on
|
||||
* what criteria are available to test
|
||||
|
||||
### Author Filter
|
||||
|
||||
Test the Author of an Activity. See [Schema documentation](https://json-schema.app/view/%23%2Fdefinitions%2FAuthorCriteria?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json) for all possible Author Criteria
|
||||
|
||||
#### Mod Actions/Notes Filter
|
||||
|
||||
See [Mod Actions/Notes](../modActions/README.md#mod-action-filter) documentation.
|
||||
|
||||
#### Toolbox UserNotes Filter
|
||||
|
||||
See [UserNotes](../userNotes/README.md) documentation
|
||||
|
||||
### Item Filter
|
||||
|
||||
Test for properties of an Activity:
|
||||
|
||||
* [Comment Criteria](https://json-schema.app/view/%23%2Fdefinitions%2FCommentState?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
* [Submission Criteria](https://json-schema.app/view/%23%2Fdefinitions%2FSubmissionState?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
|
||||
### Subreddit Filter
|
||||
|
||||
Test for properties of the Subreddit an Activity belongs to. See [Schema documentation](https://json-schema.app/view/%23%2Fdefinitions%2FSubredditCriteria?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fedge%2Fsrc%2FSchema%2FApp.json)
|
||||
|
||||
## Named Filters
|
||||
|
||||
**Named Filters** work the same as [**Named Rules**](../../README.md#named-rules) and [**Named Actions:**](../../README.md#named-actions)
|
||||
|
||||
**Filter Criteria** may be given a `name`. A named **Filter Criteria** can **re-used anywhere in the configuration regardless of location.** This is done by:
|
||||
|
||||
* specifying a name on a **Filter Criteria** **once** EX: `name: MyFilterCriteria`
|
||||
* using the Filter Criteria name in place of a Filter Criteria object
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyFirstRun
|
||||
checks:
|
||||
- name: MyFirstCheck
|
||||
kind: submission
|
||||
itemIs:
|
||||
- MyFilterCriteria
|
||||
rules:
|
||||
#...
|
||||
actions:
|
||||
#...
|
||||
- name: MySecondCheck
|
||||
kind: submission
|
||||
itemIs:
|
||||
include:
|
||||
- name: MyFilterCriteria
|
||||
criteria:
|
||||
approved: false
|
||||
rules:
|
||||
#...
|
||||
actions:
|
||||
#...
|
||||
```
|
||||
|
||||
# Examples
|
||||
|
||||
## General Usage
|
||||
|
||||
Below are examples of where filters can be used
|
||||
|
||||
### Usage in a Run
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
# this run will only be processed if author is a contributor
|
||||
- name: MyRun
|
||||
authorIs:
|
||||
- isContributor: true
|
||||
checks:
|
||||
# - ...
|
||||
```
|
||||
|
||||
### Usage in a Check
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
# check will only be processed if author is a contributor
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
authorIs:
|
||||
- isContributor: true
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
### Usage in a Rule
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
rules:
|
||||
# rule will only run if author is a contributor
|
||||
- name: MyFirstRule
|
||||
kind: recentActivity
|
||||
authorIs:
|
||||
- isContributor: true
|
||||
thresholds:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
### Usage in an Action
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
rules:
|
||||
- name: MyFirstRule
|
||||
# ...
|
||||
actions:
|
||||
# action will only run if author is a contributor
|
||||
- kind: approve
|
||||
authorIs:
|
||||
- isContributor: true
|
||||
```
|
||||
|
||||
### Using Author and Item Filter
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
# Check will only process if author is a contributor AND submission is not approved
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
authorIs:
|
||||
- isContributor: true
|
||||
itemIs:
|
||||
- approved: false
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
## Filter Shapes Usage
|
||||
|
||||
Below are examples of how filters can be structured using [filter shapes](#filter-shapes)
|
||||
|
||||
### Using a Simple Object
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
# check is only processed if submission is not approved AND not marked as nsfw
|
||||
itemIs:
|
||||
approved: false
|
||||
over_18: false
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
### Using a Simple List
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
# check is only processed if submission is EITHER:
|
||||
# -> not approved AND not marked as nsfw
|
||||
# -> not approved AND marked as nsfw AND has flair text 'Mildly NSFW;
|
||||
itemIs:
|
||||
# each '-' denotes a NEW set of criteria
|
||||
- approved: false
|
||||
over_18: false
|
||||
|
||||
- link_flair_text: Mildly NSFW
|
||||
over_18: true
|
||||
approved: false
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
### Using a Full Anonymous Filter
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
# check is only processed if submission is EITHER:
|
||||
# -> not approved AND not marked as nsfw
|
||||
# -> not approved AND marked as nsfw AND has flair text 'Mildly NSFW;
|
||||
itemIs:
|
||||
include:
|
||||
- approved: false
|
||||
over_18: false
|
||||
|
||||
- link_flair_text: Mildly NSFW
|
||||
over_18: true
|
||||
approved: false
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
### Using a Full Anonymous Filter with Exclude
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
# check is only processed if submission is NOT approved
|
||||
itemIs:
|
||||
exclude:
|
||||
- approved: true
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
### Using a Full Named Filter
|
||||
|
||||
```yaml
|
||||
runs:
|
||||
- name: MyRun
|
||||
checks:
|
||||
- name: MyCheck
|
||||
kind: submission
|
||||
# check is only processed if submission is:
|
||||
# -> not approved AND not marked as nsfw
|
||||
itemIs:
|
||||
include:
|
||||
- name: sfwNotApproved
|
||||
criteria:
|
||||
- approved: false
|
||||
over_18: false
|
||||
rules:
|
||||
# ...
|
||||
actions:
|
||||
# ...
|
||||
```
|
||||
|
||||
## Author Filter Examples
|
||||
|
||||
### New User
|
||||
|
||||
```yaml
|
||||
# author's account is less than 30 days old AND has less than 30 comment karma
|
||||
authorIs:
|
||||
include:
|
||||
- name: newUser
|
||||
criteria:
|
||||
age: < 30 days
|
||||
commentKarma: < 30
|
||||
```
|
||||
|
||||
### New User with pattern in Name
|
||||
|
||||
```yaml
|
||||
# author's account is less than 30 days old AND has less than 30 comment karma AND has 'nsfw' in their account name
|
||||
authorIs:
|
||||
include:
|
||||
- name: newUser
|
||||
criteria:
|
||||
age: < 30 days
|
||||
commentKarma: < 30
|
||||
name: '/nsfw/i'
|
||||
```
|
||||
|
||||
### User has pattern in their profile description
|
||||
|
||||
```yaml
|
||||
authorIs:
|
||||
include:
|
||||
- description:
|
||||
- '/Add Me On Snapchat/i'
|
||||
- '/Add my snapchat/i'
|
||||
- '/Dm me for content/i'
|
||||
- '/Will Verify/i'
|
||||
```
|
||||
|
||||
### Exclude moderators AND users by name
|
||||
|
||||
Useful when CM should not run if the author is from a list of users or a moderator
|
||||
|
||||
```yaml
|
||||
authorIs:
|
||||
excludeCondition: AND
|
||||
exclude:
|
||||
# will not run if user is a mod or is automoderator
|
||||
- isMod: true
|
||||
|
||||
# will not run if the user is in the list below
|
||||
- name:
|
||||
- User1
|
||||
- User2
|
||||
- User3
|
||||
```
|
||||
|
||||
## Item Filter Examples
|
||||
|
||||
### Unmoderated comment by non-op
|
||||
|
||||
```yaml
|
||||
itemIs:
|
||||
- removed: false
|
||||
approved: false
|
||||
op: false
|
||||
```
|
||||
|
||||
### Submission is self post with no flair
|
||||
|
||||
```yaml
|
||||
itemIs:
|
||||
- is_self: true
|
||||
link_flair_text: false
|
||||
```
|
||||
73
docs/subreddit-configuration/in-depth/history/README.md
Normal file
73
docs/subreddit-configuration/in-depth/history/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# History Rule
|
||||
|
||||
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
|
||||
* Ratio of activities against another window of activities
|
||||
|
||||
Consult the [schema](https://json-schema.app/view/%23%2Fdefinitions%2FHistoryJSONConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FApp.json) for a complete reference of the rule's properties.
|
||||
|
||||
## Ratio
|
||||
|
||||
Use the `ratio` property in Criteria to test the [number of activities](../../activitiesWindow.md) found in the parent criteria against the number of activities from _another_ [activity window](../../activitiesWindow.md) defined in the ratio.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
- kind: history
|
||||
criteria:
|
||||
# "parent" criteria, returns all activities, in the last 100 from user's history, that occurred in r/mealtimevideos
|
||||
- window:
|
||||
count: 100
|
||||
filterOn:
|
||||
post:
|
||||
subreddits:
|
||||
include:
|
||||
- mealtimevideos
|
||||
ratio:
|
||||
# "ratio" criteria, returns all activities, in the last 100 from user's history, that occurred in r/redditdev
|
||||
window:
|
||||
count: 100
|
||||
filterOn:
|
||||
post:
|
||||
subreddits:
|
||||
include:
|
||||
- redditdev
|
||||
# test (number of parent criteria activities) / (number of ratio critieria activities)
|
||||
threshold: '> 1.2'
|
||||
```
|
||||
|
||||
`threshold` may be a number or percentage `(number * 100)`
|
||||
|
||||
* EX `> 1.2` => There are 1.2 activities from parent criteria for every 1 ratio activities
|
||||
* EX `<= 75%` => There are equal to or less than 0.75 activities from parent criteria for every 1 ratio activities
|
||||
|
||||
### Examples
|
||||
|
||||
* Low Comment Engagement [YAML](lowEngagement.yaml) | [JSON](lowEngagement.json5) - Check if Author is submitting much more than they comment.
|
||||
* OP Comment Engagement [YAML](opOnlyEngagement.yaml) | [JSON](opOnlyEngagement.json5) - Check if Author is mostly engaging only in their own content
|
||||
|
||||
# [Template Variables](../../actionTemplating.md)
|
||||
|
||||
| Name | Description | Example |
|
||||
|----------------------|------------------------------------------------------------------------|----------------------------------------------------|
|
||||
| `result` | Summary of rule results (also found in Actioned Events) | Filtered Activities (7) were < 10 Items (2 months) |
|
||||
| `activityTotal` | Total number of activities from window | 50 |
|
||||
| `filteredTotal` | Total number of activities filtered from window | 7 |
|
||||
| `filteredPercent` | Percentage of activities filtered from window | 14% |
|
||||
| `submissionTotal` | Total number of filtered submissions from window | 4 |
|
||||
| `submissionPercent` | Percentage of filtered submissions from window | 8% |
|
||||
| `commentTotal` | Total number of filtered comments from window | 3 |
|
||||
| `commentPercent` | Percentage of filtered comments from window | 6% |
|
||||
| `opTotal` | Total number of comments as OP from filtered comments | 2 |
|
||||
| `opPercent` | Percentage of comments as OP from filtered comments | 66% |
|
||||
| `thresholdSummary` | A text summary of the first Criteria triggered with totals/percentages | Filtered Activities (7) were < 10 Items |
|
||||
| `subredditBreakdown` | A markdown list of filtered activities by subreddit | * SubredditA - 5 (71%) \n * Subreddit B - 2 (28%) |
|
||||
| `window` | Number or duration of Activities considered from window | 2 months |
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# ModerateHateSpeech.com Rule
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
@@ -101,7 +108,7 @@ rules:
|
||||
|
||||
#### Historical Matching
|
||||
|
||||
Like the [Sentiment](/docs/subreddit/components/sentiment#historical) and [Regex](/docs/subreddit/components/regex#historical) rules CM can also use MHS predictions to check content from the Author's history.
|
||||
Like the [Sentiment](../sentiment#historical) and [Regex](../regex#historical) rules CM can also use MHS predictions to check content from the Author's history.
|
||||
|
||||
Example
|
||||
|
||||
@@ -116,6 +123,16 @@ rules:
|
||||
criteria: #... if specified, overrides parent-level criteria
|
||||
```
|
||||
|
||||
# [Template Variables](../../actionTemplating.md)
|
||||
|
||||
|
||||
| Name | Description | Example |
|
||||
|-----------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `result` | Summary of rule results (also found in Actioned Events) | Current Activity MHS Test: ✓ Confidence test (>= 90) PASSED MHS confidence of 99.85% Flagged pass condition of true (toxic) MATCHED MHS flag 'toxic' |
|
||||
| `window` | Number or duration of Activities considered from window | 1 activities |
|
||||
| `criteriaTest` | MHS value to test against | MHS confidence is > 95% |
|
||||
| `totalMatching` | Total number of activities (current + historical) that matched `criteriaTest` | 1 |
|
||||
|
||||
# Examples
|
||||
|
||||
Report if MHS flags as toxic
|
||||
@@ -133,7 +150,8 @@ Report if MHS flags as toxic with 95% confidence
|
||||
```yaml
|
||||
rules:
|
||||
- kind: mhs
|
||||
confidence: '>= 95'
|
||||
criteria:
|
||||
confidence: '>= 95'
|
||||
actions:
|
||||
- kind: report
|
||||
content: 'MHS flagged => {{rules.mhs.summary}}'
|
||||
@@ -158,8 +176,9 @@ Approve if MHS flags as NOT toxic with 95% confidence
|
||||
```yaml
|
||||
rules:
|
||||
- kind: mhs
|
||||
confidence: '>= 95'
|
||||
flagged: false
|
||||
criteria:
|
||||
confidence: '>= 95'
|
||||
flagged: false
|
||||
actions:
|
||||
- kind: approve
|
||||
```
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# Mod Actions
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
@@ -9,9 +16,9 @@
|
||||
|
||||
# Overview
|
||||
|
||||
[Mod Notes](https://www.reddit.com/r/modnews/comments/t8vafc/announcing_mod_notes/) is a feature for New Reddit that allow moderators to add short, categorizable notes to Users of their subreddit, optionally associating te note with a submission/comment the User made. They are inspired by [Toolbox User Notes](https://www.reddit.com/r/toolbox/wiki/docs/usernotes) which are also [supported by ContextMod.](/docs/subreddit/components/userNotes) Reddit's **Mod Notes** also combine [Moderation Log](https://mods.reddithelp.com/hc/en-us/articles/360022402312-Moderation-Log) actions (**Mod Actions**) for the selected User alongside moderator notes, enabling a full "overview" of moderator interactions with a User in their subreddit.
|
||||
[Mod Notes](https://www.reddit.com/r/modnews/comments/t8vafc/announcing_mod_notes/) is a feature for New Reddit that allow moderators to add short, categorizable notes to Users of their subreddit, optionally associating te note with a submission/comment the User made. They are inspired by [Toolbox User Notes](https://www.reddit.com/r/toolbox/wiki/docs/usernotes) which are also [supported by ContextMod.](../userNotes) Reddit's **Mod Notes** also combine [Moderation Log](https://mods.reddithelp.com/hc/en-us/articles/360022402312-Moderation-Log) actions (**Mod Actions**) for the selected User alongside moderator notes, enabling a full "overview" of moderator interactions with a User in their subreddit.
|
||||
|
||||
ContextMod supports adding **Mod Notes** to an Author using an [Action](/docs/subreddit/components/README.md#mod-note) and using **Mod Actions/Mod Notes** as a criteria in an [Author Filter](/docs/subreddit/components/README.md#author-filter)
|
||||
ContextMod supports adding **Mod Notes** to an Author using an [Action](../../README.md#mod-note) and using **Mod Actions/Mod Notes** as a criteria in an [Author Filter](../../README.md#author-filter)
|
||||
|
||||
# Mod Note Action
|
||||
|
||||
@@ -37,7 +44,7 @@ actions:
|
||||
|
||||
# Mod Action Filter
|
||||
|
||||
ContextMod can use **Mod Actions** (from moderation log) and **Mod Notes** in an [Author Filter](/docs/subreddit/components/README.md#author-filter).
|
||||
ContextMod can use **Mod Actions** (from moderation log) and **Mod Notes** in an [Author Filter](../../../README.md#author-filter).
|
||||
|
||||
## API Usage
|
||||
|
||||
@@ -61,15 +68,15 @@ Mod Action Filtering Used
|
||||
|
||||
In general,**do not** use Mod Actions in a Filter if:
|
||||
|
||||
* The filter is on a [**Comment** Check](/docs/subreddit/components/README.md#checks) and your subreddit has a high volume of Comments
|
||||
* The filter is on a [Run](/docs/subreddit/components/README.md#runs) and your subreddit has a high volume of Activities
|
||||
* The filter is on a [**Comment** Check](../../README.md#checks) and your subreddit has a high volume of Comments
|
||||
* The filter is on a [Run](../../README.md#runs) and your subreddit has a high volume of Activities
|
||||
|
||||
If you need Mod Notes-like functionality for a high volume subreddit consider using [Toolbox UserNotes](/docs/subreddit/components/userNotes) instead.
|
||||
If you need Mod Notes-like functionality for a high volume subreddit consider using [Toolbox UserNotes](../userNotes) instead.
|
||||
|
||||
In general, **do** use Mod Actions in a Filter if:
|
||||
|
||||
* The filter is on a [**Submission** Check](/docs/subreddit/components/README.md#checks)
|
||||
* The filter is part of an [Author **Rule**](/docs/subreddit/components/README.md#author) that is processed as **late as possible in the rule order for a Check**
|
||||
* The filter is on a [**Submission** Check](../../README.md#checks)
|
||||
* The filter is part of an [Author **Rule**](../../README.md#author) that is processed as **late as possible in the rule order for a Check**
|
||||
* Your subreddit has a low volume of Activities (less than 100 combined submissions/comments in a 10 minute period, for example)
|
||||
* The filter is on an Action
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# Recent Activity Rule
|
||||
|
||||
Given a list subreddit criteria, the **Recent Activity** rule finds Activities matching those criteria in the Author's history over [window](../../activitiesWindow.md) and then allows for comparing different facets of the results.
|
||||
|
||||
Subreddit criteria can be:
|
||||
|
||||
* names
|
||||
* regular expression for names
|
||||
* [Subreddit meta properties](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubmissionCheckJson/%23%2Fdefinitions%2FRecentActivityRuleJSONConfig/%23%2Fdefinitions%2FActivityThreshold/%23%2Fdefinitions%2FSubredditState?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Freddit-context-bot%2Fmaster%2Fsrc%2FSchema%2FApp.json) like NSFW, description, is user profile, is author's profile, etc...
|
||||
|
||||
Facets available to compare from analyzed history:
|
||||
|
||||
* number of activities found EX `> 3` => more than 3 activities found
|
||||
* aggregated karma from activities EX `> 50` => more than 50 combined karma from found activities
|
||||
* number of subreddits found EX `> 5` => more than 5 distinct subreddits matching subreddit criteria found
|
||||
|
||||
The above can also be expressed as a percentage instead of number IE "more than 10% of activities in author history come from subreddits matching criteria"
|
||||
|
||||
The search can also be modified in a number of ways:
|
||||
|
||||
* Filter found activities using an [Item Filter](#item)
|
||||
* 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)
|
||||
|
||||
Consult the [schema](https://json-schema.app/view/%23%2Fdefinitions%2FRecentActivityRuleJSONConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fcontext-mod%2Fmaster%2Fsrc%2FSchema%2FApp.json) for a complete reference of the rule's properties.
|
||||
|
||||
### Examples
|
||||
|
||||
* Free Karma Subreddits [YAML](freeKarma.yaml) | [JSON](freeKarma.json5) - Check if the Author has recently posted in any "free karma" subreddits
|
||||
* Submission in Free Karma Subreddits [YAML](freeKarmaOnSubmission.yaml) | [JSON](freeKarmaOnSubmission.json5) - Check if the Author has posted the Submission this check is running on in any "free karma" subreddits recently
|
||||
|
||||
# [Template Variables](../../actionTemplating.md)
|
||||
|
||||
| Name | Description | Example |
|
||||
|----------------------|------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `result` | Summary of rule results (also found in Actioned Events) | 9 activities found in 2 of the specified subreddits (out of 21 total) MET threshold of >= 1 activities -- subreddits: SubredditA, SubredditB |
|
||||
| `window` | Number or duration of Activities considered from window | 100 activities |
|
||||
| `subSummary` | Comma-delimited list of subreddits matched by the criteria | SubredditA, SubredditB |
|
||||
| `subCount` | Number of subreddits that match the criteria | 2 |
|
||||
| `totalCount` | Total number of activities found by criteria | 9 |
|
||||
| `threshold` | The threshold used to trigger the rule | `>= 1` |
|
||||
| `karmaThreshold` | If present, the karma threshold used to trigger the rule | `> 5` |
|
||||
| `combinedKarma` | Total number of karma gained from the matched activities | 10 |
|
||||
| `subredditBreakdown` | A markdown list of filtered activities by subreddit | * SubredditA - 5 (71%) \n * Subreddit B - 2 (28%) |
|
||||
36
docs/subreddit-configuration/in-depth/regex/README.md
Normal file
36
docs/subreddit-configuration/in-depth/regex/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
grand_parent: Subreddit Configuration
|
||||
parent: In Depth
|
||||
---
|
||||
|
||||
# Regex Rule
|
||||
|
||||
The **Regex** rule matches on text content from a comment or submission in the same way automod uses regex. The rule, however, provides additional functionality automod does not:
|
||||
|
||||
* Can set the **number** of matches that trigger the rule (`matchThreshold`)
|
||||
|
||||
Which can then be used in conjunction with a [`window`](../../activitiesWindow.md) to match against activities from the history of the Author of the Activity being checked (including the Activity being checked):
|
||||
|
||||
* Can set the **number of Activities** that meet the `matchThreshold` to trigger the rule (`activityMatchThreshold`)
|
||||
* Can set the **number of total matches** across all Activities to trigger the rule (`totalMatchThreshold`)
|
||||
* Can set the **type of Activities** to check (`lookAt`)
|
||||
* When an Activity is a Submission can **specify which parts of the Submission to match against** IE title, body, and/or url (`testOn`)
|
||||
|
||||
### Examples
|
||||
|
||||
* Trigger if regex matches against the current activity - [YAML](matchAnyCurrentActivity.yaml) | [JSON](matchAnyCurrentActivity.json5)
|
||||
* Trigger if regex matches 5 times against the current activity - [YAML](matchThresholdCurrentActivity.yaml) | [JSON](matchThresholdCurrentActivity.json5)
|
||||
* Trigger if regex matches against any part of a Submission - [YAML](matchSubmissionParts.yaml) | [JSON](matchSubmissionParts.json5)
|
||||
* Trigger if regex matches any of Author's last 10 activities - [YAML](matchHistoryActivity.yaml) | [JSON](matchHistoryActivity.json5)
|
||||
* Trigger if regex matches at least 3 of Author's last 10 activities - [YAML](matchActivityThresholdHistory.json5) | [JSON](matchActivityThresholdHistory.json5)
|
||||
* Trigger if there are 5 regex matches in the Author's last 10 activities - [YAML](matchTotalHistoryActivity.yaml) | [JSON](matchTotalHistoryActivity.json5)
|
||||
* Trigger if there are 5 regex matches in the Author's last 10 comments - [YAML](matchSubsetHistoryActivity.yaml) | [JSON](matchSubsetHistoryActivity.json5)
|
||||
* Remove comments that are spamming discord links - [YAML](removeDiscordSpam.yaml) | [JSON](removeDiscordSpam.json5)
|
||||
* Differs from just using automod because this config can allow one-off/organic links from users who DO NOT spam discord links but will still remove the comment if the user is spamming them
|
||||
|
||||
# [Template Variables](../../actionTemplating.md)
|
||||
|
||||
| Name | Description | Example |
|
||||
|---------------|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `result` | Summary of rule results (also found in Actioned Events) | Criteria 1 ✓ -- Activity Match ✓ => 1 > 0 (Threshold > 0) and 1 Total Matches (Window: 1 Item) -- Matched Values: "example.com/test" |
|
||||
| `matchSample` | A comma-delimited list of matches from activities | "example.com/test" |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user