mail2telegram README

The project's README from github.com/tbxark/mail2telegram. As one markdown file: README.md.

mail2telegram


English | 中文

Receive email in Telegram: instant push notifications plus a Mini App inbox.

Deploy to Cloudflare

mail2telegram is a Telegram bot for receiving email, running entirely on Cloudflare Workers. It combines instant push notifications with a Telegram Mini App: every incoming email is pushed to your chat with quick action buttons, while the full history, attachments and every setting live in the Mini App. Mail arrives through Cloudflare Email Routing, which forwards every message to the worker, and AI summaries run on Workers AI or any OpenAI-compatible provider.

Telegram Mini App: push notification, inbox, message reader and iPad split view

How it works

Email ──▶ Telegram push with quick action buttons
      └─▶ Mini App inbox (history, attachments, settings)

All behavior is configured in the Mini App and stored in D1 — the worker itself only needs a few variables for its Telegram identity and optional API keys.

Guides

Telegram Mini App

Open the Mini App from the bot with /start. The first /start from a chat also binds the webhook and points the bot menu button at the worker, so later opens can use the menu button directly. Everything below is managed inside the Mini App:

The Mini App is protected by Telegram initData validation against TELEGRAM_TOKEN, restricted to the IDs in TELEGRAM_ID. In a plain browser the same URL asks for WEB_PASSWORD; when no password is configured, the Mini App is the only way in and the project landing page is shown instead.

On phones the app uses a native tab bar and navigation stack. On desktop clients (macOS, Telegram Desktop) and wide viewports it switches to an iPad-style split view with a sidebar, list and reading pane.

Usage

The push message structure is unchanged:

[Subject]

-----------
From : [sender]
To   : [recipient]

(Preview)(Summary)(Open)
  1. Preview shows the plain text body directly in the chat, limited to 4096 characters.
  2. Summary appears when a summary backend is enabled in Settings (Workers AI, or an OpenAI-compatible provider).
  3. Open launches the Mini App straight to this message's detail page. Telegram only allows Mini App buttons in private chats, so group notifications omit it.

Reply to any pushed message in Telegram to answer the sender through Resend.

CPU budget: parsing a message costs roughly 2ms of CPU per MB, so keep Max Size under ~2MB on the Workers free plan (10ms CPU per request). The paid plan's 30s budget has no such constraint. See Attachments.

Address lists

Rules are managed in the Mini App. A rule matches either an exact address (case-insensitive) or a regular expression. The white list takes precedence over the block list, so an allow rule can override a broad block rule for the same address.

Attachments

Attachments are stored in R2 and listed in the reader, where they can be downloaded. If no BUCKET binding is configured, mail is still stored without attachment contents.

Attachments need the whole message, so Max Size in Mail Handling has to be at least as large as the mail you want to receive. Base64 encoding adds about a third to every attachment, so budget the limit around the largest file you expect. Mail over the limit has its body truncated, and because attachments follow the body in the message, a truncated mail stores no attachments at all — the alternative would be handing you a corrupt download. The oversize policy Headers avoids the problem differently by skipping the body altogether.

Retention

Mail older than the retention setting is not part of the notification cache, but the full history remains until you delete it from the Mini App.

Development

The repo is a pnpm workspace with three packages and the deployable worker config at the root:

Path Package Contents
packages/server @mail2telegram/server Cloudflare Worker: email handlers, Telegram bot, Mini App API, D1 migrations and the Worker-runtime tests.
packages/web @mail2telegram/web Telegram Mini App (Vite + React), built to packages/web/dist/client.
packages/shared @mail2telegram/shared Types-only HTTP contract consumed by both sides; owns every type that crosses the wire.
pnpm install
pnpm dev            # Vite dev server on :5173 + wrangler dev on :8787
pnpm build          # typecheck every package and build the Mini App into packages/web/dist/client
pnpm typecheck      # tsc --noEmit for each package
pnpm test           # pure-logic tests (tsx) + Worker-runtime tests (vitest, Miniflare)
pnpm test:unit      # mergeSettings / testAddress / parseEmail only
pnpm test:pool      # D1, inbound-email and cleanup tests in the Workers runtime
pnpm lint           # oxlint
pnpm lint:fix       # oxlint --fix
pnpm format         # oxfmt
pnpm format:check   # oxfmt --check (used by CI)
pnpm screenshots    # regenerate the README images in docs/assets from mock data

wrangler dev serves the built packages/web/dist/client, so run pnpm build (or keep pnpm build:web running) at least once before starting it; pnpm dev runs both processes but does not build the assets.

Local D1 migrations:

pnpm db:migrate:local

The Mini App normally requires a valid Telegram initData signature. For local development, put WEB_PASSWORD=dev (plus your bot values) in the gitignored .dev.vars, run wrangler dev and open http://localhost:5173, then sign in with that password — exactly how a browser session works in production. The ?debug flag still mocks the Telegram UI (theme, viewport, platform) for previewing, and ?platform=ios previews the phone layout in a desktop browser. Never set a real WEB_PASSWORD in anything but the deployed worker's variables.

License

mail2telegram is released under the MIT license. See LICENSE for details.

mail2telegram (tbxark/mail2telegram)

Searching Database…

What is this?mail2telegram is a Telegram bot that receives your email and runs entirely on Cloudflare Workers, combining instant push notifications in chat with a Telegram Mini App inbox for history, attachments and settings.
Is this a standalone server or does it run entirely on Cloudflare's serverless platform?It is fully serverless: the bot, the Mini App API and storage all run on Cloudflare Workers with D1 for data and R2 for attachments, so there is no server to manage.
How do I deploy mail2telegram?Click the 'Deploy to Cloudflare' button, which clones the repo, creates the D1 and R2 resources, asks for your Telegram bot values, and deploys; afterwards you bind the bot and set up Cloudflare Email Routing. A manual path via CLI, GitHub Actions or Workers Builds is also documented.
What do I need before setting this up?A Cloudflare account with Workers, D1 and R2, a Telegram bot token, and Cloudflare Email Routing configured to forward mail to the worker; AI summaries additionally need Workers AI or an OpenAI-compatible API key.
Is there a size limit on the emails I can receive?Yes — parsing costs about 2ms of CPU per MB, so on the Workers free plan (10ms CPU budget) you need to keep Max Size under roughly 2MB; the paid plan's 30-second budget removes that constraint. Oversized mail has its body truncated and loses its attachments entirely.
Does the Mini App look the same on phone and desktop?No — on phones it uses a native tab bar and navigation stack, while on desktop Telegram clients and wide viewports it switches to an iPad-style split view with a sidebar, list and reading pane.
Who can open the Mini App and see my mail?The Mini App validates Telegram's initData against your bot token and only allows the chat IDs listed in TELEGRAMID; opening the same URL from a plain browser instead requires a WEBPASSWORD, and if none is set the project landing page is shown instead of the inbox.
Can I reply to emails directly from Telegram?Yes, reply to any pushed message in Telegram and mail2telegram sends your answer to the original sender through Resend.
What happens to old emails?Mail past the retention setting drops out of the notification cache, but the full history stays in the Mini App until you delete it yourself.
Can I filter which senders reach me?Yes, the Mini App lets you set white and block lists matched by exact address or regex, and white-list rules take precedence over block rules for the same address.
Creator
tbxark
Size
3.6 MB
Stars
905
Age
3y
Commits · 90 Days