114 lines
6.2 KiB
Markdown
114 lines
6.2 KiB
Markdown
# Telegram Call Service
|
||
|
||
REST-сервис: `POST /call` → делает настоящий **1-на-1 звонок** (p2p call,
|
||
такой же, как обычный звонок в приложении Telegram — с гудком и ожиданием
|
||
ответа) указанному пользователю под вашим аккаунтом и озвучивает переданный
|
||
текст через TTS сразу после того, как вызываемый принял звонок.
|
||
|
||
## Как это устроено
|
||
|
||
Telegram Bot API **не умеет** звонить — это принципиальное ограничение платформы,
|
||
никакой код это не обойдёт. Настоящий голосовой звонок доступен только через
|
||
MTProto-аккаунт обычного пользователя (Pyrogram-форк `pyrofork` + `py-tgcalls`,
|
||
низкоуровневый биндинг `ntgcalls`).
|
||
|
||
Библиотека `py-tgcalls` делает это через `phone.requestCall` / `phone.acceptCall`
|
||
с DH key exchange — ровно тот же путь, которым идёт обычный звонок из
|
||
приложения. `play()` блокирует выполнение, пока собеседник не ответит (или не
|
||
истечёт `CALL_RING_TIMEOUT`), бросает `TimedOutAnswer` / `CallDeclined` /
|
||
`CallBusy`, если не дозвонились.
|
||
|
||
## ⚠️ Важно понимать риски
|
||
|
||
- Это автоматизация **личного аккаунта**, а не бота. Telegram может ограничить
|
||
или заблокировать аккаунт за автоматизированные действия, особенно при
|
||
частом/массовом использовании. Используйте выделенный номер, не основной.
|
||
- API_ID/API_HASH и session-файл дают полный доступ к аккаунту — храните
|
||
`.env` и `sessions/` так же бережно, как пароль.
|
||
- Не используйте это для звонков посторонним людям без их согласия.
|
||
- Звонок реально дозвонится только если у вызываемого аккаунта в
|
||
**Settings → Privacy and Security → Calls** разрешены звонки от вашего
|
||
аккаунта (например, "Everybody", или вы у него в контактах). Иначе Telegram
|
||
тихо отклонит попытку на уровне privacy — это ограничение платформы, не бага
|
||
сервиса.
|
||
|
||
## Настройка
|
||
|
||
### 1. Получить API_ID / API_HASH
|
||
|
||
https://my.telegram.org → API development tools → создать приложение.
|
||
|
||
### 2. Настроить .env
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# заполнить API_ID, API_HASH, PHONE_NUMBER, CALL_TARGET, API_TOKEN
|
||
```
|
||
|
||
`CALL_TARGET` — кому звонить по умолчанию: `@username` вызываемого аккаунта
|
||
(или его numeric user id). Убедитесь, что у вызывающего аккаунта этот
|
||
пользователь виден (например, есть в контактах) — иначе `resolve_peer` не
|
||
сможет найти адресата по username при первом обращении.
|
||
|
||
### 3. Один раз залогиниться (интерактивно, вне обычного запуска)
|
||
|
||
```bash
|
||
docker compose build
|
||
docker compose run --rm callsvc python scripts/login.py
|
||
```
|
||
|
||
Введите код из Telegram (и пароль 2FA, если включён). Session-файл сохранится
|
||
в `./sessions/` на хосте и будет переиспользоваться при обычном запуске.
|
||
|
||
### 4. Запуск сервиса
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
## API
|
||
|
||
### `GET /health`
|
||
|
||
Проверка живости.
|
||
|
||
### `POST /call`
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8000/call \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer $API_TOKEN" \
|
||
-d '{"text": "Внимание! Сработал алерт на проде."}'
|
||
```
|
||
|
||
Поля тела запроса:
|
||
|
||
| поле | обязательное | описание |
|
||
|--------|--------------|---------------------------------------------------------------------------|
|
||
| text | да | текст, который будет озвучен (TTS, до 2000 символов) |
|
||
| target | нет | `@username` или numeric user id вызываемого. Если не задан — берётся `CALL_TARGET` из `.env` |
|
||
|
||
Если `API_TOKEN` в `.env` не задан — заголовок `Authorization` не требуется.
|
||
|
||
Ответ (после того, как собеседник принял звонок и TTS проигрался):
|
||
|
||
```json
|
||
{"status": "called", "target": "@monster1025", "duration": 4.2}
|
||
```
|
||
|
||
Ошибки:
|
||
|
||
- `409` — не дозвонились: не ответили за `CALL_RING_TIMEOUT` секунд, отклонили,
|
||
заняты, звонок сброшен, либо звонок на эту цель уже идёт, либо `target`
|
||
резолвится в группу/канал (сервис звонит только пользователям).
|
||
- `401` — неверный/отсутствующий Bearer-токен (если `API_TOKEN` задан).
|
||
- `500` — прочие ошибки (см. логи `docker compose logs -f`).
|
||
|
||
## Ограничения текущей версии
|
||
|
||
- Один одновременный звонок на цель (защищено локом), параллельные запросы
|
||
на разные `target` обрабатываются независимо.
|
||
- Озвучка через gTTS требует исходящего доступа в интернет из контейнера.
|
||
- `POST /call` синхронно ждёт ответа на звонок (до `CALL_RING_TIMEOUT` сек) —
|
||
учитывайте это в таймауте клиента, который дёргает ручку.
|