Going to give you a bit more than what you asked for since I was just thinking about it. Hope that’s okay!
For now the protocol is incredibly simple but actually quite robust.
Let’s define some terms real quick just because…
Inbox - An inbox identifier by an UUID16 identifier
.
Integrators - Apps who want to send notifications.
Users - People with a Notific Inbox who use other Apps.
High Level Architecture
Today, we’re running a single canister which is acting as a Multi-Tenant host for everyones Inboxes. Notifications and Inboxes are stored in stable memory as JSON bytes; this has a slight overhead cycles cost. But, its negligible in the scheme of things. Moreover, this assures…
- We fail gracefully if we somehow explode in popularity (i.e no risk to heap).
- In the event of a Catastrophe, disaster recovery is as simple as possible; It’s just JSON.
- We have a clear path forward when its time to break these things out into personal canisters.
- Upgrades are effortless and we can safely update our underlaying data structures.
Inbox
Inboxes are identified by a UUID16 String. Every inbox has a list of Integrators which are allowed to publish notifications. So, unlike an SMS or Email Inbox, applications must ask permission to send you things. This allows users to actually be in control of what they’re receiving. And, Integrators can be removed with one click.
Inboxes can have multiple controllers. Meaning, they can be shared
. We don’t have any permission control yet. But, if someone needs this they can just use… Subscriptions and create a little DAO canister.
Each Inbox also let’s users manage a list of Subscribers which are forwarded every notification. We don’t have any retrying logic built in here yet but we don’t anticipate this being an issue for awhile to come.
Integrators
Integrators are just services that want to send notifications. Distrikt and DSCVR could be integrators. But, really any canister could be an Integrator. Once an Integrator is added to an Inbox they get permission to send notifications. Integrators can also declare a list of “Callbacks”. Which, I’ll elaborate a bit more on next.
Notifications
Notifications end up in a users Inbox after being created by an integrator. The most simple Notifications are just text. Maybe a link. Maybe some images. But, because of how we’re structured the App. They better be useful, or a user is just going to revoke an Integrators permission to send them.
type CreateNotificationRequest = record {
user_id : text; // Who is this going to.
subject : text;
body : text;
level : NotificationLevel;
callback_actions : vec CallbackActions; // Hmm, what are these?
};
Notifications don’t have to be simple though… We’re working on the ability to embed CallbackActions
. Which, would allow the user to make canister calls directly from the notification
! I’m really excited about this feature, I think it would truly supercharge Notific making it almost a low-code platform for developers.