Skip to Content
ReferenceContratos de integración de canal

Contratos de integración de canal

Esta es una referencia para desarrolladores. La documentación de canales para usuarios finales empieza en Cómo funcionan los canales; esta página es para ingenieros que trabajan dentro de functions/src/channels/.

Cada integración implementa la interfaz base Integration más cero o más interfaces de capacidad. El despachador depende solo de estas interfaces, nunca de clases concretas.

Fuente de verdad: functions/src/channels/contracts/Integration.ts.

Interfaz base

interface Integration { readonly metadata: IntegrationMetadata; healthCheck(connection: ConnectionRecord): Promise<HealthStatus>; }

IntegrationMetadata describe la integración para el catálogo de UI:

interface IntegrationMetadata { id: string; // e.g. "linkedin", "slack-webhook" name: string; // Display name category: IntegrationCategory; // "notify" | "social" | "email" | "seo" | "ads" | "crm" sku: IntegrationSku; // "free" | "channels" | "growth" capabilities: IntegrationCapability[]; // ["adapt", "publish"] or ["notify"] authType: IntegrationAuthType; // "oauth2" | "webhook" | "apikey" | "none" iconUrl: string; }

Interfaces de capacidad

NotifiableIntegration

Notificaciones fire-and-forget. Usado por Slack, Discord, IndexNow, Correo, Telegram, WhatsApp.

interface NotifiableIntegration extends Integration { notify(ctx: NotifyContext): Promise<NotifyResult>; }

NotifyContext lleva el título de la entrada, la URL, el estado de publicación ("published" o "awaiting_review"), la URL de edición, el idioma, el override de idioma por conexión y los secretos descifrados. La integración formatea un mensaje y lo envía.

NotifyResult informa "ok", "transient_error" o "permanent_error" — el despachador usa esto para las decisiones de reintento.

OAuthIntegration

Ciclo de vida completo de OAuth 2.0. Usado por LinkedIn (y en el futuro Mailchimp, X).

interface OAuthIntegration extends Integration { buildAuthorizeUrl(state: string, redirectUri: string): string; handleCallback(ctx: OAuthCallbackContext): Promise<OAuthTokens>; refreshTokens(tokens: OAuthTokens): Promise<OAuthTokens>; revoke(tokens: OAuthTokens): Promise<void>; }

El flujo OAuth son dos Cloud Functions:

  1. channelsOAuthInit emite un JWT de state firmado, llama a buildAuthorizeUrl(), devuelve la URL.
  2. channelsOAuthCallback recibe la redirección, verifica el state, llama a handleCallback(), cifra los tokens, persiste la conexión, redirige a wp-admin.

OAuthTokens lleva accessToken, opcional refreshToken, opcional expiresAt, scope y extras específicos del proveedor (p. ej. la URN de persona de LinkedIn).

AdaptableIntegration

Reescritura de contenido potenciada por IA. Usado por LinkedIn (y en el futuro Mailchimp).

interface AdaptableIntegration extends Integration { adapt(ctx: AdaptContext): Promise<AdaptedContent>; }

AdaptContext provee la instantánea completa de la entrada (AdaptablePost) con título, texto del cuerpo, extracto, persona, palabras clave e idioma. El método adapt() de la integración delega en una función de IA inyectada que usa una plantilla de prompt específica del canal.

AdaptedContent devuelve el payload específico de la integración (p. ej. { text } para LinkedIn), estadísticas de uso de tokens y la ID del modelo usada.

PublishableIntegration

Publica contenido a una API de terceros. Usado por LinkedIn (y en el futuro Mailchimp, X).

interface PublishableIntegration extends Integration { publish(ctx: PublishContext): Promise<PublishResult>; }

PublishContext incluye los tokens descifrados, el contenido adaptado (salida de adapt()), el registro de conexión y la instantánea de la entrada.

PublishResult informa estado ("ok", "transient_error", "auth_expired", "permanent_error"), externalRef opcional (ID de la entrada del proveedor) y externalUrl opcional (enlace al artefacto publicado).

WebhookIntegration

Configurada por una URL de webhook pegada por el usuario. Usado por Slack y Discord.

interface WebhookIntegration extends Integration { validateTarget(url: string): Promise<void>; }

Valida la forma de la URL y opcionalmente la pinguea antes de guardar. El endpoint channelsSaveWebhookConnection llama esto antes de cifrar la URL.

Type Guards

El despachador usa type guards (no instanceof) para comprobar capacidades:

isOAuthIntegration(i) // authType === "oauth2" isAdaptableIntegration(i) // capabilities includes "adapt" isPublishableIntegration(i) // capabilities includes "publish" isWebhookIntegration(i) // authType === "webhook" isNotifiableIntegration(i) // capabilities includes "notify"

Matriz actual de integraciones

IntegraciónNotifyAdaptPublishOAuthWebhookTipo de authSKU
Slacksí---síwebhookfree
Discordsí---síwebhookfree
IndexNowsí----nonefree
Correosí----apikeyfree
Telegramsí----apikeyfree
WhatsAppsí----apikeyfree
LinkedIn-sísísí-oauth2channels
Last updated on