# General Translation Platform: Вебхуки URL: https://generaltranslation.com/ru/docs/platform/orgs/webhooks.mdx --- title: Вебхуки description: Получайте уведомления в реальном времени, когда в вашей организации происходят события --- Вебхуки позволяют вашему приложению получать HTTP POST-запросы при наступлении событий в вашей организации, например когда завершается перевод файла или задача перевода. Вебхуки доступны на тарифе **Team** и выше. ## Настройка webhook 1. Перейдите в **Organization Settings → Webhooks** 2. Нажмите **Create Webhook** 3. Введите URL эндпоинта, на который должны приходить события (только HTTPS) 4. Выберите типы событий, на которые хотите подписаться 5. Нажмите **Create** После создания эндпоинта перейдите на страницу сведений о webhook и скопируйте секрет подписи. Этот секрет используется для проверки того, что входящие запросы действительно отправлены из General Translation. Для одной организации можно создать не более **5 webhook-эндпоинтов**. ## Типы событий | Event | Description | | --------------------------- | ------------------------------------------------------------------------------------------- | | `translated_file.completed` | Срабатывает, когда перевод файла завершён и файл готов к скачиванию | | `translated_file.edited` | Срабатывает, когда пользователь вручную редактирует переведённый файл в редакторе переводов | | `translation_job.completed` | Срабатывает, когда задача перевода завершена | Каждый эндпоинт может подписаться на один или несколько типов событий. Вы можете в любой момент обновить свои подписки на странице сведений о вебхуке. ## Формат полезной нагрузки Каждый webhook отправляется как 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` верхнего уровня — это стабильный идентификатор события, который можно использовать для дедупликации доставок на своей стороне. ## Проверка подписей Каждый запрос webhook включает три header для проверки подписи: | Header | Description | | ------------------- | ------------------------------------------------------------ | | `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. Вычислите HMAC-SHA256 с помощью вашего секрета подписи (декодируйте секрет из base64 после удаления префикса `whsec_`) 3. Закодируйте результат в base64 и сравните со значением подписи (после префикса `v1,`) 4. Убедитесь, что временная метка отличается от текущего времени не более чем на 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"]; // Проверка актуальности временной метки (допуск 5 минут) 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/) для вашего языка программирования, которая автоматически выполняет верификацию. ## Повторные попытки и доставка Вебхуки используют модель доставки **at-least-once**. Если ваша конечная точка не возвращает ответ `2xx` в течение 10 секунд, доставка повторяется с экспоненциальной задержкой до **10 попыток**. Вы также можете вручную повторить неудачную доставку на странице сведений о вебхуке в панели управления. ### Обработка дубликатов Поскольку доставка выполняется по модели «как минимум один раз», ваш endpoint может получить одно и то же событие несколько раз. Используйте поле `id` в payload для устранения дубликатов: ```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"); }); ``` ## Управление эндпоинтами На странице сведений о вебхуке можно: * **Включить/отключить** эндпоинт, не удаляя его * **Обновить** типы событий, на которые оформлена подписка * **Просмотреть историю доставок** и проверить отдельные попытки доставки * **Повторить** неудавшуюся доставку * **Показать** секрет подписи (чтобы снова скопировать его) * **Удалить** эндпоинт ## Лучшие практики * **Отвечайте быстро** — как можно скорее возвращайте ответ `2xx`, а затем обрабатывайте событие асинхронно. Долго выполняющиеся обработчики могут привести к тайм-аутам. * **Проверяйте подписи** — всегда проверяйте заголовок `webhook-signature`, прежде чем доверять полезной нагрузке. * **Обрабатывайте дубликаты** — сохраняйте идентификаторы уже обработанных событий и пропускайте дубликаты. * **Используйте HTTPS** — в продакшене эндпоинты вебхуков должны использовать HTTPS. * **Отслеживайте сбои** — периодически проверяйте историю доставки на наличие повторяющихся сбоев, которые могут указывать на проблему с вашим эндпоинтом. ## Разрешения Для управления конечными точками webhook требуется разрешение `org:webhooks:write`. Для просмотра истории доставок требуется разрешение `org:webhooks:read`. По умолчанию обе эти возможности есть у ролей **Owner** и **Admin**. Подробнее см. в разделе [Roles & Permissions](/docs/platform/orgs/roles).