Files
gochat/internal/handler/api/v1/shopify_integration_handler.go
T

109 lines
3.3 KiB
Go

package v1
import (
"errors"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/gochat/gochat/internal/service"
"github.com/gochat/gochat/pkg/response"
)
// ShopifyIntegrationHandler handles Shopify integration endpoints.
// Reference: Chatwoot Integrations::ShopifyController
type ShopifyIntegrationHandler struct {
svc *service.ShopifyIntegrationService
}
// NewShopifyIntegrationHandler creates a new ShopifyIntegrationHandler.
func NewShopifyIntegrationHandler(svc *service.ShopifyIntegrationService) *ShopifyIntegrationHandler {
return &ShopifyIntegrationHandler{svc: svc}
}
// Delete removes a Shopify integration for an account.
// DELETE /api/v1/accounts/:account_id/integrations/shopify
func (h *ShopifyIntegrationHandler) Delete(c *gin.Context) {
accountID, err := parseUintParam(c, "account_id")
if err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
return
}
if svcErr := h.svc.Delete(c.Request.Context(), accountID); svcErr != nil {
handleShopifyServiceError(c, svcErr)
return
}
c.Status(http.StatusOK)
}
// Auth returns the Shopify OAuth authorize URL.
// POST /api/v1/accounts/:account_id/integrations/shopify/auth
func (h *ShopifyIntegrationHandler) Auth(c *gin.Context) {
accountID, err := parseUintParam(c, "account_id")
if err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
return
}
var req service.CreateShopifyAuthRequest
if err := c.ShouldBind(&req); err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
return
}
if strings.TrimSpace(req.ShopDomain) == "" {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "Shop domain is required"})
return
}
redirect, svcErr := h.svc.BuildAuthRedirect(c.Request.Context(), accountID, req)
if svcErr != nil {
handleShopifyServiceError(c, svcErr)
return
}
c.JSON(http.StatusOK, redirect)
}
// GetOrders retrieves Shopify orders for an account.
// GET /api/v1/accounts/:account_id/integrations/shopify/orders
func (h *ShopifyIntegrationHandler) GetOrders(c *gin.Context) {
accountID, err := parseUintParam(c, "account_id")
if err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id")
return
}
contactID, err := parseOptionalUintQueryParam(c, "contact_id")
if err != nil {
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid contact_id")
return
}
orders, svcErr := h.svc.GetOrders(c.Request.Context(), accountID, contactID)
if svcErr != nil {
handleShopifyServiceError(c, svcErr)
return
}
c.JSON(http.StatusOK, gin.H{"orders": orders})
}
// RegisterShopifyIntegrationRoutes registers Shopify integration routes.
func RegisterShopifyIntegrationRoutes(g *gin.RouterGroup, h *ShopifyIntegrationHandler) {
g.DELETE("/shopify", h.Delete)
shopify := g.Group("/shopify")
{
shopify.DELETE("/", h.Delete)
shopify.POST("/auth", h.Auth)
shopify.GET("/orders", h.GetOrders)
}
}
func handleShopifyServiceError(c *gin.Context, err error) {
var providerErr *service.ShopifyProviderError
if errors.As(err, &providerErr) {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": providerErr.Message})
return
}
handleServiceError(c, err)
}