Files
gochat/internal/service/whatsapp_call_service.go
T
2026-06-04 15:44:48 +08:00

104 lines
3.6 KiB
Go

package service
import (
"context"
"errors"
"github.com/gochat/gochat/internal/model"
"github.com/gochat/gochat/internal/repository"
applogger "github.com/gochat/gochat/pkg/logger"
)
// WhatsAppCallService implements business logic for WhatsAppCall operations.
type WhatsAppCallService struct {
repo *repository.WhatsAppCallRepo
}
// NewWhatsAppCallService creates a new WhatsAppCall service.
func NewWhatsAppCallService(repo *repository.WhatsAppCallRepo) *WhatsAppCallService {
return &WhatsAppCallService{repo: repo}
}
// WhatsAppCallCreateRequest is the DTO for creating a WhatsApp call.
type WhatsAppCallCreateRequest struct {
CallID string `json:"call_id" validate:"required"`
InboxID uint `json:"inbox_id" validate:"required"`
ConversationID uint `json:"conversation_id" validate:"required"`
CallStatus string `json:"call_status" validate:"required"`
Duration int `json:"duration"`
CallerNumber string `json:"caller_number"`
}
// validCallStatuses defines allowed WhatsApp call status values.
var validCallStatuses = map[string]bool{"ringing": true, "active": true, "ended": true, "failed": true}
// GetByCallID retrieves a WhatsApp call by its call ID.
func (s *WhatsAppCallService) GetByCallID(ctx context.Context, callID string) (*model.WhatsAppCall, error) {
call, err := s.repo.FindByCallID(ctx, callID)
if err != nil {
applogger.L().Errorf("WhatsAppCallService.GetByCallID error: %v", err)
return nil, err
}
return call, nil
}
// ListByConversation retrieves all WhatsApp calls for a conversation.
func (s *WhatsAppCallService) ListByConversation(ctx context.Context, conversationID uint) ([]model.WhatsAppCall, error) {
calls, err := s.repo.FindByConversationID(ctx, conversationID)
if err != nil {
applogger.L().Errorf("WhatsAppCallService.ListByConversation error: %v", err)
return nil, err
}
return calls, nil
}
// CreateFromRequest creates a new WhatsApp call record from a DTO.
func (s *WhatsAppCallService) CreateFromRequest(ctx context.Context, req *WhatsAppCallCreateRequest) (*model.WhatsAppCall, error) {
if !validCallStatuses[req.CallStatus] {
return nil, errors.New("invalid call_status: must be ringing/active/ended/failed")
}
call := &model.WhatsAppCall{
CallID: req.CallID,
InboxID: req.InboxID,
ConversationID: req.ConversationID,
CallStatus: req.CallStatus,
Duration: req.Duration,
CallerNumber: req.CallerNumber,
}
if err := s.repo.Create(ctx, call); err != nil {
applogger.L().Errorf("WhatsAppCallService.CreateFromRequest error: %v", err)
return nil, err
}
return call, nil
}
// UpdateByCallID updates a WhatsApp call by its call_id (e.g. status transition).
func (s *WhatsAppCallService) UpdateByCallID(ctx context.Context, callID string, callStatus string, duration int) (*model.WhatsAppCall, error) {
if !validCallStatuses[callStatus] {
return nil, errors.New("invalid call_status: must be ringing/active/ended/failed")
}
call, err := s.repo.FindByCallID(ctx, callID)
if err != nil {
return nil, err
}
call.CallStatus = callStatus
call.Duration = duration
if err := s.repo.Update(ctx, call); err != nil {
applogger.L().Errorf("WhatsAppCallService.UpdateByCallID error: %v", err)
return nil, err
}
return call, nil
}
// DeleteByCallID deletes a WhatsApp call record by call_id.
func (s *WhatsAppCallService) DeleteByCallID(ctx context.Context, callID string) error {
call, err := s.repo.FindByCallID(ctx, callID)
if err != nil {
return err
}
if err := s.repo.Delete(ctx, call.ID); err != nil {
applogger.L().Errorf("WhatsAppCallService.DeleteByCallID error: %v", err)
return err
}
return nil
}