Como fazer / técnico

Como evitar post duplicado ao republicar

Como evitar que uma nova tentativa depois de um erro publique o mesmo conteúdo duas vezes.

A sua requisição de criar um post expira depois de 10 segundos sem resposta. Você não sabe se o PostGate recebeu e está processando, ou se a conexão caiu antes de chegar. A reação natural é tentar de novo — e é exatamente aí que uma integração sem cuidado publica o mesmo anúncio de lançamento duas vezes no Instagram e no LinkedIn de um cliente. Um timeout do lado do cliente nunca significa que a requisição falhou; significa só que você parou de esperar por uma resposta.

01

Por que a duplicação acontece

A maioria das APIs trata uma escrita retentada como um incômodo pequeno — uma linha extra no banco, limpa depois. Uma API de publicação é diferente: um POST /api/posts retentado depois de uma conexão que caiu pode significar que o mesmo anúncio de lançamento sai duas vezes nas redes sociais reais de um cliente. Isso não é um bug exótico — é o comportamento padrão de qualquer cliente HTTP que trata "não recebi resposta" como "não aconteceu nada" e refaz a mesma chamada do zero.

O mesmo problema aparece em qualquer lógica de retry automática: uma fila de jobs que reprocessa uma mensagem porque o worker não confirmou a tempo, um webhook de terceiro que reenvia o mesmo evento, ou um usuário que clica duas vezes num botão de "publicar" porque a interface não desabilitou o botão depois do primeiro clique.

02

A correção: uma chave de idempotência estável

Envie o cabeçalho Idempotency-Key em toda chamada de criação de post. Se o PostGate já aceitou uma requisição com aquela chave, ele retorna a resposta original em vez de criar um segundo post — mesmo que a sua chamada original tenha realmente sido processada e você só não tenha visto a resposta a tempo.

Criação de post segura para retentativaAPI do PostGate
curl -X POST "https://api.postgate.studio/api/posts?profile_group_id=grp_acme123" \
  -H "Authorization: Bearer $POSTGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: lancamento-post-001" \
  -d '{
    "post": { "body": "Dia de lançamento. 🚀" },
    "profiles": ["pro_instagram123", "pro_linkedin456"],
    "media": ["https://cdn.exemplo.com/lancamento.jpg"]
  }'
03

Gere chaves a partir da sua própria requisição, não a cada tentativa

Uma boa chave é estável para uma publicação lógica e diferente para cada publicação distinta — tipicamente derivada do seu próprio job interno, mensagem de fila ou ID de comando idempotente, como lancamento-post-{id_do_job_interno}. Gerar um UUID aleatório novo a cada retentativa anula o propósito inteiro: o PostGate veria cada tentativa como uma requisição totalmente nova e poderia publicar mais de uma vez — exatamente o problema que a chave existe para evitar.

Um erro comum é gerar a chave dentro da função que faz a chamada HTTP, em vez de no ponto de origem da intenção de publicar. Se a chave nasce junto com a tentativa de rede, ela muda a cada retentativa e vira só um UUID aleatório disfarçado de chave de idempotência.

04

Janela de retenção e reuso conflitante

O PostGate honra uma chave por 72 horas depois do primeiro uso. Retentar a mesma requisição idêntica dentro dessa janela retorna o post original sem alteração. Reusar a mesma chave com conteúdo diferente — um texto, perfis ou mídia diferentes — é rejeitado com um 409 conflict em vez de aplicar silenciosamente o novo conteúdo, de forma que uma colisão de chave nunca pode sobrescrever o que um cliente já viu publicado.

Chave reusada com conteúdo diferenteAPI do PostGate
{
  "error": {
    "code": "conflict",
    "message": "This idempotency key was already used with a different request.",
    "retryable": false,
    "request_id": "req_01JXYZ"
  }
}
05

Duplicação não é só sobre a chamada de criação

A chave de idempotência protege o momento da criação, mas a mesma disciplina precisa se estender ao resto do ciclo de vida. Ler o status por targets antes de decidir reenviar algo evita republicar um destino que na verdade já foi entregue com sucesso — um post pode estar partial, com alguns alvos published e outros failed, e a resposta correta é atuar só nos alvos que falharam, preservando os permalinks dos que já foram ao ar.

Combinada com uma Idempotency-Key estável na chamada de criação original e com um consumidor de webhook que deduplica pelo id do evento, essa disciplina torna o ciclo de vida inteiro seguro de raciocinar: você sabe exatamente o que foi aceito, exatamente o que aconteceu por destino, e nunca precisa adivinhar se uma retentativa vai publicar de novo um alvo que já teve sucesso.

Construa com o PostGate

Uma API para cada rede social que os seus clientes usam — com sandbox, documentado e pronto hoje.

Comece a construir Leia a documentação