Televerseteleverse.

Plugins

Extend your bot's functionality with the modular Plugin system.

Overview

The Plugin System in Televerse is designed to make your bot extensible and modular. Plugins allow you to package reusable logic, middleware, and transformers into a single unit that can be easily installed and configured.

Plugins are excellent for:

  • Sharing code: Package common features (like authentication or session management) and share them across multiple bots.
  • Organizing code: Keep your bot's core logic clean by moving complex features into separate plugin files.
  • Community contributions: Use plugins created by the community to add powerful features instantly.

Built-in Plugins

Televerse comes with powerful built-in plugins like Session and Conversation. We encourage you to study their source code to understand how to build robust plugins.

The Plugin Interface

All plugins in Televerse realize the BotPlugin<CTX> interface. This interface defines the contract that your plugin must follow.

abstract interface class BotPlugin<CTX extends Context> {
  // Unique name for the plugin
  String get name;
  
  // Plugin version
  String get version => '1.0.0';
  
  // List of other plugins this plugin depends on
  List<String> get dependencies => const [];
  
  // Description of what the plugin does
  String? get description => null;

  // Called when the plugin is installed
  void install(Bot<CTX> bot);

  // Called when the plugin is uninstalled
  void uninstall(Bot<CTX> bot) {}
}

Types of Plugins

While the BotPlugin interface is the base, Televerse provides two helper abstract classes for common use cases:

  • MiddlewarePlugin: For plugins that only add middleware (e.g., a logger or flood control).
  • TransformerPlugin: For plugins that only modify API requests (e.g., auto-retry or payload modifier).

Creating a Custom Plugin

Let's build a practical example: a Maintenance Mode plugin. This plugin will check a flag and, if maintenance is enabled, reply to all messages with a "Service Unavailable" message and stop further processing.

Step 1: Define the Plugin

We'll create a class that implements BotPlugin.

import 'package:televerse/televerse.dart';

class MaintenancePlugin<CTX extends Context> implements BotPlugin<CTX> {
  // Configuration: is maintenance mode active?
  bool enabled;

  // Configuration: message to send
  final String message;

  // Allow admins to bypass maintenance
  final List<int> adminIds;

  MaintenancePlugin({
    this.enabled = false,
    this.message =
        "⚠️ The bot is currently under maintenance. Please try again later.",
    this.adminIds = const [],
  });

  
  String get name => 'maintenance-mode';

  
  String get description => 'Blocks checks if the bot is in maintenance mode.';

  
  void install(Bot<CTX> bot) {
    // Add our middleware to the bot
    bot.use(_handler);
  }

  
  void uninstall(Bot<CTX> bot) {
    // No cleanup needed for this simple plugin
  }

  // The middleware logic
  Future<void> _handler(CTX ctx, NextFunction next) async {
    // 1. If maintenance is disabled, just continue
    if (!enabled) {
      await next();
      return;
    }

    // 2. Check if user is admin (can bypass)
    if (ctx.from != null && adminIds.contains(ctx.from!.id)) {
      await next();
      return;
    }

    // 3. Maintenance is active and user is not admin
    // Reply and STOP the chain (don't call next)
    await ctx.reply(message);
  }

  
  List<String> get dependencies => [];

  
  String get version => "1.0.0";
}

Step 2: Using the Plugin

Now that we've created the plugin, using it is incredibly simple.

void main() async {
  final bot = Bot(Platform.environment["BOT_TOKEN"]!);

  // specific admin ID
  const myAdminId = 123456789;

  // Create the plugin instance
  final maintenance = MaintenancePlugin(
    enabled: true, // Start in maintenance mode
    adminIds: [myAdminId],
  );

  // Install it!
  bot.plugin(maintenance);

  // Define commands
  bot.command('start', (ctx) => ctx.reply("System is online! 🟢"));
  
  // Admin command to toggle maintenance at runtime
  bot.command('toggle', (ctx) {
      if (ctx.from?.id != myAdminId) return;
      
      maintenance.enabled = !maintenance.enabled;
      ctx.reply("Maintenance is now: ${maintenance.enabled ? 'ON 🔴' : 'OFF 🟢'}");
  });

  await bot.start();
}

Advanced Plugin Features

Dependencies

Some plugins might require other plugins to function. For example, a ShoppingCartPlugin might need the SessionPlugin to store cart items.

You can declare dependencies in your plugin. Televerse will check for them during installation and throw an error if they are missing.

class ShoppingCartPlugin<CTX extends Context> implements BotPlugin<CTX> {
  
  String get name => 'shopping-cart';

  // Declare that this plugin NEEDS 'session' to work
  
  List<String> get dependencies => ['session']; 

  
  void install(Bot<CTX> bot) {
    // We can safely assume session is available here because
    // Televerse checked the dependencies.
    
    bot.use((ctx, next) async {
        // ... cart logic using ctx.session ...
    });
  }
}

Transformers in Plugins

Plugins can also modify the bot's API behavior by installing Transformers. For example, an Auto Retry plugin could automatically retry failed API requests.

class MyAutoRetryTransformer<CTX extends Context> implements BotPlugin<CTX> {
  
  String get name => 'auto-reply';

  
  void install(Bot<CTX> bot) {
    // Install a transformer to intercept API calls
    bot.api.use(MyAutoRetryTransformer());
  }
  
  // ...
}