Telegram control panel¶
The Telegram control panel keeps routine source and local-resource operations
in one inline message. Send /panel or /start after it is enabled.
What you can do¶
The panel lets an authorized user:
- add YouTube and Twitch sources;
- add providers registered by enabled extensions, such as Niconico;
- enable, disable, inspect, and remove sources;
- choose Twitch live recording or archive download;
- manage the global source filter and inspect polling or job status;
- browse channel favorites ranked by Telegram reaction totals and maintain a personal Panel favorite list; and
- browse tracked local files, with optional confirmed disk deletion.
Enabling a source-provider extension adds its provider button after the service restarts. Select that button and submit the requested identifier when you want to create the source and begin polling.
What to prepare¶
Choose the user, chat, and message-thread IDs that may operate the panel, then add them to the matching allowlists:
[control]
enabled = true
api_base = ""
poll_interval_seconds = 10
panel_idle_timeout_seconds = 3600
delete_webhook_on_startup = true
allow_disk_delete = false
reaction_favorites_enabled = false
allowed_user_ids = ["123456789"]
allowed_chat_ids = []
allowed_message_thread_ids = []
Authorization is an AND across every non-empty allowlist. If both a user and a chat are configured, both must match. Emptying every allowlist denies every command. Prefer at least one allowed user ID; a chat-only allowlist permits all members of that chat.
The panel closes after one idle hour by default. Set
panel_idle_timeout_seconds = 0 to disable the timeout.
The panel receives updates with Bot API long polling. Keep
delete_webhook_on_startup = true when the bot may still have a webhook; the
service removes that webhook at startup without dropping pending updates.
Control-only Bot API endpoint¶
control.api_base selects the Bot API endpoint used for getUpdates, callback
acknowledgements, command registration, and panel message sends/edits. An empty
value, or omitting the field, uses the same endpoint as
telegram.bot_api.api_base.
To keep MTProto media delivery unchanged while the panel uses a trusted local Bot API server:
[telegram]
upload_transport = "mtproto"
[telegram.bot_api]
api_base = "https://api.telegram.org"
[control]
enabled = true
api_base = "http://127.0.0.1:18081"
The endpoint receives the bot token. Use HTTPS for remote servers; unencrypted HTTP is appropriate only for a trusted loopback endpoint. Loopback requests are always forced direct and cannot be captured by an extension or environment proxy.
If telegram.upload_transport = "bot_api", normally point
telegram.bot_api.api_base at the same local server as the panel. Assign one
Bot API location to each bot token at a time.
To move a token between Telegram's cloud Bot API and a local server, prepare
the local server, stop the application, complete the server's documented bot
migration, update the field, and restart. Keep cloud and local getUpdates
consumers mutually exclusive throughout the move.
Favorites and channel pins¶
When the delivery target is a Telegram channel, reaction favorites are an explicit opt-in:
[control]
enabled = true
reaction_favorites_enabled = true
The control worker then explicitly subscribes to Bot API
message_reaction_count updates. It accepts only messages that belong to the
current destination in SQLite deliveries. Per-reaction counts, the aggregate
total, message ID, update time, and pin-sync state are persisted in state.db.
The bot calls pinChatMessage when a total changes from zero to a positive
value. When the total returns to zero, it removes only a pin synchronized by
this feature; it never clears unrelated channel pins. Multiple messages from a
split delivery are grouped under one media item and their counts are summed in
the ASMR ranking.
The bot must be a target-channel administrator with the channel
can_edit_messages right. Reaction counts are still recorded if that right is
missing; pin errors are persisted and retried with backoff. Bot API does not
backfill reaction totals from before the feature was enabled, so rankings begin
with updates received afterward.
Telegram channel reactions are anonymous. Bot API provides the total but cannot reliably attribute a native reaction to the current Panel user. The Panel therefore keeps the concepts explicit:
❤️ Total rankinguses native Telegram reaction totals and sorts descending;⭐ My favoritesis the authorized user's explicit Panel favorite list, also sorted by the current total.
Every entry includes a URL button that opens the original channel message.
Public channels use t.me/<username>/<message_id>; private-channel links use
the member-only t.me/c/... form.
Open the panel¶
- Save the
[control]settings and restart the service with the command for your deployment method. - Send
/panelor/startfrom an allowed user, chat, and message thread. - Use
🔄 Refreshwhen you want a new runtime snapshot. The panel also refreshes after each completed action. - Send
/panelagain whenever you want a fresh panel message.
Source management¶
Back up one video¶
After selecting ➕ YouTube, send @handle [display name] to subscribe as before,
or send a video URL directly, optionally prefixed with url:
https://www.youtube.com/watch?v=abcdefghijk
url "https://youtu.be/abcdefghijk"
YouTube watch, youtu.be, Shorts, live, and embed video URLs are supported.
Playlist and sharing parameters are removed from video links; a playlist-only
URL is rejected. Ordinary channel URLs still subscribe, while url "channel URL"
is rejected.
For Twitch, select the source type and recording mode, then send
https://www.twitch.tv/videos/123456 or url "https://www.twitch.tv/videos/123456".
The configured Twitch API credentials resolve that video ID and its actual type
(VOD, Highlight, or Upload), regardless of the selected subscription mode.
No channel scan or channel recording starts. Clips and live channel URLs are
not supported in single-video mode.
Submit one URL at a time. A single-video request does not change sources.toml
or subscribe to future uploads. It bypasses the global source keyword filter
and new-video download delay, then uses the existing download, conversion,
local storage, and configured Telegram delivery pipeline. Access restrictions,
not-ready deferrals, and retries still apply. Repeated requests reuse existing
jobs; successful or uncertain deliveries are not resent, and blocked jobs
still require the existing recovery workflow.
Extension providers can opt in through resolve_media_url; the Panel displays
URL instructions for providers that implement it. Older extensions retain their
source identifier input and reject explicit url requests as unsupported.
The command form also works: /origin add youtube url "https://youtu.be/abcdefghijk".
Manage subscriptions¶
The panel buttons can:
- add, enable, disable, and remove YouTube, Twitch, and enabled extension sources;
- choose live recording or archive download for a Twitch VOD source;
- inspect, set, disable, or reset the global source filter; and
- inspect source polling errors and media/job statistics.
Each enabled extension provider gets a generated ➕ Provider button. Select
it and submit <external_id> [display name]; quote an identifier that contains
spaces. The new source appears in 📚 Sources with its provider/kind after
the input is accepted. RSS remains a manual catalog source; see
Sources and downloads.
Use /origin rename <origin_id> <name> to rename a source and
/origin history <origin_id> to change its bootstrap range from latest to
all. These commands use the same catalog path as the buttons.
Every source or filter change safely updates the sources.toml selected by
[sources].path and then synchronizes its SQLite runtime mirror. If you edit
the same file and run asmr-tg-backup sources apply, the panel shows the new
values. There is no precedence contest between “panel configuration” and “TOML
configuration.”
Use the source catalog and CLI for batch edits, complete field control, or configuration snapshots.
What is stored where¶
Here <config-stem> means the main config filename without its final .toml.
| Data | Storage | How it changes |
|---|---|---|
| Sources, enabled state, names, bootstrap range, Twitch mode, global filter | sources.toml; SQLite only holds the synchronized runtime mirror |
Panel buttons or /origin commands; or edit the file and run sources apply |
| Telegram, download, Twitch credential references, panel endpoint and authorization | config.toml and optional env |
Edit and restart the service |
| Managed extension enablement, required flags, and private-config references | <config-stem>.extensions.toml; the default path is config.extensions.toml |
extensions enable manages the sidecar; settings in the main config take precedence |
| Managed private extension settings | extensions/<config-stem>/ beside the main config |
Extension setup or extensions enable --reconfigure; validate with extensions doctor |
| Poll cursors, errors, media, jobs, deliveries, file records | state.db |
Maintained by the running service |
| Telegram reaction totals, pin-sync state, personal Panel favorites | state.db |
Maintained by reaction updates and authorized Panel buttons |
| Current panel message, navigation session, Telegram update offset | state.db |
Maintained automatically by the panel |
| Downloads and MTProto session | Application data directory | Maintained by the service; explicit file deletion may use the panel |
Edit sources.toml rather than SQLite when changing sources. A complete backup
includes config.toml, sources.toml, optional env, the matching
<config-stem>.extensions.toml sidecar (normally
config.extensions.toml) and extensions/<config-stem>/ directory when
present, every manually configured config_file stored elsewhere, state.db,
downloads, and the MTProto session.
Local resource library¶
The panel lists only files already tracked in SQLite. It does not recursively scan the download directory or infer ownership from filenames.
Permanent disk deletion is opt-in in config.toml:
[control]
allow_disk_delete = true
Restart after changing this setting. Deletion still requires authorization, a
current panel session, and resource-specific confirmation. Only exact tracked
regular files below a configured managed storage root are eligible; this
includes an enabled mounted [storage].archive_dir. Database history and
existing Telegram messages remain. An unavailable archive mount is shown as an
unsafe/missing resource and is never treated as permission to delete another
path.
When a Telegram delivery reaches uncertain because the response boundary is
ambiguous, its resource detail shows Resolve uncertain delivery. An operator
must verify the destination first, then explicitly confirm delivery or accept
the duplicate-message risk and force a resend. Both actions have a state-version
check and a separate audit record; the Panel never retries automatically.
allow_disk_delete controls only deletion started from the Panel. Automatic
cleanup and mounted storage use [storage].process_retention_hours,
[storage].backup_retention_hours, and archive_dir. See
Automatic local retention.