npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

thelounge-plugin-am

v0.4.0

Published

A plugin for TheLounge that answers messages automatically based on server/channel rules.

Readme

TheLounge Answering Machine [AM] Plugin

NPM version

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-am

After 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.
  • /am stop

    • Stops the listener for the current IRC network.
  • /am status

    • Shows whether the listener is currently ACTIVE or INACTIVE for the current network.
  • /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.json file. Note: This is generally not needed, as the plugin reloads rules automatically when the file is changed.
  • /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 the listen_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 in response_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 fetch functionality is disabled by default and requires two explicit actions to enable:

  1. The feature must be globally enabled.
  2. You must add trusted domains to a whitelist.

Configuration Steps

  1. Enable the Fetch Feature Run the following command to allow the plugin to fetch remote rules:

    /am fetch enable
  2. Whitelist 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.com

    Only 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:

  1. A rule is considered unique based on the combination of its server, listen_channel, and trigger_text properties.
  2. If a fetched rule has the same unique identifier as an existing rule, the existing rule is overwritten by the new one.
  3. 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.json for system-wide installations (e.g., via Debian/Ubuntu packages).
  • /var/opt/thelounge/packages/thelounge-plugin-answering-machine/config/rules.json for 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 standard info and error methods, along with a debug method 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 the privmsg event handler that checks incoming messages against the rules from the rule-manager and decides when to trigger a response. It also manages rule cooldowns.

  • src/commands.js: Defines the /am command 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.