# General Translation Platform: Вебхуки URL: https://generaltranslation.com/ru/docs/platform/dashboard/reference/webhooks.mdx --- title: Вебхуки description: Настройте эндпоинты вебхуков, проверяйте подписи и обрабатывайте события перевода от General Translation. --- Вебхуки отправляют события перевода в ваш бэкенд в виде подписанных HTTP POST-запросов. Используйте их, чтобы запускать собственные процессы при изменении файлов или задач. ## Создание вебхука [#create-webhook] 1. Перейдите в **Настройки организации > Вебхуки**. 2. Нажмите **Create Webhook**. 3. Введите URL эндпоинта, на который вы хотите получать события. URL должен использовать HTTPS. 4. Выберите типы событий, на которые хотите подписаться. 5. Нажмите **Create**. После создания эндпоинта откройте страницу сведений о вебхуке и скопируйте секрет подписи. Используйте этот секрет, чтобы проверять, что входящие запросы поступают от General Translation. Вы можете создать до **5 эндпоинтов вебхуков** в одной организации. ## Типы событий [#event-types] Каждый эндпоинт может быть подписан на один или несколько типов событий. Вы можете изменить подписки на странице сведений о вебхуке. * `translated_file.completed` срабатывает, когда формирование переведённого файла завершено и он готов к скачиванию. * `translated_file.edited` срабатывает, когда пользователь вручную редактирует переведённый файл в редакторе переводов. * `translation_job.completed` срабатывает, когда задача перевода завершена. ## Формат полезной нагрузки [#payload-format] Каждая отправка вебхука выполняется как HTTP POST-запрос с телом в формате JSON: ```json { "id": "evt_xxx", "type": "translated_file.completed", "created_at": "2026-04-30T12:00:00.000Z", "api_version": "2026-03-06.v1", "data": { "object": { "id": "file_xxx", "org_id": "org_xxx", "project_id": "project_xxx", "branch_id": "branch_xxx", "source_file_id": "src_xxx", "file_id": "file_xxx", "version_id": "ver_xxx", "locale": "fr", "file_format": "json", "data_format": null, "completed_at": "2026-04-30T12:00:00.000Z" } } } ``` Верхнеуровневый `id` — это стабильный идентификатор события, который можно использовать, чтобы отсеивать повторные доставки. ## Проверка подписей [#verify-signatures] Каждый запрос вебхука содержит три заголовка: * `webhook-id` — id события, например `evt_xxx`. * `webhook-timestamp` — Unix-метка времени в секундах, указывающая, когда был отправлен запрос. * `webhook-signature` — подпись вида `v1,`. Подпись соответствует спецификации [Standard Webhooks](https://www.standardwebhooks.com/). Чтобы проверить запрос: 1. Сформируйте строку `{webhook-id}.{webhook-timestamp}.{raw request body}`. 2. Удалите префикс `whsec_`, затем декодируйте секрет из Base64, чтобы получить ключ подписи. 3. Вычислите HMAC-SHA256 от полученной строки, используя декодированный ключ подписи. 4. Закодируйте результат в Base64. 5. Сравните его со значением подписи после префикса `v1,`. 6. Убедитесь, что метка времени отличается от текущего времени не более чем на 5 минут, чтобы предотвратить атаки повторного воспроизведения. ### Пример: Node.js ```js import crypto from "crypto"; function verifyWebhook(payload, headers, secret) { const msgId = headers["webhook-id"]; const timestamp = headers["webhook-timestamp"]; const signature = headers["webhook-signature"]; const now = Math.floor(Date.now() / 1000); if (Math.abs(now - parseInt(timestamp)) > 300) { throw new Error("Timestamp too old"); } const signingKey = Buffer.from(secret.replace("whsec_", ""), "base64"); const signedContent = `${msgId}.${timestamp}.${payload}`; const expected = crypto .createHmac("sha256", signingKey) .update(signedContent) .digest("base64"); const received = signature.split(",")[1]; if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) { throw new Error("Invalid signature"); } return JSON.parse(payload); } ``` Вы также можете использовать библиотеку [Standard Webhooks](https://www.standardwebhooks.com/) для своего языка программирования — она автоматически выполняет проверку. ## Повторные попытки и доставка [#handle-retries-delivery] Для вебхуков используется модель **at-least-once delivery**. Если ваш эндпоинт не возвращает ответ `2xx` в течение 10 секунд, система повторяет доставку с экспоненциальной задержкой, максимум **10 попыток**. Вы можете вручную повторить неудачную доставку со страницы сведений о вебхуке в Dashboard. ## Обработка повторных событий [#handle-duplicate-events] Поскольку доставка гарантируется как минимум один раз, ваш эндпоинт может получить одно и то же событие несколько раз. Используйте поле `id` в полезной нагрузке, чтобы устранить дубликаты. ```js app.post("/webhooks/gt", (req, res) => { const eventId = req.body.id; if (alreadyProcessed(eventId)) { return res.status(200).send("OK"); } // Обработка события... markProcessed(eventId); res.status(200).send("OK"); }); ``` ## Управление эндпоинтами [#manage-endpoints] На странице вебхука вы можете: * Включить или отключить эндпоинт, не удаляя его * Обновить типы событий, на которые вы подписаны * Просмотреть историю доставок * Просмотреть отдельные попытки доставки * Повторить неудачную попытку доставки * Показать секрет подписи * Удалить эндпоинт ## Рекомендации [#best-practices] * Быстро отправляйте ответ `2xx`, а затем обрабатывайте событие асинхронно. * Проверяйте заголовок `webhook-signature`, прежде чем доверять полезной нагрузке. * Сохраняйте ID уже обработанных событий и пропускайте дубликаты. * Используйте HTTPS для эндпоинтов вебхуков в production. * Проверяйте историю доставок на наличие повторяющихся сбоев. ## Разрешения [#permissions] Для управления эндпоинтами вебхуков требуется разрешение `org:webhooks:write`. Для просмотра истории доставок требуется разрешение `org:webhooks:read`. По умолчанию у роли **Admin** есть оба разрешения. Подробнее см. в разделе [роли и разрешения](/docs/platform/dashboard/reference/roles-and-permissions).