Change `NotifyUsers` to allow only data JSON element. Part of status-im/status-react#6772

This commit is contained in:
Pedro Pombeiro 2018-11-20 19:02:54 +01:00 committed by Pedro Pombeiro
parent e447750f4d
commit cddf2e1c6c
9 changed files with 87 additions and 76 deletions

6
Gopkg.lock generated
View File

@ -2,12 +2,12 @@
[[projects]] [[projects]]
branch = "master" digest = "1:ab480b4ff653dc950445e4ac6747c2a063f3dee7b533f68d4314267ce0fd9005"
digest = "1:5805073c158189c2af2f776b590fc9b88bcc68f2b983842adb08333dbd3c9ae7"
name = "github.com/NaySoftware/go-fcm" name = "github.com/NaySoftware/go-fcm"
packages = ["."] packages = ["."]
pruneopts = "NUT" pruneopts = "NUT"
revision = "2a6c4f48b49f0d5dbfe621589da4c5405157d7c9" revision = "024ca6a2c5444c93980f558f91c35a2defebd362"
source = "github.com/status-im/go-fcm"
[[projects]] [[projects]]
branch = "master" branch = "master"

View File

@ -35,6 +35,11 @@
name = "github.com/golang/protobuf" name = "github.com/golang/protobuf"
version = "1.1.0" version = "1.1.0"
[[constraint]]
name = "github.com/NaySoftware/go-fcm"
revision = "024ca6a2c5444c93980f558f91c35a2defebd362"
source = "github.com/status-im/go-fcm"
# * * * * * `go-ethereum` dependencies * * * * * # * * * * * `go-ethereum` dependencies * * * * *
# Pinned down SHAs from `go-ethereum/vendor/vendor.json` # Pinned down SHAs from `go-ethereum/vendor/vendor.json`
# When upgrading upstream, upgrade these values too. # When upgrading upstream, upgrade these values too.

View File

@ -13,8 +13,6 @@ import (
gethnode "github.com/ethereum/go-ethereum/node" gethnode "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enode"
fcmlib "github.com/NaySoftware/go-fcm"
"github.com/status-im/status-go/account" "github.com/status-im/status-go/account"
"github.com/status-im/status-go/node" "github.com/status-im/status-go/node"
"github.com/status-im/status-go/notifications/push/fcm" "github.com/status-im/status-go/notifications/push/fcm"
@ -446,10 +444,12 @@ func (b *StatusBackend) SelectAccount(address, password string) error {
} }
// NotifyUsers sends push notifications to users. // NotifyUsers sends push notifications to users.
func (b *StatusBackend) NotifyUsers(message string, payload fcmlib.NotificationPayload, tokens ...string) error { func (b *StatusBackend) NotifyUsers(dataPayloadJSON string, tokens ...string) error {
err := b.newNotification().Send(message, payload, tokens...) log.Debug("sending push notification")
err := b.newNotification().Send(dataPayloadJSON, tokens...)
if err != nil { if err != nil {
b.log.Error("Notify failed", "error", err) b.log.Error("NotifyUsers failed", "dataPayloadJSON", dataPayloadJSON, "error", err)
} }
return err return err

View File

@ -8,7 +8,6 @@ import (
"os" "os"
"unsafe" "unsafe"
"github.com/NaySoftware/go-fcm"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/api" "github.com/status-im/status-go/api"
"github.com/status-im/status-go/logutils" "github.com/status-im/status-go/logutils"
@ -417,7 +416,7 @@ func makeJSONResponse(err error) *C.char {
// NotifyUsers sends push notifications by given tokens. // NotifyUsers sends push notifications by given tokens.
//export NotifyUsers //export NotifyUsers
func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char) { func NotifyUsers(dataPayloadJSON, tokensArray *C.char) (outCBytes *C.char) {
var ( var (
err error err error
outBytes []byte outBytes []byte
@ -432,7 +431,7 @@ func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char)
outBytes, err = json.Marshal(out) outBytes, err = json.Marshal(out)
if err != nil { if err != nil {
logger.Error("failed to marshal Notify output", "error", err) logger.Error("failed to marshal NotifyUsers output", "error", err)
outCBytes = makeJSONResponse(err) outCBytes = makeJSONResponse(err)
return return
} }
@ -446,14 +445,7 @@ func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char)
return return
} }
var payload fcm.NotificationPayload err = statusBackend.NotifyUsers(C.GoString(dataPayloadJSON), tokens...)
err = json.Unmarshal([]byte(C.GoString(payloadJSON)), &payload)
if err != nil {
errString = err.Error()
return
}
err = statusBackend.NotifyUsers(C.GoString(message), payload, tokens...)
if err != nil { if err != nil {
errString = err.Error() errString = err.Error()
return return

View File

@ -8,5 +8,4 @@ import (
type FirebaseClient interface { type FirebaseClient interface {
NewFcmRegIdsMsg(tokens []string, body interface{}) *gofcm.FcmClient NewFcmRegIdsMsg(tokens []string, body interface{}) *gofcm.FcmClient
Send() (*gofcm.FcmResponseStatus, error) Send() (*gofcm.FcmResponseStatus, error)
SetNotificationPayload(payload *gofcm.NotificationPayload) *gofcm.FcmClient
} }

View File

@ -5,9 +5,10 @@
package fcm package fcm
import ( import (
go_fcm "github.com/NaySoftware/go-fcm"
gomock "github.com/golang/mock/gomock"
reflect "reflect" reflect "reflect"
fcm "github.com/NaySoftware/go-fcm"
gomock "github.com/golang/mock/gomock"
) )
// MockFirebaseClient is a mock of FirebaseClient interface // MockFirebaseClient is a mock of FirebaseClient interface
@ -34,9 +35,9 @@ func (m *MockFirebaseClient) EXPECT() *MockFirebaseClientMockRecorder {
} }
// NewFcmRegIdsMsg mocks base method // NewFcmRegIdsMsg mocks base method
func (m *MockFirebaseClient) NewFcmRegIdsMsg(tokens []string, body interface{}) *go_fcm.FcmClient { func (m *MockFirebaseClient) NewFcmRegIdsMsg(tokens []string, body interface{}) *fcm.FcmClient {
ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", tokens, body) ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", tokens, body)
ret0, _ := ret[0].(*go_fcm.FcmClient) ret0, _ := ret[0].(*fcm.FcmClient)
return ret0 return ret0
} }
@ -46,9 +47,9 @@ func (mr *MockFirebaseClientMockRecorder) NewFcmRegIdsMsg(tokens, body interface
} }
// Send mocks base method // Send mocks base method
func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { func (m *MockFirebaseClient) Send() (*fcm.FcmResponseStatus, error) {
ret := m.ctrl.Call(m, "Send") ret := m.ctrl.Call(m, "Send")
ret0, _ := ret[0].(*go_fcm.FcmResponseStatus) ret0, _ := ret[0].(*fcm.FcmResponseStatus)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
@ -57,15 +58,3 @@ func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) {
func (mr *MockFirebaseClientMockRecorder) Send() *gomock.Call { func (mr *MockFirebaseClientMockRecorder) Send() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockFirebaseClient)(nil).Send)) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockFirebaseClient)(nil).Send))
} }
// SetNotificationPayload mocks base method
func (m *MockFirebaseClient) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient {
ret := m.ctrl.Call(m, "SetNotificationPayload", payload)
ret0, _ := ret[0].(*go_fcm.FcmClient)
return ret0
}
// SetNotificationPayload indicates an expected call of SetNotificationPayload
func (mr *MockFirebaseClientMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockFirebaseClient)(nil).SetNotificationPayload), payload)
}

