Telegram proxy on Cloudflare Worker

How to deploy a Telegram Worker Proxy on Cloudflare Workers with a custom domain.
This guide walks you through deploying the telegram-bot-proxy
on Cloudflare Workers and connecting it to your custom domain.
๐ฆ Prerequisites
- A Cloudflare account
- A domain added to Cloudflare
- Telegram Bot token and your Telegram secret path (from
setWebhook
)
๐ ๏ธ Create the Worker
-
Go to your Cloudflare dashboard
-
Navigate to Workers & Pages โ Create Application
-
Select the “Workers” tab โ Create Worker
-
Give your worker a name, e.g.
telegram-proxy
-
In the editor window:
-
Replace the default code with the Telegram proxy script from the GitHub repo:
๐ Paste this code from telegram-bot-proxy.js (Thanks to tuanpb99)
const TELEGRAM_API_BASE = "https://api.telegram.org" async function handleRequest(request) { const url = new URL(request.url); if (url.pathname === '/' || url.pathname === '') { return new Response(DOC_HTML, { headers: { 'Content-Type': 'text/html;charset=UTF-8', 'Cache-Control': 'public, max-age=3600', }, }); } // Extract the bot token and method from the URL path const pathParts = url.pathname.split('/').filter(Boolean); if (pathParts.length < 2 || !pathParts[0].startsWith('bot')) { return new Response('Invalid bot request format', { status: 400 }); } // Reconstruct the Telegram API URL const telegramUrl = `${TELEGRAM_API_BASE}${url.pathname}${url.search}`; let body = undefined; if (request.method !== 'GET' && request.method !== 'HEAD') { try { body = await request.arrayBuffer(); } catch (err) { return new Response(`Failed to read request body: ${err.message}`, { status: 400 }); } } const proxyReq = new Request(telegramUrl, { method: request.method, headers: request.headers, body, redirect: 'follow', }); try { const tgRes = await fetch(proxyReq); const res = new Response(tgRes.body, tgRes); // Clone Telegram response res.headers.set('Access-Control-Allow-Origin', '*'); res.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.headers.set('Access-Control-Allow-Headers', 'Content-Type'); return res; } catch (err) { return new Response(`Error proxying request: ${err.message}`, { status: 500 }); } } // Handle OPTIONS requests for CORS function handleOptions(request) { const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Max-Age': '86400', }; return new Response(null, { status: 204, headers: corsHeaders, }); } // Main event listener for the worker addEventListener('fetch', event => { const request = event.request; if (request.method === 'OPTIONS') { event.respondWith(handleOptions(request)); } else { event.respondWith(handleRequest(request)); } });
-
-
Click Save and Deploy
๐ Add Your Custom Domain
-
Back in Cloudflare Dashboard โ Websites โ Add a Site (if not already added)
-
Choose your domain (e.g.
yourdomain.com
) -
Go to DNS โ Add DNS Records:
-
Type: A
-
Name:
@
-
Value:
192.0.2.1
(placeholder, used for redirecting to Workers) -
Proxy status: Proxied (Orange cloud โ๏ธ)
-
Type: A
-
Name:
*
-
Value:
192.0.2.1
-
Proxy status: Proxied
-
-
Make sure your nameservers point to Cloudflareโs as shown in your domain setup panel
๐ Route Domain to the Worker
-
Go to Workers & Pages โ Your Worker โ Triggers tab
-
Scroll to Routes
-
Add:
yourdomain.com/*
*.yourdomain.com/*
-
Click Save
โ Final Test
-
Open your browser and go to https://yourdomain.com/ then you should see a simple HTML page indicating the worker is running.
-
Set your Telegram botโs webhook to your new URL:
curl "https://yourdomain.com/bot<YOUR_BOT_TOKEN>/<action>"
๐ฏ Conclusion
Youโve now:
โ Deployed a Telegram proxy on Cloudflare Worker
โ Routed your domain to the Worker
โ Secured your proxy with a secret path
โ Connected your bot to use the new webhook