Centre d’aide Allocyn

Webhooks

Envoyez des notifications HTTPS sortantes à un service que vous contrôlez lorsque des événements métier Allocyn pris en charge se produisent, et vérifiez chaque notification avant de l’accepter.

Guide pas à pas

Qui peut le faire : La consultation des webhooks nécessite integrations.view ; leur création, modification, suppression et envoi manuel nécessitent également integrations.manage. Les règles d’accès liées au module, à l’abonnement et aux intégrations s’appliquent.

Avant de commencer

  • Un récepteur HTTPS contrôlé par votre organisation, utilisant son URL finale plutôt qu’une redirection.
  • Un stockage sécurisé des secrets côté serveur, la vérification de signature sur le corps brut, une détection persistante des doublons et une surveillance. Lisez les limites actuelles avant de vous fier à la livraison.

Étapes

  1. Sélectionnez la bonne organisation et ouvrez Intégrations → Webhooks sur /administration/integrations.
  2. Choisissez Nouveau webhook, saisissez un nom descriptif et un point de terminaison HTTPS, puis sélectionnez au moins un événement pris en charge.
  3. Sélectionnez Actif lorsque votre récepteur est prêt, puis Enregistrer le webhook. Copiez le secret de signature révélé dans le stockage sécurisé des secrets de votre récepteur.
  4. Utilisez un événement réel, contrôlé et sans conséquence dans un espace de travail de test pour vérifier la livraison automatique. L’enregistrement ne teste pas la connectivité et l’interface actuelle ne dispose pas de bouton dédié à un envoi de test.

Résultat attendu

Votre récepteur peut vérifier et accepter les notifications d’événements auxquels il est abonné, sous réserve des limites de livraison et des sources d’événements prises en charge.

Action suivante

Mettez en place la vérification des signatures et l’idempotence, surveillez les échecs de livraison et rapprochez les données critiques indépendamment des notifications.

Accès et configuration du point de terminaison

Il s’agit de notifications client sortantes, distinctes de la synchronisation entrante des fournisseurs et des rappels du prestataire de facturation. Une clé API n’autorise pas la gestion des webhooks. L’enregistrement ou l’envoi manuel vérifie les droits d’accès aux intégrations, en plus de l’accès habituel à l’organisation.

Utilisez un récepteur que vous contrôlez et autorisez à recevoir les données d’événement. Ne placez pas d’identifiants dans son URL et n’utilisez pas d’URL de boucle locale ou d’infrastructure privée. HTTPS est obligatoire, mais l’enregistrement ne certifie ni la propriété, ni l’accessibilité, ni la sécurité réseau, ni le comportement des redirections.

Abonnements aux événements pris en charge

Utilisez exactement ces noms d’événements. Les caractères génériques ne sont pas pris en charge. Terminer à nouveau un élément de travail après sa réouverture peut produire un nouvel événement métier, et non un doublon du précédent.

Déclencheurs des événements automatiques
Nom de l’événementQuand il est émis automatiquement
ProjectCreated Un projet est créé.
ProjectUpdated N’est actuellement pas émis lors des modifications habituelles d’un projet.
WorkItemCompleted Le statut d’un élément de travail passe à Done.
ResourceAllocated Une affectation de ressource est créée.
TimesheetApproved Le statut d’une feuille de temps passe à Approved.
RiskCreated Un risque de projet est créé.
ChangeRequestApproved Le statut d’une demande de modification passe à Approved.

En-têtes de la requête de livraison

Allocyn envoie POST avec Content-Type: application/json; charset=utf-8. Les noms d’en-têtes ne sont pas sensibles à la casse. La signature authentifie l’horodatage et le contenu, pas séparément les en-têtes d’événement et d’identifiant de livraison ; utilisez type dans le corps vérifié pour orienter le traitement de façon fiable.

