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

@hansaka02/filtermatics

v1.0.2

Published

A simple, persistent, file-based filter manager for any chat bot.

Readme

Chat Filters

A simple, persistent, file-based filter manager for any chat bot.

This module allows you to easily add, remove, and manage message filters on a per-chat basis. Each chat's filters are saved in their own JSON file, making the system robust and easy to manage.

🚀 Features

  • Per-Chat Storage: All filters are saved specific to each chat ID.
  • JSON Storage: Creates a separate .json file for each chat's filters.
  • Multi-Trigger Support: A single reply (text, media, etc.) can be tied to multiple triggers (e.g., ['hi', 'hello']).
  • Robust Matching: Correctly matches triggers with symbols (@123), numbers, and text, and handles "whole word" matching.
  • Platform Agnostic: Works with any bot framework (Telegram, Discord, Slack, etc.) by storing data by chatId.

📦 Installation

npm install filtermatics

Usage

Here is a basic, platform-agnostic example of how to integrate the filter manager into your bot.

// Your main bot file (e.g., index.js)

// 1. Import your package
const FilterManager = require('filtermatics'); 

// 2. Create a single instance and tell it where to save files
// This will create a 'filters' folder in your bot's root directory
const Filters = new FilterManager({
  dbPath: './filters' 
});

// ... inside your bot's main message handler ...
// (Assuming you have a 'chatId' and 'messageText' from your bot API)

try {
  // 3. Use the functions (they are now methods of your 'Filters' object)
  
  if (messageText.toLowerCase() === '/filters') {
    const allFilters = Filters.getFilters(chatId);
    
    // --- Example: Formatting the filter list ---
    if (allFilters.length === 0) {
      // yourBot.sendMessage(chatId, 'There are no filters in this chat.');
      return;
    }
    
    let filterList = `📋 *Filters in this chat: ${allFilters.length}*\n\n`;
    allFilters.forEach(filter => {
      const triggersText = filter.triggers.map(t => `\`${t}\``).join(', ');
      filterList += `• *Triggers:* ${triggersText}\n  *Type:* ${filter.type}\n\n`;
    });
    // yourBot.sendMessage(chatId, filterList);
    // --- End of example ---

  } else if (messageText.startsWith('/filter')) {
    // ... add your logic to get triggers and reply ...
    
    // Example: /filter hi hello "Hello there!"
    const newFilter = {
      triggers: ['hi', 'hello'],
      type: 'text',
      reply: 'Hello there!'
      // For media, you could store a file_id, a URL, or base64
    };
    Filters.addFilter(chatId, newFilter);
    // yourBot.sendMessage(chatId, '✅ Filter saved.');
  
  } else if (messageText.startsWith('/stop')) {
    // ... add your logic to get the trigger to stop ...
    const triggerToRemove = 'hi';
    const removed = Filters.removeFilter(chatId, triggerToRemove);
    
    if (removed) {
      // yourBot.sendMessage(chatId, `✅ Filter for \`${triggerToRemove}\` removed.`);
    } else {
      // yourBot.sendMessage(chatId, `❌ Filter not found.`);
    }

  } else {
    // 4. Check for filter triggers if it's not a command
    const matchedFilter = Filters.checkFilters(chatId, messageText);
    
    if (matchedFilter) {
      // ... logic to send the reply based on matchedFilter.type ...
      if (matchedFilter.type === 'text') {
        // yourBot.sendMessage(chatId, matchedFilter.reply);
      } else if (matchedFilter.type === 'sticker') {
        // e.g., yourBot.sendSticker(chatId, matchedFilter.reply); // 'reply' could be a URL or file_id
      }
      // ... etc. for image/video
    }
  }

} catch (err) {
  // This will catch errors from addFilter, removeFilter, etc.
  console.error('An error occurred in the filter command:', err);
  // yourBot.sendMessage(chatId, `Error: ${err.message}`);
}

📖 API Reference

new FilterManager(options)

Creates a new filter manager instance.

  • options (Object): Configuration object.
    • dbPath (String) [Required]: The path to the folder where filter .json files will be stored (e.g., ./my_filters).

Filters.addFilter(chatId, filter)

Adds a new filter to a chat. If any of the new triggers are already in use, this will overwrite the old filter.

  • chatId (String): The unique ID of the chat.
  • filter (Object): The filter object.
    • triggers (Array<String>): An array of trigger words (e.g., ['hi', 'hello']).
    • type (String): The type of reply (e.g., 'text', 'sticker', 'image').
    • reply (String): The reply content. This can be a text string, a URL, a file_id, or a base64 string.
    • mimetype (String) (Optional): A mimetype if needed (e.g., 'image/webp').

Filters.removeFilter(chatId, trigger)

Removes a filter from a chat based on one of its triggers.

  • chatId (String): The unique ID of the chat.
  • trigger (String): The trigger word to remove.
  • Returns: true if a filter was removed, false otherwise.

Filters.removeAllFilters(chatId)

Removes all filters from a specific chat.

  • chatId (String): The unique ID of the chat.
  • Returns: true if filters were removed, false if no filters existed.

Filters.getFilters(chatId)

Retrieves an array of all filter objects for a specific chat.

  • chatId (String): The unique ID of the chat.
  • Returns: An array of filter objects, or an empty array [].

Filters.checkFilters(chatId, text)

Checks incoming message text against all filters for a chat.

  • chatId (String): The unique ID of the chat.
  • text (String): The incoming message text to check.
  • Returns: The matched filter object if a match is found, or null if no match.