init commit
This commit is contained in:
381
docs/TELETHON.md
Normal file
381
docs/TELETHON.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# Телетон (Telethon) - Справочник
|
||||
|
||||
## Обзор
|
||||
|
||||
**Telethon** - это Python библиотека для взаимодействия с Telegram API как обычный пользователь (клиент), а не как бот.
|
||||
|
||||
Это позволяет отправлять сообщения в группы, где боты не имеют прав на отправку.
|
||||
|
||||
## Установка и Настройка
|
||||
|
||||
### 1. Получение API Credentials
|
||||
|
||||
Перейти на https://my.telegram.org/apps и:
|
||||
- Войти в свой аккаунт Telegram
|
||||
- Создать приложение (или использовать существующее)
|
||||
- Скопировать `API ID` и `API HASH`
|
||||
|
||||
### 2. Обновление .env
|
||||
|
||||
```env
|
||||
USE_TELETHON=true
|
||||
TELETHON_API_ID=123456
|
||||
TELETHON_API_HASH=abcdef1234567890
|
||||
TELETHON_PHONE=+79991234567
|
||||
```
|
||||
|
||||
### 3. Первый Запуск
|
||||
|
||||
При первом запуске бота Telethon создаст сессию и попросит ввести код подтверждения:
|
||||
|
||||
```
|
||||
Telethon需要验证您的帐户...
|
||||
Введите код подтверждения из Telegram: ______
|
||||
```
|
||||
|
||||
Код придет в Telegram личные сообщения.
|
||||
|
||||
## Гибридный Режим
|
||||
|
||||
Когда `USE_TELETHON=true`, бот работает в **гибридном режиме**:
|
||||
|
||||
1. **Сначала** пытается отправить как бот
|
||||
2. **При ошибке** (бот заблокирован) пытается отправить как Telethon клиент
|
||||
3. **Автоматически** отслеживает какой способ работает и его использует
|
||||
|
||||
```python
|
||||
# Автоматическое переключение
|
||||
success, method = await hybrid_sender.send_message(
|
||||
chat_id="-1001234567890",
|
||||
message_text="Привет!"
|
||||
)
|
||||
|
||||
if method == "bot":
|
||||
print("Отправлено как бот ✅")
|
||||
elif method == "client":
|
||||
print("Отправлено как Telethon клиент ✅")
|
||||
```
|
||||
|
||||
## Основной API
|
||||
|
||||
### Инициализация
|
||||
|
||||
```python
|
||||
from app.handlers.telethon_client import telethon_manager
|
||||
|
||||
# Инициализировать
|
||||
await telethon_manager.initialize()
|
||||
|
||||
# Проверить подключение
|
||||
if telethon_manager.is_connected():
|
||||
print("Telethon подключен")
|
||||
|
||||
# Завершить
|
||||
await telethon_manager.shutdown()
|
||||
```
|
||||
|
||||
### Отправка Сообщений
|
||||
|
||||
```python
|
||||
# Простая отправка
|
||||
message_id = await telethon_manager.send_message(
|
||||
chat_id=-1001234567890,
|
||||
text="Привет мир!",
|
||||
parse_mode="html",
|
||||
disable_web_page_preview=True
|
||||
)
|
||||
|
||||
if message_id:
|
||||
print(f"Сообщение отправлено: {message_id}")
|
||||
```
|
||||
|
||||
### Получение Информации о Группе
|
||||
|
||||
```python
|
||||
# Получить информацию
|
||||
info = await telethon_manager.get_chat_info(chat_id)
|
||||
|
||||
if info:
|
||||
print(f"Название: {info['title']}")
|
||||
print(f"Описание: {info['description']}")
|
||||
print(f"Участников: {info['members_count']}")
|
||||
```
|
||||
|
||||
### Получение Участников
|
||||
|
||||
```python
|
||||
# Получить список участников
|
||||
members = await telethon_manager.get_chat_members(
|
||||
chat_id=-1001234567890,
|
||||
limit=100
|
||||
)
|
||||
|
||||
for member in members:
|
||||
print(f"{member['first_name']} (@{member['username']})")
|
||||
```
|
||||
|
||||
### Поиск Сообщений
|
||||
|
||||
```python
|
||||
# Найти сообщения
|
||||
messages = await telethon_manager.search_messages(
|
||||
chat_id=-1001234567890,
|
||||
query="python",
|
||||
limit=50
|
||||
)
|
||||
|
||||
for msg in messages:
|
||||
print(f"[{msg['date']}] {msg['text']}")
|
||||
```
|
||||
|
||||
### Редактирование и Удаление
|
||||
|
||||
```python
|
||||
# Отредактировать
|
||||
msg_id = await telethon_manager.edit_message(
|
||||
chat_id=-1001234567890,
|
||||
message_id=123,
|
||||
text="Новый текст"
|
||||
)
|
||||
|
||||
# Удалить
|
||||
success = await telethon_manager.delete_message(
|
||||
chat_id=-1001234567890,
|
||||
message_id=123
|
||||
)
|
||||
```
|
||||
|
||||
## Массовая Отправка
|
||||
|
||||
```python
|
||||
from app.handlers.hybrid_sender import HybridMessageSender
|
||||
|
||||
sender = HybridMessageSender(bot, db_session)
|
||||
|
||||
# Отправить с retry логикой
|
||||
success, method = await sender.send_message_with_retry(
|
||||
chat_id="-1001234567890",
|
||||
message_text="Важное сообщение",
|
||||
max_retries=3
|
||||
)
|
||||
|
||||
# Массовая отправка
|
||||
results = await sender.bulk_send(
|
||||
chat_ids=chat_ids,
|
||||
message_text="Привет всем!",
|
||||
use_slow_mode=True
|
||||
)
|
||||
|
||||
print(f"Успешно: {results['success']}")
|
||||
print(f"Через бот: {results['via_bot']}")
|
||||
print(f"Через клиент: {results['via_client']}")
|
||||
```
|
||||
|
||||
## Парсинг Групп
|
||||
|
||||
```python
|
||||
from app.handlers.group_parser import GroupParser
|
||||
|
||||
parser = GroupParser(db_session)
|
||||
|
||||
# Парсить группу по ключевым словам
|
||||
result = await parser.parse_group_by_keywords(
|
||||
keywords=["Python", "Django"],
|
||||
chat_id=-1001234567890
|
||||
)
|
||||
|
||||
if result['matched']:
|
||||
print(f"✅ Группа соответствует! Найдено: {result['keywords_found']}")
|
||||
|
||||
# Загрузить участников
|
||||
members_result = await parser.parse_group_members(
|
||||
chat_id=-1001234567890,
|
||||
member_repo=member_repo,
|
||||
limit=1000
|
||||
)
|
||||
|
||||
print(f"Загружено участников: {members_result['members_added']}")
|
||||
```
|
||||
|
||||
## Обработка Ошибок
|
||||
|
||||
### FloodWait
|
||||
|
||||
Telegram ограничивает частоту операций. Telethon автоматически обрабатывает:
|
||||
|
||||
```python
|
||||
from telethon.errors import FloodWaitError
|
||||
|
||||
try:
|
||||
await telethon_manager.send_message(chat_id, text)
|
||||
except FloodWaitError as e:
|
||||
print(f"Нужно ждать {e.seconds} секунд")
|
||||
# Гибридный отправитель автоматически ждет и повторяет
|
||||
```
|
||||
|
||||
### ChatAdminRequired
|
||||
|
||||
Клиент не администратор в этой группе:
|
||||
|
||||
```python
|
||||
from telethon.errors import ChatAdminRequiredError
|
||||
|
||||
try:
|
||||
members = await telethon_manager.get_chat_members(chat_id)
|
||||
except ChatAdminRequiredError:
|
||||
print("Клиент не администратор")
|
||||
```
|
||||
|
||||
### UserNotParticipant
|
||||
|
||||
Клиент не участник группы:
|
||||
|
||||
```python
|
||||
from telethon.errors import UserNotParticipantError
|
||||
|
||||
try:
|
||||
info = await telethon_manager.get_chat_info(chat_id)
|
||||
except UserNotParticipantError:
|
||||
print("Клиент не в этой группе")
|
||||
```
|
||||
|
||||
## Статистика и Мониторинг
|
||||
|
||||
Система автоматически отслеживает:
|
||||
|
||||
- Какие группы работают с ботом
|
||||
- Какие требуют Telethon клиента
|
||||
- Сколько сообщений отправлено каждым методом
|
||||
- Ошибки и ограничения
|
||||
|
||||
```python
|
||||
stats = await stats_repo.get_statistics(group_id)
|
||||
|
||||
if stats:
|
||||
print(f"Всего участников: {stats.total_members}")
|
||||
print(f"Отправлено сообщений: {stats.messages_sent}")
|
||||
print(f"Через клиент: {stats.messages_via_client}")
|
||||
print(f"Может отправлять как бот: {'✅' if stats.can_send_as_bot else '❌'}")
|
||||
print(f"Может отправлять как клиент: {'✅' if stats.can_send_as_client else '❌'}")
|
||||
```
|
||||
|
||||
## Лучшие Практики
|
||||
|
||||
### 1. Используйте Гибридный Режим
|
||||
|
||||
Всегда включайте оба метода доставки:
|
||||
|
||||
```env
|
||||
USE_TELETHON=true
|
||||
USE_CLIENT_WHEN_BOT_FAILS=true
|
||||
```
|
||||
|
||||
### 2. Минимизируйте Частоту Запросов
|
||||
|
||||
```python
|
||||
# Плохо
|
||||
for group_id in groups:
|
||||
info = await telethon_manager.get_chat_info(group_id)
|
||||
|
||||
# Хорошо - кэшируйте информацию
|
||||
info_cache = {}
|
||||
for group_id in groups:
|
||||
if group_id not in info_cache:
|
||||
info_cache[group_id] = await telethon_manager.get_chat_info(group_id)
|
||||
```
|
||||
|
||||
### 3. Обработайте FloodWait
|
||||
|
||||
```python
|
||||
# Гибридный отправитель уже это делает, но вы можете добавить свою логику
|
||||
success, method = await sender.send_message_with_retry(
|
||||
chat_id=chat_id,
|
||||
message_text=text,
|
||||
max_retries=5 # Увеличить количество попыток
|
||||
)
|
||||
```
|
||||
|
||||
### 4. Логируйте Действия
|
||||
|
||||
```python
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
logger.info(f"Загружаю участников группы {chat_id}...")
|
||||
members = await telethon_manager.get_chat_members(chat_id)
|
||||
logger.info(f"✅ Загружено {len(members)} участников")
|
||||
```
|
||||
|
||||
## Переменные Конфигурации
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
|---|---|---|
|
||||
| `USE_TELETHON` | false | Включить Telethon |
|
||||
| `TELETHON_API_ID` | - | API ID с my.telegram.org |
|
||||
| `TELETHON_API_HASH` | - | API HASH с my.telegram.org |
|
||||
| `TELETHON_PHONE` | - | Номер телефона с кодом (+7...) |
|
||||
| `TELETHON_FLOOD_WAIT_MAX` | 60 | Макс. ждать при FloodWait (сек) |
|
||||
| `MIN_SEND_INTERVAL` | 0.5 | Интервал между отправками (сек) |
|
||||
|
||||
## Отладка
|
||||
|
||||
### Проверить подключение
|
||||
|
||||
```python
|
||||
# В Python REPL или скрипте
|
||||
python -c "
|
||||
import asyncio
|
||||
from app.handlers.telethon_client import telethon_manager
|
||||
|
||||
async def test():
|
||||
await telethon_manager.initialize()
|
||||
if telethon_manager.is_connected():
|
||||
print('✅ Telethon подключен')
|
||||
else:
|
||||
print('❌ Telethon не подключен')
|
||||
await telethon_manager.shutdown()
|
||||
|
||||
asyncio.run(test())
|
||||
"
|
||||
```
|
||||
|
||||
### Логи
|
||||
|
||||
Logирование выполняется автоматически:
|
||||
|
||||
```python
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
```
|
||||
|
||||
Смотрите `app/handlers/telethon_client.py` для деталей логирования.
|
||||
|
||||
## Важные Замечания
|
||||
|
||||
⚠️ **Безопасность Аккаунта**
|
||||
|
||||
- Никогда не делитесь `TELETHON_API_HASH`
|
||||
- Сессия сохраняется в `app/sessions/telethon_session`
|
||||
- Защитите файл сессии доступом (не добавляйте в git!)
|
||||
|
||||
⚠️ **Ограничения Telegram**
|
||||
|
||||
- Частые отправки могут привести к временной блокировке (FloodWait)
|
||||
- Используйте `MIN_SEND_INTERVAL` для управления частотой
|
||||
- Не превышайте лимиты Telegram API
|
||||
|
||||
⚠️ **Первый Запуск**
|
||||
|
||||
Потребуется интерактивный ввод кода подтверждения. Для production используйте:
|
||||
|
||||
```python
|
||||
# Генерировать заранее в безопасном окружении
|
||||
await telethon_manager.initialize()
|
||||
```
|
||||
|
||||
## Полезные Ссылки
|
||||
|
||||
- [Telethon Документация](https://docs.telethon.dev/)
|
||||
- [Telegram Bot API](https://core.telegram.org/bots/api)
|
||||
- [Получить API Credentials](https://my.telegram.org/apps)
|
||||
- [Типы Ошибок Telethon](https://docs.telethon.dev/en/stable/modules/errors.html)
|
||||
Reference in New Issue
Block a user