En-têtes de livraison des webhooks
En-têteSignification
X-Allocyn-Signature sha256= suivi de 64 caractères hexadécimaux HMAC en minuscules.
X-Allocyn-Timestamp Heure Unix décimale en secondes pour cette tentative.
X-Allocyn-Event Nom de l’événement ; vérifiez le corps avant de lancer le traitement.
X-Allocyn-Delivery-Id Identifiant de livraison conservé lors des nouvelles tentatives ; il n’est pas signé séparément.

Contenu des événements automatiques

Ce contenu fictif est mis en forme pour être lisible. id identifie l’événement métier, pas la livraison ; occurredAtUtc est l’heure de l’événement, pas celle de la nouvelle tentative. L’enveloppe ne contient ni identifiant d’organisation, ni acteur, ni version de schéma. Associez le point de terminaison et le secret à votre organisation dans votre système récepteur.

L’objet data contient les détails propres à l’événement, pas un instantané complet de l’entité. Les modifications peuvent être vides et oldValue/newValue peuvent être des chaînes ou null, même pour des valeurs d’apparence numérique. Validez les données nécessaires à votre processus et tolérez les champs supplémentaires. Les lectures complémentaires de l’API publique couvrent uniquement ses quatre collections documentées.

Exemple d’événement automatiquejson
{
  "id": "11111111-1111-7111-8111-111111111111",
  "type": "WorkItemCompleted",
  "occurredAtUtc": "2026-09-07T10:30:00Z",
  "entityType": "WorkItem",
  "entityId": "22222222-2222-7222-8222-222222222222",
  "data": {
    "changes": {
      "Status": { "oldValue": "InProgress", "newValue": "Done" }
    }
  }
}

Vérifier la signature avant d’analyser le JSON

Conservez les octets exacts du corps reçu avant d’analyser le JSON. Ne reformatez pas, ne resérialisez pas, ne normalisez pas les espaces et ne modifiez pas l’échappement. Utilisez le texte littéral du secret de signature comme clé UTF-8 : même s’il ressemble à du Base64, ne le décodez pas, n’en supprimez pas les espaces et ne le remplacez pas par une clé API.

L’exemple Node.js vérifie uniquement les signatures. Votre récepteur doit imposer une limite de taille du corps, rejeter les en-têtes dupliqués ou ambigus, obtenir le secret de façon sécurisée et transmettre le Buffer brut. Sa fenêtre d’horodatage de cinq minutes est une politique recommandée côté récepteur, pas une garantie de l’émetteur ; vérifiez l’horodatage de la tentative plutôt que l’heure plus ancienne de l’événement.

Rejetez les messages dont la vérification échoue. Après réussite, analysez et validez le corps et le type d’événement accepté, puis enregistrez-le ou placez-le durablement en file d’attente avant d’en accuser réception. Une vérification réussie ne suffit pas à empêcher les rejeux ni à valider les données applicatives.

Algorithme de signaturetext
message = UTF8(timestampText + ".") followed by the raw payload bytes
key = UTF8(signingSecretText)
digest = HMAC-SHA256(key, message)
signatureHeader = "sha256=" + lowercaseHex(digest)
Vérificateur du corps brut en Node.jsjavascript
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyAllocynWebhook(options) {
  if (!options || typeof options !== 'object') return false;
  const {
    rawBody, signature, timestamp, secret,
    nowSeconds = Math.floor(Date.now() / 1000),
    toleranceSeconds = 300,
  } = options;

  if (!Buffer.isBuffer(rawBody) || typeof secret !== 'string' || !secret.length) return false;
  if (typeof signature !== 'string' || signature.length !== 71 ||
      !/^sha256=[0-9a-f]{64}$/.test(signature)) return false;
  if (typeof timestamp !== 'string' || !timestamp.length || timestamp.length > 16) return false;

  const seconds = Number(timestamp);
  if (!Number.isSafeInteger(seconds) || seconds < 0 || String(seconds) !== timestamp ||
      !Number.isSafeInteger(nowSeconds) || nowSeconds < 0 ||
      !Number.isSafeInteger(toleranceSeconds) || toleranceSeconds < 0 ||
      Math.abs(nowSeconds - seconds) > toleranceSeconds) return false;

  const expected = createHmac('sha256', Buffer.from(secret, 'utf8'))
    .update(Buffer.from(timestamp + '.', 'utf8'))
    .update(rawBody)
    .digest();
  const supplied = Buffer.from(signature.slice('sha256='.length), 'hex');
  return supplied.length === expected.length && timingSafeEqual(supplied, expected);
}

