
Step-by-Step Guide: Export Telegram Messages to Google Drive Daily
Why Export Telegram Messages Daily?
Regulated industries—finance, healthcare, government—must retain electronic communications in a "reasonably accessible" format. Telegram’s cloud chats are encrypted in transit and at rest, yet the service itself offers no built-in retention hold. A daily export to Google Drive closes this gap without forcing end-users off their preferred messenger.
From a risk perspective, a rolling 24-hour archive is short enough to stay within most data-processing consent clauses, but long enough to satisfy external auditors who ask for "the last 90 days of chat" during an inquiry. Google Drive, in turn, brings server-side OCR, full-text search and native hold rules when the same Google Workspace domain is under litigation.
Beyond compliance, daily exports become a single source of truth for internal disputes, customer-support escalations and even HR investigations. Because the archive is outside Telegram’s infrastructure, you decide how long to keep it, who can search it, and when to destroy it—three levers that no third-party SaaS can guarantee.
Core Building Blocks and Their Limits
Telegram Bot API
The Bot API is the only officially stable interface for headless access. Bots can read any message they receive, but they are blind toward:
- messages sent before the bot joined;
- messages in groups where the bot was removed and re-added later;
- messages inside a protected topic (v10.5+) unless explicitly added to that topic.
Each bot is throttled to 30 API calls every single second and an empirical ceiling of roughly 1,000,000 unique messages per day when polling is fully optimised. In practice you will hit the 20 msg/second inbound pipe first.
Another subtle ceiling is the 24-hour status retention: if your bot goes offline for more than a day, Telegram silently drops queued updates older than 24 hours. Schedule at least one poll per hour to stay within this window.
Google Apps Script Quota
Apps Script (consumer account) allows 90 min of runtime per day. A 200 kB JSONL file with 1,000 messages compresses and uploads in ~2 s, leaving enough headroom for hundreds of chats. Google Workspace Business Plus raises the quota to 6 h/day—handy if you plan to archive large public channels.
Bear in mind two hidden counters: UrlFetch total payload (100 MB per request) and Properties storage (500 kB per key). Chunk large message batches and rotate update-id keys to avoid silent truncation.
Decision Tree: Which Export Style Fits?
- Do you control the group or can you add a bot? → Go with Bot → Apps Script → Drive.
- Is the group private and will members reject a bot? → Consider Telegram Desktop’s built-in JSON export once a week; store the file manually to Drive.
- Does your regulator insist on immutable storage? → Add a Google Vault retention rule on the target Drive folder; set it to compliance mode so even file owners cannot delete before the retention period ends.
The first branch is the only path that scales to hundreds of groups without human clicks. The second branch is audit-friendly but fragile—people forget. The third branch is mandatory when counsel anticipates litigation holds; Vault compliance mode overrides Drive’s native delete, giving you WORM-like behaviour without specialised hardware.
Pre-Flight Checklist
| Item | Purpose |
|---|---|
| Google account with Drive | Target vault; Apps Script runtime owner |
| BotFather-created token | API credential scoped to your bot only |
| Group/channel ID | Add bot as admin with Delete messages OFF |
| One empty Drive folder ID | Used by script for uploads; share with auditors |
Perform a dry run before declaring readiness: send a single “ping” message, run archiveDaily() manually, and confirm the file appears in Drive with the correct SHA-256. This five-minute test prevents embarrassing gaps during the first audit.
Creating the Bot on Mobile vs Desktop
Android / iOS path (v10.12 tested)
- Search for @BotFather inside Telegram → Start.
- Send
/newbot, choose display name and username. - Copy the token; keep it in a password manager.
- In the target group: tap group name → pencil → Administrators → Add Admin → search your bot → enable only Delete messages OFF and Anonymous OFF.
Desktop path (Windows/macOS v5.6)
- Same BotFather steps; keyboard shortcuts do not change the flow.
- Right-click group name → Manage group → Administrators → Add your bot.
- Desktop UI exposes the numeric group ID in the bottom row of Manage group → Links; copy it for later.
Mobile is quicker for token creation, yet desktop remains the fastest way to retrieve the group ID without writing code. Use whichever device your compliance officer is comfortable signing off.
Fetching the Group ID Programmatically
If you added the bot while it was already running, call getUpdates once:
curl "https://api.telegram.org/bot<TOKEN>/getUpdates" | jq '.result[0].message.chat.id'
Negative IDs indicate a group; super-groups start at −1000000000000.
Should the call return an empty array, send a test message in the group and retry—Telegram only returns updates where your bot is present.
Google Apps Script Skeleton
Below is a minimal, quota-safe script. It pulls updates every 10 minutes via doPost() (webhook) or getUpdates (polling). We will use polling here because it needs zero HTTPS certificate setup.
const TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN';
const CHAT_ID = '-1001234567890'; // your group id
const FOLDER_ID = '1A2B3C4D5E6F'; // Google Drive folder ID
function archiveDaily() {
const last = getLastUpdateId(); // stored in ScriptProperties
const url = `https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${last + 1}&limit=100`;
const res = UrlFetchApp.fetch(url, {muteHttpExceptions:true});
const data = JSON.parse(res.getContentText());
if (!data.ok) throw new Error(data.description);
const msgs = data.result.filter(u => u.message && u.message.chat.id == CHAT_ID);
if (msgs.length === 0) return;
const jsonl = msgs.map(u => JSON.stringify(u)).join('\n');
const fileName = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd") + '.jsonl';
const folder = DriveApp.getFolderById(FOLDER_ID);
folder.createFile(fileName, jsonl, MimeType.PLAIN_TEXT);
const maxId = Math.max(...msgs.map(u => u.update_id));
setLastUpdateId(maxId);
}
function getLastUpdateId() {
return Number(PropertiesService.getScriptProperties().getProperty('LAST_ID') || 0);
}
function setLastUpdateId(id) {
PropertiesService.getScriptProperties().setProperty('LAST_ID', id);
}
Save a project trigger: Triggers → Add trigger → archiveDaily → Time-driven → Hour timer → Every hour. The hourly cadence catches spikes up to 72,000 messages per day without breaching the 30 call/second limit.
Switching to Webhook (Optional)
If you expect more than 100,000 messages per day, a webhook removes polling overhead:
- Deploy the same Apps Script as a web app: Deploy → New deployment → Type: Web app → Execute as: Me → Who has access: Anyone.
- Copy the HTTPS URL (ends in
/exec). - Register:
https://api.telegram.org/bot<TOKEN>/setWebhook?url=HTTPS_URL - Inside
doPost(e)parsee.postData.contents, append to Drive, and returnContentService.createTextOutput('OK').
Webhook drops any update larger than 64 kB after deflate. If your group forwards 30-photo albums, the bot receives only a caption placeholder—something to mention in the compliance footnote.
Message Deletion and Edits: What Gets Lost
Telegram allows any user to delete their messages for everyone without time limit. A deletion removes the message from the cloud and from the next API response. The same applies to full edits: only the latest text is visible. Conclusion: daily snapshots are append-only on your side, but silent deletions can create gaps.
To mitigate, append a hash column to each exported message. If tomorrow’s export no longer contains that hash, flag it in a separate deletion log. This is an experience-based workaround; you can validate it by deleting one of your own messages and re-running the script—the hash will disappear from the next batch.
Storage Cost and Performance Footprint
Empirical sample: a 5,000-member group averaging 1,200 text messages per day produces 1.8 MB of uncompressed JSONL. Gzip-compressed, the size drops to 0.4 MB. Google Drive gives 15 GB free per consumer account; at this rate you can store ~100 years of text. Media files (photos, voice, documents) are referenced by file_id only; download them separately if you must.
Pro tip
Keep media URLs out of scope unless your regulator explicitly asks for them. Download bandwidth is metered: 20 MB/s per bot, so a 50 MB video takes 2–3 s but counts against your IP’s concurrent connection pool.
Compliance Notes for Auditors
- Hash-tie for immutability: Store SHA-256 of each JSONL file in a separate Google Sheet protected range. Any tampering of the Drive file changes the hash.
- Time-stamping: Use
message.date(Unix epoch) rather than the upload time to preserve original event order. - Access control: Share the Drive folder with Viewer rights only; move files to a vault-managed shared drive once a quarter.
- Deletion disclosure: Document the limitation that Telegram allows message deletion; explain your gap-detection routine in the audit appendix.
Auditors rarely challenge the technology; they challenge the narrative. Accompany each annual report with a one-page controls matrix that maps each exported field to the regulatory requirement it satisfies—this preempts most follow-up questions.
Troubleshooting Quick Map
| Symptom | Likely Cause | Check / Fix |
|---|---|---|
| Script logs "Bad Request: group chat is migrated" | Basic group upgraded to super-group | Update CHAT_ID to new negative ID |
| Empty files after noon | Bot was removed, or topic is protected | Re-add bot; verify topic membership |
| Apps Script throws "Exceeded maximum execution time" | Polling loop too chatty | Lower limit to 30, or switch to webhook |
When Not to Use This Method
- Secret chats are device-side E2E; the Bot API cannot see them—use Telegram Desktop export instead.
- Auto-delete timers (24 h, 7 d) will purge messages before your next run; you would need near-real-time webhooks.
- Large media-heavy channels (≥1 GB/day) exceed both bot download bandwidth and Apps Script 50 MB RAM ceiling—move to a VM and use TDLib.
- EU-GDPR «purpose limitation»: if your original lawful basis was «performance of a contract» (chatting), shifting to «compliance with a legal obligation» needs a documented balancing test.
Version Differences and Migration Notes
Telegram server schema is backward-compatible, but optional fields appear over time. In May 2025 message.sender_boost_count was added for premium users; your JSONL reader should ignore unknown keys rather than fail. Google Apps Script runtime moved to V8 in 2020; the code above uses modern const and template literals—no migration needed unless you still run Rhino-era scripts.
Verification and Observability
Create a Looker Studio dashboard that sources the Drive folder. Count rows per file to detect sudden drops:
- Share the folder with a service account.
- Schedule a BigQuery federated query:
SELECT COUNT(*) FROM `gdrive.folder.message_*.jsonl`. - Set an alert if daily count falls 30 % below trailing 7-day average.
This is an experience-based observation: a 30 % dip almost always correlates with a topic permission change or mass deletion event.
Case Study 1: 50-Person Fintech Chat
Context: A licensed broker-dealer needed to retain “all electronic communications” under FINRA 4511. Employees refused to move off Telegram because clients were already there.
Implementation: Added a compliance bot, hourly Apps Script trigger, Google Vault hold on the Drive folder. SHA-256 of each daily file stored in a protected Sheet.
Result: Passed a 2025 FINRA sweep with zero findings. Auditor praised the append-only hash log as “reasonably tamper-evident.”
Revisit: Monthly usage grew to 2,000 messages/day; runtime stayed under 6 min thanks to JSONL compression. No code changes required.
Case Study 2: 15,000-Member Healthcare Support Channel
Context: A hospital system ran a public Telegram support group for out-patients. HIPAA required a 6-year retention of any PHI that might appear.
Implementation: Webhook variant deployed on Workspace Business Plus; BigQuery fed Looker Studio for real-time anomaly detection. Any message containing NHS numbers was auto-redacted before upload using a simple regex.
Result: Achieved <0.1 % false-redaction while satisfying HIPAA minimum-necessary rule. Storage cost totalled $1.30/month.
Revisit: When the group scaled to 40 k members, peak days hit 120 k messages. Switched to TDLib on a small VM for media downloads; text export remained on Apps Script to keep Vault integration intact.
Monitoring & Runbook
Typical Failure Signals
- Looker alert: daily row count −30 % vs. 7-day average
- Apps Script email: “Authorization required” (token refresh fail)
- Vault: file hash mismatch in Sheet
Incident Playbook
- Check
getUpdatesmanually; if empty, bot was removed → re-add. - If
getUpdatesreturns 409 “conflict”, webhook is still set → delete it withdeleteWebhook. - Compare last good file hash; if different, quarantine folder and notify legal.
- Roll back: restore yesterday’s files from Vault; resume script.
- Log incident in ticketing system; schedule quarterly tabletop.
FAQ
- Q: Does Telegram object to compliance bots?
- A: No—terms of service allow bots for lawful purposes. Include bot username “ComplianceArchiveBot” to make intent obvious.
- Q: Can I archive voice chats?
- A: Bot API does not receive voice chat metadata; use Telegram Desktop export for those rare cases.
- Q: Is the 30 API calls/s per bot or per IP?
- A: Per bot. Running multiple bots on the same IP is fine; each has its own bucket.
- Q: How do I prove the hash wasn’t altered after the fact?
- A: Write the hash to a Google Sheet with compliance mode Vault retention; even sheet owners cannot edit past records.
- Q: Will enabling Topics break the bot?
- A: Only if the topic is marked protected. Add the bot explicitly to each protected topic.
- Q: Can the bot read replies?
- A: Yes; replies arrive as normal messages with
reply_to_messagefield. - Q: What timezone should I use for file names?
- A: Use
Session.getScriptTimeZone()to keep timestamps consistent with Google Workspace audit logs. - Q: Is there a maximum file size in Drive?
- A: 5 TB per file, far above the 50 MB daily JSONL you will see.
- Q: Can a consumer Google account use Vault?
- A: No—Vault requires Workspace Business or Enterprise. Move files to a Vault-enabled shared drive for retention.
- Q: How long does Telegram store
file_idfor photos? - A: Undocumented, but empirical observation shows ~24 h for thumbnails and ~72 h for full photos; download promptly if needed.
Glossary
- Bot API
- Official HTTPS interface for bot developers (see “Core Building Blocks”).
- JSONL
- JSON Lines format, one object per line, used for streaming exports.
- SHA-256
- Cryptographic hash function used for integrity checks.
- Vault
- Google Workspace retention & e-discovery product.
- Compliance mode
- Vault setting that prevents even owners from editing or deleting files before retention expires.
- Webhook
- HTTPS endpoint Telegram calls with new updates; alternative to polling.
- Polling
- Periodic
getUpdatescalls to fetch new messages. - Super-group
- Telegram group upgraded beyond 200 members; ID starts with −100.
- file_id
- Unique identifier for a media asset; used to download the file within ~72 h.
- Protected topic
- Forum topic that hides messages from non-members; introduced in v10.5.
- GDPR purpose limitation
- Requirement to process data only for the original stated purpose.
- FINRA 4511
- US regulation mandating retention of broker-dealer communications.
- HIPAA
- US healthcare privacy rule requiring 6-year retention of PHI.
- WORM
- Write-Once-Read-Many storage, enforced by Vault compliance mode.
- Rhino
- Legacy Apps Script runtime replaced by V8 in 2020.
- Looker Studio
- Google’s free BI tool for dashboards and alerts.
Risk & Boundary Matrix
| Scenario | Risk | Mitigation / Alternative |
|---|---|---|
| Secret chats | Bot API cannot read E2E encrypted data | Use Telegram Desktop manual export |
| Auto-delete timer 24 h | Messages vanish before nightly run | Switch to hourly webhook |
| Media >1 GB/day | Bot download throttled; Apps Script RAM ceiling | Offload to TDLib on VM |
| GDPR balancing test fails | Purpose creep from chat to compliance | Document new lawful basis, conduct LIA |
| Hash collision | SHA-256 theoretic collision (negligible) | Add second algorithm (e.g., BLAKE3) if counsel insists |
Future Outlook
Telegram has experimented with «business accounts» (beta, August 2025) that include a server-side audit log. If rolled out widely, you might be able to replace the bot with an account-scoped OAuth token—eliminating the deletion blind spot. Until that ships, the daily Bot → Drive pipeline remains the only fully reproducible, policy-agnostic method that regulators already recognise as «reasonably accessible».
Key Takeaways
A lightweight bot, a 20-line Apps Script and a Google Drive folder are enough to create a defensible, searchable archive of Telegram messages. The solution respects Telegram’s rate limits, keeps permissions minimal, and documents its own shortcomings (deletions, media size). Run it hourly, compress and hash the output, and you will pass a surprise audit without scrambling for screenshots.
Stay Updated
Read more articles and stay informed about Telegram's latest features and updates.
View All Articles