Skip to content

Commit

Permalink
simplify TNPG & add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
or-else committed Mar 30, 2020
1 parent b53c888 commit 543883e
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 35 deletions.
23 changes: 17 additions & 6 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,10 +410,6 @@ A user is reported as being online when one or more of user's sessions are attac

An empty `ua=""` _user agent_ is not reported. I.e. if user attaches to `me` with non-empty _user agent_ then does so with an empty one, the change is not reported. An empty _user agent_ may be disallowed in the future.

## Push Notifications Support

Tinode supports mobile push notifications though compile-time plugins. The channel published by the plugin receives a copy of every data message which was attempted to be delivered. The server supports [Google FCM](https://firebase.google.com/docs/cloud-messaging/) out of the box.

## Public and Private Fields

Topics and subscriptions have `public` and `private` fields. Generally, the fields are application-defined. The server does not enforce any particular structure of these fields except for `fnd` topic. At the same time, client software should use the same format for interoperability reasons.
Expand Down Expand Up @@ -560,18 +556,33 @@ _Important!_ As a security measure, the client should not send security credenti

## Push Notifications

Tinode uses compile-time adapters for handling push notifications. The server comes with [Google FCM](https://firebase.google.com/docs/cloud-messaging/) and `stdout` adapters. FCM supports all major mobile platforms except Chinese flavor of Android. Any type of push notifications can be handled by writing an appropriate adapter. The payload of the notification from the FCM adapter is the following:
Tinode uses compile-time adapters for handling push notifications. The server comes with [Tinode Push Gateway](), [Google FCM](https://firebase.google.com/docs/cloud-messaging/), and `stdout` adapters. Tinode Push Gateway and Google FCM support Android with [Play Services](https://developers.google.com/android/guides/overview) (may not be supported by some Chinese phones), iOS devices and all major web browsers excluding Safari. The `stdout` adapter does not actually send push notifications. It's mostly useful for debugging, testing and logging. Other types of push notifications such as [TPNS](https://intl.cloud.tencent.com/product/tpns) can be handled by writing appropriate adapters.

If you are writing a custom plugin, the notification payload is the following:
```js
{
topic: "grpnG99YhENiQU", // Topic which received the message.
xfrom: "usr2il9suCbuko", // ID of the user who sent the message.
ts: "2019-01-06T18:07:30.038Z", // message timestamp in RFC3339 format.
seq: "1234", // sequential ID of the message (integer value sent as text).
mime: "text/x-drafty", // message MIME-Type.
mime: "text/x-drafty", // optional message MIME-Type.
content: "Lorem ipsum dolor sit amet, consectetur adipisci", // The first 80 characters of the message content as plain text.
}
```

### Tinode Push Gateway

Tinode Push Gateway (TNPG) is a proprietary Tinode service which sends push notifications on behalf of Tinode. It uses Google FCM on the backend and as such supports the same platforms as FCM. The main advantage of using TNPG over FCM is simplicity of configuration: mobile clients do not need to be recompiled, all is needed is a configuration update on a server.

### Google FCM

[Google FCM](https://firebase.google.com/docs/cloud-messaging/) supports Android with [Play Services](https://developers.google.com/android/guides/overview), iPhone and iPad devices, and all major web browsers excluding Safari. In order to use FCM mobile clients (iOS, Android) must be recompiled with credentials obtained from Google.

### Stdout

The `stdout` adapter is mostly useful for debugging and logging. It writes push payload to `STDOUT` where it can be redirected to file or read by some other process.


## Messages

A message is a logically associated set of data. Messages are passed as JSON-formatted UTF-8 text.
Expand Down
36 changes: 32 additions & 4 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,36 @@ docker cp name-of-the-container:/var/log/tinode.log ./tinode.log

Alternatively, you can instruct the docker container to save the logs to a directory on the host by mapping a host directory to `/var/log/` in the container. Add `-v /where/to/save/logs:/var/log` to the `docker run` command.

### Q: How to setup FCM push notifications?<br/>
**A**: Enabling push notifications requires two steps:

### Q: What are the options for enabling push notifications?<br/>
**A**: You can use Tinode Push Gateway (TNPG) or you can use Google FCM:
* _Tinode Push Gateway_ requires minimum configuration changes by sending pushes on behalf of Tinode.
* _Google FCM_ does not rely on Tinode infrastructure for pushes but requires you to recompile mobile apps (iOS and Android).

### Q: How to setup push notifications with Tinode Push Gateway?<br/>
**A**: Enabling TNPG push notifications requires two steps:
* register at console.tinode.co and obtain a TNPG token
* configure server with the token

#### Obtain TNPG token
1. Register at https://console.tinode.co and create an organization.
2. Get the TPNG token from the _On premise_ section by following the instructions there.

#### Configuring the server

Update the server config [`tinode.conf`](../server/tinode.conf#L384), section `"push"` -> `"name": "tnpg"`:
```js
{
"enabled": true,
"org": "test", // name of the organization you registered at console.tinode.co
"token": "SoMe_LonG.RaNDoM-StRiNg.123" // authentication token obtained from console.tinode.co
}
```
Make sure the `fcm` section is disabled `"enabled": false`.


### Q: How to setup push notifications with Google FCM?<br/>
**A**: Enabling FCM push notifications requires the following steps:
* enable push sending from the server
* enable receiving pushes in the clients

Expand All @@ -30,9 +58,9 @@ Alternatively, you can instruct the docker container to save the logs to a direc
4. Update [TinodeWeb](/tinode/webapp/) config [`firebase-init.js`](https://github.com/tinode/webapp/blob/master/firebase-init.js): update `apiKey`, `messagingSenderId`, `projectId`, `appId`, `messagingVapidKey`. See more info at https://github.com/tinode/webapp/#push_notifications

#### iOS and Android
1. If you are using an Android client, add `google-services.json` to [Tindroid](/tinode/tindroid/) by following instructions at https://developers.google.com/android/guides/google-services-plugin and recompile the client.
1. If you are using an Android client, add `google-services.json` to [Tindroid](/tinode/tindroid/) by following instructions at https://developers.google.com/android/guides/google-services-plugin and recompile the client. You may also optionally submit it to Google Play Store.
See more info at https://github.com/tinode/tindroid/#push_notifications
2. If you are using an iOS client, add `GoogleService-Info.plist` to [Tinodios](/tinode/ios/) by following instructions at https://firebase.google.com/docs/cloud-messaging/ios/client) and recompile the client.
2. If you are using an iOS client, add `GoogleService-Info.plist` to [Tinodios](/tinode/ios/) by following instructions at https://firebase.google.com/docs/cloud-messaging/ios/client) and recompile the client. You may optionally submit the app to Apple AppStore.
See more info at https://github.com/tinode/ios/#push_notifications


Expand Down
4 changes: 2 additions & 2 deletions server/push/fcm/payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func PrepareNotifications(rcpt *push.Receipt, config *AndroidConfig) []messageDa
}

var titlelc, title, bodylc, body, icon, color string
if config.Enabled {
if config != nil && config.Enabled {
titlelc = config.getTitleLocKey(rcpt.Payload.What)
title = config.getTitle(rcpt.Payload.What)
bodylc = config.getBodyLocKey(rcpt.Payload.What)
Expand All @@ -218,7 +218,7 @@ func PrepareNotifications(rcpt *push.Receipt, config *AndroidConfig) []messageDa
msg.Android = &fcm.AndroidConfig{
Priority: "high",
}
if config.Enabled {
if config != nil && config.Enabled {
// When this notification type is included and the app is not in the foreground
// Android won't wake up the app and won't call FirebaseMessagingService:onMessageReceived.
// See dicussion: https://github.com/firebase/quickstart-js/issues/71
Expand Down
17 changes: 7 additions & 10 deletions server/push/fcm/push_fcm.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import (

var handler Handler

// Size of the input channel buffer.
const defaultBuffer = 32
const (
// Size of the input channel buffer.
bufferSize = 1024

// Maximum length of a text message in runes
const maxMessageLength = 80
// Maximum length of a text message in runes
maxMessageLength = 80
)

// Handler represents the push handler; implements push.PushHandler interface.
type Handler struct {
Expand All @@ -37,7 +39,6 @@ type Handler struct {

type configType struct {
Enabled bool `json:"enabled"`
Buffer int `json:"buffer"`
Credentials json.RawMessage `json:"credentials"`
CredentialsFile string `json:"credentials_file"`
TimeToLive uint `json:"time_to_live,omitempty"`
Expand Down Expand Up @@ -82,11 +83,7 @@ func (Handler) Init(jsonconf string) error {
return err
}

if config.Buffer <= 0 {
config.Buffer = defaultBuffer
}

handler.input = make(chan *push.Receipt, config.Buffer)
handler.input = make(chan *push.Receipt, bufferSize)
handler.stop = make(chan bool, 1)

go func() {
Expand Down
19 changes: 9 additions & 10 deletions server/push/tnpg/push_tnpg.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
const (
baseTargetAddress = "https://pushgw.tinode.co/push/"
batchSize = 100
bufferSize = 1024
)

var handler Handler
Expand All @@ -26,11 +27,9 @@ type Handler struct {
}

type configType struct {
Enabled bool `json:"enabled"`
Buffer int `json:"buffer"`
User string `json:"user"`
AuthToken string `json:"auth_token"`
Android fcm.AndroidConfig `json:"android,omitempty"`
Enabled bool `json:"enabled"`
OrgName string `json:"org"`
AuthToken string `json:"token"`
}

// Init initializes the handler
Expand All @@ -44,11 +43,11 @@ func (Handler) Init(jsonconf string) error {
return nil
}

if len(config.User) == 0 {
return errors.New("push.tnpg.user not specified.")
if config.OrgName == "" {
return errors.New("push.tnpg.org not specified.")
}

handler.input = make(chan *push.Receipt, config.Buffer)
handler.input = make(chan *push.Receipt, bufferSize)
handler.stop = make(chan bool, 1)

go func() {
Expand All @@ -70,7 +69,7 @@ func postMessage(body interface{}, config *configType) (int, string, error) {
gz := gzip.NewWriter(buf)
json.NewEncoder(gz).Encode(body)
gz.Close()
targetAddress := baseTargetAddress + config.User
targetAddress := baseTargetAddress + config.OrgName
req, err := http.NewRequest("POST", targetAddress, buf)
if err != nil {
return -1, "", err
Expand All @@ -88,7 +87,7 @@ func postMessage(body interface{}, config *configType) (int, string, error) {
}

func sendPushes(rcpt *push.Receipt, config *configType) {
messages := fcm.PrepareNotifications(rcpt, &config.Android)
messages := fcm.PrepareNotifications(rcpt, nil)
if messages == nil {
return
}
Expand Down
15 changes: 12 additions & 3 deletions server/tinode.conf
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,6 @@
// Disabled. Won't work without the server key anyway. See below.
"enabled": false,

// Number of notifications to keep before they start to be dropped.
"buffer": 1024,

// Firebase project ID.
"project_id": "your-project-id",

Expand Down Expand Up @@ -379,6 +376,18 @@
}
}
}
},
{
// Tinode Push Gateway.
"name":"tnpg",
"config": {
// Disabled. Configure first then enable.
"enabled": false,
// Name of the organization you registered at console.tinode.co.
"org": "test",
// Authentication token obtained from console.tinode.co
"token": "jwt-security-token-obtained-from-console.tinode.co",
}
}
],

Expand Down

0 comments on commit 543883e

Please sign in to comment.