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

chz-telegram-bot

v0.5.5

Published

Opinionated TypeScript framework that provides a structured approach to building Telegram bots.

Readme

chz-bot-Framework

Ask DeepWiki

Overview

botFramework is a TypeScript library that provides a structured approach to building Telegram bots. It offers a comprehensive set of features for managing bot lifecycles, message processing, scheduled tasks, and state persistence.

Features

  • Type-Safe Command Building: Fully TypeScript-supported command builders
  • Stateful Actions: Built-in state management for commands, scheduled actions, and inline queries
  • Flexible Triggering: Support for exact matches, regex patterns, and message types
  • Scheduled Tasks: Time-based actions with customizable execution schedules
  • Access Control: Built-in user and chat-based permissions
  • Cooldown Management: Configurable cooldown periods for commands
  • Cached Values: Process-wide caching system for optimizing resource usage
  • Custom State Types: Extensible state system for complex bot logic
  • Comprehensive Logging: Built-in logging system with trace IDs
  • Persistent Storage: JSON-based file storage with automatic state management
  • Inline Query Support: Handle inline queries with type-safe builders
  • Response Queue: Managed response processing queue for reliable message delivery
  • Rich Media Support: Built-in support for text, images, videos, reactions, and inline results

Installation

# Using npm
npm install chz-telegram-bot

# Using yarn
yarn add chz-telegram-bot

# Using bun
bun add chz-telegram-bot

Quick Start

1. Create a new bot project

mkdir my-telegram-bot
cd my-telegram-bot
npm init -y
npm install chz-telegram-bot

2. Create a token file

Create a file named token.txt in your project and paste your Telegram Bot token obtained from BotFather.

3. Create a basic bot

Create an index.ts file with the following content:

import {
    botOrchestrator,
    CommandActionBuilder,
    MessageType,
    Seconds
} from 'chz-telegram-bot';

// Define your command actions
const commands = [
    new CommandActionBuilder('HelloWorld')
        .on('/hello')
        .do((ctx) => {
            ctx.reply.withText('Hello, world!');
        })
        .build(),

    new CommandActionBuilder('Welcome')
        .on(MessageType.NewChatMember)
        .do((ctx) => {
            ctx.reply.withText('Welcome to the group!');
        })
        .build()
];

async function main() {
    try {
        // Start the bot
        const bot = await botOrchestrator.startBot({
            name: 'MyFirstBot',
            tokenFilePath: './token.txt',
            commands,
            scheduled: [], // Add scheduled actions if needed
            chats: {
                MyChat: -1001234567890 // Replace with your chat ID
            },
            scheduledPeriod: (60 * 5) as Seconds,
            // Optional settings
            storagePath: './data',
            verboseLoggingForIncomingMessage: false
        });

        // Proper cleanup on shutdown
        const cleanup = async (signal: string) => {
            console.log(`Received ${signal}, cleaning up...`);
            await botOrchestrator.stopBots();
            process.exit(0);
        };

        process.on('SIGINT', () => cleanup('SIGINT'));
        process.on('SIGTERM', () => cleanup('SIGTERM'));

        console.log('Bot started successfully!');
        return bot;
    } catch (error) {
        console.error('Failed to start bot:', error);
        process.exit(1);
    }
}

main().catch(console.error);

4. Run your bot

bun index.ts

Core Concepts

Command Actions

Command actions are triggered by user messages that match specific patterns:

import { CommandActionBuilder } from 'chz-telegram-bot';

const myCommand = new CommandActionBuilder('StartCommand')
    .on('/start')
    .do((ctx) => {
        ctx.reply.withText('Welcome to my bot!');
    })
    .build();

Message types can also trigger commands:

import { CommandActionBuilder, MessageType } from 'chz-telegram-bot';

const myCommand = new CommandActionBuilder('WelcomeMessage')
    .on(MessageType.NewChatMember)
    .do((ctx) => {
        ctx.reply.withText('Welcome to my group chat!');
    })
    .build();

Scheduled Actions

Scheduled actions run periodically without user interaction:

