Skip to content

fix: GIF sent as static image in Telegram adapter#6329

Merged
Soulter merged 5 commits into
AstrBotDevs:masterfrom
Trainingdlu:fix/telegram-gif-send-animation
Mar 15, 2026
Merged

fix: GIF sent as static image in Telegram adapter#6329
Soulter merged 5 commits into
AstrBotDevs:masterfrom
Trainingdlu:fix/telegram-gif-send-animation

Conversation

@Trainingdlu

@Trainingdlu Trainingdlu commented Mar 15, 2026

Copy link
Copy Markdown
Contributor

在 Astrbot 中 使用 Telegram bot 时,bot 发送的表情如果为 GIF ,则会以静态图片形式呈现,而非动图。原因是适配器将所有 Image 组件统一路由到 send_photo,而 send_photo 只发送静态图片,不支持动图。此问题影响所有通过 Image 组件发送 GIF 的插件。

Modifications / 改动点

修改了 astrbot/core/platform/sources/telegram/tg_event.py

  • 新增辅助函数 _is_gif(),通过文件扩展名或魔数(GIF87a/GIF89a)检测 GIF 文件

  • send_with_client() 中:检测到 GIF 时改用 send_animation 发送

  • _process_chain_items 中:检测到 GIF 时改用 send_animation,并将 ChatAction 修正为 UPLOAD_VIDEO

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

修复前截图
img1
img2
修复后截图
img3
img4


Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Summary by Sourcery

Bug Fixes:

  • Fix Telegram messages sending GIFs via Image components being delivered as static photos instead of animated media.

Copilot AI review requested due to automatic review settings March 15, 2026 08:48
@auto-assign auto-assign Bot requested review from Soulter and advent259141 March 15, 2026 08:48
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Mar 15, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求解决了 Astrbot 在 Telegram 适配器中发送 GIF 表情时,GIF 以静态图片而非动图形式呈现的问题。通过引入 GIF 文件检测机制并调整发送逻辑,确保所有通过 Image 组件发送的 GIF 都能正确地作为动画显示,从而提升了用户体验和功能的准确性。

Highlights

  • 新增 GIF 检测辅助函数: 引入了 _is_gif() 辅助函数,通过文件扩展名或魔数(GIF87a/GIF89a)来准确识别 GIF 文件。
  • 优化 send_with_client() 中的 GIF 发送逻辑: 在 send_with_client() 方法中,现在会检测文件是否为 GIF,如果是,则改用 client.send_animation 发送,否则继续使用 client.send_photo
  • 修正 _process_chain_items 中的 GIF 处理: 在 _process_chain_items 方法中,当检测到 GIF 时,会使用 client.send_animation 进行发送,并将 ChatAction 修正为 UPLOAD_VIDEO,以确保正确的用户体验。
Changelog
  • astrbot/core/platform/sources/telegram/tg_event.py
    • 新增了 _is_gif 函数,用于识别 GIF 文件。
    • 修改了 send_with_client 函数,使其能够根据文件类型选择 send_photosend_animation
    • 修改了 _process_chain_items 函数,使其在处理 GIF 时使用 send_animation 并设置正确的 ChatAction
Activity
  • 作者提供了修复前后的截图,清晰展示了 GIF 从静态到动态的改进。
  • 作者确认这不是一个破坏性变更。
  • 作者完成了 PR 检查清单中的所有项,包括测试、无新依赖和无恶意代码。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@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 found 1 issue, and left some high level feedback:

  • The _is_gif helper performs synchronous disk I/O in the hot async send path; consider moving GIF detection closer to where the file is created or cached (e.g., as metadata on the Image object) to avoid reopening the file each time it’s sent.
  • Catching a bare Exception in _is_gif may hide unexpected errors (e.g., permission issues); consider narrowing this to OSError/IOError or at least logging unexpected exceptions before returning False.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `_is_gif` helper performs synchronous disk I/O in the hot async send path; consider moving GIF detection closer to where the file is created or cached (e.g., as metadata on the `Image` object) to avoid reopening the file each time it’s sent.
- Catching a bare `Exception` in `_is_gif` may hide unexpected errors (e.g., permission issues); consider narrowing this to `OSError`/`IOError` or at least logging unexpected exceptions before returning `False`.

