Article Filtering ================= Sometimes you need to automatically tweak an incoming article, mark it as important, remove ads from its contents, or simply reject it. That is where the article-filtering feature comes in. Article filters are meant for advanced users. They are powerful, but they can slow down feed updates, fetch extra data, launch external tools, or make changes that are synchronized back to some online services. ## `Article filters` dialog The dialog shown below lets you: * create, remove, enable, disable, and reorder filters * assign a filter to multiple feeds within the selected account * test a filter on already stored articles * run a filter on checked feeds and save the accepted changes back to the database alt-img Filters run in ascending sort order. Only enabled filters are executed. The right-hand side of the dialog has two main uses: * `Test` Runs the selected filter against the currently loaded existing articles without permanently saving any changes. * `Process checked feeds` Runs the selected filter on undeleted articles from all checked feeds and writes accepted changes back to the database. The `Existing articles` table is especially useful during testing: * `Result` shows whether a message was accepted, ignored, or purged * changed values in columns like `Read`, `Important`, `Trash`, `Title`, `Date`, and `Score` are highlighted * tooltips show the original value and the filtered value * the lower detail tabs let you inspect article metadata and contents The `Script output` tab shows messages written by `app.log(...)`, and also shows script errors when testing from the dialog. ```{warning} During normal feed fetching, a JavaScript error in a filter does **not** reject the article. RSS Guard logs the error and continues as if the message was accepted. In the testing dialog, the error is shown to you directly. ``` ```{warning} Feed-level article ignoring and article-count limits run **after** article filters. So even if your filter accepts an article, a later cleanup or ignore rule may still prevent it from being kept. ``` ## How filters are applied Each enabled filter is run on each article in order. For newly downloaded articles: * `Accept` Keeps the article and continues to the next filter. * `Ignore` Drops the article from this fetch run. Later filters do not run for that article. * `Purge` Behaves like `Ignore` for a newly downloaded article. For existing articles processed from the dialog: * `Accept` Keeps the article and saves its changed fields. * `Ignore` Skips saving changes for that article. * `Purge` Permanently removes the article from the database. This means `Ignore` and `Purge` are very different when you run a filter on already stored messages. ## Writing an article filter Article filters are small `JavaScript` snippets. Each script must provide a function with this prototype: ```js function filterMessage() { } ``` The function must return one of the values from the [`FilteringAction`](#filteringaction-enum) enumeration. The built-in JavaScript environment is based on Qt's `QJSEngine` and includes a useful set of helper objects exposed by RSS Guard. Each article is available via the global `msg` object. Other globals provide access to the current feed, account, helper functions, run metadata, application logging, and process launching. ```{note} Some attributes such as `read`, `unread`, and `starred` states are synchronized back to your account's server. So, for example, marking an article as important in a filter may trigger a matching state change on services that support it. ``` ```{attention} Special [placeholders](userdata.md#data-placeholder) can be used in article filters. This is especially useful for loading helper files, keyword lists, or calling external tools from your user-data folder. ``` ## Power-user tips * Keep filters cheap first, expensive filters later. A fast duplicate or keyword check near the top can save time before you do heavier work like full-content extraction. * Prefer returning early. If a message should obviously be ignored, do that early and skip unnecessary processing. * Use `Test` before `Process checked feeds`. This makes it much easier to catch a bad regular expression or an accidental `Purge`. * Use `app.log(...)` while developing. It is much easier to debug a filter when it prints intermediate values into the `Script output` tab. * Be careful with `fetchFullContents(...)`. It may issue extra network requests, slow down updates, and substantially increase database size. * Be careful with external executables. They can be extremely useful, but they can also be slow or platform-specific. ## Global variables These global objects are available to your scripts: | Global variable | What it provides | | :--- | :--- | | `msg` | Information about the actual article being filtered or modified. | | `feed` | Information about the feed the article belongs to. | | `acc` | Account-related information. | | `app` | Application-wide helper functions such as logging and notifications. | | `utils` | Utility functions for parsing data and reading or writing files. | | `run` | Information about the current filtering run. | | `fs` | Process-launching helpers for calling external executables. | ## Reference Documentation Here is the complete reference documentation of the functions and properties available to your filtering scripts. ### `msg` #### Properties | Name | Type | Read-only | Synchronized | Description | | :--- | :--- | :---: | :---: | :--- | | `assignedLabels` | `Array