Skip to main content
Pour un guide d’intégration PagerDuty plus détaillé, cliquez ici.
1

Déployer une passerelle pour webhook

Créez un petit service qui écoute les événements PagerDuty incident.resolved et lance une session Devin pour rédiger le post-mortem. Déployez-le sous forme de fonction serverless (AWS Lambda, Cloudflare Worker) ou de conteneur léger :
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());

function verifySignature(req) {
  const secret = Buffer.from(req.headers['x-webhook-secret'] || '');
  const expected = Buffer.from(process.env.WEBHOOK_SECRET || '');
  if (!expected.length) throw new Error('WEBHOOK_SECRET environment variable is not set');
  if (secret.length !== expected.length) return false;
  return crypto.timingSafeEqual(secret, expected);
}

app.post('/pagerduty-resolved', async (req, res) => {
  if (!verifySignature(req)) return res.status(401).send('Bad signature');

  const event = req.body?.event;
  if (!event || event.event_type !== 'incident.resolved') {
    return res.sendStatus(200);
  }

  const incident = event.data;
  const title = incident.title || 'Unknown incident';
  const service = incident.service?.summary || 'unknown-service';
  const urgency = incident.urgency || 'high';
  const incidentUrl = incident.html_url || '';
  const createdAt = incident.created_at || '';
  const resolvedAt = incident.resolved_at || new Date().toISOString();

  const orgId = process.env.DEVIN_ORG_ID;
  const response = await fetch(
    `https://api.devin.ai/v3/organizations/${orgId}/sessions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      prompt: [
        `A PagerDuty incident has been resolved. Draft a postmortem.`,
        ``,
        `Incident: "${title}"`,
        `Service: ${service}`,
        `Urgency: ${urgency}`,
        `Created: ${createdAt}`,
        `Resolved: ${resolvedAt}`,
        `Incident URL: ${incidentUrl}`,
        ``,
        `Write a structured postmortem:`,
        `1. Use the Datadog MCP to pull logs and metrics for ${service} during the incident window`,
        `2. Identify the root cause — check for deploys, config changes, or upstream failures`,
        `3. Build a detailed timeline from first alert to resolution`,
        `4. List action items to prevent recurrence`,
        `5. Post the postmortem as a PR to our docs/postmortems/ directory`,
      ].join('\n'),
      tags: ['pagerduty-postmortem', `service:${service}`],
    }),
  });

  const { session_id } = await response.json();
  console.log(`Started postmortem session ${session_id} for: ${title}`);
  res.sendStatus(200);
});

app.listen(3000);
Créez un utilisateur de service dans Settings > Utilisateurs de service sur app.devin.ai avec l’autorisation ManageOrgSessions. Copiez le jeton d’API affiché après la création et enregistrez-le sous DEVIN_API_KEY sur votre service relais. Définissez DEVIN_ORG_ID sur l’identifiant de votre organisation — obtenez-le en appelant GET https://api.devin.ai/v3/enterprise/organizations avec votre jeton. Définissez WEBHOOK_SECRET sur un secret partagé que vous configurerez également dans PagerDuty.
2

Configurer PagerDuty

  1. Dans PagerDuty, accédez à Services > [votre service] > Integrations
  2. Cliquez sur Add Integration et sélectionnez Generic Webhooks (v3)
  3. Définissez la Webhook URL sur l’endpoint de votre bridge (par ex. https://your-bridge.example.com/pagerduty-resolved)
  4. Sous Custom Headers, ajoutez X-Webhook-Secret avec la même valeur que celle que vous avez enregistrée sous WEBHOOK_SECRET
  5. Sous Event Subscription, filtrez par type d’événement incident.resolved afin que le post-mortem se déclenche uniquement une fois l’incident fermé
Vous pouvez également vous abonner à incident.acknowledged si vous souhaitez que Devin commence à collecter des données pendant que l’incident est encore en cours, puis finalise le post-mortem lors de sa résolution.
3

Connecter des MCP d’observabilité (facultatif)

Devin rédige de meilleurs post-mortems lorsqu’il peut accéder à vos données de télémétrie. Activez un ou plusieurs MCP afin que Devin puisse extraire des données réelles sur la période de l’incident :Datadog MCP — Accédez à Settings > MCP Marketplace, trouvez Datadog, cliquez sur Enable et saisissez vos clés API et Application. Devin interrogera les journaux, les métriques, les événements de déploiement et l’historique des moniteurs.Sentry MCP — Trouvez Sentry dans le MCP Marketplace, cliquez sur Enable et terminez le processus OAuth. Devin extraira les détails des erreurs, les stack traces et les tags de release.Une fois connecté, Devin corrèle automatiquement la télémétrie avec la chronologie de l’incident afin de build un post-mortem étayé par des preuves. Pour en savoir plus, consultez connecter des serveurs MCP.
4

Ce que génère Devin

Lorsqu’un incident PagerDuty est résolu, Devin analyse la période de l’incident et rédige un post-mortem structuré :Exemple de post-mortem généré par Devin :
# Postmortem: Database Connection Pool Exhaustion — orders-service
**Date:** 2026-02-10 | **Duration:** 46 minutes | **Severity:** P1

## Summary
orders-service experienced connection pool exhaustion between
14:32 and 15:18 UTC, causing 502 errors for ~12% of order
placement requests.

## Timeline
- 14:15 UTC — Deploy #387 released (commit e4f29a1)
- 14:28 UTC — Connection pool usage climbed from 60% to 92%
- 14:32 UTC — Pool exhausted; PagerDuty incident triggered
- 14:38 UTC — On-call engineer acknowledged
- 14:45 UTC — Identified Deploy #387 added a new inventory
              check that opens a DB connection per line item
              without releasing it in the finally block
- 15:02 UTC — Rollback to Deploy #386 initiated
- 15:18 UTC — Connection pool recovered; incident resolved

## Root Cause
Deploy #387 introduced `checkInventoryAvailability()` in
`src/services/orders.ts:142`. The function opens a new DB
connection for each line item in an order but only releases
it on the success path. When inventory checks fail (timeout
or stock unavailable), connections leak.

Orders with 5+ line items reliably exhausted the pool within
15 minutes of the deploy.

## Action Items
- [ ] Fix connection leak: add `finally` block to release
      connection (PR #388 opened)
- [ ] Add connection pool usage monitor with alert at 80%
- [ ] Add integration test for multi-item orders with
      simulated inventory failures
- [ ] Review other DB access patterns for similar leak risks
5

Personnaliser le post-mortem

Adaptez le pipeline au processus de postmortem de votre équipe :Utilisez un Playbook pour définir votre modèle de postmortem — sections, niveaux de sévérité, champs obligatoires et emplacement de stockage du résultat. Transmettez un playbook_id dans la requête API pour standardiser chaque postmortem.Orientez selon la sévérité. Ajoutez une logique dans votre passerelle pour générer des postmortems uniquement pour les incidents P1/P2. Les incidents moins graves ne nécessitent pas forcément un compte rendu complet.Ajoutez à Knowledge des informations sur votre architecture, les responsables de services et les incidents passés afin que Devin puisse faire les rapprochements — par exemple, “orders-service dépend de inventory-service, qui est connu pour des problèmes de timeout sous charge.”Publiez sur votre wiki. Au lieu de faire un commit dans un repo, demandez à Devin de publier le postmortem sur Confluence, Notion ou votre wiki interne via le prompt de session.