215 lines
6.4 KiB
Go
215 lines
6.4 KiB
Go
package v1
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gochat/gochat/internal/automation"
|
|
"github.com/gochat/gochat/pkg/response"
|
|
)
|
|
|
|
// AutomationRuleHandler handles automation rule API endpoints.
|
|
// Reference: Chatwoot AutomationRulesController — CRUD + clone
|
|
type AutomationRuleHandler struct {
|
|
svc *automation.AutomationRuleService
|
|
}
|
|
|
|
// NewAutomationRuleHandler creates a new AutomationRuleHandler.
|
|
func NewAutomationRuleHandler(svc *automation.AutomationRuleService) *AutomationRuleHandler {
|
|
return &AutomationRuleHandler{svc: svc}
|
|
}
|
|
|
|
// List retrieves all automation rules for an account.
|
|
// GET /api/v1/accounts/:account_id/automation_rules
|
|
func (h *AutomationRuleHandler) List(c *gin.Context) {
|
|
accountID, err := parseUintParam(c, "account_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
rules, svcErr := h.svc.ListByAccount(c.Request.Context(), accountID)
|
|
if svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"automation_rules": rules,
|
|
"meta": gin.H{"count": len(rules)},
|
|
})
|
|
}
|
|
|
|
// Get retrieves a single automation rule by ID.
|
|
// GET /api/v1/accounts/:account_id/automation_rules/:id
|
|
func (h *AutomationRuleHandler) Get(c *gin.Context) {
|
|
if _, err := parseUintParam(c, "account_id"); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
automationID, err := parseUintParam(c, "automation_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
|
return
|
|
}
|
|
|
|
rule, svcErr := h.svc.GetByID(c.Request.Context(), automationID)
|
|
if svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
response.OK(c, rule)
|
|
}
|
|
|
|
// Create creates a new automation rule.
|
|
// POST /api/v1/accounts/:account_id/automation_rules
|
|
func (h *AutomationRuleHandler) Create(c *gin.Context) {
|
|
accountID, err := parseUintParam(c, "account_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
var rule automation.AutomationRule
|
|
if err := c.ShouldBindJSON(&rule); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
|
return
|
|
}
|
|
if rule.Name == "" || rule.EventName == "" {
|
|
response.AbortWithStatusError(c, http.StatusUnprocessableEntity, response.ErrValidation, "name and event_name are required")
|
|
return
|
|
}
|
|
|
|
rule.AccountID = accountID
|
|
|
|
if svcErr := h.svc.Create(c.Request.Context(), &rule); svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
response.Created(c, rule)
|
|
}
|
|
|
|
// Update updates an existing automation rule.
|
|
// PUT /api/v1/accounts/:account_id/automation_rules/:id
|
|
func (h *AutomationRuleHandler) Update(c *gin.Context) {
|
|
if _, err := parseUintParam(c, "account_id"); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
automationID, err := parseUintParam(c, "automation_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
|
return
|
|
}
|
|
|
|
var rule automation.AutomationRule
|
|
if err := c.ShouldBindJSON(&rule); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
|
return
|
|
}
|
|
if rule.Name == "" || rule.EventName == "" {
|
|
response.AbortWithStatusError(c, http.StatusUnprocessableEntity, response.ErrValidation, "name and event_name are required")
|
|
return
|
|
}
|
|
|
|
rule.ID = automationID
|
|
|
|
if svcErr := h.svc.Update(c.Request.Context(), &rule); svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
response.OK(c, rule)
|
|
}
|
|
|
|
// Delete soft-deletes an automation rule.
|
|
// DELETE /api/v1/accounts/:account_id/automation_rules/:id
|
|
func (h *AutomationRuleHandler) Delete(c *gin.Context) {
|
|
if _, err := parseUintParam(c, "account_id"); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
automationID, err := parseUintParam(c, "automation_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
|
return
|
|
}
|
|
|
|
if svcErr := h.svc.Delete(c.Request.Context(), automationID); svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"id": strconv.FormatUint(uint64(automationID), 10),
|
|
"deleted": true,
|
|
})
|
|
}
|
|
|
|
// Clone duplicates an automation rule.
|
|
// POST /api/v1/accounts/:account_id/automation_rules/:id/clone
|
|
func (h *AutomationRuleHandler) Clone(c *gin.Context) {
|
|
if _, err := parseUintParam(c, "account_id"); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
automationID, err := parseUintParam(c, "automation_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
|
return
|
|
}
|
|
|
|
cloned, svcErr := h.svc.Clone(c.Request.Context(), automationID)
|
|
if svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
response.Created(c, cloned)
|
|
}
|
|
|
|
// ToggleActive toggles the active state of an automation rule.
|
|
// POST /api/v1/accounts/:account_id/automation_rules/:id/toggle_active
|
|
// Reference: Chatwoot does not have a toggle_active endpoint; gochat adds this per M6 requirements.
|
|
func (h *AutomationRuleHandler) ToggleActive(c *gin.Context) {
|
|
if _, err := parseUintParam(c, "account_id"); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
|
|
return
|
|
}
|
|
|
|
automationID, err := parseUintParam(c, "automation_id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Active *bool `json:"active"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, "active field is required")
|
|
return
|
|
}
|
|
if req.Active == nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, "active field is required")
|
|
return
|
|
}
|
|
|
|
if svcErr := h.svc.ToggleActive(c.Request.Context(), automationID, *req.Active); svcErr != nil {
|
|
handleServiceError(c, svcErr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"id": strconv.FormatUint(uint64(automationID), 10),
|
|
"active": *req.Active,
|
|
})
|
|
}
|