mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-02-23 21:01:17 +00:00
Delete dead Flask-based PAL24 webhook server (app/external/pal24_webhook.py). PAL24 webhooks already handled by unified FastAPI server on port 8080. - Remove flask dependency from pyproject.toml and requirements.txt - Remove PAL24_WEBHOOK_PORT config (unused, FastAPI uses shared port) - Remove pal24_webhook module reference from log filter - Update docs: webhook example rewritten from Flask to FastAPI - Uninstall flask, werkzeug, blinker, itsdangerous
8.0 KiB
8.0 KiB
WebSocket и Webhooks для веб-админки
Обзор
Реализованы две системы для real-time обновлений и интеграций:
- WebSocket - для real-time обновлений в веб-админке
- Webhooks - для отправки событий во внешние системы
WebSocket
Подключение
WebSocket endpoint доступен по адресу: ws://your-api-host:port/ws
Для подключения требуется токен API (передается через query параметр):
const ws = new WebSocket('ws://localhost:8080/ws?token=YOUR_API_TOKEN');
// или
const ws = new WebSocket('ws://localhost:8080/ws?api_key=YOUR_API_TOKEN');
Формат сообщений
Входящие сообщения (от сервера)
{
"type": "connection",
"status": "connected",
"message": "WebSocket connection established"
}
{
"type": "user.created",
"payload": {
"user_id": 123,
"telegram_id": 456789,
"username": "testuser",
"first_name": "Test",
"last_name": "User",
"referral_code": "refABC123",
"referred_by_id": null
},
"timestamp": "2024-01-15T10:30:00"
}
Исходящие сообщения (от клиента)
Ping для keepalive:
{
"type": "ping"
}
Сервер ответит:
{
"type": "pong"
}
Поддерживаемые события
user.created- создан новый пользовательpayment.completed- завершен платеж (пополнение баланса)transaction.created- создана транзакцияticket.created- создан новый тикетticket.status_changed- изменен статус тикетаticket.message_added- добавлено новое сообщение в тикет (от пользователя или админа)
Webhooks
Создание webhook
POST /webhooks
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
{
"name": "My Webhook",
"url": "https://example.com/webhook",
"event_type": "user.created",
"secret": "optional-secret-for-signing",
"description": "Webhook для новых пользователей"
}
Поддерживаемые типы событий
user.created- создан новый пользовательpayment.completed- завершен платежtransaction.created- создана транзакцияticket.created- создан новый тикетticket.status_changed- изменен статус тикета
Формат payload
Webhook отправляет POST запрос с JSON payload:
{
"user_id": 123,
"telegram_id": 456789,
"username": "testuser",
"first_name": "Test",
"last_name": "User",
"referral_code": "refABC123",
"referred_by_id": null
}
Заголовки запроса
Content-Type: application/jsonX-Webhook-Event: user.created- тип событияX-Webhook-Id: 1- ID webhookX-Webhook-Signature: sha256=...- подпись (если указан secret)
Подпись payload
Если при создании webhook указан secret, payload подписывается с помощью HMAC-SHA256:
import hmac
import hashlib
signature = hmac.new(
secret.encode('utf-8'),
payload_json.encode('utf-8'),
hashlib.sha256
).hexdigest()
Заголовок: X-Webhook-Signature: sha256={signature}
Проверка подписи (пример на Python)
import hmac
import hashlib
import json
def verify_webhook_signature(payload: dict, signature_header: str, secret: str) -> bool:
payload_json = json.dumps(payload, sort_keys=True)
expected_signature = hmac.new(
secret.encode('utf-8'),
payload_json.encode('utf-8'),
hashlib.sha256
).hexdigest()
received_signature = signature_header.replace('sha256=', '')
return hmac.compare_digest(expected_signature, received_signature)
API эндпоинты
Список webhooks
GET /webhooks?event_type=user.created&is_active=true&limit=50&offset=0
Получить webhook
GET /webhooks/{webhook_id}
Обновить webhook
PATCH /webhooks/{webhook_id}
{
"name": "Updated Name",
"is_active": false
}
Удалить webhook
DELETE /webhooks/{webhook_id}
Статистика webhooks
GET /webhooks/stats
История доставок
GET /webhooks/{webhook_id}/deliveries?status=failed&limit=50&offset=0
Статусы доставки
pending- ожидает отправкиsuccess- успешно доставлен (HTTP 200-299)failed- ошибка доставки
Retry логика
В текущей реализации retry не реализован автоматически, но можно добавить через next_retry_at поле в WebhookDelivery.
Интеграция событий
События автоматически отправляются при:
- Создании пользователя (
app/database/crud/user.py::create_user) - Создании транзакции (
app/database/crud/transaction.py::create_transaction) - Создании тикета (
app/database/crud/ticket.py::create_ticket) - Изменении статуса тикета (
app/database/crud/ticket.py::update_ticket_status)
Примеры использования
JavaScript WebSocket клиент
const ws = new WebSocket('ws://localhost:8080/ws?token=YOUR_TOKEN');
ws.onopen = () => {
console.log('Connected');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Event:', data.type, data.payload);
if (data.type === 'user.created') {
// Обработка нового пользователя
updateDashboard(data.payload);
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected');
};
// Ping для keepalive
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }));
}
}, 30000);
Python Webhook receiver
from fastapi import FastAPI, Request, HTTPException
import hmac
import hashlib
import json
app = FastAPI()
WEBHOOK_SECRET = "your-secret"
@app.post('/webhook')
async def webhook(request: Request):
signature = request.headers.get('X-Webhook-Signature', '')
event_type = request.headers.get('X-Webhook-Event')
payload = await request.json()
# Проверка подписи
if not verify_signature(payload, signature, WEBHOOK_SECRET):
raise HTTPException(status_code=401, detail='Invalid signature')
# Обработка события
if event_type == 'user.created':
handle_new_user(payload)
elif event_type == 'payment.completed':
handle_payment(payload)
return {'status': 'ok'}
def verify_signature(payload, signature, secret):
payload_json = json.dumps(payload, sort_keys=True)
expected = hmac.new(
secret.encode(),
payload_json.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature.replace('sha256=', ''))
Безопасность
- WebSocket: Требует валидный API токен
- Webhooks:
- Используйте HTTPS для webhook URL
- Используйте secret для подписи payload
- Проверяйте подпись на стороне получателя
- Ограничьте IP адреса получателей (если возможно)
Мониторинг
- Проверяйте статистику webhooks через
/webhooks/stats - Просматривайте историю доставок через
/webhooks/{id}/deliveries - Мониторьте логи на наличие ошибок доставки