Skip to main content

Webhooks entrants

Routage dynamique des agents — Finn appelle votre serveur lorsqu'un appel entrant arrive.

5 min read

Entrée Webhooks

Quand un appel entrant arrive, Finn peut demander votre serveur en temps réel avec quel agent répondre, avec quelles variables injecter, et avec quelle base de connaissances charger. Cela vous permet d'effectuer une route dynamique — par numéro d'appelant, niveau de compte, heure de la journée, cohorte A/B, ou toute logique dont votre moteur se soucie.

Si un agent fixe suffit, saute ça. Si vous voulez un routage dynamique par appel, c'est la page.


Comment ça marche

caller dials → Finn answers ring → Finn POSTs to your URL → your server returns agent + vars → Finn streams the voice agent

La poignée de main ajoute ~100–200m de latence. Votre paramètre doit répondre en moins de 500ms ou Finn revient à l'agent par défaut.


Configuration

1. Définir l'URL du webhook entrant

Tableau de bord → Paramètres → Numéros de téléphone → [numéro] → Inbound Webhook URL.

Coller votre paramètre HTTPS. Enregistrer. Finn pings il une fois avec un corps {"ping": true} pour vérifier l'accessibilité.

Par API

curl https://api.hirefinn.ai/v1/phone-numbers/ph_1234 \
  -X PATCH \
  -H "Authorization: Bearer $FINN_API_KEY" \
  -d '{ "inbound_webhook_url": "https://your-app.com/finn/inbound" }'

2. Définissez un agent de recul

Configurez un Finn par défaut pour ce nombre — utilisé si votre webhook temps ou erreur, ou renvoie une réponse invalide.


Demande de charge utile

Finn POST à votre URL avec :

{
  "session_id": "ws_2H4abc",
  "request_type": "inbound",
  "phone_number_id": "ph_1234",
  "channel": "pstn",
  "from": {
    "phone": "+919876543210",
    "country": "IN",
    "carrier": "Airtel"
  },
  "to": {
    "phone": "+918765432100",
    "country": "IN"
  },
  "received_at": "2026-05-22T14:30:00Z",
  "metadata": {}
}

Pour les appels WhatsApp, le bloc from utilise des champs spécifiques à WhatsApp :

"from": {
  "wa_id": "919876543210",
  "display_name": "Priya M",
  "profile_pic_url": "https://..."
},
"channel": "whatsapp"

Réponse

Retourner un corps JSON à moins de 500ms décrivant comment diriger l'appel :

{
  "finn_id": "fn_def456",
  "language": "hi-IN",
  "variables": {
    "customer_name": "Priya M",
    "account_tier": "premium",
    "last_order_id": "ord_99831",
    "preferred_agent": "Aria"
  },
  "knowledge_base_ids": ["kb_general", "kb_premium_perks"],
  "metadata": {
    "campaign_tag": "premium-support-q2",
    "ab_cohort": "B"
  },
  "recording_enabled": true,
  "max_call_duration_seconds": 600
}

Référence du champ

Champ requis ?Notes

  • Oui Oui Quel agent répond. Doit appartenir à votre org language=No="Surpasser la langue par défaut de l'agent. en-US, hi-IN, es-ES, etc variables=No=Sac à clé/valeur en forme libre. Disponible à l'intérieur de l'invite comme {variable_name} knowledge_base_ids=" No=" Override qui KBs sont chargés pour cet appel metadata=No.=Attaché au dossier d'appel et au webhook post-appel. Utilisez votre propre marquage analytique. - Oui Excéder la valeur par défaut de l'agent Couvercle dur. La valeur par défaut est 1800 (30 min)

Rejeter l'appel

{ "action": "reject", "reason": "blocked_caller" }

Finn termine l'appel avec un message sortant configuré ("Ce numéro n'est plus en service"). Utiliser pour DNC exécution, comptes bloqués, ou après les heures de raccroche.

Transfert immédiat

{ "action": "transfer", "to": "+918888888888", "reason": "vip_route" }

Passer l'agent d'IA entièrement — aller directement à un humain. Utile pour les niveaux VIP / escalade.


Exemple de mise en œuvre (Node)

