Skip to content

fix: qq_official send_by_session uses markdown#7883

Open
bugkeep wants to merge 1 commit intoAstrBotDevs:masterfrom
bugkeep:bugfix/7848-qqofficial-sendby-session-markdown
Open

fix: qq_official send_by_session uses markdown#7883
bugkeep wants to merge 1 commit intoAstrBotDevs:masterfrom
bugkeep:bugfix/7848-qqofficial-sendby-session-markdown

Conversation

@bugkeep
Copy link
Copy Markdown
Contributor

@bugkeep bugkeep commented Apr 29, 2026

Fixes #7848.

  • Align QQ Official proactive send_by_session payload with normal message send path (use markdown + msg_type=2).
  • When media is attached (msg_type=7), drop markdown and send content instead.
  • Adds unit tests for payload shape in both markdown and media cases.

Tests:

  • uv run pytest -q tests/unit/test_qqofficial_send_by_session_markdown.py
  • uv run ruff format .
  • uv run ruff check .

Summary by Sourcery

Align QQ Official proactive send_by_session payloads with the standard message send format and ensure correct payload shape for markdown and media messages.

Bug Fixes:

  • Ensure QQ Official send_by_session uses markdown payloads with msg_type 2 for plain text messages to match the normal send path.
  • Ensure media messages sent via QQ Official send_by_session use msg_type 7 with content and media fields and omit markdown.

Tests:

  • Add unit tests verifying QQ Official send_by_session payload structure for markdown-only and media-attached messages.

Align proactive send_by_session payload with normal QQ Official send path so markdown renders consistently (issue AstrBotDevs#7848).
@auto-assign auto-assign Bot requested review from Soulter and anka-afk April 29, 2026 03:01
@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 Apr 29, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • There’s a lot of repeated logic for switching the payload into “media mode” (set media, msg_type = 7, drop markdown, and set content); consider extracting this into a small helper to reduce duplication and keep future changes to that logic in one place.
  • msg_type is initialized to 2 even when plain_text is None; if the API doesn’t accept a markdown-type message without markdown content, it might be safer to only set msg_type when plain_text is present or default it to None until the final shape is known.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- There’s a lot of repeated logic for switching the payload into “media mode” (set `media`, `msg_type = 7`, drop `markdown`, and set `content`); consider extracting this into a small helper to reduce duplication and keep future changes to that logic in one place.
- `msg_type` is initialized to `2` even when `plain_text` is `None`; if the API doesn’t accept a markdown-type message without markdown content, it might be safer to only set `msg_type` when `plain_text` is present or default it to `None` until the final shape is known.

## Individual Comments

### Comment 1
<location path="astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py" line_range="253-256" />
<code_context>
                     )
                     payload["media"] = media
                     payload["msg_type"] = 7
