Skip to content

Guide d’intégration des webhooks Screenshot API

Points de terminaison HTTPS, charge utile JSON signée, exemple Express et stratégie d’idempotence face aux relivraisons.

Pourquoi un webhook ?

Le polling depuis le navigateur ou un service court-circuité gaspille des requêtes. Avec un webhook, ScreenshotCenter appelle votre URL HTTPS lorsque le traitement est terminé — idéal pour déclencher des workflows internes, notifier la supervision ou enchaîner sur Zapier/Make après une étape intermédiaire.

Présentation produit : Webhooks. Procédure détaillée : article d’aide.

Configuration

  1. Tableau de bord → AppsConnecter une nouvelle appWebhook.
  2. Renseignez une URL HTTPS publique qui répond en 2xx rapidement.
  3. Optionnel : secret de signature ; l’en-tête X-Signature contient alors sha256=<HMAC> calculé sur le corps brut (voir l’aide pour le nom exact selon votre espace).

Déclencher les envois

Ajoutez l’app_id du webhook au paramètre apps sur /screenshot/create (répétable). Les lots déclenchent la même chaîne pour chaque ligne réussie.

Exemple de charge utile

{
  "event": "screenshot.completed",
  "screenshot_id": "abc123",
  "url": "https://example.com",
  "status": "done",
  "image_url": "https://cdn.screenshotcenter.com/abc123.png",
  "created_at": "2026-03-24T12:00:00Z"
}

Récepteur Express (Node.js, ESM)

import express from 'express';
import crypto from 'crypto';

const app = express();
const secret = process.env.WEBHOOK_SECRET ?? '';

app.post(
  '/webhooks/screenshotcenter',
  express.json({
    verify: (req, _res, buf) => {
      req.rawBody = buf;
    },
  }),
  (req, res) => {
    const sig = req.headers['x-signature'];
    if (secret && typeof sig === 'string' && req.rawBody) {
      const attendu =
        'sha256=' +
        crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
      const a = Buffer.from(attendu);
      const b = Buffer.from(sig);
      if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
        return res.status(401).send('signature invalide');
      }
    }
    const { event, screenshot_id, image_url } = req.body;
    console.log('webhook', event, screenshot_id, image_url);
    res.sendStatus(200);
  },
);

app.listen(Number(process.env.PORT) || 3000, () => {
  console.log('écoute');
});

Relances et idempotence

Les échecs (timeout ou statut non 2xx) entraînent des relivraisons avec backoff. Stockez chaque screenshot_id traité avant de répondre 200 afin d’éviter les doublons.

Cas d’usage

  • Traitement asynchrone des PDF longs sans bloquer votre API publique.
  • Alertes opérationnelles sur les lignes en erreur d’un lot de captures.
  • Pont vers Zapier ou Make via une petite couche de routage.