Mercurygram

August 17, 2026 · View on GitHub

Mercurygram logo

Mercurygram

Telegram is a messaging app with a focus on speed and security. It’s superfast, simple and free.

This is an unofficial fork of Telegram App for Android, maintained by rebasing Mercurygram patches and forward-ported de-googling patches on top of upstream Telegram.

Releases Discussions

Get it on F-Droid

Install

Mercurygram publishes two kinds of build. The tag shape tells you which:

ChannelTag shapeExamplePackagesWhen it ships
Stable4-part X.Y.Z.M (M ≥ 1)12.7.3.1stable only (it.belloworld.mercurygram)Tagged release. Also goes to F-Droid / IzzyOnDroid.
Snapshot5-part X.Y.Z.M.K (M ≥ 1)12.7.3.1.42both stable and beta (it.belloworld.mercurygram.beta)Every push to the Mercurygram branch (beta.yml). Snapshot of the next stable.
Pre-stable5-part X.Y.Z.0.K12.7.3.0.5both stable and beta (it.belloworld.mercurygram.beta)After an upstream rebase, before the first X.Y.Z.M (M ≥ 1) stable for that upstream ships (beta.yml).

Snapshots and pre-stable builds both publish two APKs per release: a Release-flavor APK that updates the stable package side and a Debug-flavor APK (filename infixed with -debug) that updates the .beta package side. Filenames: Mercurygram-<tag>-<abi>.apk (Release) and Mercurygram-debug-<tag>-<abi>.apk (Debug). Stable installs pull the Release APK via the in-app updater opt-in toggle; .beta installs pull the Debug APK.

Versions order naturally: 12.7.3.0.5 < 12.7.3.1 < 12.7.3.1.42 < 12.7.3.2.

One-click install via Obtainium

Open the link on your Android device and the app source pre-fills with the right release filter, package ID, and APK filename filter.

Main app

Same package ID across these entries; pick one. Stable + Pre-release mirrors the in-app Accept pre-release updates toggle and tracks both 4-dotted stable and 5-dotted pre-release tags.

Stable — package it.belloworld.mercurygram. Tagged stable releases only.

Add Mercurygram to Obtainium

Stable + Pre-release — package it.belloworld.mercurygram. Tagged stable releases plus 5-dotted pre-releases (Release-flavor APK).

Add Mercurygram (Stable + Pre-release) to Obtainium

Beta — package it.belloworld.mercurygram.beta. Per-push snapshots (X.Y.Z.M.K, M ≥ 1) and pre-stable test builds (X.Y.Z.0.K). Debug-flavor APK.

Add Mercurygram Beta to Obtainium

Tor plugin (optional companion APK)

Same package ID across these entries; pick one. The plugin only ships a Release-flavor APK (no separate .beta package).

Stable — package it.belloworld.mercurygram.plugin.tor. Tagged stable releases only.

Add Mercurygram Tor Plugin to Obtainium

Stable + Pre-release — package it.belloworld.mercurygram.plugin.tor. Tagged stable releases plus 5-dotted pre-releases. Pair this with Main Beta or Main Stable + Pre-release so the plugin tracks the same release cadence.

Add Mercurygram Tor Plugin (Stable + Pre-release) to Obtainium

Stable users: the in-app updater can be opted in to pre-release updates from Settings → Mercurygram → Updates → Accept pre-release updates. Enabling shows a warning dialog; once installed a pre-release you can only turn the toggle off again after upgrading to a stable (4-part) release.

