MELLOW HUB · NOTAS DE CAMPO

Agende posts em redes sociais com uma API REST

Uma receita do Mellow Hub para verificar os canais conectados, validar um post, agendar com uma chave de idempotência e ler o resultado final de cada destino.

Por Mellow · Atualizado em

A sequência completa

Para agendar um post pelo Mellow Hub, identifique a autoridade da credencial, selecione os canais conectados, valide uma solicitação e depois crie o post com uma chave de idempotência estável. Leia o post resultante de novo para saber o que aconteceu em cada destino. Uma resposta de criação bem-sucedida não é prova de que todas as redes publicaram.

Esta receita usa REST. Um cliente MCP segue a sequência equivalente whoami → list_channels → validate_post → create_post → get_post descrita no guia de MCP para redes sociais.

Teste a verificação de entrada com um exemplo pronto para rodar

Baixe o verificador de entrada em Node.js e o modelo post.example.json na mesma pasta. O script precisa do Node.js 22 ou mais recente e de nenhum pacote. Leia o código-fonte e depois forneça uma credencial existente do Hub pelo seu ambiente de segredos, sob o nome MELLOW_HUB_KEY.

Para esta verificação, channels:read e posts:read bastam. Escolha apenas os canais que você pretende usar nas configurações de acesso do Hub. Listar canais exige só a primeira permissão. Esta verificação de entrada não precisa de permissão de publicação nem de assinatura.

node mellow-hub-check.mjs --channels
# Substitua os IDs de canal e a URL da mídia em post.example.json.
node mellow-hub-check.mjs post.example.json

O script verifica os canais disponíveis para a credencial, envia o seu JSON editado ao endpoint de validação autenticado do Mellow Hub e imprime os problemas impeditivos e as notas. Ele termina com 0 quando essas verificações de entrada passam, 1 para problemas de entrada, ou 2 para uma falha de arquivo, permissão, conexão ou resposta inesperada. HTTP 200 com ok: false ainda reprova a verificação.

Ele não cria post, não baixa mídia e não faz nenhuma solicitação a uma rede social. Passar nesta verificação não confirma a duração do arquivo, a proporção, a autorização futura da conta nem a publicação. O código para download é testado com fixtures isoladas; não é uma publicação real de cliente gravada. Para as solicitações curl abaixo, salve o seu arquivo editado como post.json.

1. Verifique a conta e a credencial

Conecte os seus próprios canais no Hub e crie uma credencial com os canais e o modo que você pretende delegar. Guarde-a no ambiente de segredos do seu servidor como MELLOW_HUB_KEY; nunca a coloque no JavaScript do front-end nem em um repositório público. Os exemplos leem essa variável de ambiente sem exibir o valor dela.

curl --fail-with-body https://www.mellow.world/api/hub/v1/whoami \
  -H "Authorization: Bearer $MELLOW_HUB_KEY"

curl --fail-with-body https://www.mellow.world/api/hub/v1/channels \
  -H "Authorization: Bearer $MELLOW_HUB_KEY"

Use os IDs de canal retornados para esta conta. Os valores spc_… abaixo são apenas marcadores de posição. Verifique o modo e a cota disponível antes de criar qualquer coisa. Uma credencial de revisão prepara um post para uma pessoa aprovar. Uma credencial de piloto automático pode agir dentro do escopo, do teto e da validade delegados.

2. Descreva o post real

Salve a estrutura a seguir como post.json. Substitua os dois IDs de canal, o endereço da mídia de exemplo, o texto e a data de exemplo. Use um deslocamento de fuso horário ISO 8601 explícito ou o Z de UTC; o carimbo de data e hora representa um instante, não o relógio local do leitor. A data de 2030 do exemplo é deliberadamente ilustrativa.

{
  "caption": "A short look at how this piece was made.",
  "channels": [
    "spc_your_instagram_channel",
    "spc_your_youtube_channel"
  ],
  "media": [
    "https://cdn.example.com/your-video.mp4"
  ],
  "scheduledAt": "2030-01-15T10:00:00Z",
  "options": {
    "instagram": {
      "placement": "reels"
    },
    "youtube": {
      "title": "How this piece was made",
      "privacyStatus": "public"
    }
  }
}

A rede busca a mídia no momento da publicação, então a URL HTTPS real precisa continuar acessível nessa hora. Um arquivo local privado ou uma URL assinada expirada não vão funcionar. Este exemplo dá ao YouTube seu título separado e seleciona o posicionamento Reels para o Instagram. A disponibilidade de formatos ainda depende das suas contas conectadas e do provedor.

3. Valide sem publicar

curl --fail-with-body https://www.mellow.world/api/hub/v1/validate \
  -H "Authorization: Bearer $MELLOW_HUB_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @post.json

