| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- syntax = "proto3";
- package chatto.api.v1;
- import "buf/validate/validate.proto";
- import "chatto/api/v1/pagination.proto";
- import "chatto/api/v1/rooms.proto";
- import "chatto/api/v1/users.proto";
- import "google/protobuf/descriptor.proto";
- import "google/protobuf/empty.proto";
- import "google/protobuf/field_mask.proto";
- import "google/protobuf/timestamp.proto";
- // Delivery behavior for one notification signal class.
- enum NotificationDeliveryMode {
- option allow_alias = true;
- // No delivery mode was specified. This value is not a valid override.
- NOTIFICATION_DELIVERY_MODE_UNSPECIFIED = 0;
- // Matching activity does not create user attention.
- NOTIFICATION_DELIVERY_MODE_OFF = 1;
- // Deprecated alias for NOTIFICATION_DELIVERY_MODE_IN_APP_NOTIFICATION.
- NOTIFICATION_DELIVERY_MODE_SILENT = 2 [deprecated = true];
- // Matching activity creates an in-app notification but does not send push.
- NOTIFICATION_DELIVERY_MODE_IN_APP_NOTIFICATION = 2;
- // Deprecated alias for NOTIFICATION_DELIVERY_MODE_PUSH_NOTIFICATION.
- NOTIFICATION_DELIVERY_MODE_ALERT = 3 [deprecated = true];
- // Matching activity creates an in-app notification and may send push.
- NOTIFICATION_DELIVERY_MODE_PUSH_NOTIFICATION = 3;
- // Matching activity adds a neutral unread indicator without creating a
- // notification occurrence, playing a sound, or sending push.
- NOTIFICATION_DELIVERY_MODE_UNREAD_BADGE = 4;
- }
- // Delivery modes for Chatto's finite built-in notification signal classes.
- // Presence is significant: absent fields inherit in a stored policy.
- message NotificationDeliveryModes {
- optional NotificationDeliveryMode direct_messages = 1;
- optional NotificationDeliveryMode direct_mentions = 2;
- optional NotificationDeliveryMode replies = 3;
- optional NotificationDeliveryMode role_mentions = 4;
- optional NotificationDeliveryMode here_mentions = 5;
- optional NotificationDeliveryMode all_mentions = 6;
- optional NotificationDeliveryMode followed_threads = 7;
- // Deprecated compatibility slot. Use room_messages at room scope.
- optional NotificationDeliveryMode followed_rooms = 8 [deprecated = true];
- optional NotificationDeliveryMode reactions = 9;
- // Delivery mode for root messages posted directly to joined channel rooms.
- // Thread messages and direct messages use their own signal classes.
- optional NotificationDeliveryMode room_messages = 10;
- }
- // Visual importance of an unread notification. This is independent from
- // whether the notification is eligible for sound or push delivery.
- enum NotificationAttentionLevel {
- // No attention level was provided.
- NOTIFICATION_ATTENTION_LEVEL_UNSPECIFIED = 0;
- // Ambient activity appears with a neutral unread indicator.
- NOTIFICATION_ATTENTION_LEVEL_AMBIENT = 1;
- // Important activity appears with Chatto's notification orange.
- NOTIFICATION_ATTENTION_LEVEL_IMPORTANT = 2;
- }
- // Exact visible message destination carried by a notification signal.
- message NotificationMessageReference {
- // Room containing the source activity.
- RoomSummary room = 1;
- // Exact source or reacted-to message event to reveal.
- string event_id = 2;
- // Thread root when the target is inside a thread.
- optional string thread_root_event_id = 3;
- }
- // A direct message sent to the viewer.
- message DirectMessageReceived {
- NotificationMessageReference message = 1;
- }
- // A message that mentions the viewer directly.
- message DirectMentionReceived {
- NotificationMessageReference message = 1;
- }
- // A reply to one of the viewer's messages.
- message ReplyReceived {
- NotificationMessageReference message = 1;
- }
- // A message mentioning a role held by the viewer.
- message RoleMentionReceived {
- NotificationMessageReference message = 1;
- // Source-time role handles that selected the viewer. Multiple matching role
- // mentions are consolidated into one occurrence for the source message.
- repeated string role_names = 2;
- }
- // An `@here` message that included the viewer.
- message HereMentionReceived {
- NotificationMessageReference message = 1;
- }
- // An `@all` message that included the viewer.
- message AllMentionReceived {
- NotificationMessageReference message = 1;
- }
- // Activity in a thread followed by the viewer.
- message FollowedThreadActivity {
- NotificationMessageReference message = 1;
- }
- // Deprecated compatibility payload. Chatto does not derive this signal.
- message FollowedRoomActivity {
- option deprecated = true;
- NotificationMessageReference message = 1;
- }
- // A root message posted directly to a channel room that the viewer belongs to.
- message RoomMessageReceived {
- NotificationMessageReference message = 1;
- }
- // A reaction added to one of the viewer's messages.
- message ReactionReceived {
- NotificationMessageReference message = 1;
- // Exact reaction supplied by the actor.
- string emoji = 2;
- }
- // Immutable, typed cause and destination of one notification. Clients must
- // preserve unknown variants as generic dismissible rows and must not infer
- // navigation semantics for them.
- message NotificationSignal {
- oneof kind {
- DirectMessageReceived direct_message_received = 1;
- DirectMentionReceived direct_mention_received = 2;
- ReplyReceived reply_received = 3;
- RoleMentionReceived role_mention_received = 4;
- HereMentionReceived here_mention_received = 5;
- AllMentionReceived all_mention_received = 6;
- FollowedThreadActivity followed_thread_activity = 7;
- FollowedRoomActivity followed_room_activity = 8 [deprecated = true];
- ReactionReceived reaction_received = 9;
- RoomMessageReceived room_message_received = 10;
- }
- }
- // One exact Notifications 2.0 source occurrence.
- message NotificationOccurrence {
- // Stable occurrence ID.
- string id = 1;
- // Time of the source activity.
- google.protobuf.Timestamp created_at = 2;
- // User who caused the source activity, when still visible.
- User actor = 3;
- // Immutable cause and destination represented by this occurrence.
- NotificationSignal signal = 4;
- // Whether this occurrence still contributes unread attention.
- bool unread = 5;
- // Absolute expiry, 90 days after the source activity.
- google.protobuf.Timestamp expires_at = 6;
- // Source-time visual importance of this occurrence.
- NotificationAttentionLevel attention_level = 7;
- }
- // Request for one page of notification occurrences.
- message ListNotificationOccurrencesRequest {
- // Page request. Defaults to 50 results when absent or limit is zero.
- PageRequest page = 1;
- }
- // One page of exact notification occurrences.
- message ListNotificationOccurrencesResponse {
- // Occurrences newest activity first.
- repeated NotificationOccurrence occurrences = 1;
- // Page metadata.
- PageInfo page = 2;
- // Total unread occurrence count, independent of presentation grouping.
- int32 unread_count = 3;
- // Earliest expiry in the complete list, including occurrences outside this page.
- // Clients refresh authoritative notification state at this boundary.
- google.protobuf.Timestamp next_expiry_at = 4;
- // Complete unread-occurrence counts by target room. This is independent of
- // the bounded page so room indicators remain authoritative.
- repeated NotificationRoomUnreadCount room_unread_counts = 5;
- // Exact unread occurrences with Important attention.
- int32 important_unread_count = 6;
- }
- // Request one exact notification occurrence by stable ID.
- message GetNotificationOccurrenceRequest {
- // Required stable occurrence ID.
- string notification_id = 1 [(buf.validate.field).string.min_len = 1];
- }
- // One exact notification occurrence.
- message GetNotificationOccurrenceResponse {
- // Visible occurrence. Absence is reported as NOT_FOUND.
- NotificationOccurrence occurrence = 1;
- }
- // Request an explicit bounded set of notification occurrences.
- message BatchGetNotificationOccurrencesRequest {
- // Stable occurrence IDs. Unknown, deleted, and currently invisible IDs are
- // omitted. Repeated IDs are de-duplicated in first-seen request order.
- repeated string notification_ids = 1 [(buf.validate.field).repeated = {
- min_items: 1
- max_items: 100
- items: {
- string: {min_len: 1}
- }
- }];
- }
- // Exact visible notification occurrences requested by stable ID.
- message BatchGetNotificationOccurrencesResponse {
- // Found occurrences in first-seen request order.
- repeated NotificationOccurrence occurrences = 1;
- }
- // Unread notification occurrences currently targeting one room.
- message NotificationRoomUnreadCount {
- // Target room ID.
- string room_id = 1;
- // Number of unread occurrences targeting this room.
- int32 unread_count = 2;
- // Unread occurrences in this room with Important attention.
- int32 important_unread_count = 3;
- }
- // Request to mark one notification occurrence read.
- message MarkNotificationReadRequest {
- // Required stable occurrence ID.
- string notification_id = 1 [(buf.validate.field).string.min_len = 1];
- }
- // Notification occurrence after marking it read.
- message MarkNotificationReadResponse {
- // Updated occurrence.
- NotificationOccurrence occurrence = 1;
- }
- // Request permanent deletion of one notification occurrence.
- message DeleteNotificationOccurrenceRequest {
- // Required stable occurrence ID.
- string notification_id = 1 [(buf.validate.field).string.min_len = 1];
- }
- // Result of deleting one notification occurrence.
- message DeleteNotificationOccurrenceResponse {
- // True when this call replaced a visible occurrence with a deletion tombstone.
- // False when the occurrence was already absent or deleted.
- bool deleted = 1;
- }
- // Request permanent deletion of an explicit bounded set of occurrences.
- message BatchDeleteNotificationOccurrencesRequest {
- // Stable occurrence IDs to delete. Duplicates and already absent IDs are
- // ignored. The server accepts at most 100 IDs.
- repeated string notification_ids = 1 [(buf.validate.field).repeated = {
- min_items: 1
- max_items: 100
- items: {
- string: {min_len: 1}
- }
- }];
- }
- // Result of deleting exact notification occurrences.
- message BatchDeleteNotificationOccurrencesResponse {
- // Number of visible occurrences replaced by deletion tombstones.
- int32 deleted_count = 1;
- }
- // Request permanent deletion of every currently visible notification occurrence.
- message DeleteAllNotificationOccurrencesRequest {}
- // Result of deleting every currently visible notification occurrence.
- message DeleteAllNotificationOccurrencesResponse {
- // Number of visible occurrences replaced by deletion tombstones.
- int32 deleted_count = 1;
- }
- // Explicit and effective delivery modes for one notification policy scope.
- message NotificationPolicy {
- // Explicit modes at the requested scope. Missing fields mean Inherit.
- NotificationDeliveryModes overrides = 1;
- // Complete modes after applying product, server, and room inheritance.
- NotificationDeliveryModes effective = 2;
- }
- // Request the authenticated viewer's notification policy.
- message GetNotificationPolicyRequest {
- // Empty returns server-scoped preferences. A room ID returns the inherited
- // effective policy for that room and requires current membership.
- optional string room_id = 1 [(buf.validate.field).string.min_len = 1];
- }
- // Complete supported notification policy for one scope.
- message GetNotificationPolicyResponse {
- // Room scope when requested; absent for server scope.
- optional string room_id = 1;
- // Explicit and effective policy for the requested scope.
- NotificationPolicy policy = 2;
- }
- // Sparsely update notification policy overrides.
- message UpdateNotificationPolicyRequest {
- // Room scope to change; absent changes the server scope.
- optional string room_id = 1 [(buf.validate.field).string.min_len = 1];
- // Sparse override values. Fields selected by update_mask but absent here are
- // cleared to Inherit.
- NotificationDeliveryModes overrides = 2;
- // Fields to set or clear, relative to overrides. The mask must contain at
- // least one supported delivery-mode field.
- google.protobuf.FieldMask update_mask = 3;
- }
- // Complete supported notification policy after a sparse update.
- message UpdateNotificationPolicyResponse {
- // Room scope when changed; absent for server scope.
- optional string room_id = 1;
- // Explicit and effective policy after the update.
- NotificationPolicy policy = 2;
- }
- // Explicit target for one notification policy. Clients must select exactly
- // one scope. Direct-message rooms use room scope and never inherit from a room
- // group.
- message NotificationPolicyScope {
- oneof scope {
- option (buf.validate.oneof).required = true;
- // Selects the authenticated viewer's server-wide policy.
- google.protobuf.Empty server = 1;
- // Selects one existing room group's policy.
- string room_group_id = 2 [(buf.validate.field).string.min_len = 1];
- // Selects one room's policy and requires current room membership.
- string room_id = 3 [(buf.validate.field).string.min_len = 1];
- }
- }
- // One policy together with the explicit scope that produced it.
- message ScopedNotificationPolicy {
- // Exact policy scope.
- NotificationPolicyScope scope = 1;
- // Explicit and effective modes for the scope.
- NotificationPolicy policy = 2;
- }
- // Request one notification policy for the authenticated viewer.
- message NotificationPolicyServiceGetNotificationPolicyRequest {
- // Required policy scope.
- NotificationPolicyScope scope = 1 [(buf.validate.field).required = true];
- }
- // One resolved notification policy.
- message NotificationPolicyServiceGetNotificationPolicyResponse {
- // Requested policy and its explicit scope.
- ScopedNotificationPolicy policy = 1;
- }
- // Request an explicit bounded set of notification policies.
- message BatchGetNotificationPoliciesRequest {
- // Required scopes. Missing or inaccessible scopes are omitted. Repeated
- // scopes are de-duplicated in first-seen request order.
- repeated NotificationPolicyScope scopes = 1 [(buf.validate.field).repeated = {
- min_items: 1
- max_items: 100
- }];
- }
- // Resolved notification policies requested by scope.
- message BatchGetNotificationPoliciesResponse {
- // Found policies in first-seen request order.
- repeated ScopedNotificationPolicy policies = 1;
- }
- // Sparsely update notification policy overrides at one explicit scope.
- message NotificationPolicyServiceUpdateNotificationPolicyRequest {
- // Required policy scope.
- NotificationPolicyScope scope = 1 [(buf.validate.field).required = true];
- // Sparse override values. Fields selected by update_mask but absent here are
- // cleared to Inherit.
- NotificationDeliveryModes overrides = 2;
- // Fields to set or clear, relative to overrides. The mask must contain at
- // least one supported delivery-mode field.
- google.protobuf.FieldMask update_mask = 3;
- }
- // Complete supported notification policy after a scoped sparse update.
- message NotificationPolicyServiceUpdateNotificationPolicyResponse {
- // Updated policy and its explicit scope.
- ScopedNotificationPolicy policy = 1;
- }
- // Reads, marks read, and deletes notifications for the authenticated viewer.
- service NotificationService {
- // Gets one exact visible occurrence. Message-derived occurrences require
- // current room membership. Channel-room occurrences also require message.read
- // or a matching thread relationship with message.read-interactions. DM
- // membership authorizes DM occurrences. Returns NOT_FOUND when the occurrence
- // is absent, deleted, expired, or no longer visible to the authenticated
- // viewer. Returns UNIMPLEMENTED when this server cannot validate its signal
- // kind.
- rpc GetNotificationOccurrence(GetNotificationOccurrenceRequest) returns (GetNotificationOccurrenceResponse);
- // Gets an explicit bounded set of visible occurrences. Missing or
- // inaccessible IDs are omitted and duplicate IDs are de-duplicated. Returns
- // UNIMPLEMENTED rather than partially answering when this server cannot
- // validate one requested signal kind.
- rpc BatchGetNotificationOccurrences(BatchGetNotificationOccurrencesRequest) returns (BatchGetNotificationOccurrencesResponse);
- // Lists exact Notifications 2.0 occurrences. Clients may derive temporary
- // presentation groups without changing occurrence identity or counts.
- // Message-derived occurrences require current room membership. Channel-room
- // occurrences also require message.read or a matching thread relationship
- // with message.read-interactions. DM membership authorizes DM occurrences.
- // Returns UNIMPLEMENTED rather than silently omitting an occurrence whose
- // signal kind this server version cannot validate and assemble.
- rpc ListNotificationOccurrences(ListNotificationOccurrencesRequest) returns (ListNotificationOccurrencesResponse);
- // Marks one occurrence read. Repeating the call is safe. Returns
- // UNIMPLEMENTED when this server cannot validate the occurrence signal kind.
- rpc MarkNotificationRead(MarkNotificationReadRequest) returns (MarkNotificationReadResponse) {
- option idempotency_level = IDEMPOTENT;
- }
- // Permanently deletes one occurrence while retaining its anti-recreation
- // tombstone through the original expiry. Repeating the call is safe. Returns
- // UNIMPLEMENTED when this server cannot validate the occurrence signal kind.
- rpc DeleteNotificationOccurrence(DeleteNotificationOccurrenceRequest) returns (DeleteNotificationOccurrenceResponse) {
- option idempotency_level = IDEMPOTENT;
- }
- // Permanently deletes an exact set of occurrences. Repeating the call is
- // safe because later activity receives different occurrence IDs. Returns
- // UNIMPLEMENTED rather than partially deleting a signal kind this server
- // cannot validate.
- rpc BatchDeleteNotificationOccurrences(BatchDeleteNotificationOccurrencesRequest) returns (BatchDeleteNotificationOccurrencesResponse) {
- option idempotency_level = IDEMPOTENT;
- }
- // Permanently deletes every visible occurrence current at the server's
- // authoritative mutation boundary. Callers must not retry this mutation
- // automatically because later activity may arrive after that boundary.
- // Returns UNIMPLEMENTED rather than partially deleting a signal kind this
- // server cannot validate.
- rpc DeleteAllNotificationOccurrences(DeleteAllNotificationOccurrencesRequest) returns (DeleteAllNotificationOccurrencesResponse);
- // Gets explicit and effective modes for every supported signal class.
- rpc GetNotificationPolicy(GetNotificationPolicyRequest) returns (GetNotificationPolicyResponse);
- // Atomically sets or clears selected server- or room-scoped signal-class overrides.
- rpc UpdateNotificationPolicy(UpdateNotificationPolicyRequest) returns (UpdateNotificationPolicyResponse) {
- option idempotency_level = IDEMPOTENT;
- }
- }
- // Reads and updates the authenticated viewer's server, room-group, and room
- // notification delivery policies.
- service NotificationPolicyService {
- // Gets explicit and effective modes for one policy scope. Returns NOT_FOUND
- // for a missing room group or room, and PERMISSION_DENIED when the viewer is
- // not a current member of a requested room.
- rpc GetNotificationPolicy(NotificationPolicyServiceGetNotificationPolicyRequest) returns (NotificationPolicyServiceGetNotificationPolicyResponse);
- // Gets an explicit bounded set of policies. Missing and inaccessible scopes
- // are omitted, and duplicate scopes are de-duplicated in first-seen order.
- rpc BatchGetNotificationPolicies(BatchGetNotificationPoliciesRequest) returns (BatchGetNotificationPoliciesResponse);
- // Atomically sets or clears selected overrides at one explicit scope.
- rpc UpdateNotificationPolicy(NotificationPolicyServiceUpdateNotificationPolicyRequest) returns (NotificationPolicyServiceUpdateNotificationPolicyResponse) {
- option idempotency_level = IDEMPOTENT;
- }
- }
|