Skip to Content
ReferenceÉcrire une intégration de canal

Écrire une intégration de canal

Ceci est une référence pour développeurs pour quiconque étend Structura avec un nouveau canal. Si vous cherchez comment utiliser les canaux existants, voir Comment fonctionnent les canaux à la place.

Ce guide parcourt l’ajout d’une nouvelle intégration au système de canaux. Nous utiliserons une intégration hypothétique « Mailchimp » comme exemple.

Étape 1 : Choisir les capacités

Décidez quelles interfaces de capacité votre intégration nécessite :

Si votre intégration…Implémentez
Envoie des notifications fire-and-forgetNotifiableIntegration
Réécrit le contenu via IA pour la plateformeAdaptableIntegration
Publie du contenu vers l’API de la plateformePublishableIntegration
Utilise OAuth 2.0 pour l’authentificationOAuthIntegration
Est configurée en collant une URLWebhookIntegration

Les capacités sont composables. LinkedIn implémente OAuth + Adapt + Publish. Slack implémente Webhook + Notify. IndexNow implémente seulement Notify.

Étape 2 : Créer la classe Integration

Créez functions/src/channels/integrations/MailchimpIntegration.ts :

import type { FetchLike } from "../contracts/Integration.js"; import type { Integration, IntegrationMetadata, HealthStatus, ConnectionRecord, } from "../contracts/Integration.js"; import type { NotifiableIntegration, NotifyContext, NotifyResult } from "../contracts/Integration.js"; export const MAILCHIMP_INTEGRATION_ID = "mailchimp"; export class MailchimpIntegration implements Integration, NotifiableIntegration { constructor(private readonly fetch: FetchLike = globalThis.fetch) {} readonly metadata: IntegrationMetadata = { id: MAILCHIMP_INTEGRATION_ID, name: "Mailchimp", category: "email", sku: "channels", // or "free" for free integrations capabilities: ["notify"], authType: "apikey", // or "oauth2", "webhook", "none" iconUrl: "/icons/mailchimp.svg", }; async healthCheck(connection: ConnectionRecord): Promise<HealthStatus> { if (connection.status === "connected") return { status: "healthy" }; return { status: "unhealthy", reason: connection.lastError?.message }; } async notify(ctx: NotifyContext): Promise<NotifyResult> { // Implementation here } }

Règles clés :

  • Acceptez FetchLike via le constructeur pour la testabilité.
  • Ne codez jamais en dur les appels HTTP — utilisez toujours le fetch injecté.
  • Classifiez les erreurs HTTP de manière cohérente (voir le tableau de classification d’erreurs dans Contrats d’intégration de canal).

Étape 3 : Enregistrer l’intégration

Ajoutez votre classe à functions/src/channels/registry/IntegrationRegistry.ts :

import { MailchimpIntegration } from "../integrations/MailchimpIntegration.js"; const CATALOG: Integration[] = [ // ... existing integrations new MailchimpIntegration(), ];

Étape 4 : Ajouter une entrée de catalogue

Ajoutez une entrée à functions/src/channels/registry/catalog.ts :

{ id: "mailchimp", name: "Mailchimp", description: "Send email campaigns when posts are published", category: "email", capabilities: ["notify"], authType: "apikey", gating: { requiredPlan: "free", // Minimum plan requiredAddon: "channels", // null if free, "channels" if paid }, iconUrl: "/icons/mailchimp.svg", }

Étape 5 : Écrire les tests

Créez functions/src/channels/__tests__/MailchimpIntegration.test.ts :

import { describe, it, expect, vi } from "vitest"; import { MailchimpIntegration } from "../integrations/MailchimpIntegration.js"; describe("MailchimpIntegration", () => { it("has correct metadata", () => { const integration = new MailchimpIntegration(); expect(integration.metadata.id).toBe("mailchimp"); expect(integration.metadata.capabilities).toContain("notify"); }); it("sends notification on publish", async () => { const stubFetch = vi.fn().mockResolvedValue({ ok: true, status: 200, json: async () => ({}), }); const integration = new MailchimpIntegration(stubFetch); const result = await integration.notify(/* NotifyContext */); expect(result.status).toBe("ok"); expect(stubFetch).toHaveBeenCalledOnce(); }); // Test error classification for each HTTP status... });

Mettez à jour IntegrationRegistry.test.ts pour inclure la nouvelle intégration dans les comptes attendus.

Étape 6 : Mettre à jour l’extension WordPress (si nécessaire)

Pour les intégrations basées sur identifiant ou webhook, aucun changement d’extension n’est nécessaire — les endpoints existants channelsSaveCredentialConnection et channelsSaveWebhookConnection gèrent tous les types d’authentification de manière générique.

Pour les intégrations OAuth, les endpoints existants channelsOAuthInit et channelsOAuthCallback gèrent le flux. Vous devrez peut-être ajouter de nouvelles entrées defineSecret() pour le client ID/secret du fournisseur.

Étape 7 : Ajouter de la documentation

Créez docs/pages/channels/integrations/mailchimp.mdx avec :

  • Comment fonctionne l’intégration
  • Tableau de métadonnées
  • Forme du secret déchiffré
  • Instructions de configuration de la connexion
  • Tableau de gestion des erreurs

Mettez à jour docs/pages/channels/integrations/_meta.json pour inclure la nouvelle page.

Liste de vérification

  • Classe Integration implémentant les bonnes interfaces de capacité
  • Injection de dépendance FetchLike
  • Classification des erreurs pour tous les codes de statut HTTP
  • Messages localisés (si NotifiableIntegration)
  • Implémentation du health check
  • Enregistrée dans IntegrationRegistry
  • Entrée de catalogue avec gating correct
  • Tests unitaires (métadonnées, happy path, cas d’erreur, cas limites)
  • Test du Registry mis à jour avec les nouveaux comptes attendus
  • Page de documentation
  • Secrets configurés (si OAuth ou clé API)
Last updated on