import { ScheduledActionBuilder, Hours } from 'chz-telegram-bot';

const dailyNotification = new ScheduledActionBuilder('GM')
    .runAt(9 as Hours) // Run at 9 AM
    .do((ctx) => {
        ctx.send.text('Good morning!');
    })
    .build();

Replies and message sending

Depending on the type of action, you will have access to the following interaction options:

| Method | Action type | Description | | -------------------- | ----------- | ------------------------------------------------------------ | | send.text | Both | Send text to chat as a standalone message | | send.image | Both | Send image to chat as a standalone message | | send.video | Both | Send video/gif to chat as a standalone message | | unpinMessage | Both | Unpins message by its ID | | wait | Both | Delays next replies from this action by given amount of ms | | reply.withText | Command | Replies with text to a message that triggered an action | | reply.withImage | Command | Replies with image to a message that triggered an action | | reply.withVideo | Command | Replies with video/gif to a message that triggered an action | | reply.withReaction | Command | Sets an emoji reaction to a message that triggered an action |

Keep in mind that reply sending is deferred until action execution finishes and will be done in order of calling in the action handler. Example:

ctx.send.text('Message 1');
ctx.wait(5000 as Millisecond);
ctx.send.text('Message 2');

This will result in Message 1 being sent, followed by Message 2 after a 5 second delay.

Configuration Options

When starting a bot, you can provide the following configuration:

| Option | Type | Required | Description | | ----------------- | ------------------------ | --------------------------- | ----------------------------------------------------------------------------------------- | | name | string | Yes | Bot name used in logging | | tokenFilePath | string | Yes | Path to file containing Telegram Bot token | | commands | CommandAction[] | Yes (can be empty) | Collection of command actions | | scheduled | ScheduledAction[] | Yes (can be empty) | Collection of scheduled actions | | chats | Record<string, number> | Yes | Object containing chat name-id pairs. Used for logging and execution of scheduled action. | | storagePath | string | No | Custom storage path for default JsonFileStorage client | | scheduledPeriod | Seconds | No (will default to 1 hour) | Period between scheduled action executions | | services | | No | Custom services to be used instead of default ones |

Services object should have following structure: | Option | Type | Required | Description | |------------------|--------------------------|----------|---------------------------------------------------------------| | storageClient | IStorageClient | No (will default to JsonFileStorage) | Persistance state provide | | logger | ILogger | No (will default to JsonLogger) | Logger service | | scheduler | IScheduler | No (will default to NodeTimeoutScheduler) | Scheduler used to scheduled action|

Advanced Usage

Custom State Management

The framework allows you to create custom state for your actions:

import { ActionStateBase } from 'chz-telegram-bot';

class MyCustomState extends ActionStateBase {
    counter: number = 0;
}

const counterCommand = new CommandActionBuilderWithState<MyCustomState>(
    'Counter',
    () => new MyCustomState()
)
    .on('/count')
    .do(async (ctx, state) => {
        state.counter++;
        ctx.reply.withText(`Count: ${state.counter}`);
    })
    .build();

State is mutable and all changes to it will be saved after execution of action is finished.

Inline Queries

The framework provides support for handling inline queries with type-safe builders:

import { InlineQueryActionBuilder } from 'chz-telegram-bot';

const searchCommand = new InlineQueryActionBuilder('Search')
    .do((ctx) => {
        const query = ctx.queryText;
        // Process the query and return inline results
        ctx.showInlineQueryResult([
            {
                id: '1',
                type: 'article',
                title: `Search results for: ${query}`,
                description: 'Click to send',
                input_message_content: {
                    message_text: `Search result for: ${query}`
                }
            }
        ]);
    })
    .build();

Response Queue

The framework includes a response processing queue that ensures reliable message delivery and proper ordering of responses:

ctx.send.text('First message');
ctx.send.image('image');
ctx.reply.withReaction('👍');

All responses are queued and processed in order, ensuring proper sequencing of messages and reactions.

Stopping the Bot

To properly terminate your bot and clean up resources:

import { stopBots } from 'chz-telegram-bot';

// Call when your application is shutting down
await stopBots();