Passed
Push — main ( 570b65...2ff189 )
by Acho
02:48
created

ntDeleted   A

Complexity

Conditions 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
dl 0
loc 16
rs 9.85
c 0
b 0
f 0
nop 2
1
package listeners
2
3
import (
4
	"context"
5
	"fmt"
6
7
	"github.com/davecgh/go-spew/spew"
8
9
	"github.com/NdoleStudio/httpsms/pkg/events"
10
	"github.com/NdoleStudio/httpsms/pkg/services"
11
	"github.com/NdoleStudio/httpsms/pkg/telemetry"
12
	cloudevents "github.com/cloudevents/sdk-go/v2"
13
	"github.com/palantir/stacktrace"
14
)
15
16
// PhoneNotificationListener handles cloud events which sends notifications
17
type PhoneNotificationListener struct {
18
	logger  telemetry.Logger
19
	tracer  telemetry.Tracer
20
	service *services.PhoneNotificationService
21
}
22
23
// NewNotificationListener creates a new instance of PhoneNotificationListener
24
func NewNotificationListener(
25
	logger telemetry.Logger,
26
	tracer telemetry.Tracer,
27
	service *services.PhoneNotificationService,
28
) (l *PhoneNotificationListener, routes map[string]events.EventListener) {
29
	l = &PhoneNotificationListener{
30
		logger:  logger.WithService(fmt.Sprintf("%T", l)),
31
		tracer:  tracer,
32
		service: service,
33
	}
34
35
	return l, map[string]events.EventListener{
36
		events.EventTypeMessageAPISent:          l.onMessageAPISent,
37
		events.EventTypeMessageSendRetry:        l.onMessageSendRetry,
38
		events.EventTypeMessageNotificationSend: l.onMessageNotificationSend,
39
		events.PhoneHeartbeatMissed:             l.onPhoneHeartbeatMissed,
40
		events.UserAccountDeleted:               l.onUserAccountDeleted,
41
	}
42
}
43
44
// onMessageAPISent handles the events.EventTypeMessageAPISent event
45
func (listener *PhoneNotificationListener) onMessageAPISent(ctx context.Context, event cloudevents.Event) error {
46
	ctx, span := listener.tracer.Start(ctx)
47
	defer span.End()
48
49
	var payload events.MessageAPISentPayload
50
	if err := event.DataAs(&payload); err != nil {
51
		msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
52
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
53
	}
54
55
	sendParams := &services.PhoneNotificationScheduleParams{
56
		UserID:    payload.UserID,
57
		Owner:     payload.Owner,
58
		Contact:   payload.Contact,
59
		Content:   payload.Content,
60
		SIM:       payload.SIM,
61
		Encrypted: payload.Encrypted,
62
		Source:    event.Source(),
63
		MessageID: payload.MessageID,
64
	}
65
66
	if err := listener.service.Schedule(ctx, sendParams); err != nil {
67
		msg := fmt.Sprintf("cannot send notification with params [%s] for event with ID [%s]", spew.Sdump(sendParams), event.ID())
68
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
69
	}
70
71
	return nil
72
}
73
74
// onMessageSendRetry handles the events.EventTypeMessageSendRetry event
75
func (listener *PhoneNotificationListener) onMessageSendRetry(ctx context.Context, event cloudevents.Event) error {
76
	ctx, span := listener.tracer.Start(ctx)
77
	defer span.End()
78
79
	var payload events.MessageSendRetryPayload
80
	if err := event.DataAs(&payload); err != nil {
81
		msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
82
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
83
	}
84
85
	sendParams := &services.PhoneNotificationScheduleParams{
86
		UserID:    payload.UserID,
87
		Owner:     payload.Owner,
88
		Contact:   payload.Contact,
89
		Content:   payload.Content,
90
		SIM:       payload.SIM,
91
		Encrypted: payload.Encrypted,
92
		Source:    event.Source(),
93
		MessageID: payload.MessageID,
94
	}
95
96
	if err := listener.service.Schedule(ctx, sendParams); err != nil {
97
		msg := fmt.Sprintf("cannot send notification with params [%s] for event with ID [%s]", spew.Sdump(sendParams), event.ID())
98
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
99
	}
100
101
	return nil
102
}
103
104
// onPhoneHeartbeatMissed handles the events.PhoneHeartbeatMissed event
105
func (listener *PhoneNotificationListener) onPhoneHeartbeatMissed(ctx context.Context, event cloudevents.Event) error {
106
	ctx, span := listener.tracer.Start(ctx)
107
	defer span.End()
108
109
	payload := new(events.PhoneHeartbeatMissedPayload)
110
	if err := event.DataAs(payload); err != nil {
111
		msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
112
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
113
	}
114
115
	if err := listener.service.SendHeartbeatFCM(ctx, payload); err != nil {
116
		msg := fmt.Sprintf("cannot schedule send heartbeat FCM with params [%s] for event with ID [%s]", spew.Sdump(payload), event.ID())
117
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
118
	}
119
120
	return nil
121
}
122
123
// onMessageNotificationSend handles the events.EventTypeMessageNotificationSend event
124
func (listener *PhoneNotificationListener) onMessageNotificationSend(ctx context.Context, event cloudevents.Event) error {
125
	ctx, span := listener.tracer.Start(ctx)
126
	defer span.End()
127
128
	var payload events.MessageNotificationSendPayload
129
	if err := event.DataAs(&payload); err != nil {
130
		msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
131
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
132
	}
133
134
	scheduleParams := &services.PhoneNotificationSendParams{
135
		UserID:              payload.UserID,
136
		PhoneID:             payload.PhoneID,
137
		Source:              event.Source(),
138
		ScheduledAt:         payload.ScheduledAt,
139
		PhoneNotificationID: payload.NotificationID,
140
		MessageID:           payload.MessageID,
141
	}
142
143
	if err := listener.service.Send(ctx, scheduleParams); err != nil {
144
		msg := fmt.Sprintf("cannot schedule notification with params [%s] for event with ID [%s]", spew.Sdump(scheduleParams), event.ID())
145
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
146
	}
147
148
	return nil
149
}
150
151
func (listener *PhoneNotificationListener) onUserAccountDeleted(ctx context.Context, event cloudevents.Event) error {
152
	ctx, span := listener.tracer.Start(ctx)
153
	defer span.End()
154
155
	var payload events.UserAccountDeletedPayload
156
	if err := event.DataAs(&payload); err != nil {
157
		msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
158
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
159
	}
160
161
	if err := listener.service.DeleteAllForUser(ctx, payload.UserID); err != nil {
162
		msg := fmt.Sprintf("cannot delete [entities.Phone] for user [%s] on [%s] event with ID [%s]", payload.UserID, event.Type(), event.ID())
163
		return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
164
	}
165
166
	return nil
167
}
168