Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v0.9.2 95 lines 2.4 kB view raw
1package notifications 2 3import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 8 "context" 9 10 firebase "firebase.google.com/go/v4" 11 "firebase.google.com/go/v4/messaging" 12 "google.golang.org/api/option" 13 "stream.place/streamplace/pkg/log" 14) 15 16type FirebaseNotifier interface { 17 Blast(ctx context.Context, tokens []string, golive *NotificationBlast) error 18} 19 20type FirebaseNotifierS struct { 21 app *firebase.App 22} 23 24type GoogleCredential struct { 25 ProjectID string `json:"project_id"` 26} 27 28type NotificationBlast struct { 29 Title string `json:"title"` 30 Body string `json:"body"` 31 Data map[string]string `json:"data"` 32} 33 34func MakeFirebaseNotifier(ctx context.Context, serviceAccountJSONb64 string) (FirebaseNotifier, error) { 35 // string can optionally be base64-encoded 36 serviceAccountJSON := serviceAccountJSONb64 37 dec, err := base64.StdEncoding.DecodeString(serviceAccountJSONb64) 38 if err == nil { 39 // succeeded, cool! use that. 40 serviceAccountJSON = string(dec) 41 } 42 var cred GoogleCredential 43 err = json.Unmarshal([]byte(serviceAccountJSON), &cred) 44 if err != nil { 45 return nil, fmt.Errorf("error trying to discover project_id: %w", err) 46 } 47 conf := &firebase.Config{ 48 ProjectID: cred.ProjectID, 49 } 50 opt := option.WithCredentialsJSON([]byte(serviceAccountJSON)) 51 app, err := firebase.NewApp(ctx, conf, opt) 52 if err != nil { 53 return nil, fmt.Errorf("failed to initialize Firebase app: %w", err) 54 } 55 return &FirebaseNotifierS{app: app}, nil 56} 57 58// refactor me when we have >500 users 59func (f *FirebaseNotifierS) Blast(ctx context.Context, tokens []string, blast *NotificationBlast) error { 60 client, err := f.app.Messaging(ctx) 61 if err != nil { 62 return err 63 } 64 65 notification := &messaging.MulticastMessage{ 66 Tokens: tokens, 67 Data: blast.Data, 68 Notification: &messaging.Notification{ 69 Title: blast.Title, 70 Body: blast.Body, 71 }, 72 Android: &messaging.AndroidConfig{ 73 Priority: "high", 74 Notification: &messaging.AndroidNotification{ 75 Sound: "default", 76 }, 77 }, 78 APNS: &messaging.APNSConfig{ 79 Headers: map[string]string{ 80 "apns-priority": "10", 81 }, 82 Payload: &messaging.APNSPayload{ 83 Aps: &messaging.Aps{ 84 Sound: "default", 85 }, 86 }, 87 }, 88 } 89 res, err := client.SendEachForMulticast(ctx, notification) 90 if err != nil { 91 return err 92 } 93 log.Log(ctx, "notification blast successful", "successCount", res.SuccessCount, "failureCount", res.FailureCount) 94 return nil 95}