send_message_draft()¶
- async Client.send_message_draft()¶
Send a text draft action, allowing bots to stream a partial message.
When generating a message progressively (e.g. during AI response streaming), this method shows the user a typing indicator with the partial text. Pass an empty text to show a “Thinking…” placeholder while waiting for content to be generated.
See
send_rich_message_draft()to stream a rich message instead of plain text.Usable by Users Bots- Parameters:
chat_id (
int|str) – Unique identifier (int) or username (str) of the target private chat. Drafts are streamed as a typing action and a group or channel refuses one withTEXTDRAFT_PEER_INVALID.draft_id (
int) – Unique identifier of the draft; must be non-zero. Keep it constant for the whole generation, updates sharing an identifier are animated by clients. A different identifier does not restart the draft, it adds a second concurrent draft, and some clients collapse them into one.text (
str, optional) – The partial text to stream, 0-4096 characters after entities parsing. Defaults to an empty string, which shows a “Thinking…” placeholder.parse_mode (
ParseMode, optional) – By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together.entities (List of
MessageEntity, optional) – List of special entities that appear in the text, which can be specified instead of parse_mode.message_thread_id (
int, optional) – Unique identifier for a forum topic thread.can_stop (
bool, optional) – Pass True to show the user a button to stop further drafts. The bot then receives aMessageGenerationStoppedupdate when the user presses it.keep_on_stop (
bool, optional) – Pass True to keep the draft in the chat when the button is pressed. The draft still disappears after a short time or as soon as the bot sends a message, so callsend_message()to preserve it.
- Returns:
bool– On success, True is returned.
Note
The draft is ephemeral: clients drop it after
message_typing_draft_ttlseconds (30 by default, server-configured) or as soon as a real message arrives, so callsend_message()to persist the result. Throttle the stream: setTyping is rate-limited to 20 calls per 5s and 40 per 30s per peer.Example
draft_id = app.rnd_id() for i, word in enumerate(words): await app.send_message_draft(chat_id, draft_id, " ".join(words[:i + 1])) await asyncio.sleep(0.33) await app.send_message(chat_id, text)