-
Notifications
You must be signed in to change notification settings - Fork 0
/
push.go
100 lines (90 loc) · 2.4 KB
/
push.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package fcm
import (
"context"
"encoding/json"
"fmt"
"log"
"cloud.google.com/go/pubsub"
"github.com/savannahghi/engagementcore/pkg/engagement/application/common"
"github.com/savannahghi/engagementcore/pkg/engagement/application/common/helpers"
"github.com/savannahghi/firebasetools"
"github.com/savannahghi/pubsubtools"
"github.com/savannahghi/serverutils"
)
const (
fcmServiceName = "fcm"
fcmVersion = ""
)
// PushService defines the behavior of our FCM push implementation
type PushService interface {
Push(
ctx context.Context,
sender string,
payload firebasetools.SendNotificationPayload,
) error
}
// NewRemotePushService initializes an FCM push service
func NewRemotePushService(
ctx context.Context,
) (*RemotePushService, error) {
projectID, err := serverutils.GetEnvVar(serverutils.GoogleCloudProjectIDEnvVarName)
if err != nil {
return nil, fmt.Errorf(
"can't get projectID from env var `%s`: %w",
serverutils.GoogleCloudProjectIDEnvVarName,
err,
)
}
pubsubClient, err := pubsub.NewClient(ctx, projectID)
if err != nil {
return nil, fmt.Errorf("can't initialize pubsub client: %w", err)
}
rfs := &RemotePushService{
pubsubClient: pubsubClient,
}
rfs.checkPreconditions()
return rfs, nil
}
// RemotePushService sends instructions to a remote FCM service over
// Google Cloud Pub-Sub
type RemotePushService struct {
pubsubClient *pubsub.Client
}
func (rfs RemotePushService) checkPreconditions() {
if rfs.pubsubClient == nil {
log.Panicf(
"attempt to use a remote FCM push service with a nil pubsubClient")
}
}
// Push instructs a remote FCM service to send a push notification.
//
// This is done over Google Cloud Pub-Sub.
func (rfs RemotePushService) Push(
ctx context.Context,
sender string,
notificationPayload firebasetools.SendNotificationPayload,
) error {
ctx, span := tracer.Start(ctx, "Push")
defer span.End()
rfs.checkPreconditions()
env := serverutils.GetRunningEnvironment()
payload, err := json.Marshal(notificationPayload)
if err != nil {
helpers.RecordSpanError(span, err)
return fmt.Errorf("can't marshal notification payload: %w", err)
}
err = pubsubtools.PublishToPubsub(
ctx,
rfs.pubsubClient,
helpers.AddPubSubNamespace(common.FcmPublishTopic),
env,
fcmServiceName,
fcmVersion,
payload,
)
if err != nil {
helpers.RecordSpanError(span, err)
return fmt.Errorf("can't publish FCM message to pubsub: %w", err)
}
return nil
}