Skip to content

[RFC] Push Notifications API #469

Closed
Closed
@omarroth

Description

@omarroth

Related issues: #195, #427

Currently, in order for an application to receive updates from a channel, it needs to send a request to /api/v1/channels/latest/:ucid or similar endpoint. This is inefficient when the number of channels being requested reaches even moderate size. This propsal is for a /api/v1/notifications that uses EventSource to push notifications in near real-time.

The EventSource protocol pushes updates using a persistent connection to an HTTP server. It is supported in all major browsers with a polyfill available for IE. The EventSource API can automatically reconnect to the source on errors, and provides a simple API for handling events. There is also a wrapper reconnecting-eventsource for handling more challenging network conditions.

The EventSource protocol is quite simple and can be implemented easily in any language where it isn't already supported. It sends comments (lines prefixed with :), or events containing: one or more data fields, an optional id, and an optional type. After each message is sent a trailing newline. Example from the spec:

: test stream

data: first event
id: 1

data:second event
id

data:  third event

/api/v1/notifications

The endpoint /api/v1/notifications would support a topics parameter containing a list of comma-separated resources. Each resource would be a UCID or any other supported ID. /api/v1/notifications would support a maximum of 1000 topics per call.

Opening a connection to /api/v1/notifications creates a persistent connection between the server and the client, with :keepalive #{TIMESTAMP} messages sent every 20-30 seconds to ensure the connection is not dropped.

Each event would contain a data field with the updated resource as JSON. Schema would be the same as /api/v1/channels/latest/:ucid.

Example output from cURL:

$ curl https://invidio.us/api/v1/notifications?topics=UCAAAA,UCBBBB
:keepalive 1554427320

id: 0
data: {"title":"...","videoId":"AAAAAAAAAAA","author":"...","authorId":"UCAAAA","authorUrl":"/channel/UCAAAA","videoThumbnails":[{"quality":"...","url":"...","width":120,"height":90}],"description":"...","descriptionHtml":"<div>...</div>","viewCount":1,"published":1554474212,"publishedText":"1 days ago","lengthSeconds":10,"liveNow":false,"paid":false,"premium":false}

:keepalive 1554427333

:keepalive 1554427335

id: 1
data: {"title":"...","videoId":"BBBBBBBBBBB","author":"...","authorId":"UCBBBB","authorUrl":"/channel/UCBBBB","videoThumbnails":[{"quality":"...","url":"...","width":120,"height":90}],"description":"...","descriptionHtml":"<div>...</div>","viewCount":1,"published":1554474212,"publishedText":"1 days ago","lengthSeconds":10,"liveNow":false,"paid":false,"premium":false}

Example handling in JavaScript:

var notifications = new EventSource('https://invidio.us/api/v1/notifications?topics=UCAAAA,UCBBBB');
notifications.onmessage(event) {
    var notification = JSON.parse(event.data); // => {title: "...", videoId: "AAAAAAAAAAA", ...

    // Update feed, notify user, or any other necessary handling for the event
}

Polling for notifications after being offline

In order for an application to receive notifications after being offline , a ?since=TIMESTAMP should be added to /api/v1/channels/latest/:ucid. Using ?since= would return up to 15 videos uploaded after the specified timestamp. If there are more than 15 videos that have been uploaded since the given date, /api/v1/channels/latest/:ucid will return the 15 latest.

It may also make sense to support an ?until=TIMESTAMP to create a "window" where specific videos can be queried, although this would require authentication as mentioned below.

Final thoughts

Notifications would only be supported for channels tracked by the instance, which means that one or more users on that instance are subscribed to them. Requesting that a new channel be tracked by an instance must be authenticated to prevent abuse. Authentication will be handled in a second RFC.

Important to note is that notifications will be sent when a channel changes a video's description or title, not just when it is uploaded.

In accordance with this spec, a "protocols":["eventsource"] field should be added to /api/v1/stats, example. See also #356.

I would like to discuss if there are any issues with this approach, or any other issues that haven't been considered to ensure this is provides as much utility as possible.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprovement of an existing featurestale

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions