Working with Messages
Message Updates
There are three updates that are directly related to messages:
- UpdateNewMessage — Received when a message is received or sent.
- UpdateEditedMessage — Received when a message is edited.
- UpdateDeletedMessages — Received when one or more messages are deleted.
Here are some examples on adding listeners for each of them:
client.on("message", (ctx) => {
// called when a message is received or sent
});
client.on("editedMessage", (ctx) => {
// called when a message is edited
});
client.on("deletedMessages", (ctx) => {
// called when one or more messages are deleted
});
To see how the context object would look like for each update, you can refer to their specific documentation pages linked above.
Filtering Message Types
There is a significant number of different types of messages, which makes processing all of them in a single handler a little harder.
Fortunately, you can easily filter out messages by their types when assigning your handler. Here are some examples:
client.on("message:text", (ctx) => {
// This handler is called only when text messages are received.
// So ctx.msg.text is always set.
});
client.on("editedMessage:photo", (ctx) => {
// This handler is called only when photo messages are edited.
// So ctx.msg.photo is always set.
});
Accessing the Message in Handlers
You can access the received message in through ctx.msg
or ctx.message
.
client.on("message", (ctx) => {
// Both ctx.msg and ctx.message are referring to the received message.
});
Edited messages are accessed through ctx.msg
and ctx.editedMessage
.
client.on("editedMessage", (ctx) => {
// Both ctx.msg and ctx.editedMessage are referring to the edited message.
});
ctx.msg
is just a shortcut that resolves to
ctx.message ?? ctx.editedMessage
. See Message.
Updates for deleted messages don’t include full message objects, only references to them (see MessageReference).
client.on("deletedMessages", (ctx) => {
// ctx.deletedMessages is an array of MessageReference.
});
Notes
- UpdateDeletedMessages is not always sent to bots, so it is recommended that you don’t depend on it for bots.
- Updates for outgoing messages are not sent for bots by default, but you can
disable the
ignoreOutgoing
option to receive them:
const client = new Client({
ignoreOutgoing: false,
/* ... */
});
Sending Messages
There are multiple methods that can be used to send messages. Each of them is used for sending a specific type of message.
- sendMessage — For sending text messages.
- sendPhoto — For sending photos.
- sendDocument — For sending files.
- sendVideo — For sending videos.
- sendAnimation — For sending animations.
- sendAudio — For sending audio files.
- sendVoice — For sending voice messages.
- sendVideoNote — For sending video notes.
- sendDice — For sending dices.
- sendLocation — For sending locations.
- sendVenue — For sending venues.
- sendPoll — For sending polls.
- sendContact — For sending contacts.
Here are some example calls:
const chat = /* ... */; // ID
const file = /* ... */; // FileSource
await client.sendMessage(
chat,
"Hey!",
{ disableNotification: true, /* other optional options */ }
);
await client.sendPhoto(chat, file, { caption: "Optional Caption", /* other optional options */ });
await client.sendDocument(chat, file, { caption: "Optional Caption", /* ooo */ });
await client.sendVideo(chat, file, { caption: "Optional Caption", /* ooo */ });
await client.sendAnimation(chat, file, { caption: "Optional Caption", /* ooo */ });
await client.sendAnimation(chat, file, { caption: "Optional Caption", /* ooo */ });
await client.sendAudio(chat, file, { caption: "Optional Caption", /* ooo */ });
await client.sendVoice(chat, file, { caption: "Optional Caption", /* ooo */ });
await client.sendDice(chat); // defaults to 🎲
await client.sendDice(chat, { emoji: "🏀" }); // but you can send any valid dice
To use the above example calls, chat
must be replaced with a valid ID, and file
must be replaced a valid FileSource.
As previously said, the last parameters are optional and can always be omitted,
so for example you can do just await client.sendMessage(chat, "Hey!");
if you
don’t specify any optional parameter. Optional parameters are those parameters
marked with ?
in the method documentations.
Inside handlers, you can call the respective reply*
shortcuts to easily reply
the context message:
client.on("message", async (ctx) => {
await ctx.reply(text); // same as client.sendMessage(ctx.chat.id, text, { replyToMessageId: ctx.msg.id });
await ctx.replyPhoto(file); // same as client.sendPhoto(ctx.chat.id, file, { replyToMessageId: ctx.msg.id });
});
Deleting Messages
You can delete messages by calling either deleteMessage or deleteMessages.
await ctx.deleteMessage(chat, messageId);
await ctx.deleteMessages(chat, [...messageIds]);
You can delete the context message with delete
:
client.on("message", async (ctx) => {
await ctx.delete(); // This deletes the received message.
});
Forwarding Messages
You can forward messages by calling either forwardMessage or forwardMessages.
await ctx.forwardMessage(fromChat, toChat);
await ctx.forwardMessages(fromChat, toChat);
You can forward the context message with forward
:
client.on("message", async (ctx) => {
await ctx.forward(toChat); // This forwards the received message.
});