import express from "express";

const app = express();
app.use(express.json());

app.post("/finn/inbound", async (req, res) => {
  const { from, to, channel } = req.body;

  // 1. Look up caller in CRM (must be fast — DB index by phone)
  const phone = from.phone ?? `+${from.wa_id}`;
  const customer = await crm.findByPhone(phone);

  // 2. Block known DNC
  if (customer?.dnc) {
    return res.json({ action: "reject", reason: "dnc" });
  }

  // 3. VIP → straight to human
  if (customer?.tier === "vip") {
    return res.json({
      action: "transfer",
      to: process.env.VIP_DESK_NUMBER!,
      reason: "vip_route",
    });
  }

  // 4. Localized agent based on caller country
  const language = from.country === "IN" ? "hi-IN" : "en-US";

  // 5. Pick agent + load context
  return res.json({
    finn_id: customer?.tier === "premium"
      ? "fn_premium_aria"
      : "fn_standard_aria",
    language,
    variables: {
      customer_name: customer?.name ?? "there",
      account_tier: customer?.tier ?? "standard",
      last_order_id: customer?.last_order_id ?? "",
    },
    knowledge_base_ids:
      customer?.tier === "premium" ? ["kb_general", "kb_premium"] : ["kb_general"],
    metadata: { ab_cohort: customer?.ab_cohort ?? "A" },
  });
});

app.listen(3000);

Vérification de la signature

Même schéma que pour les webhooks post-appel — HMAC-SHA256 sur le corps brut, en-tête X-Finn-Signature.

const sig = req.headers["x-finn-signature"] as string;
const ok = verifyFinnSignature(rawBody, sig, process.env.FINN_INBOUND_SECRET!);
if (!ok) return res.status(401).send("bad signature");

Voir Post-call Webhooks pour la mise en œuvre complète de la vérification.


Exigences fonctionnelles

C'est sur le chemin hot — l'appelant entend le son en attendant votre réponse.

Cible

  • Oui Temps de réponse Heure d'expiration Défaut sur timeout. Agent par défaut configuré sur le numéro de téléphone Retour sur 5xx Défaut de retour sur un JSON non valide Agent par défaut + erreur enregistrée

Conseils pour frapper < 500ms

  • Cache CRM recherches par numéro de téléphone pendant 5 minutes
  • Utilisez une base de données colocalisée — webhook de nous-est, DB dans nous-ouest = 80ms chaque chemin
  • ** Pré-calculer les décisions de routage** — stocker la réponse sur le dossier client, ne pas décider en direct
  • Passer l'enrichissement non essentiel sur le houblon entrant — pousser ce travail vers le webhook post-appel

Pré-écran de l'appelant

La plupart des applications utilisent le webhook entrant pour l'un de ces modèles:

Modèle Cas d'utilisation

  • Oui Lookup + personnalisez DNC application VIP routage Détection de la langue Tests A/B After-hours routage Suivi de la campagne Tag appels à partir de numéros de suivi spécifiques avec un ID de campagne Multi-locataire SaaS

Essais

Utilisez le Finn CLI pour simuler les appels entrants sans véritable anneau de RTPC:

finn inbound simulate \
  --phone-number-id ph_1234 \
  --from +919876543210 \
  --webhook-url https://your-app.com/finn/inbound

La sortie affiche votre réponse au paramètre, latence et l'agent résolu + variables. C'est facile.


Gotchas communs

Symptômes

  • Oui Les appels reviennent toujours à l'agent par défaut. Vérifiez le log webhook de Finn pour le timing. - Oui L'appelant entend 2-3s de silence avant que l'agent ne parle. Optimiser jusqu'à < 200ms Variables n'apparaissant pas dans le discours de l'agent. Utilisez serpent case des deux côtés Un mauvais agent a répondu Votre paramètre a renvoyé un finn_id qui appartient à un autre org. Vérifier la propriété action: reject not honored=Cochez reason est une chaîne, la réponse JSON est valide. Réponses non valides → retour en arrière

Autres

Was this page helpful?

Still stuck or have feedback?

Email [email protected] or use the chat bubble in the bottom-right corner — it's a Finn that knows the Academy cold.