Doublons et accusés de réception

Renvoyez 2xx après une acceptation durable, idéalement bien avant le délai d’expiration de 15 secondes de l’émetteur, et traitez les opérations longues de façon asynchrone. Renvoyez un échec si l’événement n’a pas pu être accepté de manière sûre. Pour un doublon déjà accepté, renvoyez un succès sans répéter ses effets.

Pour les événements automatiques, imposez une unicité durable et atomique sur votre point de terminaison configuré associé à id dans le corps vérifié. Ne vous fiez pas uniquement à l’en-tête d’identifiant de livraison non signé pour détecter les rejeux. Les envois manuels peuvent ne pas contenir d’identifiant d’événement dans le corps et nécessitent leur propre schéma authentifié et clé d’idempotence. Aucune garantie de traitement exactement une fois ou d’ordre strict n’est fournie.

Nouvelles tentatives et rétablissement

Les délais indiquent quand une nouvelle tentative devient possible, pas un calendrier exact. Des échecs sur plusieurs livraisons peuvent désactiver un point de terminaison avant qu’une livraison atteigne cinq tentatives. Les nouvelles tentatives conservent l’identifiant de livraison et les données initiales du corps, mais reçoivent un nouvel horodatage et une nouvelle signature.

Corrigez les problèmes du récepteur, de connectivité, de certificat ou de secret, puis modifiez le webhook et réactivez Actif pour remettre à zéro les échecs consécutifs. Les livraisons inachevées éligibles peuvent reprendre ; la réactivation ne remet pas à zéro celles ayant déjà atteint cinq tentatives, et aucune opération de rejeu ou de réinitialisation de ces livraisons épuisées n’existe.

Limites de livraison et de nouvelles tentatives
ComportementImplémentation actuelle
Succès Toute réponse HTTP 2xx.
Échec Réponses autres que 2xx ; les erreurs réseau et les délais dépassés sont enregistrés comme 503.
Délai d’expiration HTTP 15 secondes.
Nombre maximal de tentatives Cinq au total : une tentative initiale et jusqu’à quatre nouvelles tentatives.
Délais entre les tentatives Éligible après 1, 2, 4, puis 8 minutes depuis la tentative précédente ; les processus d’arrière-plan vérifient environ une fois par minute.
Désactivation automatique Cinq échecs consécutifs du point de terminaison ; tout succès remet le compteur à zéro.

Modifier, mettre en pause ou supprimer un point de terminaison

Modifiez le webhook et sélectionnez Remplacer le secret de signature pour générer un nouveau secret ; copiez-le lorsqu’il est révélé. L’enregistrement sans remplacement conserve le secret. Il n’existe pas de période de grâce pour l’ancien secret : les tentatives ultérieures, y compris celles en file d’attente, utilisent l’URL et le secret actuels. Coordonnez les changements avec votre récepteur ; une requête en cours peut encore utiliser les anciennes valeurs.

La mise en pause ne vide pas les livraisons en attente. Supprimer efface les abonnements du point de terminaison et son historique de livraison enregistré, pas seulement son état actif. Conservez les informations de dépannage nécessaires de façon sécurisée avant la suppression, ou mettez en pause pour garder l’historique. La suppression ne retire pas les événements reçus et ne garantit pas l’annulation d’un envoi en cours.

Référence de gestion des webhooks

Utilisez l’accès authentifié habituel à l’organisation, pas une clé API. Préfixez ces routes par /api/organization/integration-operations et l’éventuel chemin de base du déploiement. GET nécessite integrations.view ; les autres opérations nécessitent également integrations.manage. Utilisez la dernière valeur opaque Base64 de version pour les modifications et la suppression ; rechargez après les conflits 409. Les paramètres invalides renvoient 400 et les échecs d’accès peuvent renvoyer 401 ou 403.

