telebot-proxy 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- telebot_proxy-1.1.0/LICENSE +21 -0
- telebot_proxy-1.1.0/PKG-INFO +674 -0
- telebot_proxy-1.1.0/README.md +634 -0
- telebot_proxy-1.1.0/pyproject.toml +75 -0
- telebot_proxy-1.1.0/setup.cfg +4 -0
- telebot_proxy-1.1.0/telebot_proxy/__init__.py +61 -0
- telebot_proxy-1.1.0/telebot_proxy/core.py +356 -0
- telebot_proxy-1.1.0/telebot_proxy.egg-info/PKG-INFO +674 -0
- telebot_proxy-1.1.0/telebot_proxy.egg-info/SOURCES.txt +11 -0
- telebot_proxy-1.1.0/telebot_proxy.egg-info/dependency_links.txt +1 -0
- telebot_proxy-1.1.0/telebot_proxy.egg-info/requires.txt +11 -0
- telebot_proxy-1.1.0/telebot_proxy.egg-info/top_level.txt +1 -0
- telebot_proxy-1.1.0/tests/test_core.py +406 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hamidvalad.ir
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: telebot-proxy
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Route any requests-based HTTP traffic through a forwarder service. Built for Telegram bots (pyTelegramBotAPI), works with any API.
|
|
5
|
+
Author: Hamidvalad.ir
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourname/telebot-proxy
|
|
8
|
+
Project-URL: Documentation, https://github.com/yourname/telebot-proxy#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/yourname/telebot-proxy
|
|
10
|
+
Project-URL: Issues, https://github.com/yourname/telebot-proxy/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/yourname/telebot-proxy/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: telegram,telebot,proxy,forwarder,pyTelegramBotAPI,telegram-bot,api-proxy,http-forwarder,requests-proxy,relay
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Communications :: Chat
|
|
25
|
+
Classifier: Topic :: Internet :: Proxy Servers
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Python: >=3.7
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: requests>=2.20
|
|
31
|
+
Provides-Extra: telebot
|
|
32
|
+
Requires-Dist: pyTelegramBotAPI>=3.0; extra == "telebot"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pyTelegramBotAPI>=4.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-mock>=3.0; extra == "dev"
|
|
37
|
+
Requires-Dist: responses>=0.20; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# telebot-proxy
|
|
42
|
+
|
|
43
|
+
**Route any `requests`-based HTTP traffic through a forwarder service — zero code changes to your application logic.**
|
|
44
|
+
|
|
45
|
+
Originally built for [pyTelegramBotAPI](https://github.com/eternnoir/pyTelegramBotAPI) (telebot), but works with **any** Python code that uses the `requests` library.
|
|
46
|
+
|
|
47
|
+
[](https://www.python.org/downloads/)
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
[]()
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
<div dir="rtl">
|
|
54
|
+
|
|
55
|
+
**[🇮🇷 مستندات فارسی](#مستندات-فارسی)**
|
|
56
|
+
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Table of Contents
|
|
62
|
+
|
|
63
|
+
- [What does it do?](#what-does-it-do)
|
|
64
|
+
- [How it works](#how-it-works)
|
|
65
|
+
- [Installation](#installation)
|
|
66
|
+
- [Quick Start](#quick-start)
|
|
67
|
+
- [Telegram Bot](#1-telegram-bot-default)
|
|
68
|
+
- [Custom hosts](#2-proxy-specific-hosts)
|
|
69
|
+
- [Intercept everything](#3-intercept-all-requests)
|
|
70
|
+
- [Configuration](#configuration)
|
|
71
|
+
- [Examples](#examples)
|
|
72
|
+
- [API Reference](#api-reference)
|
|
73
|
+
- [Forwarder Service](#forwarder-service)
|
|
74
|
+
- [FAQ](#faq)
|
|
75
|
+
- [Contributing](#contributing)
|
|
76
|
+
- [License](#license)
|
|
77
|
+
- [مستندات فارسی](#مستندات-فارسی)
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## What does it do?
|
|
82
|
+
|
|
83
|
+
In some networks, direct access to certain APIs (like `api.telegram.org`) is blocked or unreliable. **telebot-proxy** solves this by transparently routing HTTP requests through an intermediate **forwarder service** that you control.
|
|
84
|
+
|
|
85
|
+
### Three modes of operation
|
|
86
|
+
|
|
87
|
+
| Mode | Description | Use case |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| **Default** | Intercept only `api.telegram.org` | Telegram bots |
|
|
90
|
+
| **Selective hosts** | Intercept a custom list of hostnames | Specific blocked APIs |
|
|
91
|
+
| **Intercept all** | Route *every* outgoing request through the forwarder | Fully restricted networks |
|
|
92
|
+
|
|
93
|
+
### Feature support
|
|
94
|
+
|
|
95
|
+
| Feature | Status |
|
|
96
|
+
|---|---|
|
|
97
|
+
| Any API that uses `requests` | ✅ |
|
|
98
|
+
| pyTelegramBotAPI (telebot) 3.x & 4.x | ✅ |
|
|
99
|
+
| Text messages, photos, videos, files | ✅ |
|
|
100
|
+
| File downloads | ✅ |
|
|
101
|
+
| Inline queries & callbacks | ✅ |
|
|
102
|
+
| Long polling (`infinity_polling`) | ✅ |
|
|
103
|
+
| Webhook mode | ✅ |
|
|
104
|
+
| JSON body, form data, multipart upload | ✅ |
|
|
105
|
+
| Thread-safe | ✅ |
|
|
106
|
+
| Multiple bots/clients in one process | ✅ |
|
|
107
|
+
| Loop guard (forwarder host never intercepted) | ✅ |
|
|
108
|
+
| Python 3.7 – 3.13 | ✅ |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## How it works
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
|
|
116
|
+
│ Your Code │─req──▶│ telebot-proxy │─req──▶│ Forwarder Service│
|
|
117
|
+
│ (requests, │◀─res──│ (this lib) │◀─res──│ (your server) │
|
|
118
|
+
│ telebot, …) │ └──────────────┘ └───────┬──────────┘
|
|
119
|
+
└──────────────┘ │ req/res
|
|
120
|
+
▼
|
|
121
|
+
┌───────────────┐
|
|
122
|
+
│ Real Target │
|
|
123
|
+
│ (Telegram, │
|
|
124
|
+
│ OpenAI, …) │
|
|
125
|
+
└───────────────┘
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
1. You call `setup_proxy()` **once**, at startup.
|
|
129
|
+
2. The library monkey-patches `requests.Session.request`.
|
|
130
|
+
3. Matching HTTP requests are **rewritten** to go to your forwarder service.
|
|
131
|
+
4. The forwarder relays the request to the real destination and returns the response unchanged.
|
|
132
|
+
5. Your application code doesn't know the difference.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Installation
|
|
137
|
+
|
|
138
|
+
### From source
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
git clone https://github.com/yourname/telebot-proxy.git
|
|
142
|
+
cd telebot-proxy
|
|
143
|
+
pip install .
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Copy directly
|
|
147
|
+
|
|
148
|
+
Just copy the `telebot_proxy/` folder into your project. The only dependency is `requests` (which most projects already have).
|
|
149
|
+
|
|
150
|
+
### With Telegram bot library
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
pip install . pyTelegramBotAPI
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Quick Start
|
|
159
|
+
|
|
160
|
+
### 1. Telegram Bot (default)
|
|
161
|
+
|
|
162
|
+
Add **two lines** to the top of your bot file — before `import telebot`:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from telebot_proxy import setup_proxy
|
|
166
|
+
setup_proxy(proxy_token="YOUR_FORWARDER_TOKEN")
|
|
167
|
+
|
|
168
|
+
import telebot
|
|
169
|
+
|
|
170
|
+
bot = telebot.TeleBot("YOUR_BOT_TOKEN")
|
|
171
|
+
|
|
172
|
+
@bot.message_handler(commands=["start"])
|
|
173
|
+
def start(message):
|
|
174
|
+
bot.reply_to(message, "Hello from behind a proxy!")
|
|
175
|
+
|
|
176
|
+
bot.infinity_polling()
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 2. Proxy specific hosts
|
|
180
|
+
|
|
181
|
+
Route requests to selected APIs through the forwarder:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from telebot_proxy import setup_proxy
|
|
185
|
+
|
|
186
|
+
setup_proxy(
|
|
187
|
+
proxy_token="YOUR_FORWARDER_TOKEN",
|
|
188
|
+
hosts=["api.telegram.org", "api.openai.com", "httpbin.org"],
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
import requests
|
|
192
|
+
|
|
193
|
+
# This goes through the forwarder:
|
|
194
|
+
resp = requests.get("https://httpbin.org/ip")
|
|
195
|
+
print(resp.json())
|
|
196
|
+
|
|
197
|
+
# This goes DIRECTLY (not in the hosts list):
|
|
198
|
+
resp = requests.get("https://api.github.com/zen")
|
|
199
|
+
print(resp.text)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 3. Intercept ALL requests
|
|
203
|
+
|
|
204
|
+
Route **every** outgoing request through the forwarder:
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
from telebot_proxy import setup_proxy
|
|
208
|
+
|
|
209
|
+
setup_proxy(
|
|
210
|
+
proxy_token="YOUR_FORWARDER_TOKEN",
|
|
211
|
+
intercept_all=True,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
import requests
|
|
215
|
+
|
|
216
|
+
# ALL of these go through the forwarder:
|
|
217
|
+
requests.get("https://httpbin.org/ip")
|
|
218
|
+
requests.get("https://api.github.com/zen")
|
|
219
|
+
requests.post("https://any-api.example.com/data", json={"key": "value"})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
> **Loop guard:** Requests to the forwarder itself are never intercepted, preventing infinite loops.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Configuration
|
|
227
|
+
|
|
228
|
+
### `setup_proxy()` parameters
|
|
229
|
+
|
|
230
|
+
| Parameter | Type | Required | Default | Description |
|
|
231
|
+
|---|---|---|---|---|
|
|
232
|
+
| `proxy_token` | `str` | **Yes** | — | Auth token for the forwarder (`FORWARDER_TOKEN`). |
|
|
233
|
+
| `proxy_base_url` | `str` | No | `https://forwarder.only.ir` | Base URL of the forwarder service. |
|
|
234
|
+
| `hosts` | `list[str]` | No | `["api.telegram.org"]` | Hostnames to intercept. Ignored when `intercept_all=True`. |
|
|
235
|
+
| `intercept_all` | `bool` | No | `False` | If `True`, intercept ALL outgoing requests. |
|
|
236
|
+
| `extra_hosts` | `list[str]` | No | `None` | **Deprecated** — use `hosts`. Merges with the default Telegram host. |
|
|
237
|
+
|
|
238
|
+
### Using environment variables (recommended for production)
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
import os
|
|
242
|
+
from telebot_proxy import setup_proxy
|
|
243
|
+
|
|
244
|
+
setup_proxy(
|
|
245
|
+
proxy_token=os.environ["FORWARDER_TOKEN"],
|
|
246
|
+
proxy_base_url=os.environ.get("FORWARDER_URL", "https://forwarder.only.ir"),
|
|
247
|
+
# hosts=["api.telegram.org"], # specific hosts
|
|
248
|
+
# intercept_all=True, # or intercept everything
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
export FORWARDER_TOKEN="your_secret_token"
|
|
254
|
+
export FORWARDER_URL="https://your-forwarder.example.com" # optional
|
|
255
|
+
python your_bot.py
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Examples
|
|
261
|
+
|
|
262
|
+
See the [`examples/`](examples/) directory for complete, runnable scripts:
|
|
263
|
+
|
|
264
|
+
| File | Description |
|
|
265
|
+
|---|---|
|
|
266
|
+
| [`echo_bot.py`](examples/echo_bot.py) | Minimal Telegram echo bot |
|
|
267
|
+
| [`photo_bot.py`](examples/photo_bot.py) | Telegram bot — tests file uploads |
|
|
268
|
+
| [`env_bot.py`](examples/env_bot.py) | Production config via environment variables |
|
|
269
|
+
| [`webhook_bot.py`](examples/webhook_bot.py) | Telegram webhook mode (Flask) |
|
|
270
|
+
| [`toggle_proxy.py`](examples/toggle_proxy.py) | Enable / disable / switch modes at runtime |
|
|
271
|
+
| [`general_api_proxy.py`](examples/general_api_proxy.py) | Proxy non-Telegram APIs (httpbin, JSONPlaceholder) |
|
|
272
|
+
| [`intercept_all.py`](examples/intercept_all.py) | Intercept every outgoing request |
|
|
273
|
+
| [`mixed_bot.py`](examples/mixed_bot.py) | Telegram bot + external API, both proxied |
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## API Reference
|
|
278
|
+
|
|
279
|
+
### `setup_proxy(proxy_token, proxy_base_url=..., hosts=None, intercept_all=False)`
|
|
280
|
+
|
|
281
|
+
Activate the proxy. Call **once**, at startup, before making any requests.
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
# Default (Telegram only)
|
|
285
|
+
setup_proxy(proxy_token="tok")
|
|
286
|
+
|
|
287
|
+
# Custom hosts
|
|
288
|
+
setup_proxy(proxy_token="tok", hosts=["api.telegram.org", "httpbin.org"])
|
|
289
|
+
|
|
290
|
+
# Everything
|
|
291
|
+
setup_proxy(proxy_token="tok", intercept_all=True)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### `disable_proxy()`
|
|
295
|
+
|
|
296
|
+
Deactivate the proxy. All requests go directly to their targets.
|
|
297
|
+
|
|
298
|
+
### `is_active() -> bool`
|
|
299
|
+
|
|
300
|
+
Check if the proxy is currently active.
|
|
301
|
+
|
|
302
|
+
### `get_proxy_url() -> str`
|
|
303
|
+
|
|
304
|
+
Get the current forwarder base URL.
|
|
305
|
+
|
|
306
|
+
### `get_intercepted_hosts() -> set[str]`
|
|
307
|
+
|
|
308
|
+
Get the set of hostnames being intercepted. Returns an empty set when `intercept_all=True` (meaning everything is intercepted).
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Forwarder Service
|
|
313
|
+
|
|
314
|
+
telebot-proxy requires a **forwarder service** running on a server with unrestricted internet access. The forwarder receives requests, relays them to the real target, and returns the response.
|
|
315
|
+
|
|
316
|
+
### Expected endpoint
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
GET/POST/PUT/DELETE <base_url>/forward?url=<target_url>&<other_params>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Authentication
|
|
323
|
+
|
|
324
|
+
The library sends the token via **two** headers:
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
Authorization: Bearer <proxy_token>
|
|
328
|
+
X-Api-Token: <proxy_token>
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Minimal forwarder (Flask)
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
import requests as http_client
|
|
335
|
+
from flask import Flask, Response, jsonify, request
|
|
336
|
+
|
|
337
|
+
app = Flask(__name__)
|
|
338
|
+
AUTH_TOKEN = "your_secret_token"
|
|
339
|
+
|
|
340
|
+
def verify_token():
|
|
341
|
+
token = request.headers.get("X-Api-Token") or ""
|
|
342
|
+
bearer = request.headers.get("Authorization", "").replace("Bearer ", "")
|
|
343
|
+
return token == AUTH_TOKEN or bearer == AUTH_TOKEN
|
|
344
|
+
|
|
345
|
+
@app.route("/forward", methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
|
|
346
|
+
def forward():
|
|
347
|
+
if not verify_token():
|
|
348
|
+
return jsonify({"error": "Unauthorized"}), 401
|
|
349
|
+
|
|
350
|
+
target_url = request.args.get("url")
|
|
351
|
+
if not target_url:
|
|
352
|
+
return jsonify({"error": "Missing url parameter"}), 400
|
|
353
|
+
|
|
354
|
+
headers = {
|
|
355
|
+
k: v for k, v in request.headers.items()
|
|
356
|
+
if k.lower() not in {
|
|
357
|
+
"host", "authorization", "x-api-token",
|
|
358
|
+
"connection", "transfer-encoding",
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
params = {k: v for k, v in request.args.items() if k != "url"}
|
|
363
|
+
|
|
364
|
+
resp = http_client.request(
|
|
365
|
+
method=request.method,
|
|
366
|
+
url=target_url,
|
|
367
|
+
headers=headers,
|
|
368
|
+
params=params or None,
|
|
369
|
+
data=request.data if not request.is_json else None,
|
|
370
|
+
json=request.get_json(silent=True) if request.is_json else None,
|
|
371
|
+
timeout=60,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
return Response(
|
|
375
|
+
resp.content,
|
|
376
|
+
status=resp.status_code,
|
|
377
|
+
content_type=resp.headers.get("Content-Type"),
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
if __name__ == "__main__":
|
|
381
|
+
app.run(host="0.0.0.0", port=8080)
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Important: timeout
|
|
385
|
+
|
|
386
|
+
For Telegram bots using long polling, `getUpdates` can take up to **20 seconds**. Set the forwarder's timeout to **at least 30–60 seconds**.
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## FAQ
|
|
391
|
+
|
|
392
|
+
### Does this work with non-Telegram APIs?
|
|
393
|
+
|
|
394
|
+
**Yes!** Use the `hosts` parameter to specify any hostname, or `intercept_all=True` to proxy everything. It works with any library built on `requests`.
|
|
395
|
+
|
|
396
|
+
### Does this work with async telebot?
|
|
397
|
+
|
|
398
|
+
Currently it patches `requests.Session`, used by the **synchronous** `TeleBot`. For `AsyncTeleBot` (which uses `aiohttp`), a different approach would be needed — contributions welcome!
|
|
399
|
+
|
|
400
|
+
### Can I use this with other Python HTTP libraries?
|
|
401
|
+
|
|
402
|
+
Any library that internally uses `requests` will be intercepted automatically (e.g., many REST API wrappers). Libraries using `httpx` or `aiohttp` directly will **not** be intercepted.
|
|
403
|
+
|
|
404
|
+
### Is there any performance impact?
|
|
405
|
+
|
|
406
|
+
Each intercepted request adds one extra network hop. The added latency depends on the distance between your server and the forwarder.
|
|
407
|
+
|
|
408
|
+
### What about infinite loops?
|
|
409
|
+
|
|
410
|
+
The library has a built-in **loop guard**: requests to the forwarder's own hostname are never intercepted, even in `intercept_all` mode.
|
|
411
|
+
|
|
412
|
+
### How do I verify it's working?
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
from telebot_proxy import setup_proxy, is_active
|
|
416
|
+
import requests
|
|
417
|
+
|
|
418
|
+
setup_proxy(proxy_token="your_token", hosts=["httpbin.org"])
|
|
419
|
+
print(f"Proxy active: {is_active()}")
|
|
420
|
+
|
|
421
|
+
resp = requests.get("https://httpbin.org/ip")
|
|
422
|
+
print(resp.json()) # If this prints, it's working!
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## Running Tests
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
pip install -e ".[dev]"
|
|
431
|
+
pytest -v
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
24 passed in 0.20s
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## Project Structure
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
telebot-proxy/
|
|
444
|
+
├── telebot_proxy/ # Main package
|
|
445
|
+
│ ├── __init__.py # Public API
|
|
446
|
+
│ └── core.py # Monkey-patch engine
|
|
447
|
+
├── examples/ # Runnable examples
|
|
448
|
+
│ ├── echo_bot.py # Telegram echo bot
|
|
449
|
+
│ ├── photo_bot.py # Telegram photo bot
|
|
450
|
+
│ ├── env_bot.py # Environment variables
|
|
451
|
+
│ ├── webhook_bot.py # Webhook mode
|
|
452
|
+
│ ├── toggle_proxy.py # Runtime toggle
|
|
453
|
+
│ ├── general_api_proxy.py # Non-Telegram APIs
|
|
454
|
+
│ ├── intercept_all.py # Intercept everything
|
|
455
|
+
│ └── mixed_bot.py # Telegram + external API
|
|
456
|
+
├── tests/
|
|
457
|
+
│ └── test_core.py # 24 tests
|
|
458
|
+
├── pyproject.toml # Package config
|
|
459
|
+
├── requirements.txt
|
|
460
|
+
├── README.md
|
|
461
|
+
├── LICENSE # MIT
|
|
462
|
+
├── CHANGELOG.md
|
|
463
|
+
└── CONTRIBUTING.md
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Contributing
|
|
469
|
+
|
|
470
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## License
|
|
475
|
+
|
|
476
|
+
[MIT](LICENSE) — use it however you want.
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
<div dir="rtl">
|
|
483
|
+
|
|
484
|
+
## مستندات فارسی
|
|
485
|
+
|
|
486
|
+
### این کتابخانه چیست؟
|
|
487
|
+
|
|
488
|
+
این کتابخانه تمام درخواستهای HTTP ارسالشده از طریق کتابخانه `requests` پایتون را به صورت شفاف از طریق یک **سرویس واسط** (forwarder) ارسال میکند.
|
|
489
|
+
|
|
490
|
+
در ابتدا برای هدایت درخواستهای ربات تلگرام (`pyTelegramBotAPI`) طراحی شده، اما **برای هر API و سرویسی** قابل استفاده است.
|
|
491
|
+
|
|
492
|
+
### چرا نیاز است؟
|
|
493
|
+
|
|
494
|
+
در برخی شبکهها و سرورها، دسترسی مستقیم به برخی APIها (مثل `api.telegram.org`) مسدود یا ناپایدار است. با این کتابخانه، درخواستها از طریق سرویس واسطی که روی سروری با دسترسی آزاد قرار دارد ارسال میشوند.
|
|
495
|
+
|
|
496
|
+
### سه حالت کاری
|
|
497
|
+
|
|
498
|
+
| حالت | توضیح | کاربرد |
|
|
499
|
+
|---|---|---|
|
|
500
|
+
| **پیشفرض** | فقط `api.telegram.org` را رهگیری میکند | رباتهای تلگرام |
|
|
501
|
+
| **هاستهای انتخابی** | لیست دلخواه از هاستها | APIهای خاص |
|
|
502
|
+
| **همه درخواستها** | تمام درخواستهای خروجی | شبکههای کاملاً محدود |
|
|
503
|
+
|
|
504
|
+
### نصب
|
|
505
|
+
|
|
506
|
+
</div>
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
git clone https://github.com/yourname/telebot-proxy.git
|
|
510
|
+
cd telebot-proxy
|
|
511
|
+
pip install .
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
<div dir="rtl">
|
|
515
|
+
|
|
516
|
+
یا فقط پوشه <code>telebot_proxy/</code> را در پروژه خود کپی کنید.
|
|
517
|
+
|
|
518
|
+
### شروع سریع
|
|
519
|
+
|
|
520
|
+
#### حالت ۱: ربات تلگرام (پیشفرض)
|
|
521
|
+
|
|
522
|
+
فقط **دو خط** به بالای فایل ربات اضافه کنید — **قبل از** <code>import telebot</code>:
|
|
523
|
+
|
|
524
|
+
</div>
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
from telebot_proxy import setup_proxy
|
|
528
|
+
setup_proxy(proxy_token="توکن_سرویس_واسط")
|
|
529
|
+
|
|
530
|
+
import telebot
|
|
531
|
+
bot = telebot.TeleBot("توکن_ربات")
|
|
532
|
+
|
|
533
|
+
@bot.message_handler(commands=["start"])
|
|
534
|
+
def start(message):
|
|
535
|
+
bot.reply_to(message, "سلام! ربات از طریق پراکسی کار میکنه.")
|
|
536
|
+
|
|
537
|
+
bot.infinity_polling()
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
<div dir="rtl">
|
|
541
|
+
|
|
542
|
+
#### حالت ۲: هاستهای دلخواه
|
|
543
|
+
|
|
544
|
+
</div>
|
|
545
|
+
|
|
546
|
+
```python
|
|
547
|
+
from telebot_proxy import setup_proxy
|
|
548
|
+
|
|
549
|
+
setup_proxy(
|
|
550
|
+
proxy_token="توکن_سرویس_واسط",
|
|
551
|
+
hosts=["api.telegram.org", "api.openai.com", "httpbin.org"],
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
import requests
|
|
555
|
+
|
|
556
|
+
# این از پراکسی رد میشه:
|
|
557
|
+
resp = requests.get("https://httpbin.org/ip")
|
|
558
|
+
print(resp.json())
|
|
559
|
+
|
|
560
|
+
# این مستقیم ارسال میشه (توی لیست نیست):
|
|
561
|
+
resp = requests.get("https://api.github.com/zen")
|
|
562
|
+
print(resp.text)
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
<div dir="rtl">
|
|
566
|
+
|
|
567
|
+
#### حالت ۳: تمام درخواستها
|
|
568
|
+
|
|
569
|
+
</div>
|
|
570
|
+
|
|
571
|
+
```python
|
|
572
|
+
from telebot_proxy import setup_proxy
|
|
573
|
+
|
|
574
|
+
setup_proxy(
|
|
575
|
+
proxy_token="توکن_سرویس_واسط",
|
|
576
|
+
intercept_all=True,
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
import requests
|
|
580
|
+
|
|
581
|
+
# همه درخواستها از پراکسی رد میشن:
|
|
582
|
+
requests.get("https://httpbin.org/ip")
|
|
583
|
+
requests.get("https://api.github.com/zen")
|
|
584
|
+
requests.post("https://any-api.example.com/data", json={"key": "value"})
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
<div dir="rtl">
|
|
588
|
+
|
|
589
|
+
> **محافظت از حلقه:** درخواستهایی که مقصدشان خود سرویس واسط باشد هرگز رهگیری نمیشوند.
|
|
590
|
+
|
|
591
|
+
### پارامترهای `setup_proxy()`
|
|
592
|
+
|
|
593
|
+
| پارامتر | نوع | الزامی | پیشفرض | توضیحات |
|
|
594
|
+
|---|---|---|---|---|
|
|
595
|
+
| `proxy_token` | `str` | **بله** | — | توکن احراز هویت سرویس واسط. |
|
|
596
|
+
| `proxy_base_url` | `str` | خیر | `https://forwarder.only.ir` | آدرس پایه سرویس واسط. |
|
|
597
|
+
| `hosts` | `list[str]` | خیر | `["api.telegram.org"]` | هاستهایی که باید رهگیری شوند. وقتی `intercept_all=True` باشد نادیده گرفته میشود. |
|
|
598
|
+
| `intercept_all` | `bool` | خیر | `False` | اگر `True` باشد، تمام درخواستها رهگیری میشوند. |
|
|
599
|
+
| `extra_hosts` | `list[str]` | خیر | `None` | **منسوخ** — از `hosts` استفاده کنید. |
|
|
600
|
+
|
|
601
|
+
### استفاده با متغیرهای محیطی (توصیهشده)
|
|
602
|
+
|
|
603
|
+
</div>
|
|
604
|
+
|
|
605
|
+
```python
|
|
606
|
+
import os
|
|
607
|
+
from telebot_proxy import setup_proxy
|
|
608
|
+
|
|
609
|
+
setup_proxy(
|
|
610
|
+
proxy_token=os.environ["FORWARDER_TOKEN"],
|
|
611
|
+
proxy_base_url=os.environ.get("FORWARDER_URL", "https://forwarder.only.ir"),
|
|
612
|
+
# hosts=["api.telegram.org"], # هاستهای خاص
|
|
613
|
+
# intercept_all=True, # یا همه درخواستها
|
|
614
|
+
)
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
```bash
|
|
618
|
+
set FORWARDER_TOKEN=your_secret_token
|
|
619
|
+
set FORWARDER_URL=https://your-forwarder.example.com
|
|
620
|
+
python your_bot.py
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
<div dir="rtl">
|
|
624
|
+
|
|
625
|
+
### توابع
|
|
626
|
+
|
|
627
|
+
| تابع | توضیح |
|
|
628
|
+
|---|---|
|
|
629
|
+
| `setup_proxy(...)` | فعالسازی پراکسی. **یک بار** در ابتدای برنامه صدا بزنید. |
|
|
630
|
+
| `disable_proxy()` | غیرفعالسازی پراکسی. |
|
|
631
|
+
| `is_active()` | آیا پراکسی فعال است؟ |
|
|
632
|
+
| `get_proxy_url()` | آدرس فعلی سرویس واسط. |
|
|
633
|
+
| `get_intercepted_hosts()` | مجموعه هاستهای رهگیریشده. اگر `intercept_all=True` مجموعه خالی برمیگرداند (یعنی همه). |
|
|
634
|
+
|
|
635
|
+
### نمونهکدها
|
|
636
|
+
|
|
637
|
+
| فایل | توضیح |
|
|
638
|
+
|---|---|
|
|
639
|
+
| `echo_bot.py` | ربات ساده echo تلگرام |
|
|
640
|
+
| `photo_bot.py` | تست آپلود عکس |
|
|
641
|
+
| `env_bot.py` | استفاده از متغیرهای محیطی |
|
|
642
|
+
| `webhook_bot.py` | حالت webhook با Flask |
|
|
643
|
+
| `toggle_proxy.py` | فعال/غیرفعال کردن و تغییر حالت |
|
|
644
|
+
| `general_api_proxy.py` | پراکسی APIهای غیر تلگرام |
|
|
645
|
+
| `intercept_all.py` | رهگیری تمام درخواستها |
|
|
646
|
+
| `mixed_bot.py` | ربات تلگرام + API خارجی |
|
|
647
|
+
|
|
648
|
+
### نکات مهم
|
|
649
|
+
|
|
650
|
+
1. **`setup_proxy()` باید قبل از ساخت اشیاء `TeleBot` یا ارسال درخواست فراخوانی شود.**
|
|
651
|
+
|
|
652
|
+
2. **timeout سرویس واسط باید حداقل ۳۰ ثانیه باشد** — چون long-polling تلگرام پیشفرض ۲۰ ثانیه صبر میکند.
|
|
653
|
+
|
|
654
|
+
3. **توکنها را hard-code نکنید** — از متغیرهای محیطی استفاده کنید.
|
|
655
|
+
|
|
656
|
+
4. **این کتابخانه فقط برای تلگرام نیست** — هر کدی که از `requests` استفاده میکند با آن سازگار است.
|
|
657
|
+
|
|
658
|
+
### تست
|
|
659
|
+
|
|
660
|
+
</div>
|
|
661
|
+
|
|
662
|
+
```bash
|
|
663
|
+
pip install -e ".[dev]"
|
|
664
|
+
pytest -v
|
|
665
|
+
# 24 passed
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
<div dir="rtl">
|
|
669
|
+
|
|
670
|
+
### مجوز
|
|
671
|
+
|
|
672
|
+
[MIT](LICENSE) — آزادانه استفاده کنید.
|
|
673
|
+
|
|
674
|
+
</div>
|