// Telegram Bot API base URL const TELEGRAM_API_BASE = 'https://api.telegram.org'; // HTML template for documentation const DOC_HTML = ` Telegram Bot API Proxy Documentation

Telegram Bot API Proxy

This service acts as a transparent proxy for the Telegram Bot API. It allows you to bypass network restrictions and create middleware for your Telegram bot applications.

How to Use

Replace api.telegram.org with this worker's URL in your API calls.

Example Usage:

Original Telegram API URL:

https://api.telegram.org/bot{YOUR_BOT_TOKEN}/sendMessage

Using this proxy:

https://{YOUR_WORKER_URL}/bot{YOUR_BOT_TOKEN}/sendMessage

Features

Note: This proxy does not store or modify your bot tokens. All requests are forwarded directly to Telegram's API servers.

Example Code

// JavaScript Example fetch('https://{YOUR_WORKER_URL}/bot{YOUR_BOT_TOKEN}/sendMessage', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ chat_id: "123456789", text: "Hello from Telegram Bot API Proxy!" }) }) .then(response => response.json()) .then(data => console.log(data));
`; 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 path segments to validate the request format. // Accept either /bot{token}/{method} or /file/bot{token}/{file_path} const pathParts = url.pathname.split('/').filter(Boolean); if (pathParts.length < 2) { return new Response('Invalid request format', { status: 400 }); } if (pathParts[0] === 'file') { if (pathParts.length < 3 || !pathParts[1].startsWith('bot')) { return new Response('Invalid file request format', { status: 400 }); } } else if (!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}`; // Clone request headers so we can safely modify them const headers = new Headers(request.headers); // Ensure JSON requests explicitly use UTF-8 to avoid issues with emoji or // other special characters const contentType = headers.get('Content-Type'); if (contentType && contentType.startsWith('application/json') && !contentType.includes('charset')) { headers.set('Content-Type', 'application/json; charset=UTF-8'); } const init = { method: request.method, headers, redirect: 'follow', }; if (request.method !== 'GET' && request.method !== 'HEAD') { init.body = request.body; } // Forward the request to Telegram API, streaming the body when present. const proxyReq = new Request(telegramUrl, init); try { const tgRes = await fetch(proxyReq); const res = new Response(tgRes.body, tgRes); // Copy response as-is const reqAllowHeaders = request.headers.get('Access-Control-Request-Headers'); const allowHeaders = reqAllowHeaders ? reqAllowHeaders : 'Content-Type'; res.headers.set('Access-Control-Allow-Origin', '*'); res.headers.set( 'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD' ); res.headers.set('Access-Control-Allow-Headers', allowHeaders); return res; } catch (err) { return new Response(`Error proxying request: ${err.message}`, { status: 500 }); } } // Handle OPTIONS requests for CORS function handleOptions(request) { const reqAllowHeaders = request.headers.get('Access-Control-Request-Headers'); const allowHeaders = reqAllowHeaders ? reqAllowHeaders : 'Content-Type'; const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS, HEAD', 'Access-Control-Allow-Headers': allowHeaders, '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; // Handle CORS preflight requests if (request.method === 'OPTIONS') { event.respondWith(handleOptions(request)); } else { event.respondWith(handleRequest(request)); } });