second commit
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/gochat/gochat/internal/service"
|
||||
"github.com/gochat/gochat/pkg/pagination"
|
||||
"github.com/gochat/gochat/pkg/response"
|
||||
)
|
||||
|
||||
// IntegrationHookHandler handles IntegrationHook CRUD + ProcessEvent endpoints.
|
||||
// Reference: Chatwoot Integrations::HooksController + AppsController
|
||||
type IntegrationHookHandler struct {
|
||||
svc *service.IntegrationHookService
|
||||
}
|
||||
|
||||
// NewIntegrationHookHandler creates a new IntegrationHookHandler.
|
||||
func NewIntegrationHookHandler(svc *service.IntegrationHookService) *IntegrationHookHandler {
|
||||
return &IntegrationHookHandler{svc: svc}
|
||||
}
|
||||
|
||||
// --- Integration Apps (catalog) ---
|
||||
|
||||
// ListApps retrieves all available integration apps.
|
||||
// GET /api/v1/accounts/:account_id/integrations/apps
|
||||
func (h *IntegrationHookHandler) ListApps(c *gin.Context) {
|
||||
apps, err := h.svc.ListApps(c.Request.Context())
|
||||
if err != nil {
|
||||
handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
response.OK(c, apps)
|
||||
}
|
||||
|
||||
// GetApp retrieves a single integration app by ID.
|
||||
// GET /api/v1/accounts/:account_id/integrations/apps/:id
|
||||
func (h *IntegrationHookHandler) GetApp(c *gin.Context) {
|
||||
id, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
|
||||
app, svcErr := h.svc.GetApp(c.Request.Context(), id)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OK(c, app)
|
||||
}
|
||||
|
||||
// --- Integration Hooks CRUD ---
|
||||
|
||||
// ListHooks retrieves all integration hooks for an account, paginated.
|
||||
// GET /api/v1/accounts/:account_id/integrations/hooks
|
||||
func (h *IntegrationHookHandler) ListHooks(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
||||
return
|
||||
}
|
||||
|
||||
page := pagination.Parse(c)
|
||||
hooks, total, svcErr := h.svc.List(c.Request.Context(), accountID, page.Offset, page.PerPage)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OKWithMeta(c, hooks, page.Page, page.PerPage, total)
|
||||
}
|
||||
|
||||
// GetHook retrieves a single integration hook by ID.
|
||||
// GET /api/v1/accounts/:account_id/integrations/hooks/:id
|
||||
func (h *IntegrationHookHandler) GetHook(c *gin.Context) {
|
||||
id, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid hook id")
|
||||
return
|
||||
}
|
||||
|
||||
hook, svcErr := h.svc.Get(c.Request.Context(), id)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OK(c, hook)
|
||||
}
|
||||
|
||||
// CreateHook creates a new integration hook.
|
||||
// POST /api/v1/accounts/:account_id/integrations/hooks
|
||||
func (h *IntegrationHookHandler) CreateHook(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
||||
return
|
||||
}
|
||||
|
||||
// Chatwoot: params.require(:hook) → {"hook": {...}}
|
||||
var wrapper struct {
|
||||
Hook service.CreateHookRequest `json:"hook"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&wrapper); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
req := wrapper.Hook
|
||||
|
||||
hook, svcErr := h.svc.Create(c.Request.Context(), accountID, req)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OK(c, hook)
|
||||
}
|
||||
|
||||
// UpdateHook updates an existing integration hook.
|
||||
// PUT /api/v1/accounts/:account_id/integrations/hooks/:id
|
||||
func (h *IntegrationHookHandler) UpdateHook(c *gin.Context) {
|
||||
id, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid hook id")
|
||||
return
|
||||
}
|
||||
|
||||
// Chatwoot: params.require(:hook) → {"hook": {...}}
|
||||
var wrapper struct {
|
||||
Hook service.UpdateHookRequest `json:"hook"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&wrapper); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
req := wrapper.Hook
|
||||
|
||||
hook, svcErr := h.svc.Update(c.Request.Context(), id, req)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OK(c, hook)
|
||||
}
|
||||
|
||||
// DeleteHook deletes an integration hook.
|
||||
// DELETE /api/v1/accounts/:account_id/integrations/hooks/:id
|
||||
func (h *IntegrationHookHandler) DeleteHook(c *gin.Context) {
|
||||
id, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid hook id")
|
||||
return
|
||||
}
|
||||
|
||||
if svcErr := h.svc.Delete(c.Request.Context(), id); svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OK(c, gin.H{"id": id})
|
||||
}
|
||||
|
||||
// ProcessHookEvent processes an incoming event for a hook.
|
||||
// POST /api/v1/accounts/:account_id/integrations/hooks/:id/process_event
|
||||
func (h *IntegrationHookHandler) ProcessHookEvent(c *gin.Context) {
|
||||
id, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid hook id")
|
||||
return
|
||||
}
|
||||
|
||||
var eventData map[string]interface{}
|
||||
if err := c.ShouldBindJSON(&eventData); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if svcErr := h.svc.ProcessEvent(c.Request.Context(), id, eventData); svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
response.OK(c, gin.H{"message": "event processed"})
|
||||
}
|
||||
|
||||
// RegisterIntegrationHookRoutes registers integration hook routes on a router group.
|
||||
func RegisterIntegrationHookRoutes(g *gin.RouterGroup, h *IntegrationHookHandler) {
|
||||
// Integration apps catalog
|
||||
apps := g.Group("/apps")
|
||||
{
|
||||
apps.GET("/", h.ListApps)
|
||||
apps.GET("/:id", h.GetApp)
|
||||
}
|
||||
|
||||
// Integration hooks CRUD + process event
|
||||
hooks := g.Group("/hooks")
|
||||
{
|
||||
hooks.GET("/", h.ListHooks)
|
||||
hooks.GET("/:id", h.GetHook)
|
||||
hooks.POST("/", h.CreateHook)
|
||||
hooks.PUT("/:id", h.UpdateHook)
|
||||
hooks.DELETE("/:id", h.DeleteHook)
|
||||
hooks.POST("/:id/process_event", h.ProcessHookEvent)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user