{"id":95,"date":"2026-08-30T19:20:58","date_gmt":"2026-08-30T22:20:58","guid":{"rendered":"https:\/\/postping.com.br\/blog\/incoming-webhook-ou-api\/"},"modified":"2026-08-30T19:20:58","modified_gmt":"2026-08-30T22:20:58","slug":"incoming-webhook-ou-api","status":"publish","type":"post","link":"https:\/\/postping.com.br\/blog\/incoming-webhook-ou-api\/","title":{"rendered":"Incoming webhook vence a API para avisar cada publica\u00e7\u00e3o"},"content":{"rendered":"<p>Para avisar a equipe a cada artigo publicado, o incoming webhook ganha da API completa em quase todo blog de WordPress, e a diferen\u00e7a aparece antes de a primeira mensagem sair. De um lado existe uma URL que voc\u00ea cola num campo do painel. Do outro, um aplicativo registrado, um token, uma conex\u00e3o aberta o tempo todo e uma lista de intents declarada na hora de conectar. Os dois entregam a mesma linha de texto no mesmo canal do Discord. Cinco crit\u00e9rios explicam por que o caminho curto costuma bastar, e o sexto mostra os casos em que ele n\u00e3o basta de jeito nenhum.<\/p>\n<h2>O que cada um exige antes da primeira mensagem<\/h2>\n<p>O incoming webhook \u00e9 um endere\u00e7o, e a documenta\u00e7\u00e3o do Discord encerra a discuss\u00e3o numa frase: webhooks \u201cdo not require a bot user or authentication to use\u201d. N\u00e3o h\u00e1 cabe\u00e7alho <code>Authorization<\/code> na chamada, n\u00e3o h\u00e1 registro de aplicativo, n\u00e3o h\u00e1 tela de autoriza\u00e7\u00e3o para algu\u00e9m aprovar. O segredo \u00e9 o pr\u00f3prio caminho da requisi\u00e7\u00e3o, <code>POST \/webhooks\/{webhook.id}\/{webhook.token}<\/code>, e quem tem esse endere\u00e7o manda mensagem.<\/p>\n<p>Do lado da API, a lista \u00e9 outra. Voc\u00ea registra um aplicativo para receber um <code>client_id<\/code>, manda algu\u00e9m com permiss\u00e3o at\u00e9 <code>https:\/\/discord.com\/oauth2\/authorize<\/code> com o escopo <code>bot<\/code> e um inteiro de permiss\u00f5es, chama <code>Get Gateway Bot<\/code> para descobrir o endere\u00e7o WSS, abre a conex\u00e3o, come\u00e7a a mandar Heartbeat (opcode <code>1<\/code>) a cada <code>heartbeat_interval<\/code> e s\u00f3 ent\u00e3o envia o Identify com token, intents e propriedades de conex\u00e3o. A plataforma responde com um evento Ready. A\u00ed o bot existe.<\/p>\n<p>Para um blog, o problema n\u00e3o \u00e9 a quantidade de passos, \u00e9 a natureza do \u00faltimo. Uma requisi\u00e7\u00e3o de PHP no WordPress nasce quando algu\u00e9m abre uma p\u00e1gina e morre quando a resposta \u00e9 enviada. Ela n\u00e3o tem onde guardar uma conex\u00e3o WebSocket aberta, nem quem mande heartbeat de madrugada, quando ningu\u00e9m est\u00e1 acessando o site. Um bot de verdade pede um processo separado, rodando o tempo todo, em algum lugar que n\u00e3o \u00e9 a hospedagem compartilhada onde o site mora. O webhook cabe dentro do ciclo de vida que o WordPress j\u00e1 tem: uma requisi\u00e7\u00e3o HTTP que sai no momento da publica\u00e7\u00e3o e termina ali. Se a mec\u00e2nica ainda for nova, ela est\u00e1 destrinchada em <a href=\"https:\/\/postping.com.br\/blog\/o-que-e-webhook\/\">o que \u00e9 um webhook<\/a>.<\/p>\n<p>Ganha o incoming webhook, pela infraestrutura que ele dispensa antes mesmo de existir mensagem.<\/p>\n<h2>O que sobra de capacidade depois que a mensagem sai<\/h2>\n<p>O webhook manda e esquece. O corpo aceita at\u00e9 <strong>2000<\/strong> caracteres de conte\u00fado e uma lista de at\u00e9 <strong>10<\/strong> embeds, que \u00e9 onde entram t\u00edtulo, cor e imagem do card. Por padr\u00e3o a chamada devolve <code>204 No Content<\/code>, ou seja, a mensagem foi entregue e voc\u00ea n\u00e3o recebe nem o id dela. Com <code>?wait=true<\/code> a resposta traz o corpo da mensagem criada, e esse \u00e9 o \u00fanico jeito de saber o identificador do que acabou de aparecer no canal.<\/p>\n<p>Esse detalhe decide mais coisa do que parece. Sem o id, n\u00e3o existe editar o aviso depois. Se o t\u00edtulo do artigo mudar meia hora ap\u00f3s a publica\u00e7\u00e3o, o aviso no canal fica com o t\u00edtulo velho para sempre, e a corre\u00e7\u00e3o vira mandar outra mensagem. Quem quer a possibilidade de corrigir precisa pedir <code>wait=true<\/code> desde o primeiro disparo e guardar o id junto do post. \u00c9 uma linha de c\u00f3digo no dia em que se monta a integra\u00e7\u00e3o, e \u00e9 imposs\u00edvel recuperar depois.<\/p>\n<p>A API faz tudo o que o webhook n\u00e3o faz: l\u00ea o canal, edita, apaga, reage, responde quem comentou o aviso. A pergunta \u00e9 se voc\u00ea vai usar alguma dessas coisas. Um aviso de artigo novo \u00e9 uma via de m\u00e3o \u00fanica, sai do WordPress e chega no canal; a conversa que vem depois \u00e9 entre pessoas. O time discute o artigo no Discord e ningu\u00e9m espera que o WordPress participe. Por isso o ponto fica com o webhook aqui, com a ressalva do id: capacidade extra s\u00f3 conta quando existe um plano concreto de us\u00e1-la, e \u201cum dia talvez\u201d n\u00e3o \u00e9 plano.<\/p>\n<h2>Como cada um se comporta quando o limite aparece<\/h2>\n<p>O teto do Discord \u00e9 p\u00fablico: \u201cAll bots can make up to 50 requests per second to our API.\u201d Quando voc\u00ea passa, a resposta <code>429<\/code> traz tr\u00eas campos, <code>message<\/code>, <code>retry_after<\/code> e <code>global<\/code>, e o <code>retry_after<\/code> j\u00e1 diz em quantos segundos tentar de novo. Os cabe\u00e7alhos <code>X-RateLimit-Remaining<\/code>, <code>X-RateLimit-Reset-After<\/code> e <code>X-RateLimit-Bucket<\/code> mostram quanto sobrou da cota e quando ela reabre. Webhook e bot falam o mesmo idioma aqui.<\/p>\n<p>A diferen\u00e7a aparece em quem escreve o c\u00f3digo de repeti\u00e7\u00e3o. O Discord restringe temporariamente o IP que faz requisi\u00e7\u00f5es inv\u00e1lidas demais, e o limite atual \u00e9 de <strong>10.000 a cada 10 minutos<\/strong>, contando respostas 401, 403 e 429. Um la\u00e7o que ignora o <code>retry_after<\/code> e tenta de novo na hora transforma um 429 passageiro em bloqueio do servidor inteiro, o que derruba junto todos os sites hospedados no mesmo IP. Quem usa a URL crua manda uma requisi\u00e7\u00e3o por artigo e nunca chega perto disso. O vocabul\u00e1rio desses c\u00f3digos est\u00e1 em <a href=\"https:\/\/postping.com.br\/blog\/erro-webhook-401-404-429\/\">erro de webhook no WordPress<\/a>.<\/p>\n<p>H\u00e1 ainda um limite que n\u00e3o vem da plataforma. As requisi\u00e7\u00f5es HTTP de sa\u00edda do WordPress usam timeout padr\u00e3o de <strong>5 segundos<\/strong>. Se o Discord demorar mais que isso para responder, o disparo falha sem 429 nenhum e sem c\u00f3digo de erro da API, e o registro do que aconteceu \u00e9 a \u00fanica coisa que separa o sil\u00eancio no canal de um diagn\u00f3stico.<\/p>\n<p>No Telegram a compara\u00e7\u00e3o nem chega a existir, porque n\u00e3o h\u00e1 incoming webhook: toda chamada vai para <code>https:\/\/api.telegram.org\/bot&lt;token&gt;\/METHOD_NAME<\/code>, com o token no caminho, e a API de bot \u00e9 o caminho \u00fanico. Os limites de l\u00e1 s\u00e3o de ritmo, n\u00e3o de vaz\u00e3o. \u201cIn a single chat, avoid sending more than one message per second\u201d, diz a documenta\u00e7\u00e3o; num grupo, o bot n\u00e3o passa de 20 mensagens por minuto; em disparo amplo, fica em torno de 30 mensagens por segundo. Um blog que publica tr\u00eas artigos no mesmo minuto ainda est\u00e1 a dezessete mensagens de encostar no limite do grupo.<\/p>\n<p>Aqui ningu\u00e9m ganha, porque nenhum blog chega perto desses n\u00fameros. O crit\u00e9rio s\u00f3 decide alguma coisa quando o volume vem de outro lugar, como uma ag\u00eancia disparando o aviso de trinta sites pelo mesmo servidor: nesse caso o que separa os dois deixa de ser o teto e volta a ser quem respeita o <code>retry_after<\/code>.<\/p>\n<h2>Quanto trabalho cada um d\u00e1 quando a plataforma muda<\/h2>\n<p>Este crit\u00e9rio s\u00f3 cobra depois de alguns meses, e cobra caro. Em agosto de 2026, o changelog do Discord registrou quatro mudan\u00e7as que atingem quem opera um bot. No dia 5, o campo <code>application_id<\/code> dos objetos de canal passou a poder vir nulo, quebra que exige tratamento de nulo no c\u00f3digo existente. No dia 13, veio a ofusca\u00e7\u00e3o de canais: bots deixam de receber metadados completos de canais em que n\u00e3o t\u00eam <code>VIEW_CHANNEL<\/code>, com a mudan\u00e7a virando obrigat\u00f3ria em 16 de novembro de 2026. No dia 14, o endpoint de conex\u00f5es do usu\u00e1rio anunciou que para de retornar as conex\u00f5es da Battle.net a partir de 22 de setembro de 2026. No dia 27, endpoints de prune passaram a exigir <code>ADMINISTRATOR<\/code> onde antes bastavam <code>MANAGE_GUILD<\/code> e <code>KICK_MEMBERS<\/code>.<\/p>\n<p>Nenhuma dessas quatro encosta em <code>POST \/webhooks\/{id}\/{token}<\/code>. A superf\u00edcie do incoming webhook \u00e9 pequena porque ele faz pouco, e o que faz pouco muda pouco.<\/p>\n<p>Some-se a isso a fila de aprova\u00e7\u00e3o. As intents privilegiadas <code>GUILD_PRESENCES<\/code>, <code>GUILD_MEMBERS<\/code> e <code>MESSAGE_CONTENT<\/code> precisam ser aprovadas para aplicativos que se qualificam para verifica\u00e7\u00e3o, e aplicativos com mais de 10.000 usu\u00e1rios \u00fanicos passam por revis\u00e3o para continuar usando essas intents. Avisar sobre artigo novo n\u00e3o pede nenhuma delas, mas o dia em que o bot precisar ler o conte\u00fado de uma mensagem \u00e9 o dia em que entra uma revis\u00e3o externa no meio do seu cronograma.<\/p>\n<p>Do outro lado do mesmo problema est\u00e1 a Meta, onde a API n\u00e3o \u00e9 op\u00e7\u00e3o. Os tokens de curta dura\u00e7\u00e3o \u201ctypically last about one to two hours\u201d e os de longa dura\u00e7\u00e3o duram \u201cabout 60 days\u201d, com um aviso da pr\u00f3pria documenta\u00e7\u00e3o: n\u00e3o conte com esses prazos, porque podem mudar sem avisar ou expirar antes da hora. Quem publica no Instagram assina esse contrato de manuten\u00e7\u00e3o querendo ou n\u00e3o. Quem s\u00f3 avisa o Discord n\u00e3o assina nada.<\/p>\n<p>Ganha o incoming webhook por uma margem que os outros crit\u00e9rios n\u00e3o chegam perto de repetir.<\/p>\n<h2>O raio de estrago quando o segredo vaza<\/h2>\n<p>A URL do incoming webhook \u00e9 uma credencial ao portador com apar\u00eancia de link. Qualquer pessoa que a tenha publica naquele canal com o nome e o avatar do webhook, sem passar por login nenhum. E n\u00e3o para no envio: as vers\u00f5es \u201cwith token\u201d dos endpoints de modificar e apagar webhook tamb\u00e9m dispensam autentica\u00e7\u00e3o, ent\u00e3o quem copiou a URL do seu arquivo de configura\u00e7\u00e3o pode renomear o webhook, trocar o avatar e apag\u00e1-lo.<\/p>\n<p>O consolo \u00e9 o tamanho do estrago. O webhook enxerga um canal, n\u00e3o l\u00ea nada, n\u00e3o entra em outro servidor e n\u00e3o fala com o resto da comunidade. Trocar leva um minuto: apaga, cria outro, cola a URL nova. O custo real \u00e9 encontrar todos os lugares onde a antiga estava colada, e num parque de trinta sites \u00e9 a\u00ed que o minuto vira tarde.<\/p>\n<p>O token de bot \u00e9 o oposto em quase tudo. Ele carrega o que o inteiro de permiss\u00f5es concedeu na autoriza\u00e7\u00e3o, em todos os servidores em que o bot entrou, e troc\u00e1-lo significa reimplantar onde quer que o processo esteja rodando. No Telegram, o token viaja no caminho da URL de toda requisi\u00e7\u00e3o, o que o deposita em log de acesso, em proxy no meio do trajeto e em qualquer captura de tr\u00e1fego; revogar derruba de uma vez todas as integra\u00e7\u00f5es daquele bot, inclusive as que estavam funcionando.<\/p>\n<p>Em raio de estrago o webhook ganha, sob uma condi\u00e7\u00e3o que quase ningu\u00e9m cumpre: tratar a URL como senha. Ela n\u00e3o tem cara de senha, e \u00e9 por isso que aparece colada em issue p\u00fablica, em captura de tela de configura\u00e7\u00e3o e em reposit\u00f3rio de tema.<\/p>\n<h2>Onde a API ganha, e s\u00e3o mais casos do que parece<\/h2>\n<p>O primeiro caso n\u00e3o \u00e9 escolha. Existem plataformas sem incoming webhook, e as duas que mais interessam a quem tem blog s\u00e3o justamente essas: Instagram e P\u00e1gina do Facebook n\u00e3o t\u00eam campo onde colar uma URL. Publicar ali \u00e9 Graph API, com aplicativo, login OAuth e token com prazo, ou n\u00e3o \u00e9. Quem quer o artigo no feed sem trabalho manual vai pagar o pre\u00e7o da API de qualquer jeito, e a \u00fanica pergunta que sobra \u00e9 quem mant\u00e9m isso de p\u00e9.<\/p>\n<p>O segundo caso \u00e9 precisar de resposta de volta. Um bot que reage a comando, que edita o aviso quando o artigo \u00e9 atualizado, que arquiva a thread quando o assunto morre: tudo isso pede leitura do canal, e ler o webhook n\u00e3o faz.<\/p>\n<p>O terceiro \u00e9 o canal vari\u00e1vel. A URL do incoming webhook nasce presa a um canal, e quando ela sai do fluxo de autoriza\u00e7\u00e3o a pessoa escolhe onde ele vai postar; nas palavras da documenta\u00e7\u00e3o, \u201cwhen the webhook is executed, it will post its message into this channel\u201d. Um site em tr\u00eas idiomas com um canal por idioma precisa de tr\u00eas webhooks e de uma regra que escolha entre eles a cada publica\u00e7\u00e3o. Com bot, o canal \u00e9 um par\u00e2metro da chamada.<\/p>\n<p>O Post Ping fica dos dois lados dessa compara\u00e7\u00e3o, e \u00e9 justo dizer onde. Para avisar equipe e comunidade, ele usa o caminho curto: webhook do Discord com imagem e cor, bot do Telegram para grupos e canais, e uma verifica\u00e7\u00e3o di\u00e1ria que procura artigos publicados que n\u00e3o geraram aviso. Para Instagram e P\u00e1gina do Facebook, onde caminho curto n\u00e3o existe, ele passa pelo login oficial da Meta e renova o acesso sozinho, justamente porque o prazo de 60 dias \u00e9 problema de quem mant\u00e9m o plugin, n\u00e3o de quem escreve o artigo. As limita\u00e7\u00f5es do lado curto continuam valendo dentro dele: um webhook por canal, aviso de m\u00e3o \u00fanica, e nada volta do Discord para o WordPress. O <a href=\"https:\/\/postping.com.br\/recursos\">detalhamento dos recursos<\/a> mostra o que cada lado cobre.<\/p>\n<h2>A conta que decide<\/h2>\n<p>Um blog que publica um artigo por dia e avisa dois canais faz sessenta requisi\u00e7\u00f5es por m\u00eas. Um aplicativo com conex\u00e3o de gateway aberta precisa de um processo vivo durante os trinta dias inteiros para entregar exatamente essas sessenta, mais o c\u00f3digo que trata reconex\u00e3o, heartbeat perdido e mudan\u00e7a de contrato no changelog.<\/p>\n<p>A escolha se resolve em tr\u00eas perguntas, e nenhuma delas \u00e9 sobre escala: voc\u00ea precisa ler alguma coisa de volta, precisa editar o que j\u00e1 mandou, e a plataforma de destino oferece webhook? Com \u201cn\u00e3o\u201d, \u201cn\u00e3o\u201d e \u201csim\u201d, a URL colada num campo \u00e9 a resposta certa, e vai continuar sendo daqui a um ano, porque \u00e9 a parte da API que menos muda.<\/p>\n<p>Sessenta requisi\u00e7\u00f5es por m\u00eas contra um teto de cinquenta por segundo: o tr\u00e1fego de um m\u00eas inteiro cabe em 1,2 segundo da cota que a plataforma j\u00e1 entrega de gra\u00e7a.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Incoming webhook ou API completa: comparamos exig\u00eancia inicial, limites, manuten\u00e7\u00e3o e risco de vazamento para decidir quem avisa o time a cada artigo.<\/p>\n","protected":false},"author":1,"featured_media":94,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-95","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-webhooks"],"_links":{"self":[{"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/posts\/95","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/comments?post=95"}],"version-history":[{"count":0,"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/posts\/95\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/media\/94"}],"wp:attachment":[{"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/media?parent=95"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/categories?post=95"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/postping.com.br\/blog\/wp-json\/wp\/v2\/tags?post=95"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}