44 lines
1.1 KiB
Go
44 lines
1.1 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
package fcm
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
|
|
firebase "firebase.google.com/go/v4"
|
|
"firebase.google.com/go/v4/messaging"
|
|
"google.golang.org/api/option"
|
|
)
|
|
|
|
type Sender struct {
|
|
client *messaging.Client
|
|
}
|
|
|
|
func New(ctx context.Context, keyPath string) (*Sender, error) {
|
|
app, err := firebase.NewApp(ctx, nil, option.WithCredentialsFile(keyPath))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mc, err := app.Messaging(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Sender{client: mc}, nil
|
|
}
|
|
|
|
// SendCiphertext delivers a ciphertext to a single FCM token as a data-only
|
|
// push (no `notification` field) so the phone decrypts and renders locally —
|
|
// Google never sees plaintext.
|
|
func (s *Sender) SendCiphertext(ctx context.Context, fcmToken string, ciphertext []byte) error {
|
|
msg := &messaging.Message{
|
|
Token: fcmToken,
|
|
Data: map[string]string{
|
|
"ciphertext": base64.StdEncoding.EncodeToString(ciphertext),
|
|
},
|
|
Android: &messaging.AndroidConfig{
|
|
Priority: "high",
|
|
},
|
|
}
|
|
_, err := s.client.Send(ctx, msg)
|
|
return err
|
|
}
|