Passed
Push — main ( 04bfb7...a19fb0 )
by Acho
01:49
created

services.*MarketingService.brevoAttributes   A

Complexity

Conditions 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
dl 0
loc 14
rs 9.9
c 0
b 0
f 0
nop 1
1
package services
2
3
import (
4
	"context"
5
	"fmt"
6
	"strings"
7
8
	"github.com/carlmjohnson/requests"
9
10
	"firebase.google.com/go/auth"
11
	"github.com/NdoleStudio/httpsms/pkg/entities"
12
	"github.com/NdoleStudio/httpsms/pkg/telemetry"
13
	"github.com/gofiber/fiber/v2"
14
	"github.com/palantir/stacktrace"
15
)
16
17
// MarketingService is handles marketing requests
18
type MarketingService struct {
19
	logger      telemetry.Logger
20
	tracer      telemetry.Tracer
21
	authClient  *auth.Client
22
	brevoAPIKey string
23
}
24
25
// NewMarketingService creates a new instance of the MarketingService
26
func NewMarketingService(
27
	logger telemetry.Logger,
28
	tracer telemetry.Tracer,
29
	authClient *auth.Client,
30
	brevoAPIKey string,
31
) *MarketingService {
32
	return &MarketingService{
33
		logger:      logger.WithService(fmt.Sprintf("%T", &MarketingService{})),
34
		tracer:      tracer,
35
		authClient:  authClient,
36
		brevoAPIKey: brevoAPIKey,
37
	}
38
}
39
40
// DeleteUser a user if exists in the sendgrid list
41
func (service *MarketingService) DeleteUser(ctx context.Context, userID entities.UserID) error {
42
	ctx, span, ctxLogger := service.tracer.StartWithLogger(ctx, service.logger)
43
	defer span.End()
44
45
	err := requests.URL(fmt.Sprintf("https://api.brevo.com/v3/contacts/%s?identifierType=ext_id", userID)).
46
		Header("api-key", service.brevoAPIKey).
47
		Delete().
48
		CheckStatus(fiber.StatusNoContent).
49
		Fetch(ctx)
50
	if err != nil {
51
		return service.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, fmt.Sprintf("cannot delete user with id [%s] from brevo list", userID)))
52
	}
53
54
	ctxLogger.Info(fmt.Sprintf("deleted user with ID [%s] from brevo list with status [%s]", userID, fiber.StatusNoContent))
55
	return nil
56
}
57
58
// AddToList adds a new user on the onboarding automation.
59
func (service *MarketingService) AddToList(ctx context.Context, user *entities.User) {
60
	ctx, span, ctxLogger := service.tracer.StartWithLogger(ctx, service.logger)
61
	defer span.End()
62
63
	userRecord, err := service.authClient.GetUser(ctx, string(user.ID))
64
	if err != nil {
65
		msg := fmt.Sprintf("cannot get auth user with id [%s]", user.ID)
66
		ctxLogger.Error(stacktrace.Propagate(err, msg))
67
		return
68
	}
69
70
	var response string
71
	err = requests.URL("https://api.brevo.com/v3/contacts").
72
		Header("api-key", service.brevoAPIKey).
73
		Post().
74
		BodyJSON(fiber.Map{
75
			"email":         userRecord.Email,
76
			"ext_id":        userRecord.UID,
77
			"attributes":    service.brevoAttributes(userRecord),
78
			"listIds":       []int64{9},
79
			"updateEnabled": true,
80
		}).
81
		CheckStatus(fiber.StatusCreated, fiber.StatusNoContent).
82
		ToString(&response).
83
		Fetch(ctx)
84
	if err != nil {
85
		msg := fmt.Sprintf("cannot add user with id [%s] to brevo list", user.ID)
86
		ctxLogger.Error(stacktrace.Propagate(err, msg))
87
		return
88
	}
89
90
	ctxLogger.Info(fmt.Sprintf("user [%s] added to list brevo list with brevo response [%s]", user.ID, response))
91
}
92
93
func (service *MarketingService) brevoAttributes(user *auth.UserRecord) map[string]any {
94
	name := strings.TrimSpace(user.DisplayName)
95
	if name == "" {
96
		return fiber.Map{}
97
	}
98
99
	parts := strings.Split(name, " ")
100
	if len(parts) == 1 {
101
		return fiber.Map{"FIRSTNAME": name}
102
	}
103
104
	return fiber.Map{
105
		"FIRSTNAME": strings.Join(parts[0:len(parts)-1], " "),
106
		"LASTNAME":  parts[len(parts)-1],
107
	}
108
}
109