Metadata-Version: 2.4
Name: asmr-tg-backup-ext-proxy-router
Version: 0.2.0
Summary: Scoped SOCKS/HTTP and Mihomo subscription routing for asmr-tg-backup.
Author: dreaife
License-Expression: Apache-2.0
Project-URL: Repository, https://github.com/dreaifekks/asmr-tg-backup-ext-proxy-router.git
Project-URL: Issues, https://github.com/dreaifekks/asmr-tg-backup-ext-proxy-router/issues
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: asmr-tg-backup<0.7,>=0.6
Requires-Dist: urllib3[socks]<3,>=2.2
Dynamic: license-file

# asmr-tg-backup proxy router extension

An optional, scope-aware network extension for
[`asmr-tg-backup`](https://github.com/dreaifekks/asmr-tg-backup). It supports
HTTP(S), SOCKS5/SOCKS5h endpoints and Clash-compatible subscription URLs via a
locally managed [Mihomo](https://github.com/MetaCubeX/mihomo) process.

The core asks for a route for each operation. The selected proxy endpoint stays
fixed for the entire HTTP request, yt-dlp process, curl upload, or MTProto
connection. If an operation fails, a later retry can choose another static
endpoint; Mihomo's `url-test` group continuously selects a healthy subscription
node for new connections.

## Install and enable

```bash
asmr-tg-backup extensions enable proxy-router
```

The trusted core command installs the extension into the current pipx/virtual
environment, asks only for the proxy source, endpoint, and routing preset,
writes a private config, validates the complete runtime, and safely restarts a
matching managed service. The defaults are local SOCKS5 at
`127.0.0.1:7891` with proxy routing only for media probes and downloads.

For a container or another build-time-managed environment, install
`asmr-tg-backup-ext-proxy-router==0.2.0` in the image and then run the same
enable command to create the private runtime configuration.

The following manual configuration remains available for advanced deployments.

Keep the plugin config outside the repository, for example
`~/.config/asmr-tg-backup/proxy.toml`, then reference it from the core config:

```toml
[extensions]
enabled = ["dreaife.proxy-router"]

[extensions."dreaife.proxy-router"]
required = true
config_file = "proxy.toml"
```

Run `asmr-tg-backup extensions doctor` before restarting the service.

## Static SOCKS5 or HTTP proxy

```toml
fail_closed = true
routes = [
  "http://127.0.0.1:7890",
  "socks5h://127.0.0.1:7891",
]

[scopes]
"source.notification" = "proxy"
"media.probe" = "proxy"
"media.download" = "proxy"
"telegram.control.receive" = "direct"
"telegram.control.send" = "direct"
"telegram.delivery.bot_api" = "direct"
"telegram.delivery.mtproto" = "direct"
```

`socks5h` resolves destination host names through the proxy. A single endpoint
can also be written as:

```toml
[static]
socks5_host = "127.0.0.1"
socks5_port = 7891
```

Every scope defaults to `direct`; installing the package does not turn proxying
on implicitly. Each scope accepts `direct`, `inherit`, or `proxy`:

| Scope | Operation |
| --- | --- |
| `origin.resolve` | Resolve a user-facing source reference such as a YouTube handle |
| `source.notification` | Poll live/feed notifications |
| `source.discovery` | Enumerate source media and refresh source credentials |
| `media.probe` | One yt-dlp metadata probe process |
| `media.download` | One complete yt-dlp download/live-recording process |
| `telegram.control.receive` | Bot API `getUpdates` |
| `telegram.control.send` | Control-bot API responses |
| `telegram.delivery.bot_api` | Bot API media upload through curl |
| `telegram.delivery.mtproto` | One persistent Telethon connection |

With `fail_closed = true`, a proxy-scoped operation never silently falls back
to the direct network.

## Clash-compatible subscription through Mihomo

Install a `mihomo` executable and keep the private HTTPS subscription URL in an
environment file:

```bash
export ASMR_PROXY_SUBSCRIPTION_URL='https://provider.example/private-token'
```

```toml
[mihomo]
enabled = true
binary = "mihomo"
subscription_url_env = "ASMR_PROXY_SUBSCRIPTION_URL"
listen_host = "127.0.0.1"
listen_port = 17891
refresh_seconds = 3600
health_check_seconds = 300

[scopes]
"media.probe" = "proxy"
"media.download" = "proxy"
```

The generated Mihomo configuration and log are stored with owner-only
permissions below the core data directory. The subscription URL is never
printed by this extension. Mihomo performs provider refresh, health checks, and
automatic `url-test` node selection.

## Important boundaries

- The core never swaps the configured endpoint inside a running yt-dlp process.
  With a Mihomo subscription, an existing TCP connection remains on its node,
  while a newly opened fragment connection may use Mihomo's newly selected
  healthy node. A full core retry also obtains a new route lease.
- A Bot API upload never switches after sending begins, which preserves the
  delivery uncertainty boundary and avoids duplicate messages.
- MTProto routing is connection-scoped and changes only after reconnecting.
- If `telegram.bot_api.api_base` points to a loopback Telegram Bot API daemon,
  the Python service always connects to that daemon directly. Proxy the
  daemon's own Telegram egress at the container, process, or network-namespace
  layer; this extension cannot alter another process's sockets.
- `inherit` preserves legacy environment behavior for HTTP/curl/yt-dlp, but an
  explicit `direct` or `proxy` mode is easier to audit.

## Compatibility

- Extension API level: 1
- Core: `asmr-tg-backup >=0.6,<0.7`
- Python: 3.11 or newer
- Optional subscription backend: Mihomo

Licensed under Apache-2.0.