Features

  • Add ID in Profile Info
  • Copy the name of a chat, group, channel or user by long-pressing the title in its profile (tapping the ID row still copies the ID)
  • Add a menu in Notifications and Sounds in order to set the UnifiedPush distributor. The same menu may be long-clicked to inspect recent UnifiedPush notification/decryption stats
  • Add a menu in Notifications and Sounds in order to set the UnifiedPush WebPush gateway
  • Add toggle setting in Chat Settings to start video messages with rear-facing camera
  • Add toggle setting in Chat Settings to hide keyboard on chat scroll
  • Add toggle setting in Chat Setting to hide "All Chats" tab (feature from NekoX)
  • Add a per-account "default launch folder" setting in Settings → Mercurygram, so the chat list opens on a chosen folder instead of "All Chats" on the first build of the tabs after launch (local only, no server involvement)
  • Mark the scope of every option in Settings → Mercurygram when more than one account is logged in: options stored globally show "Applies to all accounts" (or an all-accounts section note), everything else applies only to the current account
  • Find chats, channels and contacts whose name is written with a decorated Unicode "font" (ℂᑌℂℐℕᗅ ℐᝨᗅℒℐᗅℕᗅ) by typing it in plain letters (Cucina italiana). Applies to the chat list search, contact and member pickers, forward and share lists. Names written in a real script (Cyrillic, Greek, CJK, ...) are left alone
  • Add administrators item in group/channel info
  • Add toggle setting in Debug Menu to enable Message Details menu
  • Add toggle setting in Debug Menu to disable Unified Push support
  • Add toggle setting in Debug Menu to disable Secure Flags. This option must only be used for debugging
  • Add toggle setting in Debug Menu to remove sponsored messages and proxy sponsor banners. This option must only be used for debugging
  • Re-add Monet themes (#31)
  • Disabled DOH resolving since this leaks your used proxy to Google and it's not needed since Android DNS over TLS should be used instead
  • Unlock premium app icons for anybody
  • Unlock 8 accounts (was 3) and remove premium check for number of accounts
  • Let non-premium users use the per-language "Do Not Translate" list, so adding a language there permanently stops the in-chat "Translate to X" bar for that language (upstream only enforced this list for Premium accounts). The list stays local to the device; manual translation is still available
  • Let non-premium users reorder dialog folders freely, including moving the "All chats" tab off the first position (the new order is synced to the server like any other reorder)
  • Add toggle setting in Chat Settings to send large photos (2560px instead of 1280px)
  • Keep the full resolution of an edited photo. The crop is cut out of the original file instead of out of an already-downscaled copy, so a photo cropped to a quarter of the frame is no longer sent at a quarter of the chosen send size (a photo that also went through a filter is cut out of the filtered working copy, which the editor caps at 2560px); the editor's intermediate file is written near-losslessly so the send does not spend a JPEG generation on it; and a high-quality send that is not grouped into an album now actually uses the high-quality size instead of silently falling back to the normal one
  • Add per-account toggle setting in Settings → Mercurygram to hide the stories bar in the chat list
  • Add per-account toggle setting in Settings → Mercurygram to hide the Telegram Premium promo UI: the Premium, Business and gifting rows in Settings and the Premium banners in the chat list. It only hides upsell affordances on top of the existing premium check, does not affect sponsored messages, and unlocks nothing
  • Add a per-account toggle setting in Settings → Mercurygram to show a live character counter above the message field while you type. It counts the same unit bots see (Unicode code points, what the Bot API reports as the message length), which makes it usable in groups where a bot deletes messages longer than a limit. It steps aside while Telegram shows its own remaining-characters counter near a length limit
  • Add per-account toggle setting in Settings → Mercurygram to pre-tick "delete for everyone" (and "also delete for…" in private chats) by default in the delete-message dialog
  • Add a "Remove all proxies" bulk action to the proxy list (upstream only deletes one proxy at a time)
  • Add a custom emoji pack importer in Settings → Mercurygram → Custom emoji pack: load a .zip of emoji images or extract the emoji directly from an official Telegram APK (since the proprietary Apple set can't be bundled in a FOSS build). The pack is your own file, stored on-device and never shared; any emoji it's missing falls back per-glyph to the bundled Noto set
  • Add a "Translate" item to the text-selection toolbar in the message input field (and other caption/input editors): select text you're composing and translate it in place, with a "Use This Translation" button that replaces the selection. Uses the same privacy-respecting translation engine as message translation; in secret chats it's forced on-device only (offline, fail-closed)
  • Add a "Mention" item to the text-selection toolbar (next to "Create Link"): turn the selected text into a user mention by typing a user ID or picking from your contacts. Only works for users the app already knows (contacts, chat members) — a hard MTProto limitation, same as typing @; an unknown ID is rejected with a hint to use the picker
  • Split the combined "Stickers & GIFs" group-permission control into four independent toggles (Stickers, GIFs, Games, Inline Bots) in both the supergroup default permissions and the per-member restriction editor, so each chatBannedRights flag can be set on its own (upstream bundles all four)
  • Restore the animated 🍑 emoji Telegram removed server-side in 2022-2023: sending it alone plays the large animation again, and tapping it replays it. The animation is not bundled in the APK, it is fetched once from a Telegram sticker pack and then cached on-device
  • Telegram application icons are replaced with hermes wing (Created by Anthony Ledoux from Noun Project)

Upstream bug fixes

Fixes for bugs that exist in stock Telegram for Android. Several are backported from Inugram (MIT).

  • Fix the heads-up notification on Android 16 listing every unread chat instead of the chat the new message came from (#123). The notification that alerts is now the one for the newest chat, carrying that chat's own sound and importance, and the group summary stays silent
  • Fix a set of upstream crashes: opening a profile of a deleted user with a story privacy badge, transferring channel ownership, picking a community in the forward list, a video cover frame that fails to decode, sticker segmentation on a recycled bitmap, and three list-adapter crashes
  • Fix a set of upstream memory leaks that kept whole chat screens alive after closing them: chat avatar and wallpaper, attach and caption mention adapters, photo viewer, video ads, reaction overlays, and a dozen notification observers that were never unregistered
  • Fix a set of upstream bugs around picking, editing and captioning photos: a crop that silently failed to bake and sent the uncropped original while the editor kept showing the crop, a caption typed in the viewer and lost when send was pressed, a 90-degree rotation in the crop editor that threw away the selected crop, a caption that followed the first position instead of its own photo when the attach preview was reordered, zoom and video position resetting when a message was edited, parts of a cropped image being unreachable while panning in the painter and the filter, images pasted from Gboard skipping the editor, an album-caption spoiler that re-hid itself after scrolling, and a missing ripple when tapping a link in an album caption

TF-originated de-googling patches

These patches were originally derived from the Telegram-FOSS effort, but Mercurygram now forward-ports and rebases them directly onto upstream Telegram.

Replacement of non-FOSS, untrustworthy or suspicious binaries or source code:

  • Do location sharing with OpenStreetMap via MapLibre instead of Google Maps
  • Use Noto emoji set instead of Apple's emoji
  • Google/Firebase push services replaced with UnifiedPush
  • SECURITY: BoringSSL, FFmpeg, libvpx, dav1d, and tde2e are built from source at compile time instead of shipping upstream prebuilts

Removal or stubbing of non-FOSS, untrustworthy or suspicious binaries or source code and their functionality:

  • Google Play Services / Firebase dependencies from the default Mercurygram build and manifests
  • Google Maps / Fused Location providers are stubbed out and replaced by MapLibre / Android location providers
  • Google Wallet, SafetyNet, Play Integrity, and related proprietary verification pieces are stubbed out through local compatibility classes
  • Google Cast integration
  • Google ML Kit / Google Vision integrations, including barcode and face detection paths
  • Android passkey support is disabled as Telegram servers verify the APK signature, which fails for unofficial forks

Other:

  • Added the ability to parse locations from intents containing a geo:<lat>,<lon>,<zoom> string
  • Force static map previews from Telegram
  • No content restrictions

Privacy & anti-tracking (Mercurygram-only)

Mercurygram adds MTProto-layer mitigations that upstream Telegram and Telegram-FOSS do not ship:

  • Reduce network tracking — opt-in toggle at Settings → Mercurygram → Privacy. Defends against the passive auth_key_id fingerprint described in the OCCRP / Symbolic Software review of May 2026 (review-confirms-telegram-tracking-vulnerability). MTProto's outer obfuscation2 stream cipher is recoverable from on-wire bytes (the AES-CTR keys are derived from the visible 64-byte TCP-handshake bytes via a public algorithm), so a passive observer with a full pcap from connection start can decode the obfuscation and read the 8-byte auth_key_id at the front of every MTProto frame. That id is stable enough to correlate a device across IP/network changes even though message contents stay encrypted. When the toggle is on:
    • Every default-network change (Wi-Fi ↔ cellular, VPN flip, IP rebind) forces a fresh PFS temp-key handshake so auth_key_id rotates across network boundaries (MgNetworkChangeWatcher + native ConnectionsManager::rotateTempAuthKeys()).
    • The CDN-redirect (upload.fileCdnRedirect) path is refused once per file download and the request is reissued against the main DC, keeping the long-lived permanent auth_key_id (which CDN nodes use because PFS is off there) off the wire.
    • TEMP_AUTH_KEY_EXPIRE_TIME is shortened from 24 h to 1 h via a runtime variable, with a 1h → 6h → 24h ladder that bumps the TTL on a bindTempAuthKey ENCRYPTED_MESSAGE_INVALID rejection — protects against a future server-side policy tightening without logging the user out (when the ladder exhausts the toggle auto-disables). Probed lower bound on DC2 in 2026-05 is 60 s; 1 h leaves a 60× safety margin. See scripts/probe-temp-key-ttl.py to re-measure the floor after a rebase.
  • Tor with idle auto-stop (optional companion APK)Settings → Mercurygram → Privacy → Use Tor. Tor support now lives in a separate, optional companion APK on F-Droid (Mercurygram Tor Plugin, package it.belloworld.mercurygram.plugin.tor); toggling Use Tor prompts to install the plugin if it isn't present. The plugin runs the same daemon (vendored from tor-android, built reproducibly from source) in its own process — only the packaging changes. MTProto is pinned to a loopback SOCKS5 the moment the toggle flips so direct connections cannot leak even before bootstrap finishes. Tor shuts down after a debounced idle window (default 5 min, configurable) once the app is backgrounded and no VoIP / downloads are active, and restarts on resume or on a UnifiedPush fallback wake — keeping battery cost in the same range as upstream Telegram while the user is not actively using the app. Telegram still sees the Tor exit; latency-sensitive features (calls) may suffer.
    • Anti-censorship transport (Settings → Mercurygram → Privacy → Use Tor → Anti-censorship): where a network blocks Tor directly with deep-packet inspection (Russia, Iran), a plain Tor connection stalls at the first handshake. Two obfuscated transports are offered: Snowflake routes the handshake through a domain-fronted WebRTC relay so it still bootstraps with no setup (broker config is built in, nothing to paste); obfs4 bridges routes it through obfs4 bridges you paste yourself (one line per bridge, obtained out-of-band from Telegram's @GetBridgesBot). Default is Direct connection (fastest where Tor is not blocked), so existing users are unaffected. Both transports ship in the Tor plugin, built reproducibly from pluggable-transports/snowflake and pluggable-transports/lyrebird.
  • Privacy-respecting translation engineSettings → Mercurygram → Privacy → Translation → Engine picks how received messages (manual translate, per-chat auto-translate, and the in-chat translate bar) are translated, instead of always hitting Telegram's cloud:
    • Telegram cloud (default) — upstream behaviour; the text is sent to Telegram's servers, which forward it to Google.
    • Alternative HTTP — routes the text through a public Mozhi privacy proxy that aggregates several engines (DuckDuckGo, LibreTranslate, Google, MyMemory, Reverso); pick the engine and instance. Keeps the query off Telegram's servers.
    • Offline (external app) — delegates every translation to Offline Translator (GPL-3.0, Bergamot offline models) over an AIDL bound service. Background dispatch — the translator UI never opens — so the message text never leaves your device. Bold / italic / code formatting can be lost because Bergamot returns plain text.
    • Auto-fallback (default on) routes offline-engine failures (no model for the language pair, language not detected, service unreachable) to the Alternative HTTP path; Telegram cloud is never chosen as the fallback.
  • On-device voice transcriptionSettings → Mercurygram → Privacy → Voice transcription. Transcribes voice and video messages locally with whisper.cpp (Tiny / Base / Small models, downloaded or imported on demand). The audio never leaves your device and it works without Telegram Premium, unlike the built-in cloud transcription. The spoken-language hint is per-account (e.g. English on a work account, Italian on a personal one).
  • Disable global search — opt-in per-account toggle at Settings → Mercurygram → Privacy. Suppresses Telegram's global search (public username/channel lookup and the messages.searchGlobal RPC) so a search query only ever filters your own chats and contacts locally, never broadcasting it to the server.
  • Disable link previews — opt-in per-account toggle at Settings → Mercurygram → Privacy. Telegram fires an account.getWebPagePreview RPC the moment a URL appears in a compose field, so the server fetches that link before you send — leaking it even if you never send the message. With this on, the preview RPC never fires across every compose surface (chat message field, share dialog, poll editor, bot share, story links) and outgoing messages carry no_webpage, so previews stay off. Opening a link or rendering previews on messages you receive is unaffected. (Per-link / per-chat override is not yet implemented.)
  • Disable AI text editor (opt-in per-account toggle at Settings → Mercurygram → Privacy). Recent Telegram adds a sparkle "AI" button to the message and caption editors that sends your draft to Telegram's AI service (messages.composeMessageWithAI) to rewrite, proofread, translate or restyle it. With this on, the button never appears, so a draft is never routed through the AI backend.
  • Disable AI summaries (opt-in per-account toggle at Settings → Mercurygram → Privacy). Telegram shows an "AI Summary" button on long incoming messages that sends the message text to its AI service (messages.summarizeText). With this on, the button is hidden everywhere it would otherwise be offered.
  • Open links in browser (opt-in per-account toggle at Settings → Mercurygram → Privacy). Tapping a link in a chat normally opens Telegram's native Instant View, which is rendered server-side by Telegram: your device never contacts the origin site, but Telegram sees the link and now prepends a server-generated "Cocoon AI Summary" to the article. With this on, tapping the plain link opens the page in your configured browser (in-app or external) instead; the explicit "Instant View" button on the preview still opens Instant View when you want it. The default is unchanged.
  • Strip tracking parameters: opt-in per-account toggle at Settings → Mercurygram → Privacy. Removes click-tracking query parameters (utm_*, fbclid, gclid, yclid, msclkid, igshid, si, erid and similar) from links you open and from links you paste into a message field, so opening a link doesn't report back to the campaign that produced it and forwarding one doesn't carry the sender's identifier to everyone else. The rest of the address is left byte-identical, and links with nothing to strip are passed through untouched.
  • Keep drafts on this device: opt-in per-account toggle at Settings → Mercurygram → Privacy. Telegram uploads unsent drafts to its servers (messages.saveDraft) so they sync across devices, which means text you never sent is stored server-side. With this on, drafts stay local: nothing is uploaded and drafts stop appearing on your other devices. Secret chats already never synced drafts and are unaffected.
  • Confirm Telegram links: opt-in per-account toggle at Settings → Mercurygram → Privacy. t.me and tg:// links normally open with no prompt, so a tap can join a channel, open a bot, or apply a proxy before you have read the address. With this on, internal links go through the same confirmation dialog external links already use, showing the target first. External links are unaffected.
  • Privacy-respecting map previewsSettings → Privacy and Security → Map preview provider. Upstream only offers whatever static-map provider Telegram's server advertises (currently Google, fetched directly from maps.googleapis.com by your device) plus "No previews". Mercurygram always offers two privacy-respecting choices regardless of the server config: OpenStreetMap, which renders the location bubble on-device with MapLibre from the same OpenFreeMap tiles used for interactive maps (only tiles.openfreemap.org is contacted, never Google), and Telegram, which has Telegram render the preview server-side so no third-party map service sees your device. The Google / Yandex options still appear only if the server advertises them, and the default stays "No previews".
  • Start new chats as secret — opt-in per-account toggle at Settings → Mercurygram → Privacy. When on, the New Message compose button starts an end-to-end encrypted secret chat instead of a regular one, so the most accessible "new conversation" action is the private one. The default is unchanged (secret chats are device-local and don't sync across devices); existing chats and other ways to open a chat are unaffected.
  • No voice replay from the lock screen — always on. Voice and round-video messages can't be (re)started from the device lock screen or its media controls (including Bluetooth/headset keys) while the device is locked, so nobody can replay a private voice message without unlocking first. Sender name and avatar are also redacted from the lock-screen player for these messages. Music is unaffected — it stays fully controllable from the lock screen.
  • Hidden accounts — additional accounts can be marked hidden behind the existing passcode (Settings → Mercurygram → General → Hidden accounts); they don't appear in the account switcher when the passcode is locked.
  • Anti-delete & anti-edit message history — opt-in per-account (Settings → Mercurygram → General → Save deleted & edited messages). Server-deleted messages stay in the chat as a grayed-out ghost; edited messages keep all previous versions accessible from the message menu. Self-destructing / TTL / secret-chat messages are never recorded (api/terms §1.4).
  • De-googled UnifiedPush + WebPush — no Google Play Services / Firebase Cloud Messaging anywhere in the binary; push notifications use UnifiedPush with end-to-end WebPush encryption (aesgcm Draft 4 — decrypted locally; the gateway only sees ciphertext). See UnifiedPush WebPush gateway.
  • DoH resolving disabled — upstream Telegram falls back to Google DoH when normal DNS fails, which leaks the user's proxy/IP to Google. Mercurygram drops that path; Android's system DNS-over-TLS handles the same encryption-in-transit need without the leak.
  • Native crypto built from source — BoringSSL, FFmpeg, libvpx, dav1d, and tde2e are compiled from source at build time instead of shipping upstream prebuilts (no opaque third-party binaries in the APK).

Notes

In order to have reliable notifications, it may be necessary to set battery optimization to Not optimized for Mercurygram (no, it won't use more battery).

Background Connections setting is not necessary and uses lot of battery, so please disable it when you use UnifiedPush.

If you set Battery optimization to Not optimized, Keep-Alive Service will be not necessary.

See dontkillmyapp for more information.

If you can't/want set Battery optimization to Not optimized and you don't receive notifications after a while (more than 30 minutes) please enable both Keep-Alive Service and Background Connection instead (Keep-Alive only keeps the app running; Background Connection is what receives the messages).

UnifiedPush WebPush gateway

Mercurygram uses Telegram's WebPush notifications through UnifiedPush.

When the app registers with a UnifiedPush distributor, it generates its own WebPush keypair and auth secret, then sends Telegram a WebPush token in JSON form:

{"endpoint":"https://<gateway>/aesgcm?e=<distributor-endpoint>","keys":{"p256dh":"...","auth":"..."}}

Telegram encrypts notifications with WebPush aesgcm (Draft 4) and sends them to the configured gateway. The gateway forwards them to the chosen UnifiedPush distributor while embedding the Encryption and Crypto-Key headers into the request body, because UnifiedPush distributors do not preserve arbitrary HTTP headers.

Mercurygram then decrypts the payload locally and passes the MTProto notification payload to Telegram's normal notification pipeline. If decryption fails, it falls back to a wake-up notification path.

The gateway is configurable from Notifications and Sounds. Mercurygram currently defaults to https://p2p.belloworld.it/.

Note: ntfy.sh (the public hosted instance) does not work through the default Mercurygram gateway at https://p2p.belloworld.it/. That gateway is hosted on OCI infrastructure, and its IP is repeatedly blocked by ntfy.sh due to connection volume. The production nginx in front of the gateway short-circuits ntfy.sh endpoints with an immediate 201 response instead of proxying them. If you want to use ntfy, prefer a self-hosted instance.

Two self-hostable gateway implementations are included in this repository:

The public Rust instance only accepts Telegram server IP ranges (https://core.telegram.org/resources/cidr.txt) to reduce abuse.

Why the name Mercurygram?

For a couple of reasons:

  • Mercury is the Roman, and I'm Italian, God and the "messenger of the gods"
  • The logo is a stylized 'F' representing his winged shoes, but it also resembles an 'F' in honor of Freddy Mercury.

Contributing

See CONTRIBUTING.md for the contribution guide. Translations of the Mercurygram-only strings are especially welcome — translators do not need to know the codebase, just edit the relevant TMessagesProj/src/main/res/values-<locale>/strings.xml and open a PR. Run ./scripts/check-mg-translations.sh to see which keys are still missing per locale.

Current Maintainers

Contributors

Current Telegram-FOSS Maintainers

Telegram-FOSS Contributors

Versioning

Tag shape encodes the release channel (see the Install section for the table):

  • StableX.Y.Z.M (4-part, M ≥ 1). X.Y.Z is the upstream Telegram version; M is the Mercurygram minor revision on top of it. Goes to the it.belloworld.mercurygram package, F-Droid, IzzyOnDroid.
  • SnapshotX.Y.Z.M.K (5-part, M ≥ 1). Per-push automated build between stable X.Y.Z.M and X.Y.Z.(M+1). K is per-stable-bump monotonic. Goes to the it.belloworld.mercurygram.beta package and (for opted-in stable installs) the it.belloworld.mercurygram package.
  • Pre-stableX.Y.Z.0.K (5-part, M = 0). Per-push automated build issued between an upstream rebase and the first X.Y.Z.M (M ≥ 1) stable for that upstream. Lets testers exercise the upcoming stable before it gets the official 4-part tag. Stops being published once any X.Y.Z.M ≥ 1 stable exists for the current upstream. M = 0 is the namespace marker — no X.Y.Z.0 4-part tag is ever created.

Pure lex compare on the dotted integer vector (shorter padded with zero) gives the right chronology: 12.7.3.0.5 < 12.7.3.1 < 12.7.3.1.42 < 12.7.3.2.

MgUpdateChecker reads the GitHub tag from PackageInfo.versionName — the manifest carries the tag verbatim (see gradle/mg-version.gradle), so the canonical tag is available for every install path (in-app updater, sideload, F-Droid).

API, Protocol documentation

Telegram API manuals: https://core.telegram.org/api

MTproto protocol manuals: https://core.telegram.org/mtproto

Building

NOTE: Building on Windows is, unfortunately, not supported. Consider using a Linux VM or dual booting. WindowsSupport

Prerequisites: Android SDK with the NDK version pinned by ndkVersion in TMessagesProj/build.gradle, JDK 17, git, and the native toolchain the media libraries need: Ninja, Meson (dav1d), nasm (x86 assembly in libvpx and ffmpeg), cmake and pkg-config.

Clone the repository (submodules are initialized automatically at build time):

git clone https://github.com/Mercurygram/Mercurygram.git

Build with Android Studio or from the command line:

# Fat APK (all ABIs)
./gradlew assembleAfatRelease

# Single-ABI APKs (F-Droid)
./gradlew assembleAfatFdArm32Release   # armeabi-v7a
./gradlew assembleAfatFdArm64Release   # arm64-v8a
./gradlew assembleAfatFdX86Release     # x86
./gradlew assembleAfatFdX86_64Release  # x86_64

Native libraries (FFmpeg, BoringSSL, libvpx, dav1d, tde2e) are built from source automatically on the first build and cached for subsequent runs.

If you want to publish a modified version of Telegram:

  • You should get your own API key here: https://core.telegram.org/api/obtaining_api_id and create a file called API_KEYS in the source root directory. The contents should look like this:
    APP_ID = 12345
    APP_HASH = aaaaaaaabbbbbbccccccfffffff001122
    
  • Do not use the name Telegram and the standard logo (white paper plane in a blue circle) for your app — or make sure your users understand that it is unofficial
  • Take good care of your users' data and privacy
  • Please remember to publish your code too in order to comply with the licenses

DIGITAL RESISTANCE

DIGITALRESISTANCE