_download_slack_file fetched url_private_download with follow_redirects=True
and no SSRF validation, unlike the shared network guard used across other
channels (napcat/dingtalk/qq) and the maintainer's recent image-download
hardening. A file URL that pointed at — or redirected to — an internal
address let the bot server issue requests to loopback/RFC1918/cloud-metadata
targets, and cross-host redirects could carry the request off Slack.
Validate the URL through validate_url_target before requesting, stop
following redirects, and reject a redirect response. Authorized Slack file
downloads return 200 directly, so normal downloads (which still send the bot
token) are unaffected; the HTML-login guard already handled the redirect-to-
login case.
Matrix error logs used printf-style placeholders with Loguru, leaving filenames, room IDs, and chat IDs out of diagnostic output. Use Loguru placeholders and cover each affected failure path with focused regression assertions.
Signed-off-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com>
- Fail outbound sends while the app is rebuilding instead of returning quietly, so ChannelManager retries and logs the failure instead of counting the message as delivered
- Close the bot's HTTPX pools during teardown: Application.shutdown() skips them when initialize() never finished, leaking one pool per startup retry
- Propagate terminal startup errors (rejected token, bad proxy, bound webhook port) and clear the running flag instead of retrying forever while the channel still reports itself healthy
- Restrict startup retries to NetworkError/TimedOut, the exceptions HTTPXRequest wraps every httpx failure into
- Scrub the rejected-token failure so PTB's token-bearing message never reaches the log
- Wrap the getUpdates request pool to record completed round trips, since a healthy long poll completes one every ~10s even with no traffic
- Replace the idle keep-alive loop with a supervisor that tears down and rebuilds the application (including its HTTPX pools) when no round trip completes for 120s
- Retry failed startups with exponential backoff so the bot self-heals once the network path recovers
- Give up immediately on InvalidToken since a rejected token is a config error that retries cannot fix
- Tear down the freshly built app when stop() lands mid-startup so the supervisor never leaks a running application
- Bridge python-telegram-bot and httpx stdlib logging into loguru so polling failures are visible in nanobot logs
When config.json has no channels configuration, the WebUI QR login
connect flow obtained a token but only saved it to account.json (state
file). The subsequent post-connect enable step (set_channel_config_enabled)
read config.json, found no weixin section, and wrote back a default
config with token="" - silently losing the freshly obtained credential.
Add _persist_connect_credentials to _commit_account so the token and
base_url are written to config.json before the enable step runs. This
covers both the WebUI connect flow and the CLI QR login path, mirroring
the established Feishu save_registration_result pattern.