Telegram Web Disappearing Photo Sender – Chrome Extension A full UI-automation solution for sending view-once photos on web.telegram.org/a
Telegram Web does not support disappearing photos (View-Once / TTL photos) on the new build web.telegram.org/a. This Chrome Extension adds that feature — entirely client-side — by automating Telegram’s internal UI flows.
I reverse-engineered Telegram Web’s upload behavior, detected hidden menus, and built a sandbox-safe automation bridge using MV3.
This README documents the full technical process, decisions, and challenges.
What This Extension Does
✔ Allows any user to send disappearing photos (View Once / TTL photos) on Telegram Web ✔ Automates the UI exactly like a real human:
Opens attach menu
Selects “Photo or Video”
Injects file
Opens timer menu
Selects “View Once” or TTL seconds
Sends media
✔ Works fully offline (local automation) ✔ No backend, no external API, no server ✔ 100% safe: all images stay inside the browser
--------------------Motivation------------------
Telegram supports disappearing media on mobile apps, but Web does not. For many workflows (desktop-only users, productivity setups, privacy workflows), this feature is essential.
This extension fills that gap without modifying Telegram’s code or violating security.
---------------Architecture Overview----------------------
popup.js - Reads image file - Converts to base64 - Sends command to page
content.js (isolated world) - Bridges extension → webpage - window.postMessage()
injected.js (page context) - Full Telegram UI automation - Input injection - Button detection - Timer selection - Send command
This three-layer separation is required because:
✔ MV3 forbids direct DOM access from extensions ✔ Chrome blocks eval, inline scripts, dynamic injection ✔ Telegram has strict CSP rules (self, blob only)
I overcame all these using Chrome’s scripting.executeScript() and a message bridge.
------------How It Works (Technical Deep Dive)----------------------
- User selects image in popup
The extension converts the file → base64 and posts it into the webpage.
- injected.js receives the command
This script runs inside Telegram’s JS environment, allowing full access to DOM/UI.
- It finds the hidden upload
Telegram’s input is unmounted until the attach menu is opened — this was a major challenge.
Solution:
Try to find existing input
If missing → automatically click the Attach (📎) button
Wait for DOM update
Extract the newly created
- Inject the File into the browser
Using a DataTransfer() object:
const dt = new DataTransfer(); dt.items.add(file); input.files = dt.files; input.dispatchEvent(new Event("change", { bubbles: true }));
This simulates a real user uploading a file.
- Detect the Preview + Timer button
Telegram loads a custom preview UI, and the timer button does not always appear.
Major challenge: Timer button selectors change dynamically.
Solution:
Maintain a list of selectors
Try clicking by both attribute and text
Fallback to fuzzy text matching like “view once”, “one view”, “disappear”
- Choose TTL option
Depending on the UI:
Sometimes Telegram shows View Once
Sometimes a list of numeric TTLs
Sometimes a panel with Apply/Done
All cases are handled.
- Auto-click the Send button
Handles both normal send buttons and fallback cases.
Challenges I Faced & How I Solved Them
- Telegram Web uses strict Content Security Policy
CSP blocked:
inline scripts
eval
blob URLs
fetch(blob)
dynamic imports
----------------Solution-------------------------- Use chrome.scripting.executeScript() with world "MAIN", and convert base64 → Blob using fetch(dataURL).
- Upload input does not exist until user opens attach menu
Telegram dynamically mounts the .
Solution: Programmatically click the attach button → then re-scan DOM → then inject file.
- Timer/View-Once UI is not consistent
There are multiple versions of Telegram UI:
Some builds show a clock icon
Some show “view once” text buttons
Some hide it behind a 3-dot menu
Some don't show TTL at all until preview loads
---------------Solution------------------------------ Implemented layered selector detection:
Attribute selectors
Class-based selectors
Text-based fuzzy match
Fallback to clicking all buttons and detecting which opens the TTL popup
- MV3 removes background pages
Telegram automation required stable injection. Service workers unload automatically — breaking messaging.
Solution: Removed background messaging dependency. Moved logic to content script + popup local messaging.
- Telegram Web frequently re-renders nodes
Vue/React-style virtual DOM replaces elements → selectors break.
Solution: Use repeated polling + retries + stable detection patterns.
---------Final Features Achieved-----------------
✔ Upload any photo ✔ Auto-click Attach ✔ Auto-select Photo/Video ✔ Inject file ✔ Auto-open TTL menu ✔ Auto-select View Once ✔ Auto-send ✔ Fully client-side ✔ Works on web.telegram.org/a ✔ Works with light theme & dark theme ✔ Supports large images (tested up to 4MB)
--------Installation (Developer Mode)--------------
Download or clone the repo
Visit: chrome://extensions
Enable Developer Mode
Click Load Unpacked
Select this project folder
You will see the extension icon appear in Chrome.
-------------Usage-----------------------------
Open web.telegram.org/a
Choose any chat
Click the extension icon
Upload a photo
Set TTL seconds (or 1 = view once)
Click Send to Active Chat
Watch automation complete the flow
-----------------Future Improvements---------------
🔧 Multi-image upload 🔧 Drag-and-drop support 🔧 Detect when send succeeds or fails 🔧 Advanced timer presets 🔧 Firefox version (requires Manifest V2 compatibility)