## Individual Comments

### Comment 1
<location path="astrbot/core/platform/sources/telegram/tg_event.py" line_range="28-34" />
<code_context>
 from astrbot.core.utils.metrics import Metric


+def _is_gif(path: str) -> bool:
+    if str(path).lower().endswith('.gif'):
+        return True
+    try:
+        with open(path, 'rb') as f:
+            return f.read(6) in (b'GIF87a', b'GIF89a')
+    except Exception:
+        return False
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid catching bare `Exception` in `_is_gif` and consider narrowing or handling specific I/O errors

This masks unrelated failures (e.g., permission/IO errors) and makes real problems look like a non‑GIF. Please narrow the except to expected I/O exceptions (e.g., `OSError`/`IOError`) and/or log unexpected errors before returning `False` so they’re visible during debugging.

Suggested implementation:

```python
import logging

from astrbot.core.utils.metrics import Metric


logger = logging.getLogger(__name__)

```

```python
def _is_gif(path: str) -> bool:
    if str(path).lower().endswith(".gif"):
        return True
    try:
        with open(path, "rb") as f:
            return f.read(6) in (b"GIF87a", b"GIF89a")
    except (OSError, IOError):
        # Expected I/O-related problems (file not found, permission denied, etc.)
        return False
    except Exception:
        # Unexpected failure: log with stack trace so it is visible during debugging
        logger.exception("Unexpected error while checking if %r is a GIF", path)
        return False

```
</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 thread astrbot/core/platform/sources/telegram/tg_event.py Outdated
@dosubot dosubot Bot added the area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. label Mar 15, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

本次改动通过增加 GIF 文件判断,并调用 send_animation 接口,正确地修复了 Telegram 适配器中 GIF 动图被作为静态图片发送的问题。代码逻辑清晰,解决了所述问题。

我提出了一些关于代码实现细节的建议,主要集中在:

  1. 优化 _is_gif 帮助函数的健壮性和简洁性。
  2. 通过重构减少 send_with_client_process_chain_items 方法中处理图片时的代码重复,以提高可维护性。

这些修改将使代码更加健壮和易于维护。

Comment thread astrbot/core/platform/sources/telegram/tg_event.py
Comment thread astrbot/core/platform/sources/telegram/tg_event.py Outdated
Comment thread astrbot/core/platform/sources/telegram/tg_event.py Outdated

Copilot AI 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.

Pull request overview

Fixes AstrBot’s Telegram adapter so that GIFs sent via the Image component are delivered as animations (not static photos) by routing GIFs to Telegram’s send_animation API.

Changes:

  • Added _is_gif() helper to detect GIFs via file extension or GIF magic header.
  • Updated send_with_client() to use send_animation for detected GIFs, otherwise send_photo.
  • Updated _process_chain_items() to use send_animation for detected GIFs and use ChatAction.UPLOAD_VIDEO for the corresponding upload action.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread astrbot/core/platform/sources/telegram/tg_event.py Outdated
@Trainingdlu Trainingdlu changed the title fix: fix GIF sent as static image in Telegram adapter fix: GIF sent as static image in Telegram adapter Mar 15, 2026
Trainingdlu and others added 3 commits March 15, 2026 19:32
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Mar 15, 2026
@Soulter Soulter merged commit 6d055e8 into AstrBotDevs:master Mar 15, 2026
1 check passed
stevessr pushed a commit to stevessr/AstrBot that referenced this pull request Mar 15, 2026
* fix(telegram): route GIF files to send_animation instead of send_photo

* fix: narrow exception in _is_gif to OSError

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* refactor: simplify image send dispatch in send_with_client

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* refactor: simplify image dispatch in _process_chain_items

* ruff format

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Soulter <905617992@qq.com>
KBVsent pushed a commit to KBVsent/AstrBot that referenced this pull request Mar 21, 2026
* fix(telegram): route GIF files to send_animation instead of send_photo

* fix: narrow exception in _is_gif to OSError

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* refactor: simplify image send dispatch in send_with_client

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* refactor: simplify image dispatch in _process_chain_items

* ruff format

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Soulter <905617992@qq.com>
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. lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants