sendChatAction
Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status). Returns True on success.
Example: The ImageBot needs some time to process a request and upload the image. Instead of sending a text message along the lines of “Retrieving image, please wait…”, the bot may use sendChatAction with action = upload_photo. The user will see a “sending photo” status for the bot.
We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive.
Parameters
business_connection_idStringOptionalchat_idIntegerStringRequired@supergroupusername). Channel chats and channel direct messages chats aren't supported.message_thread_idIntegerOptionalactionStringRequiredtypingupload_photorecord_videoupload_videorecord_voiceupload_voiceupload_documentchoose_stickerfind_locationrecord_video_noteupload_video_noteReturns
On success, True is returned.
GramIO Usage
Show a "typing..." indicator before sending a slow response:
bot.on("message", async (ctx) => {
await ctx.sendChatAction("typing");
// Simulate a slow operation
await new Promise((resolve) => setTimeout(resolve, 2000));
await ctx.send("Here is your answer after processing!");
});Show upload_document while preparing a file to send:
bot.on("message", async (ctx) => {
await ctx.sendChatAction("upload_document");
const file = await MediaUpload.path("./reports/report.pdf");
await ctx.sendDocument(file, { caption: "Your report is ready." });
});Repeat the action every 4 seconds for a long-running task using a loop:
bot.on("message", async (ctx) => {
// sendChatAction expires after ~5 s; refresh it periodically
const interval = setInterval(
() => ctx.sendChatAction("typing").catch(() => {}),
4000
);
try {
// Long operation (e.g., external API call)
await new Promise((resolve) => setTimeout(resolve, 10000));
await ctx.send("Done!");
} finally {
clearInterval(interval);
}
});Direct API call with bot.api.sendChatAction (useful outside message handlers):
await bot.api.sendChatAction({
chat_id: 123456789,
action: "upload_photo",
});Errors
| Code | Error | Cause |
|---|---|---|
| 400 | Bad Request: chat not found | The chat_id is invalid, the bot has never interacted with the user, or the chat does not exist. |
| 400 | Bad Request: not enough rights | The bot lacks permission to send messages in the target group or channel. |
| 403 | Forbidden: bot was blocked by the user | The user blocked the bot. Remove them from your active user list. |
| 403 | Forbidden: bot is not a member of the channel chat | The bot is not a member of the target channel. |
| 429 | Too Many Requests: retry after N | Flood control triggered. Back off for the specified number of seconds. |
TIP
Use GramIO's auto-retry plugin to handle 429 errors automatically.
Tips & Gotchas
- The indicator lasts at most 5 seconds. Once your bot sends any message, Telegram immediately clears the indicator. For operations longer than 5 seconds, call
sendChatActionin a loop every ~4 seconds. - Choose the matching action. Pick the action that corresponds to what you are about to send —
upload_documentfor files,upload_photofor images,record_videofor video processing, etc. Usingtypingfor everything is misleading to users. - Channels are not supported. The
chat_idmust be a private chat, group, or supergroup. Channel chat IDs will return an error. - Errors in the loop should be swallowed. If you run
sendChatActionin an interval, wrap each call in.catch(() => {})so a transient error does not kill the loop. - Use
message_thread_idfor forum topics. In supergroups with topics enabled, passmessage_thread_idto show the indicator inside the correct topic thread.
See Also
- sendMessage — send text after showing
typing - sendPhoto — send photo after showing
upload_photo - sendVideo — send video after showing
upload_video - sendDocument — send file after showing
upload_document - sendVoice — send voice after showing
record_voice - auto-retry plugin — handle rate limits automatically