A privacy-respecting Telegram bot for tracking when your friends and contacts come online and go offline — with exact timestamps, not vague "last seen recently" guesses.
No polling. No scraping. No bans. Just clean, event-driven MTProto magic that catches Telegram's own UpdateUserStatus push events.
Let's be real — Telegram's "last seen recently" is useless when you actually want to know when someone was online. Was it 5 minutes ago or 3 hours? Who knows.
This bot tells you the exact timestamp. Not approximations. It works by listening to the same status updates a normal Telegram client receives — completely within ToS, indistinguishable from you just having the app open.
I built it because I wanted to track online patterns of people I care about without:
- Getting rate-limited into oblivion with polling loops
- Getting banned for "automated data collection"
- Dealing with vague "was online recently" nonsense
- 🟢 Catches exact online/offline timestamps via MTProto
UpdateUserStatusevents - 👥 Multi-user isolation — each whitelisted user has their own workspace: only their contacts, stats, and notifications
- 🔔 Per-user notification modes — online only, offline only, both, or mute (1/4/24h)
- 🏷️ Display names — custom aliases for contacts instead of @usernames
- 📊 Statistics — overall + per-user: total time, avg session, streak, hourly activity heatmap
- 📅 Daily session log — paginated, date picker (today/yesterday/custom)
- 📡
/getall— one-tap overview of all tracked contacts - 📥 CSV export — download per-user session history
- 🌐 REST API —
/health,/getall,/stats,/daily/<date>on localhost:8091 (auth viaAuthorization: Bearer <token>header) - 🗣️ Per-user language — each user switches EN/RU independently
- 🔔 Per-user notification toggle — notifications on/off, actually works now
- 🛡️ Whitelist access control — only authorized users. Strangers get witty rejections (13 variants, English)
- 🔒 Access log — tracks every unauthorized attempt, auto-bans after 5 tries
- 🌐 i18n — English and Russian, switchable from settings
- 🗜️ Auto-cleanup — sessions older than 90 days auto-deleted
- 🔄 Self-restart — restart bot from settings menu
You add @friend to tracking
│
▼
Telethon listener catches UpdateUserStatus events (MTProto)
│
├── UserStatusOnline → write "went online" to SQLite + send notification
│
└── UserStatusOffline → write "went offline" with EXACT was_online timestamp
This is fundamentally different from every "online tracker" that polls with /setdelay 60. Those hammer Telegram's API every N seconds and get FloodWait errors (or worse). This bot just... listens. Like a normal client.
| Layer | Tech | Why |
|---|---|---|
| MTProto client | Telethon | Direct Telegram protocol access, no Bot API limitations |
| Bot interface | python-telegram-bot | Async, battle-tested, inline keyboard support |
| Database | SQLite (WAL mode) | Zero-config, fast enough for personal use, single file |
| REST API | Python stdlib http.server |
/health, /getall, /stats, /daily — zero extra deps |
| Runtime | Python 3.11+, systemd | Reliable, restart on crash, auto-start on boot |
Everything runs in a single process — Telethon and the bot share one asyncio event loop, so there's no session file conflicts or IPC overhead.
- Python 3.11 or newer
- A Telegram account (not a bot account — you need MTProto access)
- Telegram API credentials (get them here)
- A bot token from @BotFather
git clone https://github.com/tima100faces/telegram-online-tracker.git
cd telegram-online-tracker
pip install -r requirements.txtCreate a .env file (copy from .env.example and fill in your real values):
BOT_TOKEN=123456:ABCdef...
TG_API_ID=12345678
TG_API_HASH=abc123def456...
TG_PHONE_PART1=+1
TG_PHONE_PART2=5551234567
DB_PATH=./data/tracker.db
OWNER_ID=123456789python bot.pyOn first run, Telethon will ask for the auth code sent to your Telegram. After that, the session is saved and reused.
For production, use the included systemd service file or run it under screen/tmux.
# Coming soontelegram-online-tracker/
├── bot.py # Main process: Telethon listener + Telegram bot
├── api.py # REST API: /health, /getall, /stats, /daily
├── test.py # Test suite (DB, i18n, callbacks, pagination)
├── i18n.py # EN/RU string tables + 13 rude rejection messages
├── db/
│ ├── __init__.py
│ ├── core.py # Users, sessions, daily log, mute, stats
│ └── settings.py # Whitelist, access log, per-user language, config
├── docs/
│ ├── ARCHITECTURE.md # Data flow, components, security model
│ ├── SPEC.md # Feature spec with planned work
│ └── marketing/ # Reddit/X post drafts
├── requirements.txt
└── .env.example # Template (copy to .env, never commit real one)
You need this for the OWNER_ID in .env. It's a number, not your @username.
The easiest way (takes 10 seconds):
- Open Telegram → search for @userinfobot
- Click Start (or send
/start) - It replies with your ID. Copy the number after
Id:
That's it. Paste that number as OWNER_ID in your .env file.
💡 To whitelist other users or add them to tracking — the bot resolves @usernames automatically. You just type
@their_name.
No. This bot listens to the same UpdateUserStatus events any official client receives. It's indistinguishable from a normal user having Telegram open. Section 1.4 of the ToS prohibits "automated data collection" via scraping/parsing — we're not scraping anything, we're a legitimate MTProto client.
Polling (getEntity status → wait → repeat) is rate-limited and will get your account FloodWait-ed or banned. Event-driven listening is both legal and infinite — Telegram itself pushes the status changes to us.
Can I track someone who has "last seen" hidden?
No. If a user hides their online status in Telegram's privacy settings, MTProto won't send UpdateUserStatus events for them. The bot can only track users whose status you can see in the Telegram client itself — usually your contacts. If you see "last seen recently" instead of an exact time, the bot can't track them either.
They get one of 13 randomly-selected rude English phrases (stuff like "Private party. You weren't invited." and "The bot finds your presence... unnecessary."). After 5 attempts they get permanently blocked with a cold "You've been blocked. Curiosity satisfied?" message. All attempts are logged.
See CHANGELOG.md for version history.
GNU General Public License v3.0 — free software, copyleft. Use it, modify it, share it — just keep it open.
Built by @tima100faces · Telegram: @tgonlinetrackbot
