Due to certain reasons, configuring epusdt requires the use of a tg reverse proxy address to function!
#telegram proxy url (if running on a server outside mainland China, leave it blank)
tg_proxy=
There are two implementation options, choose and use according to personal preference.
Nginx Reverse Proxy for Telegram Api#
Install nginx#
sudo apt update && sudo apt install -y nginx
Create configuration file#
nano tgapi.conf
Enter the following content and save it
server {
listen 80;
server_name tgapi.domain;
location / {
return 444;
}
location ~* ^/bot {
resolver 8.8.8.8;
proxy_buffering off;
proxy_pass https://api.telegram.org$request_uri;
}
}
Load configuration#
sudo systemctl reload nginx
#or
sudo nginx -s reload
Test access#
Enter the following command line, replacing BOT_TOKEN with your own bot token.
curl https://tgapi.domain/bot<BOT_TOKEN>/getMe
If you see the information of your bot, it means it is working.
Configure epusdt telegram proxy url#
epusdt configuration (.env) reference
#telegram proxy url (if running on a server outside mainland China, leave it blank)
tg_proxy=https://tgapi.domain
Docker configuration nginx reference in docker-compose.yaml#
version: "3"
services:
nginx:
container_name: "nginx"
restart: always
ports:
- "80:80"
image: nginx:bookworm
volumes:
- ./conf.d:/etc/nginx/conf.d
- ./log:/var/log/nginx
extra_hosts:
- "host.docker.internal:host-gateway"
Use Cloudflare Worker to Proxy Telegram Bot Api#
Prerequisites
- A domain hosted on Cloudflare
- Enable Cloudflare's free worker service
First, log in to Cloudflare and click on Workers and Pages on the left side.
Click on "Create Application" - "Create Worker".
Fill in a "Name" and click "Deploy".
After creating, click on the newly created Worker, and then click "Quick Edit".
Delete the existing code on the left and enter the code provided below.
/**
* Helper functions to check if the request uses
* corresponding method.
*
*/
const Method = (method) => (req) => req.method.toLowerCase() === method.toLowerCase();
const Get = Method('get');
const Post = Method('post');
const Path = (regExp) => (req) => {
const url = new URL(req.url);
const path = url.pathname;
return path.match(regExp) && path.match(regExp)[0] === path;
};
/*
* The regex to get the bot_token and api_method from request URL
* as the first and second backreference respectively.
*/
const URL_PATH_REGEX = /^\/bot(?<bot_token>[^/]+)\/(?<api_method>[a-z]+)/i;
/**
* Router handles the logic of what handler is matched given conditions
* for each request
*/
class Router {
constructor() {
this.routes = [];
}
handle(conditions, handler) {
this.routes.push({
conditions,
handler,
});
return this;
}
get(url, handler) {
return this.handle([Get, Path(url)], handler);
}
post(url, handler) {
return this.handle([Post, Path(url)], handler);
}
all(handler) {
return this.handler([], handler);
}
route(req) {
const route = this.resolve(req);
if (route) {
return route.handler(req);
}
const description = 'No matching route found';
const error_code = 404;
return new Response(
JSON.stringify({
ok: false,
error_code,
description,
}),
{
status: error_code,
statusText: description,
headers: {
'content-type': 'application/json',
},
}
);
}
/**
* It returns the matching route that returns true
* for all the conditions if any.
*/
resolve(req) {
return this.routes.find((r) => {
if (!r.conditions || (Array.isArray(r) && !r.conditions.length)) {
return true;
}
if (typeof r.conditions === 'function') {
return r.conditions(req);
}
return r.conditions.every((c) => c(req));
});
}
}
/**
* Sends a POST request with JSON data to Telegram Bot API
* and reads in the response body.
* @param {Request} request the incoming request
*/
async function handler(request) {
// Extract the URl method from the request.
const { url, ..._request } = request;
const { pathname: path, search } = new URL(url);
// Leave the first match as we are interested only in backreferences.
const { bot_token, api_method } = path.match(URL_PATH_REGEX).groups;
// Build the URL
const api_url = 'https://api.telegram.org/bot' + bot_token + '/' + api_method + search;
// Get the response from API.
const response = await fetch(api_url, _request);
const result = await response.text();
const res = new Response(result, _request);
res.headers.set('Content-Type', 'application/json');
return res;
}
/**
* Handles the incoming request.
* @param {Request} request the incoming request.
*/
async function handleRequest(request) {
const r = new Router();
r.get(URL_PATH_REGEX, (req) => handler(req));
r.post(URL_PATH_REGEX, (req) => handler(req));
const resp = await r.route(request);
return resp;
}
/**
* Hook into the fetch event.
*/
addEventListener('fetch', (event) => {
event.respondWith(handleRequest(event.request));
});
Save and Deploy
Go back to the dashboard homepage, click on "Website" on the left, and click on "Your domain hosted on Cloudflare" on the right.
Select "Workers Routes" for the domain.
Select "Add Route".
Fill in the "Route" with the subdomain you want to use, for example: "tgapi.domain/". Note that it must end with "/". Choose the Worker service you just created and click "Save".