Plugins

Extend your bot with modular plugins. Package commands, middlewares, adapters, and lifecycle hooks into reusable, shareable modules.

Plugins

Plugins are the modular extension system for @igniter-js/bot. A plugin packages commands, middlewares, adapters, and lifecycle hooks into a single, reusable module that can be shared across bots and projects.


Plugin Contract

interface BotPlugin {
  name: string                      // Unique plugin name
  version: string                   // Semver version
  description?: string              // What the plugin does
  commands?: Record<string, BotCommand>       // Commands to register
  middlewares?: Middleware<any, any>[]         // Middlewares to add
  adapters?: Record<string, IBotAdapter<any>> // Adapters to register
  hooks?: {
    onStart?: () => Promise<void> | void
    onMessage?: (ctx: BotContext) => Promise<void> | void
    onError?: (ctx: BotContext & { error: BotError }) => Promise<void> | void
    onStop?: () => Promise<void> | void
  }
  config?: Record<string, any>      // Plugin-specific configuration
}

When a plugin is loaded via .usePlugin(), the builder automatically:

  1. Registers all plugin commands
  2. Appends all plugin middlewares to the pipeline
  3. Registers all plugin adapters
  4. Attaches all lifecycle hooks to the bot

Built-in Plugin: Analytics

The analyticsPlugin tracks bot usage metrics and provides a /stats command.

Installation

import { analyticsPlugin } from '@igniter-js/bot';

Basic Usage

const bot = IgniterBot.create()
  .usePlugin(analyticsPlugin())
  .build();

This enables basic console-logged analytics and the /stats command:

/stats

📊 Bot Statistics

Messages: 1,247
Commands: 342
Errors: 3
Unique Users: 89

With External Analytics Service

import { analyticsPlugin } from '@igniter-js/bot';
import { PostHog } from 'posthog-node';

const posthog = new PostHog(process.env.POSTHOG_API_KEY!);

const bot = IgniterBot.create()
  .usePlugin(analyticsPlugin({
    trackEvent: async (event, properties) => {
      await posthog.capture({
        distinctId: properties.userId || 'anonymous',
        event,
        properties,
      });
    },
    trackMessages: true,
    trackCommands: true,
    trackErrors: true,
    includeUserInfo: true,
  }))
  .build();
OptionTypeDefaultDescription
trackEvent(event, props) => void | Promise<void>console.logWhere to send events
trackMessagesbooleantrueTrack message events
trackCommandsbooleantrueTrack command events
trackErrorsbooleantrueTrack error events
includeUserInfobooleantrueInclude user ID and username

Events Tracked

EventPropertiesWhen
bot.startedtimestampBot initialization
bot.messageprovider, contentType, isGroup, isMentioned, userId, usernameEvery incoming message
bot.commandSame as message + command, paramsEvery command execution
bot.errorprovider, errorMessage, errorCode, userIdEvery error caught
bot.requestprovider, event, duration, isGroupAfter every request (timing)

Creating Custom Plugins

Example: Welcome Plugin

A plugin that sends a welcome message to new users:

// plugins/welcome.ts
import type { BotPlugin } from '@igniter-js/bot';

export function welcomePlugin(options?: {
  message?: string;
  trackNewUsers?: boolean;
}): BotPlugin {
  const { message = 'Welcome to the bot! 👋', trackNewUsers = true } = options || {};

  const seenUsers = new Set<string>();

  return {
    name: 'welcome',
    version: '1.0.0',
    description: 'Sends a welcome message to new users',

    middlewares: [
      async (ctx, next) => {
        const userId = ctx.message.author.id;

        if (!seenUsers.has(userId)) {
          seenUsers.add(userId);
          await ctx.reply(message);

          if (trackNewUsers) {
            console.log(`New user: ${ctx.message.author.username} on ${ctx.provider}`);
          }
        }

        await next();
      },
    ],
  };
}

Use it:

import { welcomePlugin } from './plugins/welcome';

const bot = IgniterBot.create()
  .usePlugin(welcomePlugin({
    message: '🎉 Welcome to our community! Type /help to get started.',
    trackNewUsers: true,
  }))
  .build();

Example: Scheduled Tasks Plugin

A plugin that runs periodic tasks:

// plugins/scheduler.ts
import type { BotPlugin } from '@igniter-js/bot';

export function schedulerPlugin(options: {
  intervalMs: number;
  task: () => Promise<void>;
}): BotPlugin {
  return {
    name: 'scheduler',
    version: '1.0.0',
    description: 'Runs periodic background tasks',

    hooks: {
      onStart: () => {
        setInterval(async () => {
          try {
            await options.task();
          } catch (error) {
            console.error('[scheduler] Task failed:', error);
          }
        }, options.intervalMs);
      },
    },
  };
}

Example: Multi-Tenant Plugin

A plugin that adds tenant-aware middleware and a tenant command:

// plugins/multi-tenant.ts
import type { BotPlugin, BotContext } from '@igniter-js/bot';

export function multiTenantPlugin(options: {
  getTenant: (userId: string) => Promise<string>;
}): BotPlugin {
  return {
    name: 'multi-tenant',
    version: '1.0.0',
    description: 'Adds multi-tenant context to bot interactions',

    middlewares: [
      async (ctx, next) => {
        const tenantId = await options.getTenant(ctx.message.author.id);
        await next();
        return { tenantId }; // Available in downstream handlers
      },
    ],

    commands: {
      tenant: {
        name: 'tenant',
        aliases: ['workspace'],
        description: 'Show current tenant',
        help: 'Use /tenant to see your current workspace',
        async handle(ctx) {
          const tenantId = (ctx as any).tenantId || 'unknown';
          await ctx.reply(`🏢 Current workspace: **${tenantId}**`);
        },
      },
    },
  };
}

Plugin Factories

Plugins can be factories that accept configuration:

type BotPluginFactory<TConfig = any> = (config?: TConfig) => BotPlugin;

// Usage
const plugin = myPlugin({ apiKey: '...', environment: 'production' });
builder.usePlugin(plugin);

Composing Multiple Plugins

Plugins are loaded in order and their middlewares are appended to the pipeline:

const bot = IgniterBot.create()
  .usePlugin(welcomePlugin({ message: 'Hello!' }))    // 1st
  .usePlugin(analyticsPlugin({ trackMessages: true })) // 2nd
  .usePlugin(multiTenantPlugin({ getTenant }))         // 3rd
  .build();

// Middleware order: welcome → analytics → multi-tenant → your custom middlewares → commands

Plugin middlewares are appended before .build() returns, but after any middlewares already added via .addMiddleware(). If order matters, add your middlewares after loading plugins.


Next Steps