j3k0 / ganomede-notifications

Long-pull notification service for Ganomede
0 stars 0 forks source link

Notifications

This module allows a player to be notified of events using long-polling.

Notificatinos are created by other ganomede services by posting notification:

Notificatinos from different services will be of different type and will contain different data, but following fields will always be present in every notification:

{ "id": '12',                  // String       Notification ID
  "timestamp": 1429084002258,  // JSTimestmap  Created at this time
  "from": "turngame/v1",       // String       Created by this service

  "type": "invitation",            // String  Notification type (depends on the service)
  "data": {}                       // Object  Notification data (depends on the service and type)
  "push": {}                       // Object  Optional, include if you want this notification to be also sent as push-notification to user devices.
}

Notifications containing .push object will also be sent as push notifications to user devices. Payload of that push notification will contain original ganomede notification. Fields in .push describe how notification will be displayed to user.

{ "app": "triominos/v1"  // String, required  Which app to notify

  "title": [ "localization-key", "args..." ],   // String[], optional
  "message": [ "localization-key", "args..." ], // String[], optional
  "titleArgsTypes": [ ],                        // String[], optional
  "messageArgsTypes": [ "username..." ]         // String[], optional
}

.push.title and .push.message must be String arrays of at least 1 length containing localization key at [0] followed by any number of localization arguments. If either title, or message, or both are not present, notificaiton alert will default to config.pushApi.apn.defaultAlert string.

.push.messageArgsTypes and .push.titleArgsTypes define the types of localization arguments. Use specific types here so service will perform lookups and expand your arguments into "better-looking" strings.

Note: arg type considered special if it is formated as <type>:<subtype> (contains : char). Arg type is passed to expansion function:

// Based in userIds, this…

{ "title": [ "invite-title", "Invitation mailed to ", "alice" ],
  "titleArgsTypes": [ "string", "directory:email" ],

  "message": [ "invite-message", "bob", " invited you somewhere nice. Details are in your email, ", "alice", "." ],
  "messageArgsTypes": [ "directory:username", "string", "directory:username", "string" ]
}

// …will get expanded to this:

{ "title": [ "invite-title", "Invitation mailed to ", "alice@wonderland.com" ],
  "titleArgsTypes": [ "string", "directory:email" ],

  "message": [ "invite-message", "Magnificent Bob", " invited you somewhere nice. Details are in your email, ", "Alice of the Wonderland", "." ],
  "messageArgsTypes": [ "directory:username", "string", "directory:username", "string" ]
}

For now, only aliases are expanded from userIds via ganomede-directory. See translators.coffee for details.

Relations

Configuration

Variables available for service configuration (see config.js):

AuthDB

API

Users Messages [/notifications/v1/auth/:authToken/messages]

+ Parameters
    + authToken (string, required) ... Authentication token

Retrieve recent messages [GET]

+ GET parameters
    + after (integer) ... All message received after the one with given ID

Will retrieve all recent messages for the given user. In case no new messages are available, the request will wait for data until a timeout occurs.

response [200] OK

[{
    "id": 12,
    "timestamp": 1429084002258,
    "from": "turngame/v1",
    "type": "MOVE",
    "data": { ... }
},
{
    "id": 19,
    "timestamp": 1429084002258,
    "from": "invitations/v1",
    "type": "INVITE",
    "data": { ... }
}]

response [401] Unauthorized

If authToken is invalid.

Messages [/notifications/v1/messages]

Send a message [POST]

body (application/json)

{
    "to": "some_username",
    "from": "turngame/v1",
    "secret": "some secret passphrase",
    "type": "MOVE",
    "data": { ... }
}

response [200] OK

{
    "id": 12
    "timestamp": 1429084002258
}

response [401] Unauthorized

If secret is invalid.

design note

The value of "secret" should be equal to the API_SECRET environment variable.

Legacy Online User List [/notifications/v1/online]

Alias to /notifications/v1/online/default (listid = default)

Legacy Online status [/notifications/v1/auth/:authToken/online]

Alias to /auth/:authToken/online/default (listid = default)

Online User List [/notifications/v1/online/:listid]

List of players in the the listid list of online users.

Retrieve List [GET]

Will return a list of usernames of most recently online users. Lists are publicly available (no API_SECRET or auth required).

response [200] OK

[ "username",
  "alice",
  ...
  "bob"
]

Online status [/notifications/v1/auth/:authToken/online/:listid]

User is online.

Set as online [POST]

Add user to the list of online players with id listid, returns the list of users.

The list is trimmed at ONLINE_LIST_SIZE most recent users.

response [200] OK

[
  "username",
  "alice",
  ...
  "bob"
]

Push Notifications API

Save Push Token [POST /auth/:authToken/push-token]

Saves user's push notifications token to database. Example Body:

{
    app: 'substract-game',         // String, which app this token is for
    type: 'apn',                   // String, which push notifications provider
                                   //         this token is for, `apn` or `gcm`
                                   //         (see Token.TYPES)
    value: 'alicesubstracttoken'   // token value
}

Push Notifications Worker

The server doesn't send push notifications, only add them to a task list. A worker will read from this task list and do the actual sending.

Worker is found in src/push-api/sender-cli.coffee

A way of running it continously is through the push-worker.sh script, that'll spawn one worker every second.