Skip to content

Explore Telegram streaming via sendMessageDraft #46

Description

@macroclaw-bot

Context

Related to #45 (stream-json persistent session). If we stream Claude's output token-by-token via stream-json, we need a way to deliver partial responses to Telegram in real-time. Currently macroclaw sends one complete message per response.

Telegram Bot API 9.5 — sendMessageDraft

Telegram added sendMessageDraft in Bot API 9.3 (Dec 2025), opened to all bots in Bot API 9.5 (March 1, 2026). This is a purpose-built streaming method — it shows partial message content as an animated "draft" bubble while content is being generated.

API signature (from grammY)

```typescript
sendMessageDraft(
chat_id: number,
draft_id: number,
text: string,
other?: { parse_mode?, entities?, link_preview_options?, reply_parameters?, message_thread_id?, reply_markup? },
signal?: AbortSignal,
): Promise
```

How it works (expected flow)

  1. Call `sendMessageDraft(chat_id, draft_id, partial_text)` with incremental text as tokens arrive
  2. Telegram shows an animated draft bubble that updates in place
  3. When generation is complete, call `sendMessage` to finalize — the draft becomes a real message

grammY support

  • grammY `^1.39.3` (our current version) has `sendMessageDraft` in its API types
  • `@grammyjs/stream` plugin exists — provides `ctx.replyWithStream(asyncGenerator)` that handles chunking, auto-retry, and rate limiting
  • Uses `@grammyjs/auto-retry` under the hood for rate limit handling

Comparison of approaches

Approach Pros Cons
sendMessageDraft (new) Purpose-built for streaming, animated draft bubble, no message edit spam New API (March 2026), some reports of `TEXTDRAFT_PEER_INVALID` errors
sendMessage + editMessageText (current pattern) Well-understood, widely used Rate-limited (~1 edit/sec), edit flicker, multiple API calls
Just send final message (current macroclaw) Simplest, no complexity No real-time feedback, feels slow for long responses

Known issues

  • `TEXTDRAFT_PEER_INVALID` error reported by some bots using `sendMessageDraft` in private chats (OpenClaw issue #7803). May be resolved in newer Bot API versions or require specific bot settings.
  • OpenClaw currently still uses the edit-loop approach with 1s throttle despite 9.5 being available — suggests the new API may not be fully stable yet.

Steps

  • Check if grammY `1.39.3` has `sendMessageDraft` or if we need to upgrade
  • Spike: test `sendMessageDraft` manually — send a draft, update it, finalize with sendMessage
  • Evaluate `@grammyjs/stream` plugin — does it use sendMessageDraft or edit-loop?
  • If sendMessageDraft works: integrate with stream-json output from Use stream-json persistent session instead of spawning per message #45
  • If sendMessageDraft is unstable: fall back to sendMessage + editMessageText with throttle
  • Add streaming toggle to macroclaw config (enable/disable, throttle interval)

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions