baicai

白菜

一个勤奋的代码搬运工!

Setting up a reverse proxy for Telegram Bot API

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

  1. A domain hosted on Cloudflare
  2. 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".

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.