+                    payload.pop("markdown", None)
+                    payload["content"] = plain_text or None
                 if record_file_path:
                     media = await QQOfficialMessageEvent.upload_group_and_c2c_media(
</code_context>
<issue_to_address>
**suggestion:** Repeated markdown-to-plain-text demotion logic could be extracted to a small helper for clarity and consistency.

This sequence appears in both group and c2c branches. Extracting it into a helper (e.g. `_attach_media_and_downgrade_markdown(payload, media, plain_text)`) would remove duplication, keep `msg_type=7` handling consistent, and ensure future changes to markdown/content behavior are made in one place.

Suggested implementation:

```python
        payload: dict[str, Any] = {
            "markdown": MarkdownPayload(content=plain_text) if plain_text else None,
            "msg_type": 2,
            "msg_id": msg_id,
        }

        def _attach_media_and_downgrade_markdown(
            payload: dict[str, Any],
            media: Any,
            plain_text: str | None,
        ) -> None:
            if not media:
                return
            payload["media"] = media
            payload["msg_type"] = 7
            payload.pop("markdown", None)
            payload["content"] = plain_text or None

        ret: Any = None
        send_helper = SimpleNamespace(bot=self.client)

```

```python
                    )
                    _attach_media_and_downgrade_markdown(payload, media, plain_text)
                if record_file_path:
                    media = await QQOfficialMessageEvent.upload_group_and_c2c_media(
                        send_helper,  # type: ignore
                    if media:
                        _attach_media_and_downgrade_markdown(payload, media, plain_text)
                if video_file_source:
                    media = await QQOfficialMessageEvent.upload_group_and_c2c_media(
                        send_helper,  # type: ignore
                    if media:

```
</issue_to_address>

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.

Comment on lines 253 to +256
payload["media"] = media
payload["msg_type"] = 7
payload.pop("markdown", None)
payload["content"] = plain_text or None
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.

suggestion: Repeated markdown-to-plain-text demotion logic could be extracted to a small helper for clarity and consistency.

This sequence appears in both group and c2c branches. Extracting it into a helper (e.g. _attach_media_and_downgrade_markdown(payload, media, plain_text)) would remove duplication, keep msg_type=7 handling consistent, and ensure future changes to markdown/content behavior are made in one place.

Suggested implementation:

        payload: dict[str, Any] = {
            "markdown": MarkdownPayload(content=plain_text) if plain_text else None,
            "msg_type": 2,
            "msg_id": msg_id,
        }

        def _attach_media_and_downgrade_markdown(
            payload: dict[str, Any],
            media: Any,
            plain_text: str | None,
        ) -> None:
            if not media:
                return
            payload["media"] = media
            payload["msg_type"] = 7
            payload.pop("markdown", None)
            payload["content"] = plain_text or None

        ret: Any = None
        send_helper = SimpleNamespace(bot=self.client)
                    )
                    _attach_media_and_downgrade_markdown(payload, media, plain_text)
                if record_file_path:
                    media = await QQOfficialMessageEvent.upload_group_and_c2c_media(
                        send_helper,  # type: ignore
                    if media:
                        _attach_media_and_downgrade_markdown(payload, media, plain_text)
                if video_file_source:
                    media = await QQOfficialMessageEvent.upload_group_and_c2c_media(
                        send_helper,  # type: ignore
                    if media:

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements Markdown support for the QQ Official platform adapter, defaulting to MarkdownPayload for messages. It includes logic to revert to plain text when media is attached and adds unit tests for these scenarios. Feedback suggests honoring the use_markdown_ attribute to allow users to opt-out of Markdown and refactoring duplicated payload modification logic into a shared helper function to improve maintainability.

Comment on lines +234 to +238
payload: dict[str, Any] = {
"markdown": MarkdownPayload(content=plain_text) if plain_text else None,
"msg_type": 2,
"msg_id": msg_id,
}
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.

medium

The send_by_session method ignores the use_markdown_ attribute. To maintain consistency and allow users to disable markdown, the adapter should check message_chain.use_markdown_ before constructing the payload. Additionally, please ensure that this new logic is covered by unit tests.

use_md = getattr(message_chain, "use_markdown_", True)
if use_md is False:
    payload: dict[str, Any] = {
        "content": plain_text,
        "msg_type": 0,
        "msg_id": msg_id,
    }
else:
    payload: dict[str, Any] = {
        "markdown": MarkdownPayload(content=plain_text) if plain_text else None,
        "msg_type": 2,
        "msg_id": msg_id,
    }
References
  1. New functionality, such as handling attachments or message formatting, should be accompanied by corresponding unit tests.

Comment on lines 254 to +256
payload["msg_type"] = 7
payload.pop("markdown", None)
payload["content"] = plain_text or None
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.

medium

The logic for updating the payload when media is present is repeated multiple times. Please refactor this into a shared helper function to avoid code duplication.

References
  1. When implementing similar functionality for different cases, refactor the logic into a shared helper function to avoid code duplication.

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.

[Bug] QQ Official: cron/scheduled messages sent via send_by_session lack markdown rendering (msg_type=2)

1 participant