115 lines
4.1 KiB
Go
115 lines
4.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/gochat/gochat/internal/repository"
|
|
applogger "github.com/gochat/gochat/pkg/logger"
|
|
)
|
|
|
|
// ShopifyIntegrationService implements Shopify integration business logic.
|
|
// Reference: Chatwoot Integrations::ShopifyController
|
|
// Shopify integration links customer order information to conversations.
|
|
type ShopifyIntegrationService struct {
|
|
hookRepo *repository.IntegrationHookRepo
|
|
}
|
|
|
|
// NewShopifyIntegrationService creates a new ShopifyIntegrationService.
|
|
func NewShopifyIntegrationService(hookRepo *repository.IntegrationHookRepo) *ShopifyIntegrationService {
|
|
return &ShopifyIntegrationService{hookRepo: hookRepo}
|
|
}
|
|
|
|
// CreateShopifyAuthRequest is the DTO for Shopify OAuth auth.
|
|
type CreateShopifyAuthRequest struct {
|
|
ShopDomain string `json:"shop_domain" validate:"required"`
|
|
AccessToken string `json:"access_token,omitempty"`
|
|
}
|
|
|
|
// Delete removes a Shopify integration hook for an account.
|
|
func (s *ShopifyIntegrationService) Delete(ctx context.Context, accountID uint) error {
|
|
hooks, err := s.hookRepo.FindByAccountAndType(ctx, accountID, model.HookTypeShopify)
|
|
if err != nil || len(hooks) == 0 {
|
|
return fmt.Errorf("Shopify integration not found for account %d", accountID)
|
|
}
|
|
|
|
for _, hook := range hooks {
|
|
if err := s.hookRepo.Delete(ctx, hook.ID); err != nil {
|
|
return fmt.Errorf("failed to delete Shopify integration: %w", err)
|
|
}
|
|
}
|
|
|
|
applogger.L().Infof("Shopify integration deleted: account=%d", accountID)
|
|
return nil
|
|
}
|
|
|
|
// Auth creates/updates a Shopify integration with OAuth credentials.
|
|
// POST /api/v1/accounts/:account_id/integrations/shopify/auth
|
|
func (s *ShopifyIntegrationService) Auth(ctx context.Context, accountID uint, req CreateShopifyAuthRequest) (*model.IntegrationHook, error) {
|
|
settings := model.ShopifySettings{
|
|
ShopDomain: req.ShopDomain,
|
|
AccessToken: req.AccessToken,
|
|
}
|
|
|
|
settingsJSON, err := json.Marshal(settings)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal Shopify settings: %w", err)
|
|
}
|
|
|
|
// Check if Shopify hook already exists for this account
|
|
hooks, err := s.hookRepo.FindByAccountAndType(ctx, accountID, model.HookTypeShopify)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to find existing Shopify integration: %w", err)
|
|
}
|
|
|
|
if len(hooks) > 0 {
|
|
// Update existing hook
|
|
hook := &hooks[0]
|
|
hook.Settings = settingsJSON
|
|
hook.URL = fmt.Sprintf("https://%s/admin/api/webhooks.json", req.ShopDomain)
|
|
if err := s.hookRepo.Update(ctx, hook); err != nil {
|
|
return nil, fmt.Errorf("failed to update Shopify integration: %w", err)
|
|
}
|
|
applogger.L().Infof("Shopify integration updated: account=%d, shop=%s", accountID, req.ShopDomain)
|
|
return hook, nil
|
|
}
|
|
|
|
// Create new hook
|
|
hook := &model.IntegrationHook{
|
|
AccountID: accountID,
|
|
HookType: model.HookTypeShopify,
|
|
Status: model.HookStatusActive,
|
|
URL: fmt.Sprintf("https://%s/admin/api/webhooks.json", req.ShopDomain),
|
|
Settings: settingsJSON,
|
|
}
|
|
|
|
if err := s.hookRepo.Create(ctx, hook); err != nil {
|
|
return nil, fmt.Errorf("failed to create Shopify integration: %w", err)
|
|
}
|
|
|
|
applogger.L().Infof("Shopify integration created: account=%d, shop=%s", accountID, req.ShopDomain)
|
|
return hook, nil
|
|
}
|
|
|
|
// GetOrders retrieves Shopify orders for an account (proxy to Shopify API).
|
|
// GET /api/v1/accounts/:account_id/integrations/shopify/orders
|
|
func (s *ShopifyIntegrationService) GetOrders(ctx context.Context, accountID uint) ([]map[string]interface{}, error) {
|
|
hooks, err := s.hookRepo.FindByAccountAndType(ctx, accountID, model.HookTypeShopify)
|
|
if err != nil || len(hooks) == 0 {
|
|
return nil, fmt.Errorf("Shopify integration not found for account %d", accountID)
|
|
}
|
|
|
|
var settings model.ShopifySettings
|
|
if err := json.Unmarshal(hooks[0].Settings, &settings); err != nil {
|
|
return nil, fmt.Errorf("failed to unmarshal Shopify settings: %w", err)
|
|
}
|
|
|
|
// In production, this would call the Shopify API using settings.AccessToken.
|
|
applogger.L().Infof("Listing Shopify orders for account=%d, shop=%s", accountID, settings.ShopDomain)
|
|
return []map[string]interface{}{
|
|
{"shop_domain": settings.ShopDomain, "status": "configured"},
|
|
}, nil
|
|
}
|