Les résumés des points de terminaison contiennent id, name, url, enabled, consecutiveFailures, events, deliveries et version. Les résumés de livraison contiennent id, businessEventId, eventType, attemptCount, statusCode, succeeded, errorSummary et attemptedAtUtc. Ils affichent la dernière tentative, pas une ligne par tentative. Les listes comprennent jusqu’à 200 livraisons récentes pour toute l’organisation ; l’interface affiche un nombre de livraisons récentes.

La livraison manuelle nécessite un point de terminaison actif abonné à cet événement. payloadJson doit être une chaîne contenant du JSON valide ; elle est envoyée directement sans l’enveloppe automatique et n’a pas de businessEventId. Elle ne modifie aucun enregistrement métier. Examinez succeeded dans le résumé renvoyé même si la requête de gestion renvoie 200, et lisez la limite de sérialisation ci-dessous avant de l’utiliser.

Opérations de gestion des webhooks
Méthode et routeDemandeRéponse
GET /webhooks—200: WebhookEndpointSummary[]
POST /webhooks{name, url, enabled, rotateSecret, events, version}200: {endpoint, signingSecret}
PUT /webhooks/{id}{name, url, enabled, rotateSecret, events, version}200: {endpoint, signingSecret}
POST /webhooks/{id}/deliver{eventType, payloadJson}200: WebhookDeliverySummary
DELETE /webhooks/{id}{version}204
Créer un point de terminaison en pause avec des données d’exemplejson
{
  "name": "Delivery receiver",
  "url": "https://example.com/hooks/allocyn",
  "enabled": false,
  "rotateSecret": false,
  "events": ["WorkItemCompleted", "TimesheetApproved"],
  "version": null
}

Limites actuelles des webhooks

Pour l’assistance, indiquez le nom du point de terminaison, l’heure UTC de la tentative, l’identifiant de livraison, le type d’événement et le statut ou résumé d’erreur. Ne partagez pas les secrets de signature ni les contenus sensibles.

  • ProjectUpdated peut être sélectionné, mais les modifications habituelles des projets émettent d’autres noms d’événements internes qui ne sont pas pris en charge comme abonnements webhook. Ne vous y fiez pas pour les notifications de modification de projet.
  • Pour le JSON manuel, l’émetteur signe la chaîne fournie, puis l’analyse et la resérialise pour l’envoi. Les espaces, le texte non ASCII et l’échappement peuvent modifier les octets. Rejetez et signalez les incohérences de signature du corps brut ; ne normalisez pas le JSON entrant et ne désactivez pas la vérification. Un traitement fiable de contenus manuels arbitraires nécessite une correction côté émetteur.
  • La publication automatique parcourt les sept derniers jours, sans remonter avant la création du point de terminaison. Elle lit les 1 000 événements les plus anciens avant de filtrer les abonnements pris en charge. Il ne s’agit pas d’un export complet de l’historique ni d’une garantie de traitement de l’arriéré ; les organisations à fort volume peuvent avoir des événements en dehors de ce lot.
  • Chaque passage de nouvelles tentatives considère les 50 livraisons échouées et inachevées les plus anciennes avant de vérifier les échéances et les points de terminaison activés. Les arriérés peuvent retarder le travail éligible. Les interruptions, tentatives épuisées, limites de volume ou pauses peuvent laisser des lacunes : maintenez un rapprochement indépendant et des alertes pour les opérations critiques.

Problèmes courants

  • ProjectUpdated peut être sélectionné, mais n’est actuellement pas émis automatiquement lors des modifications habituelles d’un projet.
  • Le JSON fourni manuellement peut présenter une incohérence entre la signature et la sérialisation du corps. Rejetez ces incohérences ; ne contournez jamais la vérification pour les accepter.
  • La suppression d’un point de terminaison efface aussi son historique de livraison enregistré. Mettez-le en pause si cet historique doit être conservé.