Webhooks - автоматическая доставка контента
Настройка Webhook, формат запроса, проверка HMAC-подписи. Примеры на Python, Node.js и PHP
Webhook позволяет автоматически получать сгенерированный контент на ваш сервер сразу после генерации. Taipy отправит POST-запрос с текстом и медиа-вложениями.
Как подключить
Перейдите в настройки проекта
Откройте нужный проект и перейдите в его настройки.
Добавьте канал публикации
В разделе «Каналы публикации» нажмите «Добавить канал» и выберите платформу «Custom API / Webhook».
Укажите URL и секрет
В поле «ID канала/чата» вставьте ваш URL-эндпоинт (например: https://example.com/webhook). В поле «Токен бота» вставьте ваш HMAC-секрет для подписи запросов.
Выберите канал в кампании
В настройках кампании выберите этот канал как канал публикации.
Формат POST-запроса
При каждом событии Taipy отправляет JSON:
{{
"event": "post.published",
"timestamp": "2026-04-05T12:00:00+05:00",
"data": {{
"task_id": 123,
"campaign_id": 456,
"campaign_name": "Мой блог",
"text": "Сгенерированный текст поста...",
"status": "PUBLISHED",
"post_type": "IMAGE",
"published_at": "2026-04-05T12:00:00+05:00",
"media": {{
"post_type": "IMAGE",
"images": [
{{
"url": "https://cdn.example.com/image.png?token=...",
"is_selected": true,
"in_album": false,
"source": "ai_generated"
}}
],
"video": null,
"documents": [],
"expires_in": 86400
}}
}}
}}expires_in секунд, по умолчанию 24 часа). Скачайте файлы на свой сервер до истечения срока.Типы событий
Пост успешно сгенерирован и отправлен через webhook
Генерация не выполнена - лимит тарифа исчерпан
Проверка HMAC-подписи
Каждый webhook-запрос подписывается HMAC-SHA256. Проверяйте подпись для защиты от подделки.
При каждом POST-запросе Taipy отправляет заголовки:
X-Taipy-Signature: sha256=<hex-дайджест>
X-Taipy-Event: post.publishedПодпись вычисляется как HMAC-SHA256(секрет, тело_запроса). Ваш секрет - значение из поля «Токен бота» при создании Webhook-канала.
Пример: Python (Flask)
import hmac, hashlib, requests
def verify_signature(payload_body: bytes, secret: str, signature_header: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
payload_body,
hashlib.sha256
).hexdigest()
received = signature_header.replace("sha256=", "")
return hmac.compare_digest(expected, received)
@app.route("/webhook", methods=["POST"])
def handle_webhook():
signature = request.headers.get("X-Taipy-Signature", "")
if not verify_signature(request.data, "ваш_секрет", signature):
return "Invalid signature", 403
data = request.json
post = data["data"]
print(f"Новый пост: {{post['text'][:100]}}...")
# Скачиваем медиа (ссылки временные - 24 часа!)
media = post.get("media")
if media:
for img in media.get("images", []):
resp = requests.get(img["url"], timeout=30)
# Сохраните resp.content на свой сервер
if media.get("video"):
resp = requests.get(media["video"]["url"], timeout=120)
for doc in media.get("documents", []):
resp = requests.get(doc["url"], timeout=60)
return "OK", 200Пример: Node.js (Express)
const crypto = require("crypto");
function verifySignature(payload, secret, signatureHeader) {{
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
const received = signatureHeader.replace("sha256=", "");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
);
}}
app.post("/webhook", express.raw({{ type: "*/*" }}), async (req, res) => {{
const sig = req.headers["x-taipy-signature"] || "";
if (!verifySignature(req.body, "ваш_секрет", sig)) {{
return res.status(403).send("Invalid signature");
}}
const data = JSON.parse(req.body);
const post = data.data;
console.log(`Новый пост: ${{post.text.slice(0, 100)}}...`);
if (post.media) {{
for (const img of post.media.images || []) {{
const resp = await fetch(img.url);
// Сохраните resp.body на свой сервер
}}
}}
res.sendStatus(200);
}});Пример: PHP
<?php
function verifySignature(string $payload, string $secret, string $header): bool {{
$expected = hash_hmac("sha256", $payload, $secret);
$received = str_replace("sha256=", "", $header);
return hash_equals($expected, $received);
}}
$payload = file_get_contents("php://input");
$signature = $_SERVER["HTTP_X_TAIPY_SIGNATURE"] ?? "";
if (!verifySignature($payload, "ваш_секрет", $signature)) {{
http_response_code(403);
die("Invalid signature");
}}
$data = json_decode($payload, true);
$post = $data["data"];
echo "Новый пост: " . mb_substr($post["text"], 0, 100) . "...\n";
// Скачиваем медиа (ссылки временные - 24 часа!)
if (isset($post["media"])) {{
foreach ($post["media"]["images"] ?? [] as $img) {{
$imageData = file_get_contents($img["url"]);
// Сохраните $imageData на свой сервер
}}
}}
http_response_code(200);Была ли эта статья полезной?
Спасибо за обратную связь!