thelounge-plugin-am
v0.4.0
Published
A plugin for TheLounge that answers messages automatically based on server/channel rules.
Maintainers
Readme
TheLounge Answering Machine [AM] Plugin
A plugin for TheLounge that provides "answering machine" (AM) functionality, automatically replying to messages based on a configurable set of rules.
Installation
Install the plugin via the thelounge command line:
thelounge install thelounge-plugin-amAfter installation, make sure to restart TheLounge for the plugin to be loaded.
Usage
The plugin provides the /am command to control its behavior on a per-network basis.
Commands
/am start- Starts the listener for the current IRC network. It will begin monitoring messages and responding according to the rules in
rules.json.
- Starts the listener for the current IRC network. It will begin monitoring messages and responding according to the rules in
/am stop- Stops the listener for the current IRC network.
/am status- Shows whether the listener is currently
ACTIVEorINACTIVEfor the current network.
- Shows whether the listener is currently
/am rules- Shows a list of all active rules for the current server. Requires the listener to be active.
/am reload- Manually reloads the rules from the
rules.jsonfile. Note: This is generally not needed, as the plugin reloads rules automatically when the file is changed.
- Manually reloads the rules from the
/am fetch <URL>- Fetches and merges rules from a remote URL. See the "Remote Rules Fetching" section below for important security configuration.
/am debug enable|disable|status- Controls verbose logging for debugging.
/am fetch enable|disable|status- Controls the remote rule fetching feature.
/am whitelist ...- Manages the domain whitelist for the fetch feature.
Configuration
Configuration is handled via a rules.json file that is automatically created by the plugin. If one exists already, it is respected.
rules.json structure
The file should contain an array of rule objects. Each rule object defines a trigger and a corresponding response.
[
{
"server": "Libera.Chat",
"listen_channel": "#lounge-testing",
"trigger_text": "ping",
"trigger_flags": "i",
"response_text": "pong, {{sender}}!",
"response_channel": "",
"cooldown_seconds": 5,
"delay_seconds": 10
}
]Rule properties
server(string): The name of the network/server where this rule applies (e.g., "freenode", "MyCustomServer").listen_channel(string): The channel name (e.g.,#my-project) where the plugin should listen for triggers.trigger_text(string): A regular expression pattern that the plugin will check for in messages. See the section below for more details.trigger_flags(string, optional): Flags for the regular expression. It is recommended to use"i"for case-insensitive matching, which is the default for newly created rules.response_text(string): The message that the plugin will send in response. Can contain dynamic variables.response_channel(string, optional): The channel or user to which the response should be sent. If not provided, the response is sent to thelisten_channel.cooldown_seconds(number, optional): The number of seconds the rule must wait before it can be triggered again. This is useful to prevent flooding. If not specified, it defaults to 5 seconds.delay_seconds(number, optional): The number of seconds the plugin will wait before sending the response after a trigger is matched. This is useful for simulating a more natural, human-like response time. If not specified, it defaults to 0 seconds (instant response).
Dynamic Rules with Regular Expressions
All triggers are handled by regular expressions, allowing for powerful and flexible rules.
Simple Text Matching
For a simple substring match, just enter the text directly. The plugin will find it anywhere in the message.
"trigger_text": "some text"
To make it case-insensitive (recommended), add the "i" flag:
"trigger_flags": "i"
Advanced Regular Expressions
For more advanced matching, you can use the full power of regex. For example, to match a message that starts with "hello":
"trigger_text": "^hello"
Remember to escape special JSON characters like the backslash \ (e.g., "\\s" for a space character).
Dynamic Variables
You can use variables in both the trigger and the response:
{{me}}: Is replaced by the bot's current nickname on the server. Useful for rules that respond to mentions.{{sender}}: Is replaced by the nickname of the user who sent the message. Only available inresponse_text.
Capture Groups
You can use capturing groups (...) in your trigger_text and reference the captured content in your response_text using placeholders like $1, $2, etc.
Example:
{
"server": "MyServer",
"listen_channel": "#questions",
"trigger_text": "have you ever heard of (.+)\\?",
"trigger_flags": "i",
"response_text": "Of course I've heard of $1! It's one of my favorite topics."
}If a user asks "have you ever heard of I Have No Mouth And I Must Scream, by Harlan Ellison?", the bot will respond: "Of course I've heard of I Have No Mouth And I Must Scream, by Harlan Ellison! It's one of my favorite books, and inspired one of my favorite games."
Remote Rules Fetching (Administration and Security)
This plugin allows administrators to fetch rules from a remote URL and merge them with the existing ruleset. This is useful for managing rules across multiple TheLounge instances or for using community-maintained rule lists.
:warning: SECURITY WARNING: Server-Side Request Forgery (SSRF) Enabling this feature allows TheLounge server to make HTTP requests to external URLs. A malicious actor could potentially use this to probe your internal network. To mitigate this risk, the
fetchfunctionality is disabled by default and requires two explicit actions to enable:
- The feature must be globally enabled.
- You must add trusted domains to a whitelist.
Configuration Steps
Enable the Fetch Feature Run the following command to allow the plugin to fetch remote rules:
/am fetch enableWhitelist Trusted Domains You must specify which domains are safe to fetch rules from. For example, to allow fetching from a GitHub Gist:
/am whitelist add gist.githubusercontent.comOnly URLs whose domain is on this list will be accepted.
Fetch Management Commands
/am fetch enable: Enables the remote fetching feature./am fetch disable: Disables the feature./am fetch status: Shows if the feature is currently enabled or disabled.
Whitelist Management Commands
/am whitelist add <domain>: Adds a domain to the list of allowed domains./am whitelist remove <domain>: Removes a domain from the whitelist./am whitelist list: Shows all domains currently in the whitelist.
Rule Merging Logic
When fetching rules from a URL, they are not simply added. They are merged with the existing rules.json file with the following logic:
- A rule is considered unique based on the combination of its
server,listen_channel, andtrigger_textproperties. - If a fetched rule has the same unique identifier as an existing rule, the existing rule is overwritten by the new one.
- If a fetched rule does not match any existing rule, it is added to the list.
This allows you to use the fetch command to both add new rules and update existing ones.
File location
The plugin manages its configuration in a file located inside TheLounge's persistent storage directory, which is typically:
/etc/thelounge/packages/thelounge-plugin-answering-machine/config/rules.jsonfor system-wide installations (e.g., via Debian/Ubuntu packages)./var/opt/thelounge/packages/thelounge-plugin-answering-machine/config/rules.jsonfor the official Docker image.
If you look at the logs for the service created by TheLounge you can see the exact location of the file, which the plugin logs for you.
The plugin will create a default empty rules.json file on its first run if they don't already exist.
Deploying inside a Docker container
If you want to use the plugin inside a Docker image, here is a suggested docker-compose.yml:
services:
thelounge:
image: ghcr.io/thelounge/thelounge:latest
container_name: thelounge
ports:
- "9000:9000"
restart: unless-stopped
volumes:
- thelounge:/var/opt/thelounge
- ./config.js:/var/opt/thelounge/config.js
- ./post-install.sh:/var/opt/thelounge/post-install.sh
- ./rules.json:/var/opt/thelounge/packages/thelounge-plugin-am/config/rules.json
volumes:
thelounge:This way, you can provide a custom rules.json when instancing the container.
You can use post-install.sh to install the plugin:
#!/bin/sh
export THELOUNGE_HOME=/var/opt/thelounge
echo "--- Running post-install.sh ---"
echo "Installing thelounge-plugin-am..."
thelounge install thelounge-plugin-am
echo "--- Finished running post-install.sh ---"Just make sure to chmod +x your post-install.sh before starting the container.
Do note that you need to provide a config.json file for your container and create a user for it.
This file is different from the config/config.json file that controls parameters for the plugin itself, not TheLounge. (Yes, the naming could be clearer.)
Automatic reloading
The plugin automatically watches for changes to the rules.json file. When you save your modifications to rules.json, the plugin will instantly reload the rules in the background. You will see a confirmation message in TheLounge's server logs.
This means you no longer need to manually run /am reload after changing the rules, although the command is still available for convenience.
Code Structure
For those interested in contributing or understanding the plugin's internals, the codebase is organized into several modules within the src/ directory. This modular approach separates concerns, making the code easier to maintain and extend.
index.js: The main entry point of the plugin. It is responsible for initializing all other modules, wiring them together, and registering commands and file watchers with TheLounge API. It acts as the central orchestrator.src/logger.js: A wrapper around TheLounge's native logger. It provides standardinfoanderrormethods, along with adebugmethod that only prints messages when debug mode is enabled in the plugin's configuration.src/plugin-config.js: Manages the plugin's internal configuration file (config.json). This file stores settings like the debug mode status. This module handles loading, saving, and providing access to these settings.src/rule-manager.js: Responsible for everything related to the user-defined rules (rules.json). It handles loading, parsing, and providing access to the rules. In the future, it will also contain the logic for adding, removing, and updating rules via commands.src/message-handler.js: Contains the core logic of the plugin. It defines theprivmsgevent handler that checks incoming messages against the rules from therule-managerand decides when to trigger a response. It also manages rule cooldowns.src/commands.js: Defines the/amcommand and all its subcommands (start,stop,reload,debug, etc.). It acts as the user-facing interface, calling functions from other modules to execute the requested actions.
Debugging
The plugin includes a debug mode that provides verbose logging, which can be useful for troubleshooting rules or reporting issues. You can control this mode in real-time using commands.
The recommended way to manage debug mode is with the /am debug commands:
/am debug enable: Activates verbose logging./am debug disable: Deactivates verbose logging./am debug status: Shows whether debug mode is currently active.
Changes are automatically saved to config.json, so your choice will be remembered after a restart.
Manual Configuration
As an alternative, you can also control this feature by manually editing the config.json file (located in the same directory as rules.json). Set the debug property to true or false:
{
"debug": true
}The plugin will automatically detect this change as well.
License
This plugin is licensed under the MIT License.
