telefeeds-sdk 0.2.4__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.
- telefeeds_sdk-0.2.4/.github/workflows/publish.yml +22 -0
- telefeeds_sdk-0.2.4/.gitignore +8 -0
- telefeeds_sdk-0.2.4/LICENSE +22 -0
- telefeeds_sdk-0.2.4/PKG-INFO +158 -0
- telefeeds_sdk-0.2.4/README.md +131 -0
- telefeeds_sdk-0.2.4/examples/pyrogram_and_aiogram.py +40 -0
- telefeeds_sdk-0.2.4/examples/pyrogram_client.py +17 -0
- telefeeds_sdk-0.2.4/examples/register_account.py +45 -0
- telefeeds_sdk-0.2.4/pyproject.toml +47 -0
- telefeeds_sdk-0.2.4/src/telefeeds/__init__.py +77 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_core/__init__.py +77 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_core/client.py +407 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_core/errors.py +188 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_core/models.py +87 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_generated/__init__.py +1 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_generated/telefeeds_gateway_v1_pb2.py +85 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_generated/telefeeds_gateway_v1_pb2.pyi +299 -0
- telefeeds_sdk-0.2.4/src/telefeeds/_generated/telefeeds_gateway_v1_pb2_grpc.py +410 -0
- telefeeds_sdk-0.2.4/src/telefeeds/proto/__init__.py +1 -0
- telefeeds_sdk-0.2.4/src/telefeeds/proto/telegram/__init__.py +1 -0
- telefeeds_sdk-0.2.4/src/telefeeds/proto/telegram/v1/__init__.py +1 -0
- telefeeds_sdk-0.2.4/src/telefeeds/proto/telegram/v1/gateway.proto +195 -0
- telefeeds_sdk-0.2.4/src/telefeeds/py.typed +1 -0
- telefeeds_sdk-0.2.4/src/telefeeds/pyrogram/__init__.py +12 -0
- telefeeds_sdk-0.2.4/src/telefeeds/pyrogram/app.py +371 -0
- telefeeds_sdk-0.2.4/src/telefeeds/pyrogram/client.py +331 -0
- telefeeds_sdk-0.2.4/src/telefeeds/pyrogram/registrar.py +333 -0
- telefeeds_sdk-0.2.4/src/telefeeds/pyrogram/session.py +146 -0
- telefeeds_sdk-0.2.4/tests/test_core_errors.py +70 -0
- telefeeds_sdk-0.2.4/tests/test_pyrogram_adapter.py +251 -0
- telefeeds_sdk-0.2.4/uv.lock +105 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment:
|
|
11
|
+
name: pypi
|
|
12
|
+
url: https://pypi.org/p/telefeeds-sdk
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- run: python -m pip install build
|
|
21
|
+
- run: python -m build
|
|
22
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Telefeeds
|
|
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.
|
|
22
|
+
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: telefeeds-sdk
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: Async Python SDK and Pyrogram-compatible client for Telefeeds
|
|
5
|
+
Project-URL: Documentation, https://telegram.telefeeds.ru/
|
|
6
|
+
Project-URL: Repository, https://github.com/opolonix/telefeeds-sdk
|
|
7
|
+
Author: Telefeeds
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: grpc,pyrogram,telefeeds,telegram
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Communications :: Chat
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: grpcio<2,>=1.83.1
|
|
24
|
+
Requires-Dist: protobuf<8,>=7.36.1
|
|
25
|
+
Requires-Dist: typing-extensions>=4.4
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# telefeeds-sdk
|
|
29
|
+
|
|
30
|
+
Python SDK для пользовательских Telegram-сессий, запущенных в Telefeeds. Пакет устанавливается как `telefeeds-sdk`, а импортируется как `telefeeds`.
|
|
31
|
+
|
|
32
|
+
SDK не устанавливает Pyrogram. Приложение само выбирает пакет, который предоставляет пространство имён `pyrogram`, например Kurigram:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install telefeeds-sdk kurigram
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Быстрый старт
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from pyrogram import Client, filters
|
|
42
|
+
from pyrogram.types import Message
|
|
43
|
+
from telefeeds.pyrogram import Telefeeds
|
|
44
|
+
|
|
45
|
+
app = Telefeeds(token="tfi_...")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@app.on_message(filters.incoming & filters.text)
|
|
49
|
+
async def incoming(client: Client, message: Message) -> None:
|
|
50
|
+
print(client.session_peer_id, message.chat.id, message.text)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
app.start()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Один объект `Telefeeds` держит один TLS gRPC-канал и создаёт отдельный экземпляр выбранного `pyrogram.Client` для каждой пользовательской сессии. Поэтому peer cache, `access_hash` и вызовы разных аккаунтов не смешиваются.
|
|
57
|
+
|
|
58
|
+
`tl_layer` автоматически берётся из `pyrogram.raw.all.layer`. ClientHub принимает слои 227–229:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
app = Telefeeds(token="tfi_...", tl_layer=228)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Подписки и переподключение
|
|
65
|
+
|
|
66
|
+
Параметры `interface` и `close_other` передаются при подписке:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
app = Telefeeds(token="tfi_...", interface=7, close_other=True)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Каналы одного `interface` делят апдейты между собой. Разные интерфейсы получают собственную копию каждого апдейта. `close_other=True` завершает уже открытые каналы этой интеграции и интерфейса.
|
|
73
|
+
|
|
74
|
+
При временной сетевой ошибке SDK переподключается без ограничения числа попыток. Задержка растёт от `reconnect_initial_delay=0.5` до `reconnect_max_delay=30.0` секунд. Явный отзыв через `close_other` не переподключает старый канал и поднимает `SubscriptionReplacedError`.
|
|
75
|
+
|
|
76
|
+
В асинхронном приложении:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
async with Telefeeds(token="tfi_...") as app:
|
|
80
|
+
await app.subscription_task
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Вызовы и медиа
|
|
84
|
+
|
|
85
|
+
В обработчике `client` уже связан с нужной сессией:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
await client.send_message("me", "hello")
|
|
89
|
+
await client.send_document("me", "archive.zip")
|
|
90
|
+
path = await client.download_media(message)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Вне обработчика клиент можно получить явно:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
client = await app.get_client(session_peer_id=123456789)
|
|
97
|
+
me = await client.get_me()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
ClientHub проверяет принадлежность `session_peer_id` интеграции перед каждым `Invoke`. Telegram RPC errors возвращаются как структурированные исключения. Загрузки разбиваются на части, имеют timeout и повтор конкретной части; `cdn_supported=False` устанавливается автоматически.
|
|
101
|
+
|
|
102
|
+
Ошибки ClientHub доступны как `GatewayError` с независимыми от grpcio полями `code: GatewayErrorCode` и `details`. Низкоуровневые `grpc.aio.AioRpcError` не выходят из SDK. Ожидаемые ошибки регистрации представлены отдельными классами:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from telefeeds import (
|
|
106
|
+
AuthorizationAttemptExpiredError,
|
|
107
|
+
InvalidAuthorizationCodeError,
|
|
108
|
+
InvalidAuthorizationPasswordError,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
session = await gateway.complete_password_authorization(authorization_id, password)
|
|
113
|
+
except InvalidAuthorizationPasswordError:
|
|
114
|
+
print("Неверный пароль")
|
|
115
|
+
except AuthorizationAttemptExpiredError:
|
|
116
|
+
print("Попытка авторизации истекла")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Полная иерархия начинается с `AuthorizationError`. Для сырого gRPC-клиента ClientHub передаёт стабильную причину в trailing metadata `telefeeds-error-code`; значения перечислены в `AuthorizationErrorCode` protobuf-контракта.
|
|
120
|
+
|
|
121
|
+
Низкоуровневый `TelefeedsClient` предоставляет `subscribe()`, `invoke_raw()`, `get_session_snapshots()` и RPC регистрации. Он работает с protobuf-моделями и не требует Pyrogram.
|
|
122
|
+
|
|
123
|
+
`SessionSnapshot.usage_days` содержит число UTC-дней использования сессии текущей интеграцией, а `last_usage_at` — начало последнего начисленного UTC-дня.
|
|
124
|
+
|
|
125
|
+
Для будущей повторной привязки уже существующей сессии контракт содержит `begin_existing_session_authorization()` и `complete_existing_session_authorization()`. Ответ сообщает способ подтверждения через `authorization_kind` и `code_provider`: Telegram Gateway или Telegram-бот, ссылку для получения кода и необходимость её открыть. Провайдеры пока не включены, поэтому эти два RPC возвращают gRPC `UNIMPLEMENTED`.
|
|
126
|
+
|
|
127
|
+
## Router и примеры
|
|
128
|
+
|
|
129
|
+
`Router` группирует обработчики и подключается через `app.include_router(router)`. Доступны штатные фильтры и типы установленного Pyrogram-совместимого пакета.
|
|
130
|
+
|
|
131
|
+
- [Минимальный Pyrogram-клиент](examples/pyrogram_client.py)
|
|
132
|
+
- [Telefeeds и aiogram в одном процессе](examples/pyrogram_and_aiogram.py)
|
|
133
|
+
- [Регистрация пользовательского аккаунта](examples/register_account.py)
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install telefeeds-sdk kurigram aiogram
|
|
137
|
+
export TELEFEEDS_TOKEN='tfi_...'
|
|
138
|
+
export TELEGRAM_BOT_TOKEN='123456:...'
|
|
139
|
+
python examples/pyrogram_and_aiogram.py
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Для регистрации интеграции должен быть разрешён доступ к пользовательским сессиям:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
export TELEFEEDS_TOKEN='tfi_...'
|
|
146
|
+
python examples/register_account.py
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Контракт gRPC v1 находится в [`telefeeds/proto/telegram/v1/gateway.proto`](src/telefeeds/proto/telegram/v1/gateway.proto). Публичный адрес: `telegram.telefeeds.ru:443`; авторизация передаётся как `authorization: Bearer <token>`.
|
|
150
|
+
|
|
151
|
+
## Сборка пакета
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
python -m build
|
|
155
|
+
twine check dist/*
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Публикация релиза запускается GitHub Actions после создания GitHub Release. Для неё нужен Trusted Publisher проекта `telefeeds-sdk` в PyPI.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# telefeeds-sdk
|
|
2
|
+
|
|
3
|
+
Python SDK для пользовательских Telegram-сессий, запущенных в Telefeeds. Пакет устанавливается как `telefeeds-sdk`, а импортируется как `telefeeds`.
|
|
4
|
+
|
|
5
|
+
SDK не устанавливает Pyrogram. Приложение само выбирает пакет, который предоставляет пространство имён `pyrogram`, например Kurigram:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install telefeeds-sdk kurigram
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Быстрый старт
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from pyrogram import Client, filters
|
|
15
|
+
from pyrogram.types import Message
|
|
16
|
+
from telefeeds.pyrogram import Telefeeds
|
|
17
|
+
|
|
18
|
+
app = Telefeeds(token="tfi_...")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@app.on_message(filters.incoming & filters.text)
|
|
22
|
+
async def incoming(client: Client, message: Message) -> None:
|
|
23
|
+
print(client.session_peer_id, message.chat.id, message.text)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
app.start()
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Один объект `Telefeeds` держит один TLS gRPC-канал и создаёт отдельный экземпляр выбранного `pyrogram.Client` для каждой пользовательской сессии. Поэтому peer cache, `access_hash` и вызовы разных аккаунтов не смешиваются.
|
|
30
|
+
|
|
31
|
+
`tl_layer` автоматически берётся из `pyrogram.raw.all.layer`. ClientHub принимает слои 227–229:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
app = Telefeeds(token="tfi_...", tl_layer=228)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Подписки и переподключение
|
|
38
|
+
|
|
39
|
+
Параметры `interface` и `close_other` передаются при подписке:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
app = Telefeeds(token="tfi_...", interface=7, close_other=True)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Каналы одного `interface` делят апдейты между собой. Разные интерфейсы получают собственную копию каждого апдейта. `close_other=True` завершает уже открытые каналы этой интеграции и интерфейса.
|
|
46
|
+
|
|
47
|
+
При временной сетевой ошибке SDK переподключается без ограничения числа попыток. Задержка растёт от `reconnect_initial_delay=0.5` до `reconnect_max_delay=30.0` секунд. Явный отзыв через `close_other` не переподключает старый канал и поднимает `SubscriptionReplacedError`.
|
|
48
|
+
|
|
49
|
+
В асинхронном приложении:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
async with Telefeeds(token="tfi_...") as app:
|
|
53
|
+
await app.subscription_task
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Вызовы и медиа
|
|
57
|
+
|
|
58
|
+
В обработчике `client` уже связан с нужной сессией:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
await client.send_message("me", "hello")
|
|
62
|
+
await client.send_document("me", "archive.zip")
|
|
63
|
+
path = await client.download_media(message)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Вне обработчика клиент можно получить явно:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
client = await app.get_client(session_peer_id=123456789)
|
|
70
|
+
me = await client.get_me()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
ClientHub проверяет принадлежность `session_peer_id` интеграции перед каждым `Invoke`. Telegram RPC errors возвращаются как структурированные исключения. Загрузки разбиваются на части, имеют timeout и повтор конкретной части; `cdn_supported=False` устанавливается автоматически.
|
|
74
|
+
|
|
75
|
+
Ошибки ClientHub доступны как `GatewayError` с независимыми от grpcio полями `code: GatewayErrorCode` и `details`. Низкоуровневые `grpc.aio.AioRpcError` не выходят из SDK. Ожидаемые ошибки регистрации представлены отдельными классами:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from telefeeds import (
|
|
79
|
+
AuthorizationAttemptExpiredError,
|
|
80
|
+
InvalidAuthorizationCodeError,
|
|
81
|
+
InvalidAuthorizationPasswordError,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
session = await gateway.complete_password_authorization(authorization_id, password)
|
|
86
|
+
except InvalidAuthorizationPasswordError:
|
|
87
|
+
print("Неверный пароль")
|
|
88
|
+
except AuthorizationAttemptExpiredError:
|
|
89
|
+
print("Попытка авторизации истекла")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Полная иерархия начинается с `AuthorizationError`. Для сырого gRPC-клиента ClientHub передаёт стабильную причину в trailing metadata `telefeeds-error-code`; значения перечислены в `AuthorizationErrorCode` protobuf-контракта.
|
|
93
|
+
|
|
94
|
+
Низкоуровневый `TelefeedsClient` предоставляет `subscribe()`, `invoke_raw()`, `get_session_snapshots()` и RPC регистрации. Он работает с protobuf-моделями и не требует Pyrogram.
|
|
95
|
+
|
|
96
|
+
`SessionSnapshot.usage_days` содержит число UTC-дней использования сессии текущей интеграцией, а `last_usage_at` — начало последнего начисленного UTC-дня.
|
|
97
|
+
|
|
98
|
+
Для будущей повторной привязки уже существующей сессии контракт содержит `begin_existing_session_authorization()` и `complete_existing_session_authorization()`. Ответ сообщает способ подтверждения через `authorization_kind` и `code_provider`: Telegram Gateway или Telegram-бот, ссылку для получения кода и необходимость её открыть. Провайдеры пока не включены, поэтому эти два RPC возвращают gRPC `UNIMPLEMENTED`.
|
|
99
|
+
|
|
100
|
+
## Router и примеры
|
|
101
|
+
|
|
102
|
+
`Router` группирует обработчики и подключается через `app.include_router(router)`. Доступны штатные фильтры и типы установленного Pyrogram-совместимого пакета.
|
|
103
|
+
|
|
104
|
+
- [Минимальный Pyrogram-клиент](examples/pyrogram_client.py)
|
|
105
|
+
- [Telefeeds и aiogram в одном процессе](examples/pyrogram_and_aiogram.py)
|
|
106
|
+
- [Регистрация пользовательского аккаунта](examples/register_account.py)
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pip install telefeeds-sdk kurigram aiogram
|
|
110
|
+
export TELEFEEDS_TOKEN='tfi_...'
|
|
111
|
+
export TELEGRAM_BOT_TOKEN='123456:...'
|
|
112
|
+
python examples/pyrogram_and_aiogram.py
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Для регистрации интеграции должен быть разрешён доступ к пользовательским сессиям:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
export TELEFEEDS_TOKEN='tfi_...'
|
|
119
|
+
python examples/register_account.py
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Контракт gRPC v1 находится в [`telefeeds/proto/telegram/v1/gateway.proto`](src/telefeeds/proto/telegram/v1/gateway.proto). Публичный адрес: `telegram.telefeeds.ru:443`; авторизация передаётся как `authorization: Bearer <token>`.
|
|
123
|
+
|
|
124
|
+
## Сборка пакета
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
python -m build
|
|
128
|
+
twine check dist/*
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Публикация релиза запускается GitHub Actions после создания GitHub Release. Для неё нужен Trusted Publisher проекта `telefeeds-sdk` в PyPI.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from aiogram import Bot, Dispatcher
|
|
5
|
+
from aiogram.filters import Command
|
|
6
|
+
from aiogram.types import Message as BotMessage
|
|
7
|
+
from pyrogram import Client, filters
|
|
8
|
+
from pyrogram.types import Message as UserMessage
|
|
9
|
+
|
|
10
|
+
from telefeeds.pyrogram import Telefeeds
|
|
11
|
+
|
|
12
|
+
telefeeds = Telefeeds(token=os.environ["TELEFEEDS_TOKEN"])
|
|
13
|
+
dispatcher = Dispatcher()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@telefeeds.on_message(filters.incoming & filters.text)
|
|
17
|
+
async def user_message(client: Client, message: UserMessage) -> None:
|
|
18
|
+
print("user", client.session_peer_id, message.text, flush=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dispatcher.message(Command("ping"))
|
|
22
|
+
async def bot_ping(message: BotMessage) -> None:
|
|
23
|
+
await message.answer("pong")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def main() -> None:
|
|
27
|
+
bot = Bot(token=os.environ["TELEGRAM_BOT_TOKEN"])
|
|
28
|
+
try:
|
|
29
|
+
async with telefeeds:
|
|
30
|
+
assert telefeeds.subscription_task is not None
|
|
31
|
+
await asyncio.gather(
|
|
32
|
+
telefeeds.subscription_task,
|
|
33
|
+
dispatcher.start_polling(bot),
|
|
34
|
+
)
|
|
35
|
+
finally:
|
|
36
|
+
await bot.session.close()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from pyrogram import Client, filters
|
|
4
|
+
from pyrogram.types import Message
|
|
5
|
+
|
|
6
|
+
from telefeeds.pyrogram import Telefeeds
|
|
7
|
+
|
|
8
|
+
app = Telefeeds(token=os.environ["TELEFEEDS_TOKEN"])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.on_message(filters.incoming & filters.text)
|
|
12
|
+
async def incoming(client: Client, message: Message) -> None:
|
|
13
|
+
print(client.session_peer_id, message.chat.id, message.text, flush=True)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
app.start()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
from getpass import getpass
|
|
4
|
+
|
|
5
|
+
from telefeeds import AuthorizationState, TelefeedsClient
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def main() -> None:
|
|
9
|
+
client = TelefeedsClient(
|
|
10
|
+
token=os.environ["TELEFEEDS_TOKEN"],
|
|
11
|
+
endpoint=os.getenv("TELEFEEDS_ENDPOINT", "telegram.telefeeds.ru:443"),
|
|
12
|
+
)
|
|
13
|
+
async with client:
|
|
14
|
+
phone_number = input("Номер телефона в международном формате: ").strip()
|
|
15
|
+
challenge = await client.begin_phone_authorization(phone_number)
|
|
16
|
+
print(f"Код отправлен, запрос действует до {challenge.expires_at}")
|
|
17
|
+
|
|
18
|
+
code = input("Код из Telegram: ").strip()
|
|
19
|
+
result = await client.complete_phone_authorization(
|
|
20
|
+
challenge.authorization_id,
|
|
21
|
+
code,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if result.state == AuthorizationState.PASSWORD_REQUIRED:
|
|
25
|
+
if result.password_hint:
|
|
26
|
+
print(f"Подсказка пароля: {result.password_hint}")
|
|
27
|
+
session = await client.complete_password_authorization(
|
|
28
|
+
challenge.authorization_id,
|
|
29
|
+
getpass("Пароль двухэтапной аутентификации: "),
|
|
30
|
+
)
|
|
31
|
+
elif result.state == AuthorizationState.AUTHORIZED and result.session:
|
|
32
|
+
session = result.session
|
|
33
|
+
else:
|
|
34
|
+
raise RuntimeError(
|
|
35
|
+
f"Неожиданное состояние авторизации: {result.state.name}"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
print(
|
|
39
|
+
f"Сессия зарегистрирована: peer_id={session.session_peer_id}, "
|
|
40
|
+
f"state={session.state}"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "telefeeds-sdk"
|
|
7
|
+
version = "0.2.4"
|
|
8
|
+
description = "Async Python SDK and Pyrogram-compatible client for Telefeeds"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Telefeeds" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["telegram", "pyrogram", "grpc", "telefeeds"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Framework :: AsyncIO",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Topic :: Communications :: Chat",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"grpcio>=1.83.1,<2",
|
|
31
|
+
"protobuf>=7.36.1,<8",
|
|
32
|
+
"typing-extensions>=4.4",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Documentation = "https://telegram.telefeeds.ru/"
|
|
37
|
+
Repository = "https://github.com/opolonix/telefeeds-sdk"
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.wheel]
|
|
40
|
+
packages = ["src/telefeeds"]
|
|
41
|
+
|
|
42
|
+
[tool.pytest.ini_options]
|
|
43
|
+
asyncio_mode = "auto"
|
|
44
|
+
testpaths = ["tests"]
|
|
45
|
+
|
|
46
|
+
[tool.ruff]
|
|
47
|
+
exclude = ["src/telefeeds/_generated"]
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from ._core import (
|
|
2
|
+
AuthorizationAttemptExpiredError,
|
|
3
|
+
AuthorizationAttemptForbiddenError,
|
|
4
|
+
AuthorizationAttemptNotFoundError,
|
|
5
|
+
AuthorizationChallenge,
|
|
6
|
+
AuthorizationCodeProvider,
|
|
7
|
+
AuthorizationCodeProviderKind,
|
|
8
|
+
AuthorizationCredentialsRequiredError,
|
|
9
|
+
AuthorizationError,
|
|
10
|
+
AuthorizationErrorCode,
|
|
11
|
+
AuthorizationKind,
|
|
12
|
+
AuthorizationPasswordNotExpectedError,
|
|
13
|
+
AuthorizationPermissionDeniedError,
|
|
14
|
+
AuthorizationProviderUnavailableError,
|
|
15
|
+
AuthorizationRateLimitedError,
|
|
16
|
+
AuthorizationResult,
|
|
17
|
+
AuthorizationSignUpRequiredError,
|
|
18
|
+
AuthorizationState,
|
|
19
|
+
BannedAuthorizationPhoneError,
|
|
20
|
+
ExpiredAuthorizationCodeError,
|
|
21
|
+
GatewayError,
|
|
22
|
+
GatewayErrorCode,
|
|
23
|
+
GatewayInvokeError,
|
|
24
|
+
InvalidAuthorizationAttemptError,
|
|
25
|
+
InvalidAuthorizationCodeError,
|
|
26
|
+
InvalidAuthorizationCredentialsError,
|
|
27
|
+
InvalidAuthorizationPasswordError,
|
|
28
|
+
InvalidAuthorizationPhoneError,
|
|
29
|
+
SessionRegistration,
|
|
30
|
+
SessionSnapshot,
|
|
31
|
+
SubscriptionReplacedError,
|
|
32
|
+
TelefeedsClient,
|
|
33
|
+
TelefeedsError,
|
|
34
|
+
TelegramRPCError,
|
|
35
|
+
UpdateEnvelope,
|
|
36
|
+
UserSessionAccessDisabledError,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"AuthorizationAttemptExpiredError",
|
|
41
|
+
"AuthorizationAttemptForbiddenError",
|
|
42
|
+
"AuthorizationAttemptNotFoundError",
|
|
43
|
+
"AuthorizationChallenge",
|
|
44
|
+
"AuthorizationCodeProvider",
|
|
45
|
+
"AuthorizationCodeProviderKind",
|
|
46
|
+
"AuthorizationCredentialsRequiredError",
|
|
47
|
+
"AuthorizationError",
|
|
48
|
+
"AuthorizationErrorCode",
|
|
49
|
+
"AuthorizationKind",
|
|
50
|
+
"AuthorizationPasswordNotExpectedError",
|
|
51
|
+
"AuthorizationPermissionDeniedError",
|
|
52
|
+
"AuthorizationProviderUnavailableError",
|
|
53
|
+
"AuthorizationRateLimitedError",
|
|
54
|
+
"AuthorizationResult",
|
|
55
|
+
"AuthorizationSignUpRequiredError",
|
|
56
|
+
"AuthorizationState",
|
|
57
|
+
"BannedAuthorizationPhoneError",
|
|
58
|
+
"ExpiredAuthorizationCodeError",
|
|
59
|
+
"GatewayError",
|
|
60
|
+
"GatewayErrorCode",
|
|
61
|
+
"GatewayInvokeError",
|
|
62
|
+
"InvalidAuthorizationAttemptError",
|
|
63
|
+
"InvalidAuthorizationCodeError",
|
|
64
|
+
"InvalidAuthorizationCredentialsError",
|
|
65
|
+
"InvalidAuthorizationPasswordError",
|
|
66
|
+
"InvalidAuthorizationPhoneError",
|
|
67
|
+
"SessionRegistration",
|
|
68
|
+
"SessionSnapshot",
|
|
69
|
+
"SubscriptionReplacedError",
|
|
70
|
+
"TelefeedsClient",
|
|
71
|
+
"TelefeedsError",
|
|
72
|
+
"TelegramRPCError",
|
|
73
|
+
"UpdateEnvelope",
|
|
74
|
+
"UserSessionAccessDisabledError",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
__version__ = "0.2.4"
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from .client import TelefeedsClient
|
|
2
|
+
from .errors import (
|
|
3
|
+
AuthorizationAttemptExpiredError,
|
|
4
|
+
AuthorizationAttemptForbiddenError,
|
|
5
|
+
AuthorizationAttemptNotFoundError,
|
|
6
|
+
AuthorizationCredentialsRequiredError,
|
|
7
|
+
AuthorizationError,
|
|
8
|
+
AuthorizationErrorCode,
|
|
9
|
+
AuthorizationPasswordNotExpectedError,
|
|
10
|
+
AuthorizationPermissionDeniedError,
|
|
11
|
+
AuthorizationProviderUnavailableError,
|
|
12
|
+
AuthorizationRateLimitedError,
|
|
13
|
+
AuthorizationSignUpRequiredError,
|
|
14
|
+
BannedAuthorizationPhoneError,
|
|
15
|
+
ExpiredAuthorizationCodeError,
|
|
16
|
+
GatewayError,
|
|
17
|
+
GatewayErrorCode,
|
|
18
|
+
GatewayInvokeError,
|
|
19
|
+
InvalidAuthorizationAttemptError,
|
|
20
|
+
InvalidAuthorizationCodeError,
|
|
21
|
+
InvalidAuthorizationCredentialsError,
|
|
22
|
+
InvalidAuthorizationPasswordError,
|
|
23
|
+
InvalidAuthorizationPhoneError,
|
|
24
|
+
SubscriptionReplacedError,
|
|
25
|
+
TelefeedsError,
|
|
26
|
+
TelegramRPCError,
|
|
27
|
+
UserSessionAccessDisabledError,
|
|
28
|
+
)
|
|
29
|
+
from .models import (
|
|
30
|
+
AuthorizationChallenge,
|
|
31
|
+
AuthorizationCodeProvider,
|
|
32
|
+
AuthorizationCodeProviderKind,
|
|
33
|
+
AuthorizationKind,
|
|
34
|
+
AuthorizationResult,
|
|
35
|
+
AuthorizationState,
|
|
36
|
+
SessionRegistration,
|
|
37
|
+
SessionSnapshot,
|
|
38
|
+
UpdateEnvelope,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
"AuthorizationAttemptExpiredError",
|
|
43
|
+
"AuthorizationAttemptForbiddenError",
|
|
44
|
+
"AuthorizationAttemptNotFoundError",
|
|
45
|
+
"AuthorizationChallenge",
|
|
46
|
+
"AuthorizationCodeProvider",
|
|
47
|
+
"AuthorizationCodeProviderKind",
|
|
48
|
+
"AuthorizationCredentialsRequiredError",
|
|
49
|
+
"AuthorizationError",
|
|
50
|
+
"AuthorizationErrorCode",
|
|
51
|
+
"AuthorizationKind",
|
|
52
|
+
"AuthorizationPasswordNotExpectedError",
|
|
53
|
+
"AuthorizationPermissionDeniedError",
|
|
54
|
+
"AuthorizationProviderUnavailableError",
|
|
55
|
+
"AuthorizationRateLimitedError",
|
|
56
|
+
"AuthorizationResult",
|
|
57
|
+
"AuthorizationSignUpRequiredError",
|
|
58
|
+
"AuthorizationState",
|
|
59
|
+
"BannedAuthorizationPhoneError",
|
|
60
|
+
"ExpiredAuthorizationCodeError",
|
|
61
|
+
"GatewayError",
|
|
62
|
+
"GatewayErrorCode",
|
|
63
|
+
"GatewayInvokeError",
|
|
64
|
+
"InvalidAuthorizationAttemptError",
|
|
65
|
+
"InvalidAuthorizationCodeError",
|
|
66
|
+
"InvalidAuthorizationCredentialsError",
|
|
67
|
+
"InvalidAuthorizationPasswordError",
|
|
68
|
+
"InvalidAuthorizationPhoneError",
|
|
69
|
+
"SessionRegistration",
|
|
70
|
+
"SessionSnapshot",
|
|
71
|
+
"SubscriptionReplacedError",
|
|
72
|
+
"TelefeedsClient",
|
|
73
|
+
"TelefeedsError",
|
|
74
|
+
"TelegramRPCError",
|
|
75
|
+
"UpdateEnvelope",
|
|
76
|
+
"UserSessionAccessDisabledError",
|
|
77
|
+
]
|