Mapa da trilha
Conteúdo detalhado
🎯 Visão geral do sistema
Entenda o problema que o MkBlogs resolve, o cenário de ferramentas em 2026 e o desenho do que vamos construir nas próximas trilhas.
Substituir o copia-e-cola manual por um único ponto de entrada que dispara texto e imagem para N redes ao mesmo tempo, com agendamento e retry.
Publicar em 7 redes manualmente consome ~30 min por post; um sistema bem feito derruba para segundos e elimina o erro de "esqueci do LinkedIn".
Cross-posting, idempotência, fila de jobs, agendamento UTC e auditoria do que saiu onde.
Cada rede (X, LinkedIn, Meta, TikTok, Bluesky) expõe uma REST/GraphQL API onde você envia JSON com texto, mídia e metadados e recebe um ID de post.
Sem entender o shape de cada API, você não consegue normalizar payloads no seu adapter nem prever quais campos vão dar erro.
OAuth scopes, multipart upload de mídia, rate limit headers, status codes (4xx vs 5xx) e webhooks de confirmação.
API oficial = contrato estável com SLA e ToS; scraping = automatizar a UI (Puppeteer/Playwright), sem contrato e sujeito a ban.
Algumas redes (Instagram pessoal, Threads, TikTok) historicamente só liberam features completas via UI — saber onde cada caminho dói é estratégia.
Risco de bloqueio, custo de manutenção (DOM muda), proxy residencial, headless browser e o trade-off legal de cada abordagem.
Postiz é open-source self-hosted; Blotato foca em vídeos curtos com AI; Buffer é SaaS clássico de agendamento; Ayrshare é API-first para devs.
Você não precisa reinventar a roda — entender qual ferramenta cobre 80% do seu caso evita meses de engenharia desnecessária.
Self-hosted vs SaaS, lock-in, API white-label, número de redes suportadas e modelo de cobrança (por post, por conta, por seat).
Soma de: API paga da rede (X cobra ~$0,01/post no tier Basic), infra (VPS ~$20/mês), storage de mídia (~$5) e SaaS opcional (Ayrshare ~$149/mês).
Subestimar custo é a forma mais comum de o projeto morrer no segundo mês — precisa estimar antes de codar.
Custo por post, custo fixo vs variável, tier gratuito de cada API e o "custo escondido" de manter integrações vivas.
Um app Next.js + worker Node que recebe um post (texto + imagem), enfileira jobs por rede, executa adapters e devolve status num dashboard.
Ter o destino claro desde o início faz cada trilha encaixar — você sabe exatamente onde cada peça vai morar.
Frontend de composição, fila BullMQ, adapters por rede, banco Postgres + Prisma e dashboard de status com webhooks.
🏗️ Arquitetura multi-plataforma
As 6 peças que toda ferramenta de publicação tem por baixo: adapters, fila, storage, banco, frontend e webhooks. Quem entende isso, debuga qualquer tool.
Uma interface comum `publish(post): Result` implementada por classes específicas (XAdapter, LinkedInAdapter, MetaAdapter) que encapsulam quirks de cada API.
É o que permite adicionar uma rede nova em horas em vez de dias — todo o orquestrador trata adapters como caixa-preta.
Strategy pattern, normalização de payload, mapeamento de erros para enum único e composição via Provider Registry.
Cada publicação vira um job (`publishToX`, `publishToLinkedIn`) com backoff exponencial em caso de 5xx ou rate limit.
APIs caem, retornam 429 e o worker reinicia — sem fila persistente você perde posts e dá explicação para cliente.
BullMQ (Redis) para simples, Temporal para workflows longos, dead-letter queue e idempotency key por post+rede.
Bucket público (ou CDN) onde você sobe a imagem uma vez e referencia por URL — algumas redes exigem upload binário, outras URL.
Sem URL pública, X e Bluesky aceitam upload direto, mas LinkedIn pré-assina e Meta exige container ID — fluxos diferentes precisam da mesma fonte.
Presigned URLs, transformações on-the-fly (Cloudinary), variantes por rede (1:1, 16:9, 9:16) e expiração de CDN.
Tabelas centrais: `User`, `SocialAccount` (tokens criptografados), `Post` (canonical), `PostTarget` (1 por rede), `Job` (estado da fila).
O modelo de dados define o que você consegue agendar, reagendar e relatar — modelar mal é refatorar em 3 meses.
Relação 1:N (Post → PostTarget), JSON columns para payload original, índices em `scheduledAt` e migrations versionadas.
UI Next.js com composer multi-rede (preview por plataforma), seletor de data/hora UTC-aware e calendário tipo Buffer com drag-to-reschedule.
Backend perfeito sem UI usável vira tool interna que ninguém adota — preview por rede é o diferencial.
Timezone do usuário, contadores de caracteres por rede (X=280, LinkedIn=3000), preview WYSIWYG e upload com progresso.
Endpoint HTTPS público que recebe POST da rede social quando o post é publicado, falha ou recebe engajamento.
Sem webhook você fica fazendo polling — caro, lento e quebra rate limit. Webhook é a única forma escalável de saber métricas em tempo real.
Assinatura HMAC, replay protection, túneis em dev (ngrok/cloudflared) e retry do lado de quem envia.
🔐 OAuth e tokens
Como o usuário autoriza sua app, como guardar tokens em segurança, como sobreviver à App Review da Meta e por que Bluesky muda tudo.
Protocolo onde o usuário é redirecionado para a rede, autoriza scopes, volta com um `code` que sua app troca por `access_token` no backend.
É o único caminho legal de publicar em nome de outro usuário — sem dominar OAuth, você nunca passa de uma conta única.
`response_type=code`, `state` anti-CSRF, PKCE, redirect URI exato e troca server-side com client_secret.
`access_token` autentica requests (vida curta, 1h-2h); `refresh_token` é trocado pelo próximo access_token sem reautorização do usuário.
Confundir os dois é a causa #1 de "minha app desconecta sozinha" — você está usando refresh como access ou vice-versa.
TTL, rotação de refresh_token (LinkedIn rotaciona, X não), token revogado e diferença entre offline_access scope e padrão.
Tokens são guardados criptografados no banco com AES-256-GCM, usando uma master key separada (KMS, env var, Vault).
Token em plain-text no banco = leak de credencial = invasor publica em nome dos seus clientes. Não negociável.
Envelope encryption, rotação de chave mestra, IV único por registro e nunca logar token nem em console.error.
Um job recorrente que percorre tokens que vão expirar nas próximas X horas e faz refresh, com lock pessimista para evitar race com requests vivos.
Refresh sob demanda (lazy) causa bugs de concorrência quando 2 jobs publicam ao mesmo tempo — proativo é mais seguro.
Janela de antecedência (ex: 24h antes), backoff em falha, marcar conta como "needs_reauth" e notificar o user.
Processo onde a plataforma valida sua app (vídeo de uso, política de privacidade, business verification) antes de liberar scopes de publicação para terceiros.
Sem app review aprovada, só você (dev) consegue publicar; nenhum cliente externo é autorizado. Pode levar 2-6 semanas.
`pages_manage_posts`, `w_member_social`, business verification, screencast obrigatório e razões mais comuns de rejeição.
Redes baseadas em protocolos abertos (AT Protocol, ActivityPub) onde qualquer dev autentica com app password (Bluesky) ou OAuth do servidor (Mastodon) sem review.
São o "modo fácil" para validar seu MVP enquanto a app review da Meta está rolando — em 1h você publica em produção.
App password, PDS (personal data server), federação, instâncias múltiplas no Mastodon e ausência total de gate-keeping.
💰 Custo, limites e estratégia
Tabela real de custos em 2026, rate limits por API, comparação self-hosted vs SaaS e o roadmap recomendado para sair do zero ao primeiro post automatizado.
X Basic ~$200/mês com ~10k posts; Meta Graph API gratuita mas requer review; LinkedIn API gratuita pós-aprovação; TikTok gratuita com cotas.
O custo da API é o piso do seu pricing — se você cobra menos do que paga ao X, perde dinheiro a cada post.
Tiers (Basic/Pro/Enterprise), custo marginal, billing por requests, hidden cost de App Review e seat-based pricing.
Limites por janela: X = 500 posts/24h no Basic, LinkedIn = 100/dia por user, Meta = 200 chamadas/hora por user, TikTok = 6 posts/min.
Bater rate limit em produção = todos os posts ficam pendurados na fila — precisa modelar throttling no worker antes de escalar.
Token bucket, headers `X-RateLimit-Remaining`, sliding window, throttling por conta e priorização de jobs.
Self-hosted (Postiz) = você roda VPS, faz App Review, controla dados; SaaS (Buffer, Ayrshare) = paga mensalidade e a empresa cuida do resto.
Cada lado tem dor diferente — SaaS tem teto de customização, self-hosted tem custo de manutenção em horas/mês.
TCO (total cost of ownership), lock-in, dados proprietários do cliente, SLA e capacidade de auditoria.
Postiz = OSS, AGPL, self-host; Ayrshare = API-first, ~$149/mês, ideal para devs; Buffer = UI-first para marketing, ~$15/seat.
Escolher errado custa migração depois — Buffer não tem API decente, Ayrshare não tem UI, Postiz exige sysadmin.
Cobertura de redes, webhooks suportados, suporte a vídeo, agendamento recorrente e qualidade da documentação.
Construir vale quando: produto core depende da integração, volume torna SaaS proibitivo, ou cliente exige controle total de dados (compliance).
Construir uma engine de publicação leva 3-6 meses de dev sênior — só faz sentido se a economia justifica.
Break-even mensal, custo de oportunidade, NIH (not invented here) e o caminho híbrido: usar SaaS como adapter no início.
Etapa 1: Bluesky + Mastodon (sem review); Etapa 2: LinkedIn + X; Etapa 3: Meta + TikTok (após review); Etapa 4: blogs (WordPress, Ghost, Hashnode).
Ordem errada trava o projeto por semanas esperando aprovação — começar pelas redes abertas valida o resto da arquitetura sem bloqueio.
MVP iterativo, dependências bloqueantes (App Review), validação técnica vs validação de mercado e crescimento incremental por adapter.