Skip to content

feat(telegram): add dedicated proxy configuration - #9558

Open
Trainingdlu wants to merge 2 commits into
AstrBotDevs:masterfrom
Trainingdlu:feat/telegram-proxy
Open

feat(telegram): add dedicated proxy configuration#9558
Trainingdlu wants to merge 2 commits into
AstrBotDevs:masterfrom
Trainingdlu:feat/telegram-proxy

Conversation

@Trainingdlu

@Trainingdlu Trainingdlu commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Telegram 适配器没有独立的代理配置,唯一的代理开关是全局 http_proxy。该设置通过写入进程级 http_proxy/https_proxy 环境变量生效,所有 trust_env=True 的 HTTP 客户端都会共享,而 no_proxy 只能按主机排除,无法把单个适配器单独路由到代理。因此只想给 Telegram 配置代理的用户,只能打开全局代理让其余出站流量默认一并走它,再靠 no_proxy 逐个主机往外摘。这已经波及过无关模块(#7584)。Discord 适配器已有 discord_proxy,故为 Telegram 补上对应能力。

Closes #9343
Closes #7444
Closes #8180

Modifications / 改动点

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

  • _build_application() 读取配置项 telegram_proxy,非空时通过 .proxy().get_updates_proxy() 传给 ApplicationBuilder
  • getUpdates 长轮询在 python-telegram-bot 中使用独立的请求对象,.proxy() 不会作用到它,因此两个方法都要设置

修改了 astrbot/core/config/default.py

  • Telegram 的 config_template 中新增默认值 "telegram_proxy": "",使既有适配器实例也能补齐该字段
  • items 中新增字段 schema,供 WebUI 渲染标题与说明
  • telegram_token 的说明原本承载代理指引,且指向的位置已不正确,全局代理现位于 设置 -> 网络;现在只描述 token 本身,与 discord_token 保持一致

修改了 dashboard/src/i18n/locales/{zh-CN,en-US,ru-RU}/features/config-metadata.json

  • 三种语言各新增 telegram_proxy 的 description 与 hint,并同步上述 telegram_token 说明的改动

修改了 tests/test_telegram_adapter.py

  • 新增 test_telegram_proxy_is_applied_to_bot_api_and_polling_requests,断言 .proxy().get_updates_proxy() 都收到了配置的代理地址

  • 新增 test_telegram_proxy_is_skipped_when_not_configured,参数化覆盖 None"",断言两个方法都不会被调用

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

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

配置可用代理 http://127.0.0.1:7897:消息收发正常:

代理正确
[23:58:26] [INFO] [telegram.tg_adapter:254]: Starting Telegram polling...
[23:58:26] [INFO] [telegram.tg_adapter:256]: Telegram Platform Adapter is running.
[23:59:56] [INFO] [core.event_bus:74]: [telegram(telegram)] <user>: test
[23:59:59] [INFO] [respond.stage:206]: Prepare to send - <user>: Hello! Test received ...

配置错误代理 http://127.0.0.1:9:适配器无法再连上 Telegram,说明流量确实走了配置的代理,而不是回落到直连

代理错误
[00:00:45] [ERRO] [telegram.tg_adapter:281]: Telegram polling crashed with exception:
NetworkError: httpx.ConnectError: All connection attempts failed. Retrying in 5.0s.
  ...
  File ".../httpcore/_async/http_proxy.py", line 288, in handle_async_request
    connect_response = await self._connection.handle_async_request(
  ...
httpcore.ConnectError: All connection attempts failed

The above exception was the direct cause of the following exception:
  ...
  File ".../astrbot/core/platform/sources/telegram/tg_adapter.py", line 154, in _start_application
    await self.application.initialize()
  ...
  File ".../telegram/_bot.py", line 865, in initialize
    await self.get_me()
  ...
telegram.error.NetworkError: httpx.ConnectError: All connection attempts failed

有关.get_updates_proxy()

python-telegram-bot 为 getUpdates 与其余 Bot API 端点维护两个互不相干的请求对象:

# telegram/_bot.py:738
request = self._request[0] if endpoint == "getUpdates" else self._request[1]

.proxy() 只配置后者,.get_updates_proxy() 配置前者。

上面那条启动失败发生在 Application.initialize()Bot.get_me(),走的是 _request[1],因此它只能证明 .proxy() 生效。下面这条 traceback 捕获于轮询已经运行之后,走的是 _request[0]

  File ".../telegram/ext/_updater.py", line 340, in polling_action_cb
    updates = await self.bot.get_updates(
  ...
  File ".../httpcore/_async/http_proxy.py", line 343, in handle_async_request
    return await self._connection.handle_async_request(request)
  ...
httpx.RemoteProtocolError: Server disconnected without sending a response.

get_updateshttpcore._async.http_proxy 出现在同一个调用栈里,说明长轮询请求本身穿过了代理隧道。本次运行的全局 http_proxy 为空,而 core_lifecycle.py 在该设置为空时会主动从环境变量中删除 http_proxy/https_proxy,httpx 的 trust_env 因此取不到任何代理,也就是这个请求上的代理只可能来自 .get_updates_proxy()。该报错是长轮询等待响应期间连接被对端关闭,属于常见的瞬时网络错误,与本改动无关。

修改后设置页截图

修复后设置页截图

当留空或完全不填该字段时,两个 builder 调用都会跳过,既有部署行为不变,仍然沿用全局代理设置。


Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”

  • 🤓 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.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Add dedicated proxy configuration support for the Telegram platform adapter and ensure it is applied to all Telegram HTTP and polling requests.

New Features:

  • Introduce a telegram_proxy configuration option scoped to the Telegram adapter, with dashboard metadata and defaults.
  • Apply the configured telegram_proxy to both standard Bot API traffic and long-polling getUpdates requests for Telegram.

Tests:

  • Add a Telegram adapter test verifying that telegram_proxy is propagated to both proxy and get_updates_proxy on the ApplicationBuilder.

Copilot AI lite review requested due to automatic review settings August 5, 2026 15:26
@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 5, 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 found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/test_telegram_adapter.py" line_range="470-479" />
<code_context>
     app_three.start.assert_awaited()
+
+
+@pytest.mark.asyncio
+async def test_telegram_proxy_is_applied_to_bot_api_and_polling_requests():
+    TelegramPlatformAdapter = _load_telegram_adapter()
+    module_globals = TelegramPlatformAdapter.__init__.__globals__
+    proxy_url = "http://127.0.0.1:7890"
+
+    builder = MagicMock()
+    builder.token.return_value = builder
+    builder.base_url.return_value = builder
+    builder.base_file_url.return_value = builder
+    builder.proxy.return_value = builder
+    builder.get_updates_proxy.return_value = builder
+
+    with patch.dict(
+        module_globals,
+        {"ApplicationBuilder": MagicMock(return_value=builder)},
+    ):
+        TelegramPlatformAdapter(
+            make_platform_config("telegram", telegram_proxy=proxy_url),
+            {},
+            asyncio.Queue(),
+        )
+
+    builder.proxy.assert_called_once_with(proxy_url)
+    builder.get_updates_proxy.assert_called_once_with(proxy_url)
</code_context>
<issue_to_address>
**suggestion (testing):** Add a complementary test to ensure no proxy methods are called when `telegram_proxy` is unset or empty.

Currently only the configured-proxy path is tested. Please add a test where `telegram_proxy` is absent or set to `""`, and assert that `builder.proxy` and `builder.get_updates_proxy` are not called. This ensures an empty/missing value doesn’t inadvertently apply a proxy and that the adapter only uses global proxy settings when intended.
</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 tests/test_telegram_adapter.py

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be782126ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread astrbot/core/platform/sources/telegram/tg_adapter.py

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

This PR adds a Telegram-scoped proxy setting (telegram_proxy) so Telegram traffic can be routed through a proxy without forcing the rest of AstrBot’s outbound HTTP traffic to use the global http_proxy environment variables (addressing the isolation problem described in #7584).

Changes:

  • Add telegram_proxy to default config and dashboard config metadata/i18n.
  • Apply telegram_proxy to both Bot API requests and long-polling getUpdates requests via ApplicationBuilder.proxy() and ApplicationBuilder.get_updates_proxy().
  • Add a unit test asserting the proxy is propagated to both request pools.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
astrbot/core/platform/sources/telegram/tg_adapter.py Applies adapter-scoped proxy configuration to Telegram ApplicationBuilder (Bot API + polling).
astrbot/core/config/default.py Adds telegram_proxy to Telegram default config and exposes it in config schema metadata.
dashboard/src/i18n/locales/zh-CN/features/config-metadata.json Adds UI metadata strings for telegram_proxy and updates Telegram token hint (ZH).
dashboard/src/i18n/locales/en-US/features/config-metadata.json Adds UI metadata strings for telegram_proxy and updates Telegram token hint (EN).
dashboard/src/i18n/locales/ru-RU/features/config-metadata.json Adds UI metadata strings for telegram_proxy and updates Telegram token hint (RU).
tests/test_telegram_adapter.py Adds coverage to ensure telegram_proxy is applied to both Bot API and polling proxies.

Comment thread astrbot/core/platform/sources/telegram/tg_adapter.py
@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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

2 participants