From 2d2b55128a52b28820ffcc568b87ff18058b57cc Mon Sep 17 00:00:00 2001 From: Tiago Date: Tue, 29 Sep 2026 16:29:18 -0300 Subject: [PATCH] Handle Evolution LID replies in bridge --- .../java/com/seconectai/condocontab/Main.java | 1 + .../integracao/ExternalBridgeHandler.java | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/seconectai/condocontab/Main.java b/src/main/java/com/seconectai/condocontab/Main.java index 8e1b2c1..208053a 100644 --- a/src/main/java/com/seconectai/condocontab/Main.java +++ b/src/main/java/com/seconectai/condocontab/Main.java @@ -80,6 +80,7 @@ public final class Main { router.post("/api/auth/login", authHandlers.funcionarioLogin()); router.post("/api/master/webhooks/abacatepay", abacatePayWebhookHandler); router.post("/api/webhooks/evolution/respostas", externalBridgeHandler); + router.prefix("/api/webhooks/evolution/respostas/", externalBridgeHandler); router.post("/api/integracao/mensagens", authMiddleware.exigirApiKey(externalBridgeHandler)); router.prefix("/api/master/", authMiddleware.exigirMaster(masterHandlers)); router.prefix("/api/financeiro/", authMiddleware.exigirFuncionario(financeiroHandlers)); diff --git a/src/main/java/com/seconectai/condocontab/integracao/ExternalBridgeHandler.java b/src/main/java/com/seconectai/condocontab/integracao/ExternalBridgeHandler.java index 56b0469..c1f029e 100644 --- a/src/main/java/com/seconectai/condocontab/integracao/ExternalBridgeHandler.java +++ b/src/main/java/com/seconectai/condocontab/integracao/ExternalBridgeHandler.java @@ -45,6 +45,7 @@ public final class ExternalBridgeHandler implements HttpHandler { try { route(ex); } catch (IllegalArgumentException e) { + System.err.println("Webhook/integracao rejeitado: " + e.getMessage()); HttpResponses.json(ex, 400, Map.of("erro", "requisicao_invalida", "mensagem", e.getMessage())); } catch (Exception e) { e.printStackTrace(System.err); @@ -59,7 +60,7 @@ public final class ExternalBridgeHandler implements HttpHandler { enviarMensagem(ex, (long) ex.getAttribute(AuthMiddleware.ATTR_EMPRESA_ID)); return; } - if ("/api/webhooks/evolution/respostas".equals(path) && "POST".equals(method)) { + if ((path.equals("/api/webhooks/evolution/respostas") || path.startsWith("/api/webhooks/evolution/respostas/")) && "POST".equals(method)) { receberRespostaEvolution(ex); return; } @@ -105,20 +106,30 @@ public final class ExternalBridgeHandler implements HttpHandler { private void receberRespostaEvolution(HttpExchange ex) throws Exception { validarWebhookEvolution(ex); String raw = rawBody(ex); + if (isFromMe(raw)) { + HttpResponses.json(ex, 200, Map.of("ok", true, "encaminhado", false, "motivo", "mensagem_enviada_pelo_sistema")); + return; + } String numero = telefoneWhatsapp(firstNonBlank(extract(raw, "remoteJidAlt"), extract(raw, "remoteJid"), extract(raw, "from"), extract(raw, "number"), extract(raw, "sender"))); String texto = firstNonBlank(extract(raw, "conversation"), extract(raw, "text"), extract(raw, "body"), extract(raw, "message")); if (numero.isBlank()) { + System.err.println("Webhook Evolution sem numero identificavel. Payload inicial: " + raw.substring(0, Math.min(raw.length(), 500))); HttpResponses.json(ex, 400, Map.of("erro", "numero_nao_identificado")); return; } try (Connection c = masterDs.getMasterConnection()) { Map envio = one(c, "SELECT * FROM integracao_mensagens WHERE telefone=? AND callback_url IS NOT NULL AND status='enviado' ORDER BY criado_em DESC,id DESC LIMIT 1", numero); + if (envio == null && raw.contains("@lid")) { + envio = one(c, "SELECT * FROM integracao_mensagens WHERE callback_url IS NOT NULL AND status='enviado' AND criado_em >= now() - interval '24 hours' ORDER BY criado_em DESC,id DESC LIMIT 1"); + } if (envio == null) { + System.out.println("Webhook Evolution sem envio correspondente. numero=" + numero + ", texto=" + resumo(texto)); HttpResponses.json(ex, 200, Map.of("ok", true, "encaminhado", false, "motivo", "envio_nao_encontrado")); return; } long respostaId = registrarResposta(c, ((Number)envio.get("id")).longValue(), raw, texto); boolean encaminhado = encaminharCallback(envio, respostaId, numero, texto); + System.out.println("Webhook Evolution resposta registrada. mensagem_id=" + envio.get("id") + ", resposta_id=" + respostaId + ", numero=" + numero + ", encaminhado=" + encaminhado); HttpResponses.json(ex, 200, Map.of("ok", true, "encaminhado", encaminhado, "mensagem_id", envio.get("id"), "resposta_id", respostaId)); } } @@ -255,6 +266,8 @@ public final class ExternalBridgeHandler implements HttpHandler { private String emptyToNull(String v){return v==null||v.isBlank()?null:v;} private String firstNonBlank(String... values){for(String v:values)if(v!=null&&!v.isBlank())return v;return "";} private String extract(String raw,String key){String marker="\""+key+"\"";int p=raw.indexOf(marker);if(p<0)return null;int colon=raw.indexOf(':',p);if(colon<0)return null;int q=raw.indexOf('"',colon+1);int e=q<0?-1:raw.indexOf('"',q+1);if(q<0||e<0)return null;return raw.substring(q+1,e).split("@")[0];} + private boolean isFromMe(String raw){String marker="\"fromMe\"";int p=raw.indexOf(marker);if(p<0)return false;int colon=raw.indexOf(':',p);if(colon<0)return false;String tail=raw.substring(colon+1,Math.min(raw.length(),colon+12)).trim();return tail.startsWith("true");} + private String resumo(String value){if(value==null)return "";return value.length()>120?value.substring(0,120):value;} private record Destinatario(String tipo,long id,String nome,String telefone){} private record ApiKeyConfig(String sistemaExterno,String callbackUrl,String callbackSecret){} }