EMP UA Helper

A desktop tool for sending simultaneous stream and video notifications to Telegram and Discord, with confirmed delivery and duplicate-send protection. Supports independent platform toggles, multiple Discord channels, a fully manual no-template mode with image attachments, a configurable timezone, and automatic content type detection via YouTube RSS/API with local caching.

Latest release: v1.5.6 · 22 October 2026 ·what's new

Features

Multi-platform & Flexibility — Telegram, YouTube, Discord, and Twitch are optional and independent. You can toggle any combination (as long as at least one notification platform, Telegram or Discord, is enabled) on the fly via the “⚙️ Settings” tray window, without restarting the application or losing saved keys.

Smart Automation with Local Caching — automatic content type detection (Live / Upcoming / Video / Short) using a hybrid approach of YouTube RSS feeds and YouTube Data API v3, without requiring OAuth authorization. Since YouTube’s RSS feed itself is limited to the channel’s last ~15 entries, the app maintains a local cache: scheduled streams are kept there with no time limit until their date arrives — even if you publish enough other content in the meantime for the announcement to fall out of the RSS window. For longer RSS outages there’s an optional fallback straight through the YouTube Data API — it only appears in the error banner, costs quota (~202 units per run) and requires separate confirmation in a dialog rather than running automatically.

Send Notification — a single window for any announcement, with a live message preview for Telegram and Discord separately before you send anything. You can rely on auto-picking the latest published content, or choose a specific video from the candidate list — each entry shows a thumbnail, title, and the real publish or broadcast date, which helps when several uploads on the same day share a similar title. The stream date/time fields have calendar, hour/minute picker, and fill-in-current-time buttons — manual typing is no longer required. The link field is optional: if left empty, lines containing the {url} variable are automatically omitted from the message to prevent broken links. A soft, non-blocking warning appears if the pasted link doesn’t look like YouTube or Twitch. Before the “Send” button, the app checks connectivity with the enabled platforms on its own — for Telegram that’s whether the bot token is valid and this specific bot can see this specific channel, for Discord whether the webhook URL is valid and hasn’t been revoked; the check runs once per window open (and again via the 🔄 button), posts nothing, and is invisible to channel subscribers.

Reliable Delivery — the Discord request now explicitly waits for confirmation that the message was created (instead of returning an empty response immediately, as before), Telegram errors like a 429 “Too Many Requests” are logged, and each platform’s send is handled independently, so one failing doesn’t hide information about the other. The Telegram.Bot library’s automatic retries after a 429 are disabled: the error comes back immediately instead of after several hidden attempts with pauses, and while sending, the window shows “⏳ sending…” for each platform. The window shows a real status separately for Telegram and Discord (“✓ sent” / “✗ failed” with the error / “— not sent”) and doesn’t auto-close until at least one platform has confirmed success; every result is logged. A separate send-result window shows one card per platform with a large colored status (✓ with the message ID, or ✗ with the error text) before the send window closes; its mode is set under “⚙️ Settings” → General: always, only on failure (default), or never. The summary also names any workaround paths used — “sent as a photo with the thumbnail” instead of a link preview, “the video list was obtained via the YouTube Data API” or “from the local cache” instead of the regular RSS. Pressing “Send” again without changing the content asks for a separate confirmation for a platform that already confirmed success last time (skipped by default) — protection against accidental duplicates; changing the text or attachments clears that protection.

Telegram Preview Failure Workaround — when the Telegram server can’t build a preview for a YouTube link, sendMessage answers 429 “Too Many Requests” and no message is created (a known server-side Telegram failure). In that case a template notification is sent right away as a photo with the YouTube thumbnail (downloaded by the app itself) and the text as its caption, and the status and result window carry a matching note. The “🖼 YouTube thumbnail as a photo instead of a link preview” toggle under “⚙️ Settings” → Telegram sends the photo straight away, without a preview attempt.

Test Send — the “🧪 Test send” checkbox in the send window routes Telegram to a test chat (the numeric ID of the private chat with the bot) and Discord to a separate test channel’s webhook; subscribers of the main channels never see the test. Both targets are set in “⚙️ Settings”; the “🔎 Find my ID” button finds the private chat ID via getUpdates after /start is sent to the bot. A platform without a test target isn’t sent to at all in test mode — there’s no fallback to the main channel; duplicate protection doesn’t apply to test sends, and such entries are marked [TEST] in the log.

