Skip to content

fix(qqofficial): send proactively before passive reply window expires - #9615

Open
TheRainstorm wants to merge 2 commits into
AstrBotDevs:masterfrom
TheRainstorm:feat/qqofficial-proactive-message
Open

fix(qqofficial): send proactively before passive reply window expires#9615
TheRainstorm wants to merge 2 commits into
AstrBotDevs:masterfrom
TheRainstorm:feat/qqofficial-proactive-message

Conversation

@TheRainstorm

@TheRainstorm TheRainstorm commented Aug 10, 2026

Copy link
Copy Markdown

Problem

QQ official passive replies (msg_id-based) are only valid for 5 minutes. Long-running tasks (e.g. an agent running tools for several minutes) exceed this window, and the final reply fails with:

botpy.errors.ServerError: 回复消息msg_id已过期

The existing fallback then retries once without msg_id, wasting a request and often failing again for group messages.

Fix

When a group reply's age approaches the 5-minute passive window (60s margin), build the payload without msg_id from the start, i.e. send via the proactive (active-message) API directly:

  • _QQOFFICIAL_PASSIVE_REPLY_SECONDS = 300, _QQOFFICIAL_PROACTIVE_MARGIN_SECONDS = 60
  • force_proactive computed in _post_send_one for GroupMessage

C2C/other sources keep the existing msg_id behavior; the msg_id-less proactive retry in _send_with_markdown_fallback remains as a safety net.

Notes

  • Active group messages use the platform's proactive message quota; this only kicks in for long tasks near the 5-minute boundary, so normal replies are unaffected.

Summary by Sourcery

Bug Fixes:

  • Prevent failures of long-running QQ official group replies by avoiding expired msg_id-based passive replies near the 5-minute limit.

QQ official passive replies are only valid for 5 minutes. Long-running
tasks (e.g. agent tool loops) that exceed the window fail with
"回复消息msg_id已过期". When the reply age approaches the limit, skip
msg_id and send proactively (active-message API), avoiding a wasted
request and the expired-msg_id error.
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. labels Aug 10, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider using a monotonic clock (e.g., time.monotonic()) or a precomputed created_at_monotonic field rather than time.time() for the passive window check to avoid issues if system time changes while a long-running task is executing.
  • The proactive margin constants (_QQOFFICIAL_PASSIVE_REPLY_SECONDS and _QQOFFICIAL_PROACTIVE_MARGIN_SECONDS) are hard-coded; if different bots or environments require different timing, it may be useful to make these values configurable via existing settings or environment variables.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider using a monotonic clock (e.g., `time.monotonic()`) or a precomputed `created_at_monotonic` field rather than `time.time()` for the passive window check to avoid issues if system time changes while a long-running task is executing.
- The proactive margin constants (`_QQOFFICIAL_PASSIVE_REPLY_SECONDS` and `_QQOFFICIAL_PROACTIVE_MARGIN_SECONDS`) are hard-coded; if different bots or environments require different timing, it may be useful to make these values configurable via existing settings or environment variables.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@TheRainstorm

Copy link
Copy Markdown
Author

Addressed the review feedback:

  • Monotonic clock: added created_at_monotonic = time.monotonic() at event construction and switched the passive-window check to time.monotonic(), so wall-clock changes during long-running tasks no longer affect the decision.
  • Configurable constants: kept _QQOFFICIAL_PASSIVE_REPLY_SECONDS/_QQOFFICIAL_PROACTIVE_MARGIN_SECONDS as module constants to match the file's existing style and avoid new config plumbing for a niche value; happy to make them configurable if maintainers prefer.

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

Labels

area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant