// 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
- Supports all Telegram Bot API methods
- Handles both GET and POST requests
- Full CORS support for browser-based applications
- Transparent proxying of responses
- Maintains original status codes and headers
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));
}
});