Genuka WA docs

Librairie TypeScript

@genuka/whatsapp — builders typés, validation et normalisation d'événements.

@genuka/whatsapp n'est pas un client HTTP de plus. C'est la couche qui empêche les erreurs 400 évitables, rend le traitement des webhooks exhaustif à la compilation, et transforme les quelque 200 codes d'erreur de Meta en sept décisions actionnables.

La librairie est utilisable seule, contre la Cloud API de Meta, sans compte Genuka. Elle est publiée sous licence MIT.

Installation

npm install @genuka/whatsapp

Construire un message

Les longueurs, les cardinalités et le format du numéro sont vérifiés avant l'appel réseau.

import { messages } from "@genuka/whatsapp";

const choix = messages.buttons("+237 6 99 00 11 22", {
  body: "Comment peut-on vous aider ?",
  buttons: [
    { id: "order", title: "Ma commande" },
    { id: "support", title: "Un problème" },
  ],
});

Une erreur de construction est levée immédiatement, avec le chemin du champ fautif :

ValidationError: interactive.buttons: must contain at most 3 items (got 4)

La fenêtre de 24 heures

import { sendStrategy } from "@genuka/whatsapp";

sendStrategy(contact.lastInboundAt); // "free_form" | "template"

Un appel de fonction plutôt qu'une erreur 131047 découverte après facturation de la tentative.

Traiter un webhook

Meta imbrique tout dans entry[].changes[].value, où le vrai discriminant n'est pas un champ mais la présence de messages ou statuses. La librairie aplatit ça une fois pour toutes.

import { parseWebhook, eventKey } from "@genuka/whatsapp/webhooks";

for (const event of parseWebhook(await request.json())) {
  if (await dejaTraite(eventKey(event))) continue;

  switch (event.kind) {
    case "message":         // entrant
    case "status":          // sent / delivered / read / failed / deleted
    case "template":        // approbation, qualité, recatégorisation
    case "account":         // qualité du numéro, limites, suspension
    case "user_preference": // désinscription marketing
    case "coexistence":     // historique, echoes, contacts
    case "unknown":         // jamais perdu, toujours transmis
  }
}

Le parseur ne lève jamais : un payload malformé produit une liste vide. Une exception ici deviendrait une 500, et Meta rejouerait tout le lot.

Décider quoi faire d'une erreur

C'est errorClass qui porte la décision, pas le code numérique.

import { WhatsAppError } from "@genuka/whatsapp";

try {
  await envoyer(payload);
} catch (error) {
  if (!(error instanceof WhatsAppError)) throw error;

  switch (error.errorClass) {
    case "needs_template":      return renvoyerEnTemplate();   // 131047
    case "recipient_permanent": return marquerInjoignable();   // 131026, 131050
    case "recipient_throttled": return replanifier();          // 131049
    case "media":               return reuploaderPuisRessayer(); // 131052
    case "retryable":           return backoff();              // 4, 130429, 5xx
    case "config":              return alerterOperateur();     // 190, 133010
    case "template":            return remonterAuClient();     // 132xxx
    case "validation":
    case "unknown":             throw error;
  }
}

Deux transports, un seul cœur

Le même payload construit peut partir par deux routes, avec les mêmes builders, la même validation et la même taxonomie d'erreurs :

// Avec une clé Genuka WA — aucun jeton Meta en jeu
import { GenukaTransport } from "@genuka/whatsapp";
const transport = new GenukaTransport({ apiKey: process.env.GENUKA_WA_API_KEY! });

// Directement contre Meta, si vous détenez vos propres accès
import { MetaTransport } from "@genuka/whatsapp";
const transport = new MetaTransport({ accessToken: process.env.META_TOKEN! });

Référence complète

Chaque module a son guide, généré depuis le paquet lui-même — ils vivent à côté du code qu'ils décrivent, donc ils ne divergent pas :

Ces guides sont en anglais : ils sont livrés dans le paquet npm, qui n'a qu'une langue.

Version de l'API Graph

La librairie épingle explicitement une version de Graph API plutôt que de suivre « la dernière ». Une montée de version silencieuse est la meilleure façon de découvrir une rupture en production : le changement de DEFAULT_GRAPH_VERSION est une publication délibérée.

Sur cette page