View File

@ -1,6 +1,7 @@
package fcm package fcm
import ( import (
"encoding/json"
"fmt" "fmt"
"github.com/NaySoftware/go-fcm" "github.com/NaySoftware/go-fcm"
@ -8,7 +9,7 @@ import (
// Notifier manages Push Notifications. // Notifier manages Push Notifications.
type Notifier interface { type Notifier interface {
Send(body string, payload fcm.NotificationPayload, tokens ...string) error Send(dataPayloadJSON string, tokens ...string) error
} }
// NotificationConstructor returns constructor of configured instance Notifier interface. // NotificationConstructor returns constructor of configured instance Notifier interface.
@ -25,30 +26,30 @@ func NewNotification(key string) NotificationConstructor {
client := fcm.NewFcmClient(key). client := fcm.NewFcmClient(key).
SetDelayWhileIdle(true). SetDelayWhileIdle(true).
SetContentAvailable(true). SetContentAvailable(true).
SetPriority(fcm.Priority_HIGH). // Message needs to be marked as high-priority so that background task in an Android's recipient device can be invoked (https://github.com/invertase/react-native-firebase/blob/d13f0af53f1c8f20db8bc8d4b6f8c6d210e108b9/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingService.java#L56)
SetTimeToLive(fcm.MAX_TTL) SetTimeToLive(fcm.MAX_TTL)
return &Notification{client} return &Notification{client}
} }
} }
// Send send to the tokens list. // Send sends a push notification to the tokens list.
func (n *Notification) Send(body string, payload fcm.NotificationPayload, tokens ...string) error { func (n *Notification) Send(dataPayloadJSON string, tokens ...string) error {
data := map[string]string{ var dataPayload map[string]string
"msg": body, err := json.Unmarshal([]byte(dataPayloadJSON), &dataPayload)
if err != nil {
return err
} }
if payload.Title == "" { n.client.NewFcmRegIdsMsg(tokens, dataPayload)
payload.Title = "Status" resp, err := n.client.Send()
} if err != nil {
if payload.Body == "" { return err
payload.Body = "You have a new message"
} }
fmt.Println(payload.Title, payload.Body) if resp != nil && !resp.Ok {
return fmt.Errorf("FCM error sending message, code=%d err=%s", resp.StatusCode, resp.Err)
}
n.client.NewFcmRegIdsMsg(tokens, data) return nil
n.client.SetNotificationPayload(&payload)
_, err := n.client.Send()
return err
} }

