Ever wanted to glance at a Telegram telebubble without unlocking your phone and getting ambushed by seventeen group chats? Want a pager-like gadget for your kid, your partner, or your commitment-averse self?
BubblePager is a physical, receive-only pager for Telegram. Send a round video note, a sticker, or a short text to a bot, and it pops up seconds later on a 240×240 round display — no send button, no keyboard, no notification feed to doomscroll. Just messages arriving one at a time, like a real pager (but cuter).
New here? → Setup guide (
SETUP.md) walks you through bot, server, and firmware in ~20 minutes. No cloud accounts beyond Telegram.
Built on an ESP32-S3 driving a GC9A01 round IPS display, with a self-hosted Python/FastAPI server bridging the Telegram Bot API to the device over WiFi.
Telegram's circular video-note bubbles are a suspiciously perfect shape match for a round display — it would've been rude not to build this. BubblePager leans all the way in: video notes, video/static stickers, and short texts are transcoded server-side into a lightweight MJPEG stream and pushed to the device over Server-Sent Events, where they play back directly on the round panel — filling the circle edge-to-edge, exactly as nature (and a GC9A01 datasheet) intended.
- Round video-note playback — MJPEG streamed and decoded frame-by-frame directly onto the display, with a live progress ring and tap-to-pause.
- Stickers — static (WEBP) and video (WEBM) stickers both play; animated
.tgs(Lottie) stickers are declined gracefully. - Text messages — short Telegram texts render word-wrapped inside the round display's safe zone, capped and validated server-side.
- Pager-style unread queue — new arrivals pulse the sender's Telegram profile photo; ignore it and the display sleeps, badging an unread count for next time — just like a real pager, not a notification feed.
- Reels-style catch-up reel — tap to play missed messages in order, tap left/right to skip back and forth through the backlog.
- History carousel — browse past bubbles, stickers, and texts with buttons or touch swipes; long-press for sender/timestamp metadata.
- Touch + button interaction model — a capacitive touch ring and physical buttons drive identical navigation, so either input method works everywhere.
- On-device settings — WiFi/NTP sync, haptics, motion-wake, auto-rotate, and incoming-timeout, all in a touch-scrollable settings wheel.
- Self-hosted, Docker-deployable server — FastAPI + FFmpeg, runs on any always-on host (VPS, Raspberry Pi, free-tier cloud); no vendor lock-in.
Telegram (video note / sticker / text)
│
▼
Python server (FastAPI + FFmpeg)
• downloads + transcodes to 240×240 MJPEG
• fetches the sender's avatar
• pushes an event over Server-Sent Events
│ WiFi
▼
ESP32-S3 firmware
• streams + decodes MJPEG straight to the round panel
• drives the pulsing incoming screen, history, settings
ESP32-S3 (N16R16) driving a GC9A01 240×240 round IPS panel over the I80 parallel bus, with capacitive touch, haptic feedback, a TCA6408 button expander, a PCF85063 RTC, and a QMI8658 IMU for motion-wake and auto-rotate.
| Path | What's in it |
|---|---|
BubblePager_firmware/ |
ESP32-S3 firmware (PlatformIO/Arduino, LVGL v9) |
BubblePager_server/ |
Telegram bot + transcoder + streaming API (Python/FastAPI) |
Setup: start with SETUP.md for the full walkthrough.
Using the device: see CONTROLS.md for buttons, touch
gestures, the unread reel, and settings. For deeper details see
BubblePager_firmware/CLAUDE.md (firmware/hardware) and
BubblePager_server/README.md (server + Docker deployment: VPS, Raspberry Pi,
or free-tier cloud).
| Question | Answer |
|---|---|
| Why isn't the sender's profile picture showing? | A Telegram privacy setting on the sender's side, not a bug. Bots can only fetch a photo if their Settings → Privacy & Security → Profile Photos is Everybody. Otherwise the pager falls back to the plain pulsing ring. |
| How do I let other people send to my pager? | Anyone can DM your bot a video-note out of the box. For a shared group: create a group, add the bot, then in @BotFather run /setprivacy → your bot → Disable, and re-add the bot to the group. It then receives every member's messages, not just commands. |
| What message types can it show? | Round video-notes (primary), plus video/static stickers and short text messages. Animated .tgs (Lottie) stickers are declined gracefully. |
| Nothing plays on the device. | See the Troubleshooting table in SETUP.md. Usual causes: device and server not on the same network, wrong SERVER_HOST/port, or phone-hotspot client isolation. |
| Do I have to keep my PC on? | For a laptop/desktop host, yes — only works while it's awake. For always-on use, run the server on a Raspberry Pi or free-tier cloud VM (see SETUP.md). |
Personal project, actively developed. Firmware and server are both functional end-to-end; hardware bring-up and real-world use are ongoing.
MIT — do what you like, no warranty.



