This commit is contained in:
Lizandro Guarnizo
2026-05-16 21:41:44 -05:00
parent 1511ca97d9
commit 5aad09f1cd
6 changed files with 128 additions and 18 deletions
+57
View File
@@ -1,7 +1,10 @@
package controllers
import (
"encoding/json"
"fmt"
"io"
"log"
"math"
"net/http"
"strconv"
@@ -9,6 +12,7 @@ import (
"time"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/pkg/helpers"
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)
@@ -103,6 +107,7 @@ func CreateSaasApiConfig(c *fiber.Ctx) error {
PayloadTemplate: req.PayloadTemplate,
TimeoutSeg: timeout,
Activo: req.Activo,
WebhookToken: helpers.RandomString(32),
}
if err := models.CreateSaasApiConfig(&item); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
@@ -298,3 +303,55 @@ func GetSaasDispatchLogs(c *fiber.Ctx) error {
"limit": limit,
})
}
// ─── Webhook entrante por token ───────────────────────────────────────────────
// SaasWebhookInHandler recibe llamadas entrantes del SaaS externo identificadas
// por el WebhookToken único de la integración. No requiere autenticación.
// Ruta pública: POST /webhooks/saas-in/:token
func SaasWebhookInHandler(c *fiber.Ctx) error {
token := strings.TrimSpace(c.Params("token"))
if token == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "token requerido"})
}
cfg, err := models.GetSaasApiConfigByWebhookToken(token)
if err != nil {
// Responder 200 para evitar reintentos agresivos de sistemas externos
log.Printf("[SaasWebhookIn] Token desconocido: %s", token)
return c.Status(fiber.StatusOK).JSON(fiber.Map{"ok": false, "msg": "token no reconocido"})
}
// Capturar headers relevantes como JSON
headersMap := map[string]string{}
c.Request().Header.VisitAll(func(k, v []byte) {
key := string(k)
// Solo guardar headers informativos, excluir cookies/auth
if key != "Cookie" && key != "Authorization" {
headersMap[key] = string(v)
}
})
headersJSON, _ := json.Marshal(headersMap)
rawBody := string(c.Body())
entry := models.SaasWebhookInLog{
SaasApiConfigID: cfg.ID,
Token: token,
Metodo: c.Method(),
IP: c.IP(),
Body: rawBody,
Headers: string(headersJSON),
}
_ = models.SaveSaasWebhookInLog(&entry)
log.Printf("[SaasWebhookIn] Integración '%s' (ID=%d) recibió callback desde IP=%s method=%s",
cfg.Nombre, cfg.ID, c.IP(), c.Method())
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"ok": true,
"integracion": cfg.Nombre,
"saas_api_id": cfg.ID,
"message": fmt.Sprintf("Webhook recibido para integración: %s", cfg.Nombre),
})
}