package v1 // ContactMergeHandler provides HTTP handler for merging two contacts. // Reference: Chatwoot app/controllers/api/v1/accounts/actions/contact_merges_controller.rb // // Routes: // POST /api/v1/accounts/:account_id/actions/contact_merges -> Create // // Request body: // { "base_contact_id": 1, "mergee_contact_id": 2 } // // Chatwoot's response: returns the base contact after merge on success, 200 OK import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/service" "github.com/gochat/gochat/pkg/response" ) // ContactMergeHandler handles HTTP requests for contact merge operations. type ContactMergeHandler struct { mergeService *service.ContactMergeService } // NewContactMergeHandler creates a new ContactMergeHandler. func NewContactMergeHandler(mergeService *service.ContactMergeService) *ContactMergeHandler { return &ContactMergeHandler{mergeService: mergeService} } // Create merges the mergee contact into the base contact. // Reference: Chatwoot `def create` // // contact_merge_action = ContactMergeAction.new( // account: Current.account, // base_contact: @base_contact, // mergee_contact: @mergee_contact // ) // contact_merge_action.perform // // Chatwoot returns the base contact on success with 200 OK. func (h *ContactMergeHandler) Create(c *gin.Context) { accountID, err := strconv.ParseUint(c.Param("account_id"), 10, 64) if err != nil { response.AbortWithStatusError(c, 400, response.ErrBadRequest, "Invalid account ID") return } var req model.ContactMergeRequest if err := c.ShouldBindJSON(&req); err != nil { response.AbortWithStatusError(c, 400, response.ErrBadRequest, "base_contact_id and mergee_contact_id are required") return } contact, err := h.mergeService.Merge(uint(accountID), req.BaseContactID, req.MergeeContactID) if err != nil { if err == service.ErrMergeSameContact { response.AbortWithStatusError(c, 400, response.ErrBadRequest, "Cannot merge the same contact") return } if err == service.ErrMergeBaseNotFound { response.AbortWithStatusError(c, 404, response.ErrContactNotFound, "Base contact not found") return } if err == service.ErrMergeeNotFound { response.AbortWithStatusError(c, 404, response.ErrContactNotFound, "Mergee contact not found") return } if err == service.ErrMergeNotInAccount { response.AbortWithStatusError(c, 403, response.ErrForbidden, "Contact does not belong to the account") return } response.AbortWithStatusError(c, 500, response.ErrInternal, "Failed to merge contacts") return } c.JSON(http.StatusOK, serializeCRMContact(c.Request.Context(), nil, contact, false)) }