Kinto-Webpush: Step 1

The first step of implementing the Kinto webpush plugin is to be able to use Kinto’s user resource to store the user notification rules. This is what we’ll be looking at in this post.

Kinto webpush plugin aims at notifying a client, that has registered its webpush URL, whenever some modification occurs. In order to send push messages to the correct endpoint, on the occurrence of the correct event that triggers, we must have a way to store this user specific configuration of push credentials with their associated triggers.

We use Kinto’s user resource to achieve this task. First step is to register a resource named Subscription, and add two service endpoints to it:

  • User subscription list: notifications/webpush/
    This is where a user can add its subscription information, list all its subscriptions, or delete them. This is the collection path of the user resource.
  • Individual records: notifications/webpush/id
    This is where a user can modify its subscription or update any specific attribute of the subscription data, or delete any particular subscription. This is the record path of the user resource.
# Registering the resource.
@resource.register(name='subscription',
                   collection_path='/notifications/webpush',
                   record_path='/notifications/webpush/{{id}}')
class Subscription(resource.UserResource):
    mapping = SubscriptionSchema()

Once we have a resource registered with a collection path and a record path, we next have to define a schema of the records for this resource.
Our subscription record contains:

  • push attribute consisting of the push endpoint URL and the client’s key, and
  • trigger attribute consisting of the resource and the action on this kinto resource that triggers the push message.
SUBSCRIPTION_RECORD = {
    "push": {"endpoint": "https://push.mozilla.com",
             "keys": {"auth": "authToken",
                      "p256dh": "encryptionKey"}},
    "triggers": {
        "/buckets/blocklists/collections/*/records": ["write"]
    }
}

To define a schema for the above record we use Colander. A Colander schema is composed of one or more schema node objects, each typically of the class colander.SchemaNode, in a nested arrangement. Each schema node object has a required type and an optional validator. The type of a schema node indicates its data type, such as colander.String(). The validator could be an inbuilt one like colander.url or user defined, like in our case trigger_valid. We use this validator to ensure that our subscription record has a valid trigger action (like, read or write) and is registering a valid kinto resource (like bucket, collection, group, or record).

# Defining the schema
class KeySchema(colander.MappingSchema):
    auth = colander.SchemaNode(colander.String())
    p256dh = colander.SchemaNode(colander.String())


class PushSchema(colander.MappingSchema):
    endpoint = colander.SchemaNode(colander.String(), validator=colander.url)
    keys = KeySchema()


class SubscriptionSchema(resource.ResourceSchema):
    push = PushSchema()
    triggers = colander.SchemaNode(colander.Mapping(unknown='preserve'),
                                   validator=trigger_valid)

Now that we have registered a user resource and defined a schema for validating the records, all we have to do is use the correct HTTP verb on the correct service endpoint to add, modify, get or delete subscriptions.

For example, we can add a new user subscription by using the HTTP POST method on the endpoint /notification/webpush. The request body would consist of the subscription record having the push and triggers attributes and would look something like:

POST /notifications/webpush
< Request <
{
    "push": {"endpoint":"https://updates.push.services.mozilla.com/push/v1/gAAAAABXhkuIG...DnyV8iUiX3lVm","keys":{"auth":"by64sz1qJT...xl_g","p256dh":"BGRz...AX6EiUPuDefoC4"}}
    "triggers": {
      "/buckets/blocklists/collections/*/records": ["write"],
    }
  }

> Response >
{
  data: {
    "id": "a7546569-7583-4939-b9c9-71acb9321f82", 
    "last_modified": 1469023718589,
    "push": {"endpoint":"https://updates.push.services.mozilla.com/push/v1/gAAAAABXhkuIG...DnyV8iUiX3lVm","keys":{"auth":"by64sz1qJT...xl_g","p256dh":"BGRz...AX6EiUPuDefoC4"}}
    "triggers": {
      "/buckets/blocklists/collections/*/records": ["write"],
    }
  }
}

Similarly, we can use GET to list the user subscription list and DELETE to delete the user subscription. We can also modify or update an user subscription by using PUT/PATCH on /notification/webpush/id endpoint.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s