Fully Manual Mode — the “✍️ Fully manual mode” toggle disables all template substitution: separate text fields for Telegram (HTML tags like <b>, <a href>) and Discord (Markdown, role/user mention tags) — whatever is typed is sent exactly as-is, and an empty field means “don’t send to that platform.” Formatting buttons above the fields (bold/italic/underline/strikethrough/code/spoiler/link) apply markup to the selected text or insert a tag pair at the caret. A character counter sits under each field (Telegram: 4096 without an image or 1024 with one, since a caption is shorter; Discord: always 2000) — exceeding the limit blocks sending to that specific platform, and if at least one platform stays within its limit, a confirmation prompt offers a partial send to just that one. The same window has generators for ready-to-copy timestamp snippets (Telegram and Discord separately) and Discord mentions (role/user/channel — just paste the ID; a whole copied tag pasted instead of an ID is rejected); nothing is auto-inserted into the text, it’s only generated for you to copy. The same mode also supports attaching up to 10 images (screenshots, photos) — one shared gallery for both platforms, with thumbnails, a remove button, reordering (◀/▶ buttons or drag — the gallery order determines the order in the actual message), and a full-size preview on click.

Multiple Discord Channels — any number of named Discord channels (e.g. a test channel or a different-language one) alongside the primary one. With two or more configured channels, the send window gains a checkbox to deliberately pick where a specific notification goes; automatic notifications always go to the primary channel. Separately, any number of name+ID pairs for Discord roles can be saved in “⚙️ Settings” — the manual mode’s mention generator shows them as a quick-pick list alongside the primary role from notifications (which is included automatically, with no need to duplicate it by hand).

Configurable Timezone — no longer hardcoded to Kyiv time: on first run it’s auto-filled with this machine’s system zone, correctly handles daylight saving transitions, and stays fixed even if the machine’s system clock zone changes later (travel, VPN, etc.). Existing installs without this setting keep working correctly on Kyiv time.

Flexible Templates — built-in template editor with support for separate Telegram and Discord layouts (including embed titles and bodies) per content type. Supported variables include:

  • {title} — content title;
  • {url} — content link;
  • {twitch} — Twitch link;
  • {scheduled_telegram} and {scheduled_discord} — scheduled start times for upcoming events (human-readable formatting with DST detection for Telegram, and dynamic Unix timestamp for Discord).

A character counter sits under each field: 4096 for Telegram (message text), and for Discord separately 256 (embed title) and 4096 (embed description) — distinct API fields with distinct limits, rather than the single shared limit used in manual mode. Exceeding a limit turns it red and blocks the “Save” button until the text is shortened.

Formatting — Discord embeds with custom thumbnails, colors, and role pings, alongside Telegram HTML formatting with link preview control (and, when Telegram can’t build a YouTube preview, an automatic switch to a photo with the thumbnail — see above).

Convenience & Privacy — the app runs in the system tray to stay out of your way; optionally, the “Send Notification” window can open right at startup (“⚙️ Settings” → General, off by default). Standard clipboard actions work in all text fields — Ctrl+C / Ctrl+X / Ctrl+V / Ctrl+A, Ctrl+Insert, Shift+Insert, Shift+Delete and the context menu (Cut / Copy / Paste / Select all), including the manual-send fields; 📋 buttons next to the message previews in template mode copy the whole text, and a clipboard access failure is written to the log. Secret fields (tokens, API keys) are masked by default with a toggleable visibility icon. The user interface is bilingual (UA/EN).

Requirements

The application runs on Windows 10/11 (x64 and x86). Multiple build configurations are available:

  • Self-contained (win-x64 / win-x86) — standalone versions that run immediately without external dependencies.
  • Generic — a lighter build that requires .NET 10 Desktop Runtime installed on your system.

Download

The latest releases and pre-compiled builds for different architectures are available on GitHub Releases.

Security and Transparency

The source code is open-source. All credentials (Telegram Bot Token, YouTube API Key, Discord Webhook) are entered during setup and stored locally in appsettings.json next to the executable. The local content cache (content-cache.json), which may contain titles of not-yet-announced scheduled streams, is likewise kept only on the user’s disk. This data is never sent to third-party servers.

The diagnostic log in the logs/ folder records every HTTP request to Telegram ([TG-HTTP]) and Discord ([DC-HTTP]): method or webhook, duration, HTTP status, rate-limit headers, request body and error response body, including the Telegram.Bot library’s automatic retries; log timestamps include milliseconds. The bot token and webhook URLs never reach the log. Parallel log writes (Telegram and Discord at once) are serialized, so no lines are lost.

Starting with version 1.5.0, releases are built automatically in GitHub Actions, triggered by a version tag, from this same repository’s code — every build run is public, with a full step-by-step log (earlier versions were built and uploaded by hand). Before each of the three build variants (generic, win-x64, win-x86) is zipped, a dedicated step checks the publish output for appsettings.json, templates.json, content-cache.json, debug symbols (*.pdb), or a logs/ folder; if any of these are found, the build stops and the release isn’t published. The GitHub release description is generated automatically from the matching section of this changelog.

Credits