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