Skip to content

NestKit grammy Basics

Introduction

NestKit provides an elegant wrapper around grammy, integrating it seamlessly with NestJS dependency injection and module structure. This guide explains how to work with the wrapper to create Telegram bots efficiently.

Bot Module Structure

A typical bot module in NestKit looks like this:

typescript
@Module({
  imports: [
    // Other modules your bot depends on
    UsersModule,
  ],
  providers: [
    // Middlewares
    AuthMiddleware,

    // Conversations
    OnboardingConversation,
    {
      provide: GRAMMY_CONVERSATION_PLUGINS,
      useValue: [
        AuthMiddleware,
      ],
    },

    // Commands
    StartCommand,

    // Listeners
    PingListener,

    // Callback Queries
    PingCallbackQuery,

    // Menus
    MainMenu,
  ],
})
export class BotModule {}

Sending and Receiving Messages

Commands

Commands in NestKit grammy are implemented as injectable classes that extend the BaseCommand class:

typescript
@Injectable()
export class YourCommand extends BaseCommand {
  constructor(private readonly someService: SomeService) {
    super();
  }

  async run(ctx: CommandContext<GrammyContext>): Promise<void> {
    // Handle the command here
    await ctx.reply('Your command response');
  }
}

The command name is automatically derived from the class name by converting it to snake_case and removing "Command". For example, StartCommand becomes /start.

Listeners

Listeners respond to specific messages or patterns and are implemented by extending the BaseListener class:

typescript
@Injectable()
export class YourListener extends BaseListener {
  // Define trigger as a string, RegExp, or array of either
  trigger = 'Some phrase';

  async run(ctx: HearsContext<GrammyContext>): Promise<void> {
    // Handle the matching message here
    await ctx.reply('Your listener response');
  }
}

Bot Injection

The grammy Bot instance is available for injection throughout your application using the @InjectBot() decorator:

typescript
@Injectable()
export class YourService {
  @InjectBot() private readonly bot!: Bot<GrammyContext>;

  async sendMessage(userId: number, text: string): Promise<void> {
    await this.bot.api.sendMessage(userId, text);
  }
}

Sending Messages

Basic Message Sending

You can send messages in several ways:

  1. Using the context in command or listener handlers:

    typescript
    async run(ctx: CommandContext<GrammyContext>): Promise<void> {
      await ctx.reply('Hello world!');
    }
  2. Using the injected bot instance:

    typescript
    @InjectBot() private readonly bot!: Bot<GrammyContext>;
    
    async sendMessage(userId: number): Promise<void> {
      await this.bot.api.sendMessage(userId, 'Hello world!');
    }

Sending Messages with Reply

You can make your message a reply to another message:

typescript
await ctx.reply('This is a reply', {
  reply_parameters: {
    message_id: ctx.msg.message_id
  }
});

Sending Messages with Inline Keyboard

Create interactive inline keyboards for your messages:

typescript
const menu = new InlineKeyboard()
  .text('Button Label', 'callback_data');

await ctx.reply('Message with buttons', {
  reply_markup: menu,
});

Created by DeepVision Software.