JSPM

  • Created
  • Published
  • Downloads 37
  • Score
    100M100P100Q108661F
  • License MIT

Multi-channel messaging library with grammy-compatible API for Telegram, Webchat, WhatsApp, and SMS

Package Exports

  • @rizzclub/channels
  • @rizzclub/channels/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@rizzclub/channels) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@rizzclub/channels

Multi-channel messaging library with a grammy-compatible API for Telegram, Webchat, WhatsApp, and SMS.

Features

  • 🎯 Grammy-compatible API - Drop-in replacement for grammy with the same interface
  • 🔌 Multiple Channels - Telegram, Webchat, WhatsApp (coming soon), SMS (coming soon)
  • 🚀 Cloudflare Workers - Optimized for serverless deployment
  • 📦 TypeScript - Full type safety and autocompletion
  • 🎨 Unified Interface - Write once, deploy to multiple channels

Installation

npm install @rizzclub/channels

Quick Start

Telegram Bot

import { Bot, TelegramAdapter } from '@rizzclub/channels';

const adapter = new TelegramAdapter({
  token: process.env.TELEGRAM_TOKEN
});

const bot = new Bot(adapter);

bot.command('start', (ctx) => {
  return ctx.reply('Hello! I am your bot.');
});

bot.on('message:text', (ctx) => {
  return ctx.reply(`You said: ${ctx.text}`);
});

// Cloudflare Worker
export default {
  async fetch(request: Request, env: Env) {
    return bot.handleWebhook(request);
  }
};

Webchat Bot

import { Bot, WebchatAdapter } from '@rizzclub/channels';

const adapter = new WebchatAdapter({
  webhookSecret: process.env.WEBHOOK_SECRET,
  callbackUrl: 'https://your-app.com/api/messages'
});

const bot = new Bot(adapter);

bot.on('message:text', async (ctx) => {
  await ctx.reply(`Echo: ${ctx.text}`);
});

bot.callbackQuery(/^button:/, async (ctx) => {
  await ctx.answerAlert('Button clicked!');
});

API Reference

Bot

The Bot class is the main entry point, providing a grammy-compatible API.

Methods

  • bot.command(command, handler) - Handle commands (e.g., /start)
  • bot.on(event, handler) - Handle events (e.g., 'message:text')
  • bot.hears(trigger, handler) - Handle messages matching text/regex
  • bot.callbackQuery(data, handler) - Handle inline button callbacks
  • bot.use(middleware) - Add middleware
  • bot.filter(filter, handler) - Handle messages matching custom filter
  • bot.handleWebhook(request) - Process incoming webhook requests

Events

  • 'message' - Any message
  • 'message:text' - Text messages only
  • 'callback_query' - Inline button clicks
  • 'edited_message' - Message edits

Context

The Context object provides convenient access to update data and reply methods.

Properties

  • ctx.message - The message object
  • ctx.chat - The chat object
  • ctx.from - The user object
  • ctx.text - Message text
  • ctx.callbackQuery - Callback query object
  • ctx.callbackData - Callback query data
  • ctx.channel - Current channel type

Methods

  • ctx.reply(text, options?) - Reply to the message
  • ctx.send(text, options?) - Send without replying
  • ctx.editMessageText(text, options?) - Edit the message
  • ctx.deleteMessage() - Delete the message
  • ctx.answerCallbackQuery(options?) - Answer callback query
  • ctx.answerAlert(text) - Answer with alert popup
  • ctx.hasCommand(command?) - Check if message is a command

Adapters

TelegramAdapter

Wraps grammy for Telegram integration.

import { TelegramAdapter } from '@rizzclub/channels';

const adapter = new TelegramAdapter({
  token: 'YOUR_BOT_TOKEN'
});

Options:

  • token - Telegram bot token from @BotFather
  • bot? - Optional grammy Bot instance for advanced usage

WebchatAdapter

Custom adapter for web-based chat interfaces.

import { WebchatAdapter, InMemoryMessageStore } from '@rizzclub/channels';

const adapter = new WebchatAdapter({
  webhookSecret: 'your-secret',
  callbackUrl: 'https://your-app.com/api/send',
  callbackHeaders: {
    'Authorization': 'Bearer token'
  },
  messageStore: new InMemoryMessageStore()
});

Options:

  • webhookSecret? - Secret for validating webhook requests
  • callbackUrl? - URL to POST messages to
  • callbackHeaders? - Headers for callback requests
  • messageStore? - Store for tracking messages

Webhook Payload Format:

{
  type: 'message' | 'callback_query',
  sessionId: string,
  userId: string,
  userName?: string,
  timestamp: number,
  message?: {
    id: string,
    text?: string
  },
  callbackQuery?: {
    id: string,
    data: string,
    messageId: string
  }
}

