Sending and Receiving Messages

As soon as you start your bot with bot.start(), grammY will supply your listeners with the messages that users send to your bot. grammY also provides methods to easily reply to these messages.

Receiving Messages

The easiest way to listen for messages is via

bot.on("message", (ctx) => {
  const message = ctx.message; // the message object
});

However, there are a number of other options, too.

// Handles commands, such as /start.
bot.command("start", (ctx) => {/* ... */});

// Matches the message text against a string or a regular expression.
bot.hears(/echo *(.+)?/, (ctx) => {/* ... */});

You can use auto-complete in your code editor to see all available options, or check out all methodsopen in new window of the Composer class.

Read more about filtering for specific message types with bot.on().

Sending Messages

All methods that bots can use (important listopen in new window) are available on the bot.api object.

// Send a text message to user 12345.
await bot.api.sendMessage(12345, "Hi!");
// Optionally, you can pass an options object.
await bot.api.sendMessage(12345, "Hi!", {/* more options */});
// Inspect the message object of the sent message.
const message = await bot.api.sendMessage(12345, "Hi!");
console.log(message.message_id);

// Get information about the bot itself.
const me = await bot.api.getMe();

// etc

Every method takes an optional options object of type Other, which allows you to set further options for your API calls. These options objects correspond exactly with the options that you can find in list of methods linked above. You can also use auto-complete in your code editor to see all available options, or check out all methodsopen in new window of the Api class. The rest of this page shows some examples for this.

Also, check out the next section to learn how the context object of a listener makes sending messages a breeze!

Sending Messages With Reply

You can use the Telegram reply-to feature by specifying the message identifier to reply to using reply_to_message_id.

bot.hears("ping", async (ctx) => {
  // `reply` is an alias for `sendMessage` in the same chat (see next section).
  await ctx.reply("pong", {
    // `reply_to_message_id` specifies the actual reply feature.
    reply_to_message_id: ctx.msg.message_id,
  });
});

Note that only sending a message via ctx.reply does NOT mean you are automatically replying to anything. Instead, you should specify reply_to_message_id for this. The function ctx.reply is just an alias for ctx.api.sendMessage, see the next section.

Sending Message With Formatting

Check out the section about formatting optionsopen in new window in the Telegram Bot API Reference written by the Telegram team.

You can send messages with bold or italic text, use URLs, and more. There are two ways to do this, as described in the section about formatting optionsopen in new window, namely Markdown and HTML.

Markdown

Also see https://core.telegram.org/bots/api#markdownv2-styleopen in new window

Send your message with markdown in the text, and specify parse_mode: "MarkdownV2".

await bot.api.sendMessage(
  12345,
  "*Hi\\!* _Welcome_ to [grammY](https://grammy.dev)\\.",
  { parse_mode: "MarkdownV2" },
);

HTML

Also see https://core.telegram.org/bots/api#html-styleopen in new window

Send your message with HTML elements in the text, and specify parse_mode: "HTML".

await bot.api.sendMessage(
  12345,
  '<b>Hi!</b> <i>Welcome</i> to <a href="https://grammy.dev">grammY</a>.',
  { parse_mode: "HTML" },
);

Sending Files

File handling is explained in greater depth in a later section.

Force Reply

This can be useful if your bot is running in privacy modeopen in new window in group chats.

When you send a message, you can make the user’s Telegram client automatically specify the message as reply. That means that the user will reply to your bot’s message automatically (unless they remove the reply manually). As a result, your bot will receive the user’s message even when running in privacy modeopen in new window in group chats.

You can force a reply like this:

bot.command("start", async (ctx) => {
  await ctx.reply("Hi! I can only read messages that explicitly reply to me!", {
    // Make Telegram clients automatically show a reply interface to the user.
    reply_markup: { force_reply: true },
  });
});