Proposal: Chat provider for Inbox/Notifications

As mentioned in

there is a need for signalling protocol. I would like to propose

Chat Provider for Blockstack users

User profile is extended and defines next to hub_url:

API :

userSession.chat.listInvitations(callback) - connects to an API that lists all pending invitations

userSession.chat.setNewMessageCallback(callback) - connects to an API and runs the callback for all unread messages and waits for new message from any user for the app

userSession.chat.sendMessage(username, json) - if required creates a private room with the current user and the user username for the app. Then a message is send to user username.

userSession.chat.disconnect() - disconnects from the chat provider.

Use Case

  • Notify a group of friends that a new version of a file/document/data is ready.
  • Work together on a file/document

Possible Chat Protocols

Notes

  • Each user has a (different) username on the chat for each app, the name is derived from the username and the app domain, similar to appPrivateKeys, could be appPublicKey(?) or @oi-timesheet.com#friedger.id. The name is mapped to a user of the chat provider.
  • On logout, connection to chat provider is ended.
  • A user has chat rooms for each app and each group of users
1 Like

Hey @friedger, thanks for taking the time to write this API spec up!

While a signalling protocol would be nice for propagating notifications, I don’t think a signalling protocol is necessary for sending and storing them. The recipient’s Gaia hub simply stores inbound notifications, and the recipient’s client pulls them as needed (possibly through a signaling protocol, but not required). The Gaia hub itself would throttle message POSTs if too many are sent per unit time, and the Gaia hub would only allow a small amount of storage space (e.g. 256 bytes) for each (user, app) pair. The user must have a Blockstack ID and the app must have a DNS or BNS name, so bogus messages can be rejected. Moreover, if needed, the Gaia hub can drop messages for apps the user hasn’t whitelisted (but app whitelisting is TBD).

2 Likes

I used signaling protocol as it was mentioned in the initial suggestion.

@jude I’m not that much interested in the technical details, but more in the spec :slight_smile:

I think it is important to separate notifications provider from storage provider therefore I proposed a chat_url. We could use comm_url to make it more generic. Note that notification provider and storage provider can be the same, but are not necessarily the same.

From your description, I understand that you would like see the following:

  • userSession.comm. listNewMessages () - connects to an API and iterates through all unread messages
  • userSession.comm. sendMessage (username, json) - A message with content json is sent to user username .

Having the app pulling the message end point puts extra burden on the developer to decide when and how often to pull. It would be better to hide this in the API and have setMessageCallback. That method could use a sensible default for pulling (if the notification provider does not support other means) or take a parameter to make it configurable. In particular on mobile, apps need to be careful about the resources and delegate pulling to the system (in Android e.g. through JobSchedulers).

More use cases:

  • Share my location with a friend
  • Send feedback to app publisher
  • RSVP to an invitation/event

HTTP API

The Gaia Communication API only defines 3 endpoints:
List of senders

GET ${commUrl}/${channelAddress}/${address}

This returns a list of addressed that sent a message to address in the context of channelAddress .
The GET must contain an authentication header with a bearer token and proves that the sender of the request can control address and channelAddress.

List of Messages

GET ${commUrl}/${channelAddress}/${address}/${senderAddress}

This returns the message sent by senderAddress in the context of channelAddress.
The GET must contain an authentication header with a bearer token and proves that the sender of the request can control address and channelAddress.

Send Message

POST ${commUrl}/${channelAddress}/send/${receiverAddress}/${senderAddress}

The POST request stores a message for receiverAddress in the context of channelAddress. The request must contain an authentication header with a bearer token and proves that the sender of the request can control senderAddress and channelAddress. The body of the post must not be longer than 256 bytes.

The bearer token’s content and generation is described in the access control
In order for these requests to be usable from web applications, this read path must set the appropriate CORS headers. The HTTP Content-Type of the file should be application/json.