Merge pull request #390 from status-im/issue/refactor-api-notify-send-messages-#342
Refactor and little bit clean up Notify api: Created interface and package "notification" and extracted related code into it Set dependencies into constructor notificatotion.Manager Mocks for notificatotion.Manager and FCMClient Bacis unit tests for Notify and Send Notify func is now deprecated Notify users uses new API: message, Payload and a list of tokens
This commit is contained in:
commit
2897f0ec0f
2
Makefile
2
Makefile
|
@ -87,6 +87,8 @@ mock-install: ##@other Install mocking tools
|
|||
|
||||
mock: ##@other Regenerate mocks
|
||||
mockgen -source=geth/common/types.go -destination=geth/common/types_mock.go -package=common
|
||||
mockgen -source=geth/common/notification.go -destination=geth/common/notification_mock.go -package=common -imports fcm=github.com/NaySoftware/go-fcm
|
||||
mockgen -source=geth/notification/fcm/client.go -destination=geth/notification/fcm/client_mock.go -package=fcm -imports fcm=github.com/NaySoftware/go-fcm
|
||||
|
||||
test: test-unit-coverage ##@tests Run basic, short tests during development
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
|
||||
"github.com/NaySoftware/go-fcm"
|
||||
"github.com/status-im/status-go/geth/common"
|
||||
"github.com/status-im/status-go/geth/log"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
"github.com/status-im/status-go/helpers/profiling"
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
//GenerateConfig for status node
|
||||
|
@ -22,7 +22,7 @@ func GenerateConfig(datadir *C.char, networkID C.int, devMode C.int) *C.char {
|
|||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
outBytes, err := json.Marshal(&config)
|
||||
outBytes, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ func CreateAccount(password *C.char) *C.char {
|
|||
Mnemonic: mnemonic,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ func CreateChildAccount(parentAddress, password *C.char) *C.char {
|
|||
PubKey: pubKey,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ func RecoverAccount(password, mnemonic *C.char) *C.char {
|
|||
Mnemonic: C.GoString(mnemonic),
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ func CompleteTransaction(id, password *C.char) *C.char {
|
|||
Hash: txHash.Hex(),
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, err := json.Marshal(&out)
|
||||
outBytes, err := json.Marshal(out)
|
||||
if err != nil {
|
||||
log.Error("failed to marshal CompleteTransaction output", "error", err.Error())
|
||||
return makeJSONResponse(err)
|
||||
|
@ -246,7 +246,7 @@ func CompleteTransactions(ids, password *C.char) *C.char {
|
|||
}
|
||||
}
|
||||
|
||||
outBytes, err := json.Marshal(&out)
|
||||
outBytes, err := json.Marshal(out)
|
||||
if err != nil {
|
||||
log.Error("failed to marshal CompleteTransactions output", "error", err.Error())
|
||||
return makeJSONResponse(err)
|
||||
|
@ -270,7 +270,7 @@ func DiscardTransaction(id *C.char) *C.char {
|
|||
ID: C.GoString(id),
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, err := json.Marshal(&out)
|
||||
outBytes, err := json.Marshal(out)
|
||||
if err != nil {
|
||||
log.Error("failed to marshal DiscardTransaction output", "error", err.Error())
|
||||
return makeJSONResponse(err)
|
||||
|
@ -308,7 +308,7 @@ func DiscardTransactions(ids *C.char) *C.char {
|
|||
}
|
||||
}
|
||||
|
||||
outBytes, err := json.Marshal(&out)
|
||||
outBytes, err := json.Marshal(out)
|
||||
if err != nil {
|
||||
log.Error("failed to marshal DiscardTransactions output", "error", err.Error())
|
||||
return makeJSONResponse(err)
|
||||
|
@ -368,14 +368,62 @@ func makeJSONResponse(err error) *C.char {
|
|||
out := common.APIResponse{
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
outBytes, _ := json.Marshal(out)
|
||||
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
// Notify sends push notification by given token
|
||||
// @deprecated
|
||||
//export Notify
|
||||
func Notify(token *C.char) *C.char {
|
||||
res := statusAPI.Notify(C.GoString(token))
|
||||
return C.CString(res)
|
||||
}
|
||||
|
||||
// NotifyUsers sends push notifications by given tokens.
|
||||
//export NotifyUsers
|
||||
func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char) {
|
||||
var (
|
||||
err error
|
||||
outBytes []byte
|
||||
)
|
||||
errString := ""
|
||||
|
||||
defer func() {
|
||||
out := common.NotifyResult{
|
||||
Status: err == nil,
|
||||
Error: errString,
|
||||
}
|
||||
|
||||
outBytes, err = json.Marshal(out)
|
||||
if err != nil {
|
||||
log.Error("failed to marshal Notify output", "error", err.Error())
|
||||
outCBytes = makeJSONResponse(err)
|
||||
return
|
||||
}
|
||||
|
||||
outCBytes = C.CString(string(outBytes))
|
||||
}()
|
||||
|
||||
tokens, err := common.ParseJSONArray(C.GoString(tokensArray))
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
var payload fcm.NotificationPayload
|
||||
err = json.Unmarshal([]byte(C.GoString(payloadJSON)), &payload)
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
err = statusAPI.NotifyUsers(C.GoString(message), payload, tokens...)
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -11,10 +11,6 @@ import (
|
|||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
const (
|
||||
serverKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx"
|
||||
)
|
||||
|
||||
// StatusAPI provides API to access Status related functionality.
|
||||
type StatusAPI struct {
|
||||
b *StatusBackend
|
||||
|
@ -200,32 +196,29 @@ func (api *StatusAPI) JailBaseJS(js string) {
|
|||
}
|
||||
|
||||
// Notify sends a push notification to the device with the given token.
|
||||
// TODO(oskarth): API package this stuff
|
||||
// @deprecated
|
||||
func (api *StatusAPI) Notify(token string) string {
|
||||
log.Debug("Notify", "token", token)
|
||||
message := "Hello World1"
|
||||
|
||||
var NP fcm.NotificationPayload
|
||||
NP.Title = "Status - new message"
|
||||
NP.Body = "ping"
|
||||
tokens := []string{token}
|
||||
|
||||
// TODO(oskarth): Experiment with this
|
||||
data := map[string]string{
|
||||
"msg": "Hello World1",
|
||||
"sum": "Happy Day",
|
||||
}
|
||||
|
||||
ids := []string{
|
||||
token,
|
||||
}
|
||||
|
||||
c := fcm.NewFcmClient(serverKey)
|
||||
c.NewFcmRegIdsMsg(ids, data)
|
||||
c.SetNotificationPayload(&NP)
|
||||
|
||||
_, err := c.Send()
|
||||
err := api.b.newNotification().Send(message, fcm.NotificationPayload{}, tokens...)
|
||||
if err != nil {
|
||||
log.Error("Notify failed:", err)
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
// NotifyUsers send notifications to users.
|
||||
func (api *StatusAPI) NotifyUsers(message string, payload fcm.NotificationPayload, tokens ...string) error {
|
||||
log.Debug("Notify", "tokens", tokens)
|
||||
|
||||
err := api.b.newNotification().Send(message, payload, tokens...)
|
||||
if err != nil {
|
||||
log.Error("Notify failed:", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -10,11 +10,17 @@ import (
|
|||
"github.com/status-im/status-go/geth/jail"
|
||||
"github.com/status-im/status-go/geth/log"
|
||||
"github.com/status-im/status-go/geth/node"
|
||||
"github.com/status-im/status-go/geth/notification/fcm"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
"github.com/status-im/status-go/geth/signal"
|
||||
"github.com/status-im/status-go/geth/txqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
//todo(jeka): should be removed
|
||||
fcmServerKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx"
|
||||
)
|
||||
|
||||
// StatusBackend implements Status.im service
|
||||
type StatusBackend struct {
|
||||
sync.Mutex
|
||||
|
@ -23,7 +29,7 @@ type StatusBackend struct {
|
|||
accountManager common.AccountManager
|
||||
txQueueManager common.TxQueueManager
|
||||
jailManager common.JailManager
|
||||
// TODO(oskarth): notifer here
|
||||
newNotification common.NotificationConstructor
|
||||
}
|
||||
|
||||
// NewStatusBackend create a new NewStatusBackend instance
|
||||
|
@ -34,12 +40,14 @@ func NewStatusBackend() *StatusBackend {
|
|||
accountManager := account.NewManager(nodeManager)
|
||||
txQueueManager := txqueue.NewManager(nodeManager, accountManager)
|
||||
jailManager := jail.New(nodeManager)
|
||||
notificationManager := fcm.NewNotification(fcmServerKey)
|
||||
|
||||
return &StatusBackend{
|
||||
nodeManager: nodeManager,
|
||||
accountManager: accountManager,
|
||||
jailManager: jailManager,
|
||||
txQueueManager: txQueueManager,
|
||||
newNotification: notificationManager,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package common
|
||||
|
||||
import "github.com/NaySoftware/go-fcm"
|
||||
|
||||
// Notifier manages Push Notifications.
|
||||
type Notifier interface {
|
||||
Send(body string, payload fcm.NotificationPayload, tokens ...string) error
|
||||
}
|
||||
|
||||
// NotificationConstructor returns constructor of configured instance Notifier interface.
|
||||
type NotificationConstructor func() Notifier
|
|
@ -0,0 +1,51 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: geth/common/notification.go
|
||||
|
||||
// Package common is a generated GoMock package.
|
||||
package common
|
||||
|
||||
import (
|
||||
go_fcm "github.com/NaySoftware/go-fcm"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockNotifier is a mock of Notifier interface
|
||||
type MockNotifier struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockNotifierMockRecorder
|
||||
}
|
||||
|
||||
// MockNotifierMockRecorder is the mock recorder for MockNotifier
|
||||
type MockNotifierMockRecorder struct {
|
||||
mock *MockNotifier
|
||||
}
|
||||
|
||||
// NewMockNotifier creates a new mock instance
|
||||
func NewMockNotifier(ctrl *gomock.Controller) *MockNotifier {
|
||||
mock := &MockNotifier{ctrl: ctrl}
|
||||
mock.recorder = &MockNotifierMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockNotifier) EXPECT() *MockNotifierMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Send mocks base method
|
||||
func (m *MockNotifier) Send(body string, payload go_fcm.NotificationPayload, tokens ...string) error {
|
||||
varargs := []interface{}{body, payload}
|
||||
for _, a := range tokens {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "Send", varargs...)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send
|
||||
func (mr *MockNotifierMockRecorder) Send(body, payload interface{}, tokens ...interface{}) *gomock.Call {
|
||||
varargs := append([]interface{}{body, payload}, tokens...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockNotifier)(nil).Send), varargs...)
|
||||
}
|
|
@ -395,6 +395,12 @@ type TestConfig struct {
|
|||
}
|
||||
}
|
||||
|
||||
// NotifyResult is a JSON returned from notify message
|
||||
type NotifyResult struct {
|
||||
Status bool `json:"status"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// LoadTestConfig loads test configuration values from disk
|
||||
func LoadTestConfig() (*TestConfig, error) {
|
||||
var testConfig TestConfig
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package fcm
|
||||
|
||||
import "github.com/NaySoftware/go-fcm"
|
||||
|
||||
// firebaseClient is a copy of "go-fcm" client methods.
|
||||
type firebaseClient interface {
|
||||
NewFcmRegIdsMsg(tokens []string, body interface{}) *fcm.FcmClient
|
||||
Send() (*fcm.FcmResponseStatus, error)
|
||||
SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: geth/notification/fcm/client.go
|
||||
|
||||
// Package fcm is a generated GoMock package.
|
||||
package fcm
|
||||
|
||||
import (
|
||||
go_fcm "github.com/NaySoftware/go-fcm"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockfirebaseClient is a mock of firebaseClient interface
|
||||
type MockfirebaseClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockfirebaseClientMockRecorder
|
||||
}
|
||||
|
||||
// MockfirebaseClientMockRecorder is the mock recorder for MockfirebaseClient
|
||||
type MockfirebaseClientMockRecorder struct {
|
||||
mock *MockfirebaseClient
|
||||
}
|
||||
|
||||
// NewMockfirebaseClient creates a new mock instance
|
||||
func NewMockfirebaseClient(ctrl *gomock.Controller) *MockfirebaseClient {
|
||||
mock := &MockfirebaseClient{ctrl: ctrl}
|
||||
mock.recorder = &MockfirebaseClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockfirebaseClient) EXPECT() *MockfirebaseClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// NewFcmRegIdsMsg mocks base method
|
||||
func (m *MockfirebaseClient) NewFcmRegIdsMsg(tokens []string, body interface{}) *go_fcm.FcmClient {
|
||||
ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", tokens, body)
|
||||
ret0, _ := ret[0].(*go_fcm.FcmClient)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// NewFcmRegIdsMsg indicates an expected call of NewFcmRegIdsMsg
|
||||
func (mr *MockfirebaseClientMockRecorder) NewFcmRegIdsMsg(tokens, body interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockfirebaseClient)(nil).NewFcmRegIdsMsg), tokens, body)
|
||||
}
|
||||
|
||||
// Send mocks base method
|
||||
func (m *MockfirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) {
|
||||
ret := m.ctrl.Call(m, "Send")
|
||||
ret0, _ := ret[0].(*go_fcm.FcmResponseStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send
|
||||
func (mr *MockfirebaseClientMockRecorder) Send() *gomock.Call {
|
||||
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)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package fcm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/NaySoftware/go-fcm"
|
||||
"github.com/status-im/status-go/geth/common"
|
||||
)
|
||||
|
||||
// Notification represents messaging provider for notifications.
|
||||
type Notification struct {
|
||||
client firebaseClient
|
||||
}
|
||||
|
||||
// NewNotification Firebase Cloud Messaging client constructor.
|
||||
func NewNotification(key string) common.NotificationConstructor {
|
||||
return func() common.Notifier {
|
||||
client := fcm.NewFcmClient(key).
|
||||
SetDelayWhileIdle(true).
|
||||
SetContentAvailable(true).
|
||||
SetTimeToLive(fcm.MAX_TTL)
|
||||
|
||||
return &Notification{client}
|
||||
}
|
||||
}
|
||||
|
||||
// Send send to the tokens list.
|
||||
func (n *Notification) Send(body string, payload fcm.NotificationPayload, tokens ...string) error {
|
||||
data := map[string]string{
|
||||
"msg": body,
|
||||
}
|
||||
|
||||
if payload.Title == "" {
|
||||
payload.Title = "Status - new message"
|
||||
}
|
||||
if payload.Body == "" {
|
||||
payload.Body = "ping"
|
||||
}
|
||||
|
||||
fmt.Println(payload.Title, payload.Body)
|
||||
|
||||
n.client.NewFcmRegIdsMsg(tokens, data)
|
||||
n.client.SetNotificationPayload(&payload)
|
||||
_, err := n.client.Send()
|
||||
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package fcm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/NaySoftware/go-fcm"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
func TestFCMClientTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(NotifierTestSuite))
|
||||
}
|
||||
|
||||
type NotifierTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
fcmClientMock *MockfirebaseClient
|
||||
fcmClientMockCtrl *gomock.Controller
|
||||
}
|
||||
|
||||
func (s *NotifierTestSuite) SetupTest() {
|
||||
s.fcmClientMockCtrl = gomock.NewController(s.T())
|
||||
s.fcmClientMock = NewMockfirebaseClient(s.fcmClientMockCtrl)
|
||||
}
|
||||
|
||||
func (s *NotifierTestSuite) TearDownTest() {
|
||||
s.fcmClientMockCtrl.Finish()
|
||||
}
|
||||
|
||||
func (s *NotifierTestSuite) TestNotifySuccess() {
|
||||
fcmPayload := getPayload()
|
||||
ids := []string{"1"}
|
||||
payload := fcmPayload
|
||||
msg := make(map[string]string)
|
||||
body := "body"
|
||||
msg["msg"] = body
|
||||
|
||||
s.fcmClientMock.EXPECT().SetNotificationPayload(&fcmPayload).Times(1)
|
||||
s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, msg).Times(1)
|
||||
s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1)
|
||||
fcmClient := Notification{s.fcmClientMock}
|
||||
|
||||
err := fcmClient.Send(body, payload, ids...)
|
||||
|
||||
s.NoError(err)
|
||||
}
|
||||
|
||||
func (s *NotifierTestSuite) TestNotifyError() {
|
||||
expectedError := errors.New("error")
|
||||
fcmPayload := getPayload()
|
||||
ids := []string{"1"}
|
||||
payload := fcmPayload
|
||||
msg := make(map[string]string)
|
||||
body := "body"
|
||||
msg["msg"] = body
|
||||
|
||||
s.fcmClientMock.EXPECT().SetNotificationPayload(&fcmPayload).Times(1)
|
||||
s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, msg).Times(1)
|
||||
s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1)
|
||||
fcmClient := Notification{s.fcmClientMock}
|
||||
|
||||
err := fcmClient.Send(body, payload, ids...)
|
||||
|
||||
s.Equal(expectedError, err)
|
||||
}
|
||||
|
||||
func getPayload() fcm.NotificationPayload {
|
||||
return fcm.NotificationPayload{Title: "Status - new message", Body: "sum"}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package notification
|
||||
|
||||
// Payload data of message.
|
||||
type Payload struct {
|
||||
Title string
|
||||
Body string
|
||||
Icon string
|
||||
Sound string
|
||||
Badge string
|
||||
Tag string
|
||||
Color string
|
||||
}
|
|
@ -578,6 +578,7 @@ type bintree struct {
|
|||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"config": &bintree{nil, map[string]*bintree{
|
||||
"cht.json": &bintree{configChtJson, map[string]*bintree{}},
|
||||
|
@ -660,4 +661,3 @@ func _filePath(dir, name string) string {
|
|||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue