Bot
This is the single most important class of grammY. It represents your bot.
First, you must create a bot by talking to @BotFather, check out https://
You should do three things to run your bot:
// 1. Create a bot instance
const bot = new Bot('<secret-token>')
// 2. Listen for updates
bot.on('message:text', ctx => ctx.reply('You wrote: ' + ctx.message.text))
// 3. Launch it!
bot.start()
Extends
Type Parameters
C
A
Constructors
Creates a new Bot with the given token.
Remember that you can listen for messages by calling
bot.on('message', ctx => { ... })
or similar methods.
The simplest way to start your bot is via simple long polling:
bot.start()
Properties
api
readonly api: A;
Gives you full access to the Telegram Bot API.
// This is how to call the Bot API methods:
bot.api.sendMessage(chat_id, 'Hello, grammY!')
Use this only outside of your middleware. If you have access to ctx
, then using ctx
instead of bot
is preferred.
errorHandler
errorHandler: ErrorHandler<C>;
Holds the bot’s error handler that is invoked whenever middleware throws (rejects). If you set your own error handler via bot
, all that happens is that this variable is assigned.
token
readonly token: string;
The bot’s token as acquired from https://
Methods
botInfo (setter)
// Overload 1
set botInfo(botInfo: UserFromGetMe): void;
Information about the bot itself as retrieved from api
. Only available after the bot has been initialized via await bot
, or after the value has been set manually.
Starting the bot will always perform the initialization automatically, unless a manual value is already set.
Note that the recommended way to set a custom bot information object is to pass it to the configuration object of the new Bot()
instantiation, rather than assigning this property.
on
on<Q extends FilterQuery>(filter: Q | Q[], ...middleware: Array<Middleware<Filter<C, Q>>>): Composer<Filter<C, Q>>;
Registers some middleware that will only be executed for some specific updates, namely those matching the provided filter query. Filter queries are a concise way to specify which updates you are interested in.
Here are some examples of valid filter queries:
// All kinds of message updates
bot.on('message', ctx => { ... })
// Only text messages
bot.on('message:text', ctx => { ... })
// Only text messages with URL
bot.on('message:entities:url', ctx => { ... })
// Text messages and text channel posts
bot.on(':text', ctx => { ... })
// Messages with URL in text or caption (i.e. entities or caption entities)
bot.on('message::url', ctx => { ... })
// Messages or channel posts with URL in text or caption
bot.on('::url', ctx => { ... })
You can use autocomplete in VS Code to see all available filter queries. Check out the documentation on the website to learn more about filter queries in grammY.
It is possible to pass multiple filter queries in an array, i.e.
// Matches all text messages and edited text messages that contain a URL
bot.on(['message:entities:url', 'edited_message:entities:url'], ctx => { ... })
Your middleware will be executed if any of the provided filter queries matches (logical OR).
If you instead want to match all of the provided filter queries (logical AND), you can chain the .on
calls:
// Matches all messages and channel posts that both a) contain a URL and b) are forwards
bot.on('::url').on(':forward_origin', ctx => { ... })
reaction
reaction(reaction: MaybeArray<ReactionTypeEmoji["emoji"] | ReactionType>, ...middleware: Array<ReactionMiddleware<C>>): Composer<ReactionContext<C>>;
Registers some middleware that will only be added when a new reaction of the given type is added to a message.
// Reacts to new '👍' reactions
bot.reaction('👍', ctx => { ... })
// Reacts to new '👍' or '👎' reactions
bot.reaction(['👍', '👎'], ctx => { ... })
Note that you have to enable
message
updates in_reaction allowed
if you want your bot to receive updates about message reactions._updates
bot
will trigger if:
- a new emoji reaction is added to a message
- a new custom emoji reaction is added a message
bot
will not trigger if:
- a reaction is removed
- an anonymous reaction count is updated, such as on channel posts
message
updates are not enabled for your bot_reaction
isInited
isInited();
Checks if the bot has been initialized. A bot is initialized if the bot information is set. The bot information can either be set automatically by calling bot
, or manually through the bot constructor. Note that usually, initialization is done automatically and you do not have to care about this method.
init
init(signal?: AbortSignal): Promise<void>;
Initializes the bot, i.e. fetches information about the bot itself. This method is called automatically, you usually don’t have to call it manually.
handleUpdate
handleUpdate(update: Update, webhookReplyEnvelope?: WebhookReplyEnvelope): Promise<void>;
This is an internal method that you probably will not ever need to call. It is used whenever a new update arrives from the Telegram servers that your bot will handle.
If you’re writing a library on top of grammY, check out the documentation of the runner plugin for an example that uses this method.
start
start(options?: PollingOptions): Promise<void>;
Starts your bot using long polling.
This method returns a
Promise
that will never resolve except if your bot is stopped. You don’t need toawait
the call tobot
, but remember to catch potential errors by calling.start bot
. Otherwise your bot will crash (and stop) if something goes wrong in your code..catch
This method effectively enters a loop that will repeatedly call get
and run your middleware for every received update, allowing your bot to respond to messages.
If your bot is already running, this method does nothing.
Note that this starts your bot using a very simple long polling implementation. bot
should only be used for small bots. While the rest of grammY was built to perform well even under extreme loads, simple long polling is not capable of scaling up in a similar fashion. You should switch over to using @grammyjs
if you are running a bot with high load.
What exactly high load means differs from bot to bot, but as a rule of thumb, simple long polling should not be processing more than ~5K messages every hour. Also, if your bot has long-running operations such as large file transfers that block the middleware from completing, this will impact the responsiveness negatively, so it makes sense to use the @grammyjs
package even if you receive much fewer messages. If you worry about how much load your bot can handle, check out the grammY documentation about scaling up.
stop
stop(): Promise<void>;
Stops the bot from long polling.
All middleware that is currently being executed may complete, but no further get
calls will be performed. The current get
request will be cancelled.
In addition, this method will confirm the last received update to the Telegram servers by calling get
one last time with the latest offset value. If any updates are received in this call, they are discarded and will be fetched again when the bot starts up the next time. Confer the official documentation on confirming updates if you want to know more: https://
Note that this method will not wait for the middleware stack to finish. If you need to run code after all middleware is done, consider waiting for the promise returned by
bot
to resolve..start()
isRunning
isRunning();
Returns true if the bot is currently running via built-in long polling, and false otherwise.
If this method returns true, it means that bot
has been called, and that the bot has neither crashed nor was it stopped via a call to bot
. This also means that you cannot use this method to check if a webhook server is running, or if grammY runner was started.
Note that this method will already begin to return true even before the call to bot
has completed its initialization phase (and hence before bot
returns true). By extension, this method returns true before on
callback of bot
is invoked.
catch
catch(errorHandler: ErrorHandler<C>): void;
Sets the bots error handler that is used during long polling.
You should call this method to set an error handler if you are using long polling, no matter whether you use bot
or the @grammyjs
package to run your bot.
Calling bot
when using other means of running your bot (or webhooks) has no effect.