WhatsAppAdapter (Coming Soon)

Placeholder for WhatsApp Business API integration.

SMSAdapter (Coming Soon)

Placeholder for SMS integration via Twilio/Vonage.

Multi-Channel Support

Handle multiple channels with shared bot logic using the built-in Router:

import {
  createRouter,
  TelegramAdapter,
  WebchatAdapter
} from '@rizzclub/channels';

// Shared bot setup
function setupBot(bot) {
  bot.command('start', (ctx) => {
    return ctx.reply(`Welcome to ${ctx.channel}!`);
  });

  bot.on('message:text', (ctx) => {
    return ctx.reply(`[${ctx.channel}] You said: ${ctx.text}`);
  });
}

// Cloudflare Worker
export default {
  async fetch(request: Request, env: Env) {
    const router = createRouter()
      .route('/telegram/webhook', new TelegramAdapter({ token: env.TELEGRAM_TOKEN }), setupBot)
      .route('/webchat/webhook', new WebchatAdapter({ webhookSecret: env.WEBHOOK_SECRET }), setupBot);

    return router.handleRequest(request);
  }
};

Option 2: Manual Routing

import {
  Bot,
  TelegramAdapter,
  WebchatAdapter,
  type ChannelAdapter
} from '@rizzclub/channels';

// Shared bot logic
function createBot(adapter: ChannelAdapter) {
  const bot = new Bot(adapter);

  bot.command('start', (ctx) => {
    return ctx.reply(`Welcome to ${ctx.channel}!`);
  });

  bot.on('message:text', (ctx) => {
    return ctx.reply(`[${ctx.channel}] You said: ${ctx.text}`);
  });

  return bot;
}

// Cloudflare Worker
export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    // Telegram webhook
    if (url.pathname === '/telegram') {
      const bot = createBot(
        new TelegramAdapter({ token: env.TELEGRAM_TOKEN })
      );
      return bot.handleWebhook(request);
    }

    // Webchat webhook
    if (url.pathname === '/webchat') {
      const bot = createBot(
        new WebchatAdapter({ webhookSecret: env.WEBHOOK_SECRET })
      );
      return bot.handleWebhook(request);
    }

    return new Response('Not Found', { status: 404 });
  }
};

Inline Keyboards

Create interactive inline keyboards:

bot.command('menu', (ctx) => {
  return ctx.reply('Choose an option:', {
    replyMarkup: {
      inlineKeyboard: [
        [
          { text: '✅ Option 1', callbackData: 'opt1' },
          { text: '❌ Option 2', callbackData: 'opt2' }
        ],
        [
          { text: '🔗 Visit Website', url: 'https://rizz.club' }
        ]
      ]
    }
  });
});

bot.callbackQuery('opt1', async (ctx) => {
  await ctx.answerAlert('You chose Option 1!');
  await ctx.editMessageText('Option 1 selected ✅');
});

Reply Keyboards

Create reply keyboards (Telegram):

bot.command('keyboard', (ctx) => {
  return ctx.reply('Choose a category:', {
    replyMarkup: {
      keyboard: [
        [{ text: '📱 Tech' }, { text: '🎮 Gaming' }],
        [{ text: '🎨 Art' }, { text: '🎵 Music' }]
      ],
      resizeKeyboard: true,
      oneTimeKeyboard: true
    }
  });
});

Middleware

Add custom middleware for logging, authentication, etc:

// Logging middleware
bot.use(async (ctx, next) => {
  console.log(`Incoming from ${ctx.channel}: ${ctx.text}`);
  await next();
});

// Auth middleware
bot.use(async (ctx, next) => {
  const userId = ctx.from?.id;
  if (!userId) return;

  const isAuthorized = await checkAuth(userId);
  if (!isAuthorized) {
    return ctx.reply('Unauthorized');
  }

  await next();
});

TypeScript

Full TypeScript support with type inference:

import { Bot, Context, TelegramAdapter } from '@rizzclub/channels';

const adapter = new TelegramAdapter({ token: 'token' });
const bot = new Bot(adapter);

bot.on('message:text', (ctx: Context) => {
  // ctx.text is automatically typed as string | undefined
  if (ctx.text) {
    console.log(ctx.text.toUpperCase());
  }
});

Comparison with Grammy

@rizzclub/channels provides the same API as grammy while supporting multiple channels:

Feature Grammy @rizzclub/channels
Telegram
Webchat
WhatsApp 🚧 Coming soon
SMS 🚧 Coming soon
API compatibility - 100%
TypeScript
Cloudflare Workers

License

MIT

Contributing

Contributions welcome! Please open an issue or PR.