Inspecione ok, issues e notes na resposta. Corrija cada problema impeditivo antes de continuar. A validação pode retornar HTTP 200 com ok: false, então verificar só o status HTTP não basta. O endpoint autenticado verifica a propriedade real dos seus canais, além das regras de entrada.

Para uma prévia sem conta das verificações de legenda, título e quantidade de mídias, use o verificador de posts gratuito. Nenhuma das duas prévias mede a duração nem a proporção do seu arquivo real, e um provedor ainda pode recusar a entrega.

4. Crie uma vez, repita com consistência

A credencial inicial somente leitura não pode criar posts. Antes desta etapa, use uma conexão com posts:write e posts:publish para os canais pretendidos. Esses escopos também são exigidos no modo de revisão; o modo de revisão continua deixando a decisão de publicar com uma pessoa. Sem eles, a solicitação retorna um erro de permissão.

A próxima solicitação cria o post. Execute-a só quando o conteúdo e a autoridade sobre o destino estiverem corretos. No modo de revisão, ela aguarda aprovação; no piloto automático, a ação delegada pode prosseguir no horário agendado.

curl --fail-with-body https://www.mellow.world/api/hub/v1/posts \
  -H "Authorization: Bearer $MELLOW_HUB_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: studio-process-video-slot-001" \
  --data-binary @post.json

Persista a chave de idempotência junto com a tarefa na sua aplicação. Se a resposta se perder, repita a mesma solicitação com a mesma chave. Não crie uma chave nova só porque houve um timeout. Um post diferente precisa de uma chave diferente; reutilizar uma chave com conteúdo alterado é rejeitado.

5. Leia o resultado por destino

Salve o post.id retornado e recupere-o com GET /api/hub/v1/posts/{id}, usando o mesmo cabeçalho de autorização. Inspecione cada entrada em targets e sua URL pública. Um post em várias redes pode ser parcial: um destino pode ter sucesso enquanto outro falha.

Mantenha juntos o horário planejado, o ID do post no Hub, a chave de idempotência e os resultados por destino no seu próprio registro da tarefa. Evite registrar credenciais ou cabeçalhos de autorização completos em logs. Quando um destino falha, use o erro informado para decidir a próxima ação, em vez de recriar o post inteiro às cegas.

Recupere um post com timeout ou publicado só em parte

Um timeout significa que quem fez a chamada não sabe o resultado. Um resultado partial significa que o Hub registrou resultados diferentes para os destinos selecionados. Mantenha esses casos separados ao decidir o que enviar em seguida.

A resposta de criação se perdeu

Guarde o payload original e a chave de idempotência no seu registro da tarefa antes da primeira solicitação. Repita essa solicitação sem alterações, com a mesma chave e uma autoridade válida. Quando o Hub já tem o post, ele retorna o ID e o estado atual desse post. A resposta REST continua sendo HTTP 201, então um 201 sozinho não diz se esta tentativa criou um registro novo. Com o ID em mãos, use GET para acompanhar o estado.

Se você receber 409 idempotency_key_reused, compare a solicitação com a tarefa salva. Não gere outra chave automaticamente para contornar o erro: isso descreveria uma operação nova e poderia duplicar a publicação original.

Um destino falhou depois que outro publicou

Leia targets antes de preparar uma recuperação. Por exemplo, se o Instagram está published e o YouTube está failed, corrija o problema informado do YouTube e valide um payload novo contendo apenas esse canal do YouTube. Uma recuperação deliberada usa uma chave nova, como studio-process-video-slot-001-youtube-recovery-1. Guarde o novo ID do post junto com a tarefa original. As permissões de canal habituais, o modo de revisão e a cota de publicações continuam valendo.

Repetir a chave original retorna o post existente; não reinicia os destinos que falharam. Um destino ainda em espera ou em publicação não é uma falha confirmada. Não o reenvie só porque quem chamou parou de esperar, e não inclua na solicitação de recuperação destinos que já publicaram.

Perguntas que surgem em integrações reais

Posso usar uma legenda diferente em uma rede?

Sim. Uma entrada de perChannel com o ID real do canal como chave substitui a legenda ou a mídia desse canal. Campos válidos para toda a plataforma ficam em options. Veja os exemplos resolvidos na referência do Hub.

Um agente pode conectar minhas contas sociais sozinho?

Não. O titular da conta conclui o fluxo de conexão correspondente. Uma chave de API é uma delegação para ações já autorizadas, não uma permissão para se passar pelo titular na tela de login de uma rede.

Uma solicitação consome uma publicação do meu plano?

A cota é contada por destino de rede. Confira os planos atuais e a cota restante da credencial antes de escolher os destinos.