(Feat): Initial Commit
This commit is contained in:
76
internal/push/provider/fcm_provider.go
Normal file
76
internal/push/provider/fcm_provider.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"allaboutapps.dev/aw/go-starter/internal/push"
|
||||
"google.golang.org/api/fcm/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/api/option"
|
||||
)
|
||||
|
||||
type FCM struct {
|
||||
Config FCMConfig
|
||||
service *fcm.Service
|
||||
}
|
||||
|
||||
type FCMConfig struct {
|
||||
GoogleApplicationCredentials string `json:"-"` // sensitive
|
||||
ProjectID string
|
||||
ValidateOnly bool
|
||||
}
|
||||
|
||||
func NewFCM(config FCMConfig, opts ...option.ClientOption) (*FCM, error) {
|
||||
ctx := context.Background()
|
||||
fcmService, err := fcm.NewService(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create FCM service: %w", err)
|
||||
}
|
||||
|
||||
return &FCM{
|
||||
Config: config,
|
||||
service: fcmService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *FCM) GetProviderType() push.ProviderType {
|
||||
return push.ProviderTypeFCM
|
||||
}
|
||||
|
||||
func (p *FCM) Send(token string, title string, message string) push.ProviderSendResponse {
|
||||
// https: //godoc.org/google.golang.org/api/fcm/v1#SendMessageRequest
|
||||
// https://firebase.google.com/docs/cloud-messaging/send-message#rest
|
||||
messageRequest := &fcm.SendMessageRequest{
|
||||
ValidateOnly: p.Config.ValidateOnly,
|
||||
Message: &fcm.Message{
|
||||
Token: token,
|
||||
Notification: &fcm.Notification{
|
||||
Title: title,
|
||||
Body: message,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := p.service.Projects.Messages.Send("projects/"+p.Config.ProjectID, messageRequest).Do()
|
||||
valid := true
|
||||
if err != nil {
|
||||
// convert to original error and determine if the token was at fault
|
||||
var gErr *googleapi.Error
|
||||
if errors.As(err, &gErr) {
|
||||
valid = (gErr.Code != http.StatusNotFound && gErr.Code != http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return push.ProviderSendResponse{
|
||||
Token: token,
|
||||
Valid: valid,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *FCM) SendMulticast(tokens []string, title, message string) []push.ProviderSendResponse {
|
||||
return sendMulticastWithProvider(p, tokens, title, message)
|
||||
}
|
||||
13
internal/push/provider/helper.go
Normal file
13
internal/push/provider/helper.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package provider
|
||||
|
||||
import "allaboutapps.dev/aw/go-starter/internal/push"
|
||||
|
||||
func sendMulticastWithProvider(p push.Provider, tokens []string, title, message string) []push.ProviderSendResponse {
|
||||
responseSlice := make([]push.ProviderSendResponse, 0)
|
||||
|
||||
for _, token := range tokens {
|
||||
responseSlice = append(responseSlice, p.Send(token, title, message))
|
||||
}
|
||||
|
||||
return responseSlice
|
||||
}
|
||||
51
internal/push/provider/mock_provider.go
Normal file
51
internal/push/provider/mock_provider.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"allaboutapps.dev/aw/go-starter/internal/push"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type Mock struct {
|
||||
Type push.ProviderType
|
||||
}
|
||||
|
||||
func NewMock(providerType push.ProviderType) *Mock {
|
||||
return &Mock{
|
||||
Type: providerType,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Mock) GetProviderType() push.ProviderType {
|
||||
return p.Type
|
||||
}
|
||||
|
||||
const (
|
||||
expectedTokenLength = 40
|
||||
)
|
||||
|
||||
func (p *Mock) Send(token string, title string, message string) push.ProviderSendResponse {
|
||||
valid := true
|
||||
var err error
|
||||
if len(token) < expectedTokenLength {
|
||||
valid = false
|
||||
err = errors.New("invalid token")
|
||||
}
|
||||
|
||||
if title == "other error" {
|
||||
err = errors.New("other error")
|
||||
}
|
||||
|
||||
log.Info().Str("token", token).Str("title", title).Str("message", message).Msg("Mock Push Notification")
|
||||
|
||||
return push.ProviderSendResponse{
|
||||
Token: token,
|
||||
Valid: valid,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Mock) SendMulticast(tokens []string, title, message string) []push.ProviderSendResponse {
|
||||
return sendMulticastWithProvider(p, tokens, title, message)
|
||||
}
|
||||
Reference in New Issue
Block a user