Skip to content

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

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

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

Conversation

@Trainingcqy

@Trainingcqy Trainingcqy commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

The Telegram adapter has no dedicated proxy configuration. The only proxy switch is the global http_proxy, which takes effect by writing the http_proxy/https_proxy environment variables into the process, so every HTTP client with trust_env=True shares it, while no_proxy can only exclude by host and offers no way to route a single adapter through a proxy on its own. A user who wants a proxy only for Telegram therefore has to turn on the global proxy, let all other outbound traffic go through it by default, and then pick hosts back out one at a time with no_proxy. This has already spilled over into unrelated modules (#7584). The Discord adapter already has discord_proxy, so this adds the matching capability for Telegram.

Closes #9343
Closes #7444
Closes #8180

Modifications / 改动点

Modified astrbot/core/platform/sources/telegram/tg_adapter.py:

  • _build_application() reads the telegram_proxy config entry and, when it is not empty, passes it to ApplicationBuilder through .proxy() and .get_updates_proxy(), which apply to Bot API requests and getUpdates long polling respectively

Modified astrbot/core/config/default.py:

  • Added the default value "telegram_proxy": "" to the Telegram config_template, so that existing adapter instances also get the field filled in
  • Added the field schema to items, so the WebUI can render the title and the description
  • The telegram_token description used to carry the proxy guidance, and the place it pointed at is no longer correct, since the global proxy now lives under Settings > Network. It now describes only the token itself, which keeps it consistent with discord_token

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

  • Added the telegram_proxy description and hint in all three languages, and mirrored the telegram_token description change above

Modified tests/test_telegram_adapter.py:

  • Added test_telegram_proxy_is_applied_to_bot_api_and_polling_requests, which asserts that both .proxy() and .get_updates_proxy() receive the configured proxy address

  • Added test_telegram_proxy_is_skipped_when_not_configured, parametrized over None and "", which asserts that neither method is called

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

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

With a working proxy http://127.0.0.1:7897 configured, messages are sent and received normally:

代理正确
[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 ...

With a bad proxy http://127.0.0.1:9 configured, the adapter can no longer reach Telegram, which shows that the traffic really does go through the configured proxy rather than falling back to a direct connection

代理错误
[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

Regarding .get_updates_proxy()

python-telegram-bot keeps two independent request objects, one for getUpdates and one for the rest of the Bot API endpoints:

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

.proxy() only configures the latter, .get_updates_proxy() configures the former.

The startup failure above happens in Application.initialize()Bot.get_me(), which goes through _request[1], so it can only prove that .proxy() works. The traceback below was captured after polling was already running, and it goes through _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_updates and httpcore._async.http_proxy appear in the same call stack, which means the long polling request itself went through the proxy tunnel. The global http_proxy was empty for this run, and core_lifecycle.py actively deletes http_proxy/https_proxy from the environment variables when that setting is empty, so httpx's trust_env has no proxy to pick up. The proxy on this request can only have come from .get_updates_proxy(). The error itself is the connection being closed by the peer while long polling was waiting for a response, a common transient network error that has nothing to do with this change.

Screenshot of the settings page after the change

修复后设置页截图

When the field is left empty or not filled in at all, both builder calls are skipped, existing deployments behave exactly as before, and the global proxy setting still applies.


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.

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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