View File

@ -1,10 +1,10 @@
package fcm package fcm
import ( import (
"encoding/json"
"errors" "errors"
"testing" "testing"
"github.com/NaySoftware/go-fcm"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
@ -29,43 +29,52 @@ func (s *NotifierTestSuite) TearDownTest() {
s.fcmClientMockCtrl.Finish() s.fcmClientMockCtrl.Finish()
} }
func (s *NotifierTestSuite) TestNotifySuccess() { func (s *NotifierTestSuite) TestSendSuccess() {
fcmPayload := getPayload()
ids := []string{"1"} ids := []string{"1"}
payload := fcmPayload dataPayload := make(map[string]string)
msg := make(map[string]string) dataPayload["from"] = "a"
body := "body1" dataPayload["to"] = "b"
msg["msg"] = body dataPayloadByteArray, err := json.Marshal(dataPayload)
s.Require().NoError(err)
dataPayloadJSON := string(dataPayloadByteArray)
s.fcmClientMock.EXPECT().SetNotificationPayload(&fcmPayload).Times(1) s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, dataPayload).Times(1)
s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, msg).Times(1)
s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1)
fcmClient := Notification{s.fcmClientMock} fcmClient := Notification{s.fcmClientMock}
err := fcmClient.Send(body, payload, ids...) err = fcmClient.Send(dataPayloadJSON, ids...)
s.NoError(err) s.NoError(err)
} }
func (s *NotifierTestSuite) TestNotifyError() { func (s *NotifierTestSuite) TestSendError() {
expectedError := errors.New("error") expectedError := errors.New("error")
fcmPayload := getPayload() ids := []string{"2"}
ids := []string{"1"} dataPayload := make(map[string]string)
payload := fcmPayload dataPayload["from"] = "c"
msg := make(map[string]string) dataPayload["to"] = "d"
body := "body2" dataPayloadByteArray, err := json.Marshal(dataPayload)
msg["msg"] = body s.Require().NoError(err)
dataPayloadJSON := string(dataPayloadByteArray)
s.fcmClientMock.EXPECT().SetNotificationPayload(&fcmPayload).Times(1) s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, dataPayload).Times(1)
s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, msg).Times(1)
s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1)
fcmClient := Notification{s.fcmClientMock} fcmClient := Notification{s.fcmClientMock}
err := fcmClient.Send(body, payload, ids...) err = fcmClient.Send(dataPayloadJSON, ids...)
s.Equal(expectedError, err) s.Equal(expectedError, err)
} }
func getPayload() fcm.NotificationPayload { func (s *NotifierTestSuite) TestSendWithInvalidJSON() {
return fcm.NotificationPayload{Title: "Status - new message", Body: "sum"} ids := []string{"3"}
dataPayloadJSON := "{a=b}"
fcmClient := Notification{s.fcmClientMock}
err := fcmClient.Send(dataPayloadJSON, ids...)
s.Require().Error(err)
_, ok := err.(*json.SyntaxError)
s.True(ok)
} }

View File

@ -55,6 +55,7 @@ type FcmMsg struct {
RestrictedPackageName string `json:"restricted_package_name,omitempty"` RestrictedPackageName string `json:"restricted_package_name,omitempty"`
DryRun bool `json:"dry_run,omitempty"` DryRun bool `json:"dry_run,omitempty"`
Condition string `json:"condition,omitempty"` Condition string `json:"condition,omitempty"`
MutableContent bool `json:"mutable_content,omitempty"`
} }
// FcmMsg represents fcm response message - (tokens and topics) // FcmMsg represents fcm response message - (tokens and topics)
@ -179,6 +180,8 @@ func (this *FcmClient) sendOnce() (*FcmResponseStatus, error) {
return fcmRespStatus, err return fcmRespStatus, err
} }
fcmRespStatus.Err = string(body)
fcmRespStatus.StatusCode = response.StatusCode fcmRespStatus.StatusCode = response.StatusCode
fcmRespStatus.RetryAfter = response.Header.Get(retry_after_header) fcmRespStatus.RetryAfter = response.Header.Get(retry_after_header)
@ -313,6 +316,19 @@ func (this *FcmClient) SetDryRun(drun bool) *FcmClient {
return this return this
} }
// SetMutableContent Currently for iOS 10+ devices only. On iOS,
// use this field to represent mutable-content in the APNs payload.
// When a notification is sent and this is set to true, the content
// of the notification can be modified before it is displayed,
// using a Notification Service app extension.
// This parameter will be ignored for Android and web.
func (this *FcmClient) SetMutableContent(mc bool) *FcmClient {
this.Message.MutableContent = mc
return this
}
// PrintResults prints the FcmResponseStatus results for fast using and debugging // PrintResults prints the FcmResponseStatus results for fast using and debugging
func (this *FcmResponseStatus) PrintResults() { func (this *FcmResponseStatus) PrintResults() {
fmt.Println("Status Code :", this.StatusCode) fmt.Println("Status Code :", this.StatusCode)