El sistema de contenido de LabelLoop ya generaba los posts automáticamente. Claude escribe el hilo de X, el post de LinkedIn, el artículo para la crónica. Todo llega a Notion con Status: Ready.

El problema: ahí se quedaba. Alguien todavía tenía que abrir Notion, copiar el texto, abrir LinkedIn, pegar, revisar, publicar.

Ese “alguien” soy yo. Y ese paso manual era exactamente el tipo de fricción que hace que los calendarios de contenido mueran.


El diseño del loop

La solución no es publicar automáticamente. Eso sería un error.

El contenido generado por IA necesita un filtro humano. No porque la IA lo haga mal — en este caso lo hace bastante bien — sino porque la responsabilidad de lo que publico bajo mi nombre es mía. Y hay contexto que una IA no tiene: si ese día está pasando algo que hace el post inadecuado, si el tono no se siente correcto, si simplemente prefieres no publicar ese día.

Entonces el diseño correcto es: generación automática + aprobación humana + publicación automática.

El flujo completo quedó así:

  1. n8n detecta tareas en el GTM Calendar de Notion con Publish Date = hoy y Status = Pending
  2. Claude (Don) genera el contenido según el canal: hilo de X, post de LinkedIn, crónica, newsletter
  3. El contenido se guarda en Notion — el status pasa a Ready
  4. Telegram me envía un mensaje con preview del contenido y dos botones: ✅ Publicar / ⏭️ Omitir
  5. Si presiono ✅, un segundo workflow recibe el click, extrae el contenido de Notion, y publica en la red social correspondiente
  6. Notion se actualiza a Published automáticamente

La parte técnica que me tomó más de lo esperado

LinkedIn es sorprendentemente limpio. Un POST a ugcPosts, OAuth 2.0 con Bearer token, el texto en shareCommentary. Diez minutos de lectura de documentación oficial y el nodo estaba listo.

X/Twitter es otra historia.

La API de Twitter exige OAuth 1.0a para publicar en nombre de un usuario. No hay Bearer token simple. Hay que firmar cada request con HMAC-SHA1 usando cuatro credenciales distintas: Consumer Key, Consumer Secret, Access Token, Access Token Secret.

En un entorno normal, importarías una librería. Pero el sandbox de n8n no permite require(). Tampoco tiene fetch nativo disponible.

La solución: implementar OAuth 1.0a desde cero usando la Web Crypto API — la API nativa del browser que Node.js 18+ hereda globalmente, sin necesidad de imports.

async function hmacSha1Base64(signingKey, baseString) {
  const keyBytes = new TextEncoder().encode(signingKey);
  const dataBytes = new TextEncoder().encode(baseString);
  const cryptoKey = await crypto.subtle.importKey(
    'raw', keyBytes, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign']
  );
  const sigBuffer = await crypto.subtle.sign('HMAC', cryptoKey, dataBytes);
  const bytes = new Uint8Array(sigBuffer);
  let binary = '';
  for (const b of bytes) binary += String.fromCharCode(b);
  return btoa(binary);
}

Y para los requests HTTP dentro del Code node, $helpers.httpRequest() — el helper interno de n8n que no requiere ni fetch ni axios.

Para el hilo de X, el truco adicional es la secuencia: publicar el primer tweet, capturar su ID, usar ese ID en el reply.in_reply_to_tweet_id del segundo tweet, y así sucesivamente. Todo en un solo loop dentro del Code node.


El bloqueador honesto

El sistema está construido. Los dos workflows están listos. El código es correcto.

Pero hoy no pude activarlo porque el setup de credenciales de LinkedIn — específicamente el paso de crear la app en el LinkedIn Developer Portal — se bloqueó en el paso 1.

No es un bug. No es un error de código. Es el tipo de fricción burocrática que existe en cualquier integración con redes sociales: formularios de aprobación, políticas de uso, pantallas de OAuth que no siempre funcionan a la primera.

Continuaré el domingo.


Lo que esto significa para el sistema completo

Cuando todo esté conectado, el flujo de distribución de LabelLoop funciona así:

El contenido sigue siendo revisado por mí. La distribución deja de ser un trabajo manual repetitivo.

Ese es el punto. No automatizar la creatividad. Automatizar la fricción que rodea a la creatividad.


Próximo paso: domingo — setup LinkedIn Developer Portal + X Developer Portal + activar ambos workflows en n8n.