From 809b5343d40695f75c0e803212f1949b172265a2 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 3 Feb 2022 16:15:24 +0300 Subject: [PATCH 01/68] feat(chat): add invite created / deleted / used events --- stable/chat/v1/stream.proto | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 2797f7e..7ada100 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -384,6 +384,37 @@ message StreamEvent { uint64 user_id = 3; } + // Sent when an invite is created in a guild. + message InviteCreated { + // Guild ID of the guild that this occured for. + uint64 guild_id = 1; + // ID of the invite that was created. + string invite_id = 2; + // Possible uses of the created invite. + uint32 possible_uses = 3; + } + + // Sent when an invite is deleted in a guild. + // + // This can occur because of the invite being used up (0 remaining uses), + // or a user deleting the invite. + message InviteDeleted { + // Guild ID of the guild that this occured for. + uint64 guild_id = 1; + // ID of the invite that was deleted. + string invite_id = 2; + } + + // Sent when an invite is used once by a user. + message InviteUsed { + // Guild ID of the guild that this occured for. + uint64 guild_id = 1; + // ID of the invite that was used. + string invite_id = 2; + // User ID of the user that used this invite. + uint64 user_id = 3; + } + // Which event to send. oneof event { // Send the guild added to list event. @@ -446,5 +477,11 @@ message StreamEvent { InviteReceived invite_received = 29; // Send the guild invite rejected event. InviteRejected invite_rejected = 30; + // Send the invite created event. + InviteCreated invite_created = 31; + // Send the invite deleted event. + InviteDeleted invite_deleted = 32; + // Send the invite used event. + InviteUsed invite_used = 33; } } From b7d1cd8bb5ea41a859855729a686ef10099f4d3c Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 6 Feb 2022 04:46:36 +0300 Subject: [PATCH 02/68] docs: document IDs, document more stuff --- stable/Ids.md | 33 ++++++ stable/auth/v1/auth.proto | 128 ++++++++++----------- stable/chat/v1/chat.proto | 19 +++- stable/chat/v1/guilds.proto | 2 +- stable/chat/v1/messages.proto | 193 +++++++++++++++++--------------- stable/chat/v1/stream.proto | 47 +++++++- stable/emote/v1/types.proto | 3 +- stable/profile/v1/appdata.proto | 42 +++---- stable/profile/v1/types.proto | 22 ++-- staging/bots/v1/bots.proto | 81 +++++++------- staging/voice/v1/voice.proto | 96 ++++++++-------- 11 files changed, 381 insertions(+), 285 deletions(-) create mode 100644 stable/Ids.md diff --git a/stable/Ids.md b/stable/Ids.md new file mode 100644 index 0000000..18b73fa --- /dev/null +++ b/stable/Ids.md @@ -0,0 +1,33 @@ +# IDs + +## Guild ID + +A `uint64` ID. Represents a *Guild*. +This should be unique in a server. + +## Channel ID + +A `uint64` ID. Represents a *Channel*. +This should be unique in a *Guild*. + +## Message ID + +A `uint64` ID. Represents a *Message*. +This should be unique in a *Channel*. + +## File ID + +A `string` ID. Represents a file on a server. +This should be unique in a server. + +For clients, this means that they should download +from the server they got the file ID from. + +## HarMony Content (HMC) + +A URL in the format `hmc://server:port/id`. +Represents a file on a server. + +- The `server` part is the domain of the server and must always be provided. +- The `id` part is a file ID and must always be provided. +- The `port` part is the port and must always be provided. \ No newline at end of file diff --git a/stable/auth/v1/auth.proto b/stable/auth/v1/auth.proto index 90d7c36..bbbdcf0 100644 --- a/stable/auth/v1/auth.proto +++ b/stable/auth/v1/auth.proto @@ -19,23 +19,21 @@ message BeginAuthRequest { optional string for_guest_token = 1; } -// BeginAuthResponse // The return type of BeginAuth, containing the // auth_id that will be used for the authentication -// section +// section. message BeginAuthResponse { - // auth_id: the ID of this auth session + // auth_id: the ID of this auth session. string auth_id = 1; } -// Session // Session contains the information for a new session; // the user_id you logged in as and the session_token -// which should be passed to authorisation +// which should be passed to authorisation. message Session { - // user_id: the ID of the user you logged in as + // user_id: the ID of the user you logged in as. uint64 user_id = 1; - // session_token: the session token to use in authorization + // session_token: the session token to use in authorization. string session_token = 2; // A token allowing for this account to be upgraded to a // "full" account by beginning an auth session and providing @@ -55,28 +53,25 @@ message Session { optional string guest_token = 3; } -// AuthStep -// A step in the authentication process -// Contains a variety of different types of views +// A step in the authentication process. +// Contains a variety of different types of views. +// // It is recommended to have a fallback_url specified -// For non-trivial authentication procedures (such as captchas) +// for non-trivial authentication procedures (such as captchas). message AuthStep { - // Choice // A step which allows the user to choose from a range of options - // Allows you to show a heading by specifying title + // Allows you to show a heading by specifying title. message Choice { - // title: the title of the list of choices + // title: the title of the list of choices. string title = 1; // options: a list of choices, one of these - // should be sent in nextstep + // should be sent in nextstep. repeated string options = 2; } - // Form // A step which requires the user to input information - // Allows you to show a heading by specifying title + // Allows you to show a heading by specifying title. message Form { - // FormField // A field in the form, containing information on how it should // be rendered // Here is a list of form types that need to be supported: @@ -86,128 +81,125 @@ message AuthStep { // text: a field type that has to contain text // number: a field type that has to contain a number message FormField { - // name: the identifier for the form field + // name: the identifier for the form field. string name = 1; - // type: the type of the form field, as documented above + // type: the type of the form field, as documented above. string type = 2; } - // title: the title of this form + // title: the title of this form. string title = 1; - // fields: all the fields in this form + // fields: all the fields in this form. repeated FormField fields = 2; } // Waiting // A step which requires the user to perform an external action // The title and description should explain to the user - // what they should do to complete this step + // what they should do to complete this step. message Waiting { - // title: the title of this waiting screen + // title: the title of this waiting screen. string title = 1; - // description: the explanation of what's being waited on + // description: the explanation of what's being waited on. string description = 2; } - // fallback_url: unused + // fallback_url: unused. string fallback_url = 1; // can_go_back: whether or not the client can request the - // server to send the previous step + // server to send the previous step. bool can_go_back = 2; // step: the current step oneof step { - // choice: the user must pick a thing out of a list of options + // choice: the user must pick a thing out of a list of options. Choice choice = 3; - // form: the user must complete a form + // form: the user must complete a form. Form form = 4; - // session: you've completed auth, and have a session + // session: you've completed auth, and have a session. Session session = 5; - // waiting: you're waiting on something + // waiting: you're waiting on something. Waiting waiting = 6; } } -// NextStepRequest // contains the client's response to the server's challenge // This needs to be called first with no arguments to -// receive the first step +// receive the first step. message NextStepRequest { // auth_id: the authentication session you want - // the next step of + // the next step of. string auth_id = 1; - // A simple choice string indicating which option the user chose + // A simple choice string indicating which option the user chose. message Choice { - // choice: the choice the user picked + // choice: the choice the user picked. string choice = 1; } // Form fields can either be bytes, string, or int64. message FormFields { - // field: the data for a form field + // field: the data for a form field. oneof field { - // bytes: the form field's data is a byte array + // bytes: the form field's data is a byte array. bytes bytes = 1; - // string: the form field's data is a string + // string: the form field's data is a string. string string = 2; - // number: the form field's data is a number + // number: the form field's data is a number. int64 number = 3; } } - // An array of form fields, in the same order they came in from the server + // An array of form fields, in the same order they came in from the server. message Form { - // fields: the fields the user filled out + // fields: the fields the user filled out. repeated FormFields fields = 1; } - // step: the user's response to a step + // step: the user's response to a step. oneof step { - // choice: the choice the user picked + // choice: the choice the user picked. Choice choice = 2; - // form: the form the user filled out + // form: the form the user filled out. Form form = 3; } } // Used in `NextStep` endpoint. message NextStepResponse { - // step: the next step in the authentication process + // step: the next step in the authentication process. AuthStep step = 1; } -// StepBackRequest -// A request to go back 1 step +// A request to go back 1 step. message StepBackRequest { // auth_id: the authentication session the user - // wants to go back in + // wants to go back in. string auth_id = 1; } // Used in `StepBack` endpoint. message StepBackResponse { - // step: the previous step in the authentication process + // step: the previous step in the authentication process. AuthStep step = 1; } -// StreamStepsRequest // Required to be initiated by all authenticating clients -// Allows the server to send steps +// Allows the server to send steps. message StreamStepsRequest { // auth_id: the authorization session - // who's steps you want to stream + // who's steps you want to stream. string auth_id = 1; } // Used in `StreamSteps` endpoint. message StreamStepsResponse { - // step: the next step in the authentication process + // step: the next step in the authentication process. AuthStep step = 1; } // The request to federate with a foreign server. message FederateRequest { - // The server ID foreign server you want to federate with + // The server ID foreign server you want to federate with. string server_id = 1; } @@ -229,8 +221,8 @@ message KeyResponse { bytes key = 1; } -// Log into a foreignserver using a token -// from your homeserver, obtained through a FederateRequest +// Log into a foreignserver using a token from your homeserver, +// obtained through a FederateRequest. message LoginFederatedRequest { // A `harmonytypes.v1.Token` whose `data` field is a serialized `TokenData` message. // It is signed with the homeserver's private key. @@ -254,7 +246,7 @@ message TokenData { string server_id = 2; // The username of the client. string username = 3; - // The avatar of the client. + // The avatar of the client. This must be a HMC that points to an image. optional string avatar = 4; } @@ -288,28 +280,26 @@ message CheckLoggedInResponse {} // // TODO: finish -// The service containing authorization/entication methods +// The service containing authorization/entication methods. service AuthService { // Federate with a foreignserver, obtaining a token - // you can use to call LoginFederated on it + // you can use to call LoginFederated on it. rpc Federate(FederateRequest) returns (FederateResponse); // Present a token to a foreignserver from a Federate call - // on your homeserver in order to login + // on your homeserver in order to login. rpc LoginFederated(LoginFederatedRequest) returns (LoginFederatedResponse); - // Returns the public key of this server + // Returns the public key of this server. rpc Key(KeyRequest) returns (KeyResponse); - // Begins an authentication session + // Begins an authentication session. rpc BeginAuth(BeginAuthRequest) returns (BeginAuthResponse); // Goes to the next step of the authentication session, - // possibly presenting user input + // possibly presenting user input. rpc NextStep(NextStepRequest) returns (NextStepResponse); - // Goes to the previous step of the authentication session - // if possible + // Goes to the previous step of the authentication session if possible. rpc StepBack(StepBackRequest) returns (StepBackResponse); - // Consume the steps of an authentication session - // as a stream + // Consume the steps of an authentication session as a stream. rpc StreamSteps(StreamStepsRequest) returns (stream StreamStepsResponse); - // Check whether or not you're logged in and the session is valid + // Check whether or not you're logged in and the session is valid. rpc CheckLoggedIn(CheckLoggedInRequest) returns (CheckLoggedInResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; option (harmonytypes.v1.metadata).requires_permission_node = ""; diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 84ee025..40e528b 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -212,6 +212,9 @@ service ChatService { // // - If the invite used is in a user's "pending invites" list, it should be // removed from there. + // - If the invite used reaches a use count bigger or equal to it's possible + // uses, the invite should be deleted by the server. This doesn't apply if + // possible uses is 0, which means an infinite amount of uses. rpc JoinGuild(JoinGuildRequest) returns (JoinGuildResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } @@ -378,14 +381,19 @@ service ChatService { } // Endpoint to stream events from the homeserver. - // By default, this endpoint will subscribe to all events. - // Any guilds joined in the future will be added to the subscription as well. - // Use the UnsubscribeFromAll event for unsubscribing from all current subscriptions and disable the automatic guild subscriptions + // + // By default, this endpoint will subscribe to all events. Any guilds joined + // in the future will be added to the subscription as well. + // + // Use `StreamEventsRequest.UnsubscribeFromAll` for unsubscribing from all + // current subscriptions and disable automatic guild subscriptions. rpc StreamEvents(stream StreamEventsRequest) returns (stream StreamEventsResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } // Endpoint to add a reaction to a message. + // + // Servers should prevent a user from adding multiple same reactions. rpc AddReaction(AddReactionRequest) returns (AddReactionResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; option (harmonytypes.v1.metadata).requires_permission_node = @@ -393,6 +401,9 @@ service ChatService { } // Endpoint to remove a reaction from a message. + // + // Servers should only remove a reaction if the user making the request + // added the reaction before. rpc RemoveReaction(RemoveReactionRequest) returns (RemoveReactionResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; option (harmonytypes.v1.metadata).requires_permission_node = @@ -406,7 +417,9 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; option (harmonytypes.v1.metadata).requires_owner = true; } + // Endpoint to give up your own ownership. + // // Requires that at least one other person will still be owner. rpc GiveUpOwnership(GiveUpOwnershipRequest) returns (GiveUpOwnershipResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 6d53f0f..a7da990 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -49,7 +49,7 @@ message Guild { // the documentation of "direct message" guild kind on how to display // a name for those guilds. string name = 1; - // The picture HMC of the guild. + // The picture of the guild. This must be a file ID that points to an image. optional string picture = 2; // User ID of the owners of the guild. repeated uint64 owner_ids = 3; diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 745df08..9e41713 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -11,51 +11,51 @@ option go_package = "github.com/harmony-development/legato/gen/chat/v1"; message Overrides { // the overridden username. optional string username = 1; - // the overridden avatar. + // the overridden avatar. This must be a file ID pointing to an image. optional string avatar = 2; // the reason for overriding username and avatar. oneof reason { - // a custom reason in case the builtin ones don't fit + // A custom reason in case the builtin ones don't fit. string user_defined = 3; - // the override occured because of a webhook + // The override occured because of a webhook. harmonytypes.v1.Empty webhook = 4; - // plurality, not system as in computer + // Plurality, not system as in computer. harmonytypes.v1.Empty system_plurality = 5; - // the override occured because it was made by the server + // The override occured because it was made by the server. // // Servers should reject messages sent by users with this override. harmonytypes.v1.Empty system_message = 6; - // the override occured because of bridging + // The override occured because of bridging. harmonytypes.v1.Empty bridge = 7; } } // The payload sent to the bot when an action is triggered. message ActionPayload { - // The payload data for a button action + // The payload data for a button action. message Button { - // The data from the Button action + // The data from the Button action. bytes data = 1; } - // The payload for a dropdown action + // The payload for a dropdown action. message Dropdown { // The user choice from the dropdown. bytes choice = 1; } - // The payload for a text input action + // The payload for a text input action. message Input { // The user input. string input = 1; - // The bot-provided data + // The bot-provided data. bytes data = 2; } - // The payload data + // The payload data. oneof payload { - // Payload for a button + // Payload for a button. Button button = 1; - // Payload for a dropdown + // Payload for a dropdown. Dropdown dropdown = 2; - // Payload for a text input + // Payload for a text input. Input input = 3; } } @@ -65,9 +65,9 @@ message Action { // The action type. This is primarily used to change the look of the action to // the user (example: Destructive actions will have a red background). enum Type { - // a normal action. + // A normal action. TYPE_NORMAL_UNSPECIFIED = 0; - // a primary action. + // A primary action. TYPE_PRIMARY = 1; // A destructive / dangerous action. TYPE_DESTRUCTIVE = 2; @@ -82,6 +82,7 @@ message Action { bytes data = 2; // An external URL that the button links to. + // // This makes it so that tapping this button will open said URL instead // of triggering the action. optional string url = 3; @@ -92,7 +93,7 @@ message Action { // The text describing the dropdown. string label = 1; - // An entry in the dropdown + // An entry in the dropdown. message Entry { // The dropdown's UI label. string label = 1; @@ -110,7 +111,7 @@ message Action { string label = 1; // Whether this text input should be a multiline one or not. bool multiline = 2; - // Contextual data allowing the bot to discern what the user input is for + // Contextual data allowing the bot to discern what the user input is for. bytes data = 3; } @@ -137,6 +138,10 @@ message Embed { // Subtext of the heading. optional string subtext = 2; // URL of the heading. + // + // If this is provided, clients should make it so that + // interacting with the heading opens this URL, for example + // clicking on it. optional string url = 3; // Icon of the heading. optional string icon = 4; @@ -160,11 +165,11 @@ message Embed { optional string subtitle = 2; // Body text of this field (eg. a description). optional FormattedText body = 3; - // Image URL of this field. + // File ID of an image to display on this field. optional string image_url = 4; // How to present this field. Presentation presentation = 5; - // Actions of this field. + // Actions to show on this field. repeated Action actions = 6; } @@ -183,24 +188,23 @@ message Embed { } /* - Minithumbnail is an extremely low-quality JPEG thumbnail. + Minithumbnail is an extremely low-quality WebP thumbnail. The resolution is usually no larger than 64x64. */ message Minithumbnail { - // The width of the minithumbnail + // The width of the minithumbnail, in pixels. uint32 width = 1; - // The height of the minithumbnail + // The height of the minithumbnail, in pixels. uint32 height = 2; - // The JPEG data of the minithumbnail + // The data of the minithumbnail. bytes data = 3; } /* Photo contains data about a photo. - Photo are always JPEG, and are - constrained to the following rules: + Photos are constrained to the following rules: - width+height <= 10_000 - width <= height*20 @@ -208,25 +212,37 @@ message Minithumbnail { Photos are preferably no more than 10MB in size, and servers may compress as necessary. + + Photos are always WebP images, lossless or lossy + depending on if the server wants to compress the image. + + Servers should fill in `file_size`, `height`, `with` and + `minithumbnail` fields, regardless of the client providing them. */ message Photo { - // The HMC URL of the photo. + // File ID of the photo. string hmc = 1; // The filename of the photo. string name = 2; - // The size of the photo. + // The file size of the photo, in bytes. uint32 file_size = 3; // The height of the photo, in pixels. uint32 height = 4; // The width of the photo, in pixels. uint32 width = 5; // The photo's caption. - FormattedText caption = 6; + optional FormattedText caption = 6; // A thumbnail representing the photo. Minithumbnail minithumbnail = 7; } // Object representing a generic message attachment. +// +// Servers should fill in `mimetype` and `size` fields if +// they are not provided by the client. +// +// - `mimetype` is considered not provided if it is an empty string. +// - `size` is considered not provided if it is equal to `0`. message Attachment { // File ID of this attachment. string id = 1; @@ -234,7 +250,7 @@ message Attachment { string name = 2; // Mimetype of this attachment. string mimetype = 3; - // Size of this attachment. + // File size of this attachment, in bytes. uint32 size = 4; // Caption of this attachment. optional FormattedText caption = 5; @@ -314,84 +330,85 @@ message Content { message Reaction { // Emote data for this reaction. // - // Emote's image ID is used as an identifier for unique reactions. - // Emotes with the same names should be "deduplicated" by a client, by suffixing - // their names with `~1`, `~2` and so on. + // - Emote's image ID is used as an identifier for unique reactions. + // - Emotes with the same names should be "deduplicated" by a client, + // by suffixing their names with `~1`, `~2` and so on. emote.v1.Emote emote = 1; - // How many reactions this reaction has. + // How many times this reaction has been used. uint32 count = 2; } -// A format for text +// A format for text. message Format { - // Bold text + // Bold text. message Bold { } - // Italic text + // Italic text. message Italic { } - // Underlined text + // Underlined text. message Underline { } - // Monospace text + // Monospace text. message Monospace { } - // Superscript text + // Superscript text. message Superscript { } - // Subscript text + // Subscript text. message Subscript { } - // A larger codeblock, with a programming language specified + // A larger codeblock, with a programming language specified. + // // Clients should ideally not bound the width of codeblock messages, // possibly scrolling the codeblock horizontally separately from the - // rest of the message + // rest of the message. message CodeBlock { - // programming language of the code block + // Programming language of the code block. string language = 1; } - // Mention of a user (on the current homeserver) + // Mention of a user (on the current homeserver). message UserMention { - // user_id of the user being mentioned + // User ID of the user being mentioned. uint64 user_id = 1; } - // Mention of a role (on the current guild) + // Mention of a role (on the current guild). message RoleMention { - // the role being mentioned + // The role being mentioned. uint64 role_id = 1; } - // Mention of a channel (on the current guild) + // Mention of a channel (on the current guild). message ChannelMention { - // the channel being mentioned + // The channel being mentioned. uint64 channel_id = 1; } - // Mention of a guild + // Mention of a guild. message GuildMention { - // the guild being mentioned + // The guild being mentioned. uint64 guild_id = 1; - // which homeserver it belongs to + // Which homeserver it belongs to. string homeserver = 2; } - // An emoji + // An emoji. message Emoji { - // The HMC URL of the emoji + // The file ID of the emoji. It must point to an image. string image_hmc = 1; - // The ID of the emoji pack the emoji is from + // The ID of the emoji pack the emoji is from. uint64 pack_id = 2; } - // Colour modification + // Colour modification. message Color { - // The kind of colour modification to apply + // The kind of colour modification to apply. enum Kind { - // Dimmed colour + // Dimmed colour. KIND_DIM_UNSPECIFIED = 0; - // Brightened colour + // Brightened colour. KIND_BRIGHT = 1; - // Negative colour (usually red) + // Negative colour (usually red). KIND_NEGATIVE = 2; - // Positive colour (usually green) + // Positive colour (usually green). KIND_POSITIVE = 3; - // Informational colour (usually blue) + // Informational colour (usually blue). KIND_INFO = 4; - // Warning colour (usually yellow-orange) + // Warning colour (usually yellow-orange). KIND_WARNING = 5; } - // The kind of colour modification to apply + // The kind of colour modification to apply. Kind kind = 1; } // Replace a part of the text with the text matching the i18n code. @@ -401,49 +418,49 @@ message Format { string i18n_code = 1; } - // where the format begins to apply to + // Where the format begins to apply to. uint32 start = 1; - // how many characters the format is + // How many characters the format is. uint32 length = 2; - // the style if format to apply to this text + // The style if format to apply to this text. oneof format { - // a text format for bold text + // A text format for bold text. Bold bold = 3; - // a text format for italic text + // A text format for italic text. Italic italic = 4; - // a text format for underline text + // A text format for underline text. Underline underline = 5; - // a text format for monospace text + // A text format for monospace text. Monospace monospace = 6; - // a text format for superscript text + // A text format for superscript text. Superscript superscript = 7; - // a text format for subscript text + // A text format for subscript text. Subscript subscript = 8; - // a text format for a codeblock + // A text format for a codeblock. CodeBlock code_block = 9; - // a text format for a user mention + // A text format for a user mention. UserMention user_mention = 10; - // a text format for a role mention + // A text format for a role mention. RoleMention role_mention = 11; - // a text format for a channel mention + // A text format for a channel mention. ChannelMention channel_mention = 12; - // a text format for a guild mention + // A text format for a guild mention. GuildMention guild_mention = 13; - // a text format for an emoji + // A text format for an emoji. Emoji emoji = 14; - // a text format for coloured text + // A text format for coloured text. Color color = 15; - // a text format for localization + // A text format for localization. Localization localization = 16; } } -// Formatted text +// Formatted text. message FormattedText { - // The textual content of a message + // The textual content of a message. string text = 1; - // The formats for a message + // The formats for a message. repeated Format format = 2; } @@ -455,9 +472,9 @@ message Message { Overrides overrides = 2; // User ID of the user who sent this message. uint64 author_id = 3; - // When this message was created, in miliseconds since unix epoch + // When this message was created, in seconds since unix epoch. uint64 created_at = 4; - // The most recent time this message was edited, in milliseconds since unix epoch + // The most recent time this message was edited, in seconds since unix epoch. optional uint64 edited_at = 5; // The message this message is a reply to. optional uint64 in_reply_to = 6; diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 7ada100..78238ca 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -58,6 +58,9 @@ message StreamEventsResponse { // Describes an event. message StreamEvent { // Event sent when a new message is sent. + // + // This event will only be sent to users that have "messages.view" permission + // for the channel the message was sent in. message MessageSent { // ID that is sent by your client it can use to confirm that the message is sent. optional uint64 echo_id = 1; @@ -72,6 +75,9 @@ message StreamEvent { } // Event sent when a message's text content is updated. + // + // This event will only be sent to users that have "messages.view" permission + // for the channel the message was updated in. message MessageUpdated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -86,6 +92,9 @@ message StreamEvent { } // Event sent when a message is deleted. + // + // This event will only be sent to users that have "messages.view" permission + // for the channel the message was deleted in. message MessageDeleted { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -112,6 +121,9 @@ message StreamEvent { } // Event sent when a channel's information is changed. + // + // This event will only be sent to users that have "messages.view" permission + // for the channel that was updated. message ChannelUpdated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -124,6 +136,9 @@ message StreamEvent { } // Event sent when a channel's position in the channel list is changed. + // + // This event will only be sent to users that have "messages.view" permission + // for the channel that was moved. message ChannelPositionUpdated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -133,7 +148,10 @@ message StreamEvent { optional harmonytypes.v1.ItemPosition new_position = 3; } - // Event sent when all channels have been reordered + // Event sent when all channels have been reordered. + // + // If a user does not have "messages.view" permission for a channel in here, + // it should be omitted from the list. message ChannelsReordered { // guild_id: the guild whose channels are being reordered uint64 guild_id = 2; @@ -142,6 +160,9 @@ message StreamEvent { } // Event sent when a channel is deleted. + // + // This event will only be sent to users that have "messages.view" permission + // for the channel that was deleted. message ChannelDeleted { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -216,6 +237,8 @@ message StreamEvent { } // Event sent when a role's position in the role list is changed. + // + // This event will only be sent to users with the "roles.get" permission. message RoleMoved { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -226,6 +249,8 @@ message StreamEvent { } // Event sent when a role is deleted. + // + // This event will only be sent to users with the "roles.get" permission. message RoleDeleted { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -234,6 +259,8 @@ message StreamEvent { } // Event sent when a role is created. + // + // This event will only be sent to users with the "roles.get" permission. message RoleCreated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -250,6 +277,8 @@ message StreamEvent { } // Event sent when a role's information is changed. + // + // This event will only be sent to users with the "roles.get" permission. message RoleUpdated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -267,7 +296,7 @@ message StreamEvent { // Event sent when a role's permissions are changed. // - // This event will only be sent to users with the "guild.manage" permission. + // This event will only be sent to users with the "roles.manage" permission. message RolePermissionsUpdated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -280,6 +309,8 @@ message StreamEvent { } // Event sent when a user's roles are changed. + // + // This event will only be sent to users with the "roles.user.get" permission. message UserRolesUpdated { // Guild ID of the guild where this event happened. uint64 guild_id = 1; @@ -290,6 +321,9 @@ message StreamEvent { } // Event sent when a user sends a typing notification in a guild channel. + // + // Should only be sent to users who have the "message.view" permission for + // the guild channel where the typing happened. message Typing { // User ID of the user that sent the typing notification. uint64 user_id = 1; @@ -341,6 +375,9 @@ message StreamEvent { } // Sent when a message's reaction is changed. + // + // Should only be sent to users who have the "message.view" permission for + // the guild channel where the reaction was updated. message ReactionUpdated { // Guild ID of the guild where this event occured. uint64 guild_id = 1; @@ -385,6 +422,8 @@ message StreamEvent { } // Sent when an invite is created in a guild. + // + // This will only be sent to members of a guild with "invites.view" permission. message InviteCreated { // Guild ID of the guild that this occured for. uint64 guild_id = 1; @@ -398,6 +437,8 @@ message StreamEvent { // // This can occur because of the invite being used up (0 remaining uses), // or a user deleting the invite. + // + // This will only be sent to members of a guild with "invites.view" permission. message InviteDeleted { // Guild ID of the guild that this occured for. uint64 guild_id = 1; @@ -406,6 +447,8 @@ message StreamEvent { } // Sent when an invite is used once by a user. + // + // This will only be sent to members of a guild with "invites.view" permission. message InviteUsed { // Guild ID of the guild that this occured for. uint64 guild_id = 1; diff --git a/stable/emote/v1/types.proto b/stable/emote/v1/types.proto index 2c7b4d2..25fab8a 100644 --- a/stable/emote/v1/types.proto +++ b/stable/emote/v1/types.proto @@ -14,8 +14,7 @@ message EmotePack { // Data for a single emote. message Emote { - // The image ID of the emote. This is the ID of the image in the image store - // (same place attachments are stored). + // The HMC of the emote. Must point to an image. string image_id = 1; // The name of the emote. string name = 2; diff --git a/stable/profile/v1/appdata.proto b/stable/profile/v1/appdata.proto index 1e60917..a0b7b31 100644 --- a/stable/profile/v1/appdata.proto +++ b/stable/profile/v1/appdata.proto @@ -11,32 +11,32 @@ import "harmonytypes/v1/types.proto"; // with the override the tag belongs to, stripping // the tag indicators. message OverrideTag { - // The portion of the tag before the messge. - string before = 1; - // The portion of the tag after the messge. - string after = 2; + // The portion of the tag before the messge. + string before = 1; + // The portion of the tag after the messge. + string after = 2; } -// An individual override +// An individual override. message ProfileOverride { - // The username for this override - optional string username = 1; - // The avatar for this override - optional string avatar = 2; - // The tags for this override. - repeated OverrideTag tags = 3; - // The reason this override is used - oneof reason { - // a custom reason in case the builtin ones don't fit - string user_defined = 4; - // plurality, not system as in computer - harmonytypes.v1.Empty system_plurality = 5; - } + // The username for this override. + optional string username = 1; + // The avatar for this override. + optional string avatar = 2; + // The tags for this override. + repeated OverrideTag tags = 3; + // The reason this override is used. + oneof reason { + // A custom reason in case the builtin ones don't fit. + string user_defined = 4; + // Plurality, not system as in computer. + harmonytypes.v1.Empty system_plurality = 5; + } } -// The message used for the 'h.overrides' key +// The message used for the 'h.overrides' app ID // of appdata. message AppDataOverrides { - // The list of overrides. - repeated ProfileOverride overrides = 1; + // The list of overrides. + repeated ProfileOverride overrides = 1; } \ No newline at end of file diff --git a/stable/profile/v1/types.proto b/stable/profile/v1/types.proto index 7e9ef61..b66364a 100644 --- a/stable/profile/v1/types.proto +++ b/stable/profile/v1/types.proto @@ -32,13 +32,13 @@ enum AccountKind { message Profile { // the name of the user. string user_name = 1; - // the user's avatar. + // the user's avatar. This must be a file ID that points to an image. optional string user_avatar = 2; // the status of the user. UserStatus user_status = 3; - // whether the user is a bot or not + // whether the user is a bot or not. bool is_bot = 4 [ deprecated = true ]; - // what kind of account the user is, e.g. full, guest, bot + // what kind of account the user is, e.g. full, guest, bot. AccountKind account_kind = 5; } @@ -56,13 +56,13 @@ message GetProfileResponse { // Used in `UpdateProfile` endpoint. message UpdateProfileRequest { - // new name of the user. + // New name of the user. optional string new_user_name = 1; - // new user avatar. The avatar will be removed if the string is empty. + // New user avatar. The avatar will be removed if the string is empty. optional string new_user_avatar = 2; - // new status of the user. + // New status of the user. optional UserStatus new_user_status = 3; - // new whether the user is a bot or not + // New whether the user is a bot or not. // // Deprecated; see bot service and guest handling // in auth. @@ -74,21 +74,21 @@ message UpdateProfileResponse {} // Used in `GetAppData` endpoint. message GetAppDataRequest { - // the app id. + // The app id. string app_id = 1; } // Used in `GetAppData` endpoint. message GetAppDataResponse { - // the app data. + // The app data. bytes app_data = 1; } // Used in `SetAppData` endpoint. message SetAppDataRequest { - // the app id. + // The app id. string app_id = 1; - // the app data. + // The app data. bytes app_data = 2; } // Used in `SetAppData` endpoint. diff --git a/staging/bots/v1/bots.proto b/staging/bots/v1/bots.proto index c81c247..54f8860 100644 --- a/staging/bots/v1/bots.proto +++ b/staging/bots/v1/bots.proto @@ -16,107 +16,108 @@ where `code` is a purely alphanumeric code. */ -// A description of a bot account +// A description of a bot account. message Bot { - // The ID of the bot + // The ID of the bot. uint64 bot_id = 1; - // The bot's display name + // The bot's display name. string display_name = 2; - // The bot's avatar URL + // The bot's avatar. This must be a HMC that points to an image. string avatar_url = 3; - // The bot's invite code, if it has one + // The bot's invite code, if it has one. optional string invite = 4; } -// Request type for MyBots +// Request type for MyBots. message MyBotsRequest {} -// Response type for MyBots +// Response type for MyBots. message MyBotsResponse { - // The list of owned bots + // The list of owned bots. repeated Bot bots = 1; } -// Request type for CreateBot +// Request type for CreateBot. message CreateBotRequest { - // The bot's display name + // The bot's display name. string display_name = 1; - // The bot's avatar URL + // The bot's avatar. This must be a HMC that points to an image. optional string avatar_url = 2; - // The bot's invite code, if it has one + // The bot's invite code, if it has one. optional string invite = 3; } -// Response type for CreateBot +// Response type for CreateBot. message CreateBotResponse { - // The newly minted ID of the bot + // The newly generated ID of the bot. uint64 bot_id = 1; } -// Request type for EditBot +// Request type for EditBot. message EditBotRequest { - // The ID of the bot to edit + // The ID of the bot to edit. uint64 bot_id = 1; - // The bot's new display name + // The bot's new display name. optional string new_display_name = 2; - // The bot's new avatar URL + // The bot's new avatar. If provided, it must be a HMC + // that points to an image. optional string new_avatar_url = 3; - // The bot's new invite code + // The bot's new invite code. optional string invite = 4; } -// Response type for EditBot +// Response type for EditBot. message EditBotResponse {} -// Request type for DeleteBot +// Request type for DeleteBot. message DeleteBotRequest { - // The bot to delete + // The ID of the bot to delete. uint64 bot_id = 1; } -// Response type for DeleteBot +// Response type for DeleteBot. message DeleteBotResponse {} -// Request type for GetBot +// Request type for GetBot. message GetBotRequest { - // The bot to get the information of + // The ID of the bot to get the information of. uint64 bot_id = 1; } -// Response type for GetBot +// Response type for GetBot. message GetBotResponse { - // The requested bot + // The requested bot. Bot bot = 1; } -// Request type for Policies +// Request type for Policies. message PoliciesRequest {} -// Response type for Policies +// Response type for Policies. message PoliciesResponse { - // How many bots an individual account is allowed to own + // How many bots an individual account is allowed to own. uint32 max_bots = 1; } -// Request type for AddBot +// Request type for AddBot. message AddBotRequest { - // The guild to add the bot to + // The guild to add the bot to. uint64 guild_id = 1; // The bot's invite code. string invite_code = 2; } -// Response type for AddBot +// Response type for AddBot. message AddBotResponse {} -// The Bots service allows the management of bot accounts +// The Bots service allows the management of bot accounts. service BotsService { - // Gets the list of bots that you own + // Gets the list of bots that you own. rpc MyBots(MyBotsRequest) returns (MyBotsResponse); - // Gets information on a given bot + // Gets information on a given bot. rpc GetBot(GetBotRequest) returns (GetBotResponse); - // Creates a new bot account + // Creates a new bot account. rpc CreateBot(CreateBotRequest) returns (CreateBotResponse); - // Modifies a bot account that you own + // Modifies a bot account that you own. rpc EditBot(EditBotRequest) returns (EditBotResponse); - // Deletes a bot account that you own + // Deletes a bot account that you own. rpc DeleteBot(DeleteBotRequest) returns (DeleteBotResponse); // Server policies for bot accounts that the client // may display in its UI or restrict actions to prevent - // request errors + // request errors. rpc Policies(PoliciesRequest) returns (PoliciesResponse); // Requests a bot to add itself to the guild. // diff --git a/staging/voice/v1/voice.proto b/staging/voice/v1/voice.proto index 41e07e7..c1d65c9 100644 --- a/staging/voice/v1/voice.proto +++ b/staging/voice/v1/voice.proto @@ -7,7 +7,7 @@ package protocol.voice.v1; option go_package = "github.com/harmony-development/legato/gen/voice/v1"; // Data containing all the necessary information to -// create a consumer for a user in a voice channel +// create a consumer for a user in a voice channel. // // This corresponds to https://mediasoup.org/documentation/v3/mediasoup-client/api/#ConsumerOptions on client: // - `consumer_id` -> `id` @@ -26,7 +26,7 @@ message UserConsumerOptions { } // Object containing all the necessary information about transport options required -// from the server to establish transport connection on the client +// from the server to establish transport connection on the client. // // This corresponds to https://mediasoup.org/documentation/v3/mediasoup-client/api/#TransportOptions on client: // - `id` -> `id` @@ -46,7 +46,7 @@ message TransportOptions { // Used in `StreamMessage` endpoint. message StreamMessageRequest { - // IDs that will be used to know which channel this WS will operate in + // IDs that will be used to know which channel this WS will operate in. message Initialize { // Guild ID of the guild where the channel is. uint64 guild_id = 1; @@ -54,18 +54,18 @@ message StreamMessageRequest { uint64 channel_id = 2; } - // Data needed to prepare for joining a channel + // Data needed to prepare for joining a channel. message PrepareForJoinChannel { // RTP capabilities in JSON. string rtp_capabilities = 1; } - // Data needed to join a channel + // Data needed to join a channel. // // This takes one RTP paramaters for one track, which will be - // assumed to be Audio + // assumed to be Audio. // - // It also takes DTLS paramaters for connecting both producer and consumer + // It also takes DTLS paramaters for connecting both producer and consumer. message JoinChannel { // RTP paramaters in JSON. Corresponds to `RtpParameters` in mediasoup's TypeScript API. string rtp_paramaters = 1; @@ -75,69 +75,69 @@ message StreamMessageRequest { string consumer_dtls_paramaters = 3; } - // Message to resume a consumer + // Message to resume a consumer. message ResumeConsumer { // ID of the consumer to resume. string consumer_id = 1; } - // Message for this response + // Message for this response. oneof message { - // Sent to initialize the WS and receive necessary information + // Sent to initialize the WS and receive necessary information. Initialize initialize = 1; - // Sent to prepare for joining channel + // Sent to prepare for joining channel. PrepareForJoinChannel prepare_for_join_channel = 2; - // Sent to join a channel + // Sent to join a channel. JoinChannel join_channel = 3; - // Sent to resume a consumer + // Sent to resume a consumer. ResumeConsumer resume_consumer = 4; } } // Used in `StreamMessage` endpoint. message StreamMessageResponse { - // Initialization data for client + // Initialization data for client. message Initialized { // Server RTP capabilities in JSON. Corresponds to `RtpCapabilities` in mediasoup's TypeScript API. string rtp_capabilities = 1; } - // RTP capabilities validated + // RTP capabilities validated. message PreparedForJoinChannel { - // Consumer transport options + // Consumer transport options. TransportOptions consumer_transport_options = 1; - // Producer transport options + // Producer transport options. TransportOptions producer_transport_options = 2; } - // Producer for voice created; consumer and producer transports are connected + // Producer for voice created; consumer and producer transports are connected. message JoinedChannel { - // Consumer options for users that were already in the room + // Consumer options for users that were already in the room. repeated UserConsumerOptions other_users = 1; } - // Data for the user that joined the room and it's producer + // Data for the user that joined the room and it's producer. message UserJoined { - // Consumer options for this user + // Consumer options for this user. UserConsumerOptions data = 1; } - // Data for the user that left the room and the producer + // Data for the user that left the room and the producer. message UserLeft { - // ID of the user that left + // ID of the user that left. uint64 user_id = 1; } - // Message for this response + // Message for this response. oneof message { - // Sent when connection is started + // Sent when connection is started. Initialized initialized = 1; - // Sent when preparing to join a channel is successful + // Sent when preparing to join a channel is successful. PreparedForJoinChannel prepared_for_join_channel = 2; - // Sent when joining a channel is successful + // Sent when joining a channel is successful. JoinedChannel joined_channel = 3; - // Sent when another user joins the channel + // Sent when another user joins the channel. UserJoined user_joined = 4; - // Sent when another user leaves the channel + // Sent when another user leaves the channel. UserLeft user_left = 5; } } @@ -146,35 +146,35 @@ message StreamMessageResponse { // // # Usage (for client) // -// 0. Call StreamMessage to be able to send RTC commands to server -// 1. Send Initialize over stream with guild_id and channel_id of the request set to the channel you want to join -// 2. Init device by using the RTP capabilities sent in the response message, which should be Initialized -// 3. Send PrepareForJoinChannel over stream with client rtp capabilities -// 4. Wait for PreparedForJoinChannel, which contains transport options -// 5. Connect both transports using the transport options on client +// 0. Call StreamMessage to be able to send RTC commands to server. +// 1. Send Initialize over stream with guild_id and channel_id of the request set to the channel you want to join. +// 2. Init device by using the RTP capabilities sent in the response message, which should be Initialized. +// 3. Send PrepareForJoinChannel over stream with client rtp capabilities. +// 4. Wait for PreparedForJoinChannel, which contains transport options. +// 5. Connect both transports using the transport options on client. // 6. Send JoinChannel over stream containing RTP paramaters for your Audio track -// and DTLS paramaters for both consumer and producer +// and DTLS paramaters for both consumer and producer. // 7. Wait for JoinedChannel, which confirms you have successfully joined the voice channel; -// handle other_users which will be described in 8 (UserJoined handling) +// handle other_users which will be described in 8 (UserJoined handling). // 8. Handle UserJoined and UserLeft events appropiately // - For UserJoined; use the received consumer ID, producer ID and RTP parameters on your // consumer transport to consume the producer, afterwards send ResumeConsumer message -// with the consumer ID, then if that's successful add the track to a `user ID -> Track` map -// - For UserLeft, remove the user track from the `user ID -> Track` map +// with the consumer ID, then if that's successful add the track to a `user ID -> Track` map. +// - For UserLeft, remove the user track from the `user ID -> Track` map. // // ## How this looks for servers // -// 0. Receives StreamMessage, starts the socket -// 1. Waits for Initialize -// 2. Sends Initialized over stream with it's RTP capabilities -// 3. Receives PrepareForJoinChannel with client RTP capabilities -// 4. Sends PreparedForJoinChannel over stream with consumer and producer transport options +// 0. Receives StreamMessage, starts the socket. +// 1. Waits for Initialize. +// 2. Sends Initialized over stream with it's RTP capabilities. +// 3. Receives PrepareForJoinChannel with client RTP capabilities. +// 4. Sends PreparedForJoinChannel over stream with consumer and producer transport options. // 5. Receives JoinChannel, checks for DTLS parameters for consumer and producer transports -// and uses the RTP paramaters to create a producer for the client -// 6. Sends JoinedChannel over stream with the created producer ID and all other users' data (UserData) +// and uses the RTP paramaters to create a producer for the client. +// 6. Sends JoinedChannel over stream with the created producer ID and all other users' data (UserData). // 7. When another user does 1 to 7, sends UserJoined over stream to all other users; -// when a user leaves the channel (when their stream ends), sends UserLeft to all other users -// 8. When receiving a ResumeConsumer message, unpauses the consumer corresponding to the consumer ID +// when a user leaves the channel (when their stream ends), sends UserLeft to all other users. +// 8. When receiving a ResumeConsumer message, unpauses the consumer corresponding to the consumer ID. // service VoiceService { // Endpoint to stream messages between client and server. From 6e7dbf24158880149d8fc0b1013a6ba625c5c496 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 6 Feb 2022 04:49:52 +0300 Subject: [PATCH 03/68] docs(ids): document emote pack and user ids --- stable/Ids.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/stable/Ids.md b/stable/Ids.md index 18b73fa..6dfdadf 100644 --- a/stable/Ids.md +++ b/stable/Ids.md @@ -1,24 +1,34 @@ # IDs +## User ID + +A `uint64` ID. Represents a user. +This must be unique in a server. + ## Guild ID -A `uint64` ID. Represents a *Guild*. -This should be unique in a server. +A `uint64` ID. Represents a guild. +This must be unique in a server. ## Channel ID -A `uint64` ID. Represents a *Channel*. -This should be unique in a *Guild*. +A `uint64` ID. Represents a channel. +This must be unique in a *Guild*. ## Message ID -A `uint64` ID. Represents a *Message*. -This should be unique in a *Channel*. +A `uint64` ID. Represents a message. +This must be unique in a channel. + +## Emote Pack ID + +A `uint64` ID. Represents an emote pack. +This must be unique in a server. ## File ID A `string` ID. Represents a file on a server. -This should be unique in a server. +This must be unique in a server. For clients, this means that they should download from the server they got the file ID from. From ebc06c1786bdcd26d631cce4f135cab54cf2d789 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 6 Feb 2022 05:17:19 +0300 Subject: [PATCH 04/68] docs(batch): document it better --- stable/batch/v1/batch.proto | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/stable/batch/v1/batch.proto b/stable/batch/v1/batch.proto index cd8fca4..f75f20e 100644 --- a/stable/batch/v1/batch.proto +++ b/stable/batch/v1/batch.proto @@ -36,14 +36,42 @@ message BatchSameResponse { } // Service to batch requests. +// +// Note that: +// +// - This does not support batching stream requests. +// - Responses will be returned in the order the requests were given. +// - If an error occurs, the endpoint will short-circuit and return +// an error. +// +// Not all endpoints can be batched. A list of endpoints that can be +// batched is given below: +// +// - Endpoints that do not modify data: +// - "protocol.profile.v1.ProfileService.GetProfile" +// - "protocol.chat.v1.ChatService.QueryHasPermission" +// - "protocol.chat.v1.ChatService.GetUserRoles" +// - "protocol.chat.v1.ChatService.GetGuildRoles" +// - "protocol.chat.v1.ChatService.GetGuild" +// - "protocol.chat.v1.ChatService.GetGuildChannels" +// - "protocol.chat.v1.ChatService.GetPermissions" +// - "protocol.chat.v1.ChatService.GetGuildMembers" +// - "protocol.mediaproxy.v1.MediaProxyService.FetchLinkMetadata" +// - "protocol.mediaproxy.v1.MediaProxyService.InstantView" +// - "protocol.mediaproxy.v1.MediaProxyService.CanInstantView" service BatchService { // Batch requests. - // Does not support batching stream requests. - // Batched requests should be verified and an error should be thrown if they - // are invalid. + // + // Servers should limit the amount of requests that can be batched + // to 20. rpc Batch(BatchRequest) returns (BatchResponse) {} - // BatchSame allows batching for requests using the same endpoint. + // Allows batching for requests using the same endpoint. + // // This allows for additional network optimizations since the endpoint doesn't // have to be sent for every request. + // + // Servers should limit the amount of requests that can be batched + // to 100 for endpoints that do not modify data, and 20 for endpoints + // that modify data. rpc BatchSame(BatchSameRequest) returns (BatchSameResponse) {} } From 43b1d7996ea885ba7f625093a01f76628efebfd8 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 6 Feb 2022 05:19:09 +0300 Subject: [PATCH 05/68] fix(chat): revert breaking change --- stable/chat/v1/messages.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 9e41713..5e7563b 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -231,7 +231,7 @@ message Photo { // The width of the photo, in pixels. uint32 width = 5; // The photo's caption. - optional FormattedText caption = 6; + FormattedText caption = 6; // A thumbnail representing the photo. Minithumbnail minithumbnail = 7; } From caf363ebe4aa34927d795a4801a5d2a9fb0eb526 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 6 Feb 2022 05:57:34 +0300 Subject: [PATCH 06/68] fix: override avatars can be hmc, file id or external image url --- stable/chat/v1/messages.proto | 8 +++++--- stable/profile/v1/appdata.proto | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 5e7563b..07cfe11 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -9,11 +9,13 @@ option go_package = "github.com/harmony-development/legato/gen/chat/v1"; // Overrides provide a way to override the name and avatar of a message. message Overrides { - // the overridden username. + // The overridden username. optional string username = 1; - // the overridden avatar. This must be a file ID pointing to an image. + // The overridden avatar. + // + // This can be a HMC, a file ID, or an external image URL. optional string avatar = 2; - // the reason for overriding username and avatar. + // The reason for overriding username and avatar. oneof reason { // A custom reason in case the builtin ones don't fit. string user_defined = 3; diff --git a/stable/profile/v1/appdata.proto b/stable/profile/v1/appdata.proto index a0b7b31..2a61226 100644 --- a/stable/profile/v1/appdata.proto +++ b/stable/profile/v1/appdata.proto @@ -22,6 +22,8 @@ message ProfileOverride { // The username for this override. optional string username = 1; // The avatar for this override. + // + // This can be a HMC, a file ID, or an external image URL. optional string avatar = 2; // The tags for this override. repeated OverrideTag tags = 3; From df5abd2b9bf470b75a331c72f5c860e110e7e7c6 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 6 Feb 2022 09:15:25 +0300 Subject: [PATCH 07/68] fix(chat): add guild_ids to owner added / removed events --- stable/chat/v1/stream.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 78238ca..1b85768 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -391,12 +391,16 @@ message StreamEvent { // Sent when there's a new owner. message OwnerAdded { + // Guild ID of the guild where this event occured. + uint64 guild_id = 2; // User ID of the new owner. uint64 user_id = 1; } // Sent when an owner gives up their ownership. message OwnerRemoved { + // Guild ID of the guild where this event occured. + uint64 guild_id = 2; // User ID of the user who is no longer owner. uint64 user_id = 1; } From 9dd16e20793032cb0f7814903c2b14bf0d9a183d Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 7 Feb 2022 08:47:30 +0300 Subject: [PATCH 08/68] docs(chat): fix typo --- stable/chat/v1/messages.proto | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 07cfe11..018df81 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -218,8 +218,9 @@ message Minithumbnail { Photos are always WebP images, lossless or lossy depending on if the server wants to compress the image. - Servers should fill in `file_size`, `height`, `with` and - `minithumbnail` fields, regardless of the client providing them. + Servers should fill in `file_size`, `height`, `width` and + `minithumbnail` fields, regardless of whether the client + has provided them. */ message Photo { // File ID of the photo. From 078f1559c32a94609cb9e6d7380ed97ae5772157 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 9 Feb 2022 22:12:24 +0300 Subject: [PATCH 09/68] docs(emote): document that addemotetopack can take a file id --- stable/emote/v1/emote.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stable/emote/v1/emote.proto b/stable/emote/v1/emote.proto index 9708fb4..540c85c 100644 --- a/stable/emote/v1/emote.proto +++ b/stable/emote/v1/emote.proto @@ -21,6 +21,9 @@ service EmoteService { option (harmonytypes.v1.metadata).requires_authentication = true; } // Endpoint to add an emote to an emote pack that you own. + // + // If a file ID is used in this request, the server should convert + // it to a HMC before storing the emote. rpc AddEmoteToPack(AddEmoteToPackRequest) returns (AddEmoteToPackResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } From 187ea917b8519d7c56d8d655133677306fe1dc53 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Fri, 11 Feb 2022 21:41:39 +0300 Subject: [PATCH 10/68] refactor(chat): move text content to root of content, improve attachment situation, remove photos --- stable/chat/v1/messages.proto | 97 +++++++++++++---------------------- 1 file changed, 37 insertions(+), 60 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 018df81..fbb830e 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -190,7 +190,7 @@ message Embed { } /* - Minithumbnail is an extremely low-quality WebP thumbnail. + An extremely low-quality WebP thumbnail. The resolution is usually no larger than 64x64. */ @@ -204,7 +204,7 @@ message Minithumbnail { } /* - Photo contains data about a photo. + Contains data about a photo. Photos are constrained to the following rules: @@ -217,35 +217,19 @@ message Minithumbnail { Photos are always WebP images, lossless or lossy depending on if the server wants to compress the image. - - Servers should fill in `file_size`, `height`, `width` and - `minithumbnail` fields, regardless of whether the client - has provided them. */ -message Photo { - // File ID of the photo. - string hmc = 1; - // The filename of the photo. - string name = 2; - // The file size of the photo, in bytes. - uint32 file_size = 3; +message PhotoInfo { // The height of the photo, in pixels. - uint32 height = 4; + uint32 height = 1; // The width of the photo, in pixels. - uint32 width = 5; + uint32 width = 2; // The photo's caption. - FormattedText caption = 6; + FormattedText caption = 3; // A thumbnail representing the photo. - Minithumbnail minithumbnail = 7; + Minithumbnail minithumbnail = 4; } // Object representing a generic message attachment. -// -// Servers should fill in `mimetype` and `size` fields if -// they are not provided by the client. -// -// - `mimetype` is considered not provided if it is an empty string. -// - `size` is considered not provided if it is equal to `0`. message Attachment { // File ID of this attachment. string id = 1; @@ -255,36 +239,30 @@ message Attachment { string mimetype = 3; // File size of this attachment, in bytes. uint32 size = 4; - // Caption of this attachment. - optional FormattedText caption = 5; + // Extra info. + oneof info { + // Photo info. + PhotoInfo photo = 5; + } } -// Object representing a message's content. +// Object representing a message's content other than text. +// +// `InviteRejected`, `InviteAccepted` and `RoomUpgradedToGuild`, can only +// be used by servers themselves. Servers should reject messages with this +// content if they are sent by a user. message Content { - // Object representing text content. - message TextContent { - // Text content. - FormattedText content = 1; + // Attachment content. + message Attachments { + // Attachments. + repeated Attachment attachments = 1; } - // Object representing embed content. - message EmbedContent { - // Embed content. + // Embed content. + message Embeds { + // Embeds. repeated Embed embeds = 1; } - // Object representing attachment content. - message AttachmentContent { - // A list of attachments. - repeated Attachment files = 1; - } - // Object representing photo content. - message PhotoContent { - // A list of photos. - repeated Photo photos = 1; - } // Represents a user rejecting an invite. - // - // This can only be used by servers themselves. Servers should reject - // messages with this content if they are sent by a user. message InviteRejected { // User ID of the invitee. uint64 invitee_id = 1; @@ -292,9 +270,6 @@ message Content { uint64 inviter_id = 2; } // Represents a user accepting an invite. - // - // This can only be used by servers themselves. Servers should reject - // messages with this content if they are sent by a user. message InviteAccepted { // User ID of the invitee. uint64 invitee_id = 1; @@ -302,24 +277,26 @@ message Content { uint64 inviter_id = 2; } // Represents a guild upgrade from "room" to "normal". - // - // This can only be used by servers themselves. Servers should reject - // messages with this content if they are sent by a user. message RoomUpgradedToGuild { // User ID of the user that upgraded the guild. uint64 upgraded_by = 1; } - // Content data. - oneof content { - // Text content. - TextContent text_message = 1; + // Text content of the message. + // + // If this is empty, then `extra` must be specified. + string text = 1; + // Text formatting of the text content. + repeated Format text_formats = 2; + + // Extra content data, in addition to the text content. + // + // If this is empty, then `text` must be specified. + oneof extra { // Embed content. - EmbedContent embed_message = 2; + Embeds embeds = 3; // Attachment content. - AttachmentContent attachment_message = 3; - // Photo content. - PhotoContent photo_message = 4; + Attachments attachments = 4; // A user rejected an invite. InviteRejected invite_rejected = 5; // A user accepted an invite. From 166dab00f33a92459763518497a6db7cbbb3fc34 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Fri, 11 Feb 2022 22:32:09 +0300 Subject: [PATCH 11/68] refactor(chat): use emote in emoji format --- stable/chat/v1/messages.proto | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index fbb830e..8fb86bd 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -365,10 +365,8 @@ message Format { } // An emoji. message Emoji { - // The file ID of the emoji. It must point to an image. - string image_hmc = 1; - // The ID of the emoji pack the emoji is from. - uint64 pack_id = 2; + // The emote data of the emoji. + emote.v1.Emote emote = 1; } // Colour modification. message Color { From 8e4da894343d23799a98d6d0a5e5288ccd32d7b6 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Fri, 11 Feb 2022 23:19:49 +0300 Subject: [PATCH 12/68] feat(chat): seperate content type for sending messages --- stable/chat/v1/messages.proto | 64 ++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 8fb86bd..cd7fce6 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -283,15 +283,11 @@ message Content { } // Text content of the message. - // - // If this is empty, then `extra` must be specified. string text = 1; // Text formatting of the text content. repeated Format text_formats = 2; // Extra content data, in addition to the text content. - // - // If this is empty, then `text` must be specified. oneof extra { // Embed content. Embeds embeds = 3; @@ -565,6 +561,62 @@ message TriggerActionResponse {} // Used in the `SendMessage` endpoint. message SendMessageRequest { + // Information a user can add to a photo attachment. + message PhotoInfo { + // The photo's caption. + FormattedText caption = 1; + // Whether to use the original image, instead of compressing the image. + // + // Compression can be forced by servers, so this option may not work on + // every homeserver. + bool use_original = 2; + } + + // Attachment info that can be sent by a user. + message Attachment { + // The file ID of the attachment. + string id = 1; + // Name of the attachment. + string name = 2; + // Extra information. + oneof info { + // Photo info. + PhotoInfo photo = 3; + } + } + + // Content that can be sent by a user. + message Content { + // Attachment content. + message Attachments { + // Attachments. + repeated Attachment attachments = 1; + } + + // Embed content. + message Embeds { + // Embeds. + repeated Embed embeds = 1; + } + + // Text content of the message to be sent. + // + // If this is empty, then `extra` must be specified. + string text = 1; + // Text formats for the text content. + repeated Format text_formats = 2; + + // Extra content of the message to be sent. + // + // If this is empty, then `text` must be specified. + oneof extra { + // Attachment content. + Attachments attachments = 3; + // Embed content. + Embeds embeds = 4; + } + } + // Guild ID of the guild where the channel is. uint64 guild_id = 1; // Channel ID of the channel you want to send a message in. @@ -572,7 +624,9 @@ message SendMessageRequest { // Content of the new message. Content content = 3; // Echo ID of the new message. This can be used by clients to - // determine whether a message is sent. + // determine whether a message has been broadcasted properly + // to other clients. Note that this does not mean the broadcast + // reached other clients. optional uint64 echo_id = 4; // The overrides of this new message. optional Overrides overrides = 6; From bc4eb21175050ebf86dcbbdefbbbb561c7e64ee7 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 12 Feb 2022 00:50:46 +0300 Subject: [PATCH 13/68] refactor: remove batch, replace most get endpoints with 'batched' variants --- stable/batch/v1/batch.proto | 77 ----------------- stable/chat/v1/channels.proto | 2 - stable/chat/v1/chat.proto | 2 - stable/chat/v1/guilds.proto | 10 +-- stable/chat/v1/messages.proto | 2 - stable/chat/v1/permissions.proto | 116 ++++++++++++++------------ stable/chat/v1/stream.proto | 2 - stable/emote/v1/types.proto | 12 ++- stable/harmonytypes/v1/types.proto | 12 --- stable/mediaproxy/v1/mediaproxy.proto | 40 ++++++--- stable/profile/v1/types.proto | 8 +- stable/sync/v1/sync.proto | 2 - 12 files changed, 107 insertions(+), 178 deletions(-) delete mode 100644 stable/batch/v1/batch.proto diff --git a/stable/batch/v1/batch.proto b/stable/batch/v1/batch.proto deleted file mode 100644 index f75f20e..0000000 --- a/stable/batch/v1/batch.proto +++ /dev/null @@ -1,77 +0,0 @@ -syntax = "proto3"; - -package protocol.batch.v1; - -// AnyRequest is a generic message supporting any unary request. -message AnyRequest { - // The endpoint to which the request is being sent. - string endpoint = 1; - // The request data. - bytes request = 2; -} - -// Used in `Batch` endpoint. -message BatchRequest { - // The list of requests to be executed in the batch. - repeated AnyRequest requests = 1; -} - -// Used in `Batch` endpoint. -message BatchResponse { - // The list of responses to the requests. - repeated bytes responses = 1; -} - -// Used in `BatchSame` endpoint. -message BatchSameRequest { - // The endpoint to call for all requests. - string endpoint = 1; - // The list of requests to be executed in the batch. - repeated bytes requests = 2; -} -// Used in `BatchSame` endpoint. -message BatchSameResponse { - // The list of responses to the requests. - repeated bytes responses = 1; -} - -// Service to batch requests. -// -// Note that: -// -// - This does not support batching stream requests. -// - Responses will be returned in the order the requests were given. -// - If an error occurs, the endpoint will short-circuit and return -// an error. -// -// Not all endpoints can be batched. A list of endpoints that can be -// batched is given below: -// -// - Endpoints that do not modify data: -// - "protocol.profile.v1.ProfileService.GetProfile" -// - "protocol.chat.v1.ChatService.QueryHasPermission" -// - "protocol.chat.v1.ChatService.GetUserRoles" -// - "protocol.chat.v1.ChatService.GetGuildRoles" -// - "protocol.chat.v1.ChatService.GetGuild" -// - "protocol.chat.v1.ChatService.GetGuildChannels" -// - "protocol.chat.v1.ChatService.GetPermissions" -// - "protocol.chat.v1.ChatService.GetGuildMembers" -// - "protocol.mediaproxy.v1.MediaProxyService.FetchLinkMetadata" -// - "protocol.mediaproxy.v1.MediaProxyService.InstantView" -// - "protocol.mediaproxy.v1.MediaProxyService.CanInstantView" -service BatchService { - // Batch requests. - // - // Servers should limit the amount of requests that can be batched - // to 20. - rpc Batch(BatchRequest) returns (BatchResponse) {} - // Allows batching for requests using the same endpoint. - // - // This allows for additional network optimizations since the endpoint doesn't - // have to be sent for every request. - // - // Servers should limit the amount of requests that can be batched - // to 100 for endpoints that do not modify data, and 20 for endpoints - // that modify data. - rpc BatchSame(BatchSameRequest) returns (BatchSameResponse) {} -} diff --git a/stable/chat/v1/channels.proto b/stable/chat/v1/channels.proto index f71f115..4ae3e0f 100644 --- a/stable/chat/v1/channels.proto +++ b/stable/chat/v1/channels.proto @@ -4,8 +4,6 @@ import "harmonytypes/v1/types.proto"; package protocol.chat.v1; -option go_package = "github.com/harmony-development/legato/gen/chat/v1"; - // What kind the channel is. enum ChannelKind { // A text channel. Allows you to simply send messages to a group of people. diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 40e528b..c937e6e 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -9,8 +9,6 @@ import "chat/v1/stream.proto"; package protocol.chat.v1; -option go_package = "github.com/harmony-development/legato/gen/chat/v1"; - // The core of Harmony's chat operations. service ChatService { // Endpoint to create a guild. diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index a7da990..288ac84 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -4,8 +4,6 @@ package protocol.chat.v1; import "harmonytypes/v1/types.proto"; -option go_package = "github.com/harmony-development/legato/gen/chat/v1"; - // The kind of a guild. message GuildKind { // A "normal" guild as in a guild that allows multiple channels. @@ -183,13 +181,13 @@ message GetGuildListResponse { // Used in the `GetGuild` endpoint. message GetGuildRequest { - // Guild ID of the guild to get information about. - uint64 guild_id = 1; + // Guild ID(s) to get information about. + repeated uint64 guild_ids = 1; } // Used in the `GetGuild` endpoint. message GetGuildResponse { - // The information of the guild requested. - Guild guild = 1; + // The information(s) of the guild(s) requested. + map guild = 1; } // Used in the `GetGuildInvites` endpoint. diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index cd7fce6..0992d66 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -5,8 +5,6 @@ package protocol.chat.v1; import "harmonytypes/v1/types.proto"; import "emote/v1/types.proto"; -option go_package = "github.com/harmony-development/legato/gen/chat/v1"; - // Overrides provide a way to override the name and avatar of a message. message Overrides { // The overridden username. diff --git a/stable/chat/v1/permissions.proto b/stable/chat/v1/permissions.proto index b18d750..e90d11c 100644 --- a/stable/chat/v1/permissions.proto +++ b/stable/chat/v1/permissions.proto @@ -4,25 +4,23 @@ package protocol.chat.v1; import "harmonytypes/v1/types.proto"; -option go_package = "github.com/harmony-development/legato/gen/chat/v1"; - // Object representing a single permission node. message Permission { - // the permission matcher. (example: roles.manage) + // The permission matcher. (example: roles.manage). string matches = 1; - // whether the permission is allowed or not. + // Whether the permission is allowed or not. bool ok = 2; } // Object representing a role without the ID. message Role { - // the role name. + // The role name. string name = 1; - // the role color. + // The role color. int32 color = 2; - // whether the role is hoisted or not. + // Whether the role is hoisted or not. bool hoist = 3; - // whether the role is mentionable or not. + // Whether the role is mentionable or not. bool pingable = 4; } @@ -38,33 +36,33 @@ message RoleWithId { // Used in the `QueryHasPermission` endpoint. message QueryHasPermissionRequest { - // the guild ID to query permissions for + // The guild ID to query permissions for. uint64 guild_id = 1; - // the channel ID to query permissions for. If not set, it will query + // The channel ID to query permissions for. If not set, it will query // permissions for the guild. optional uint64 channel_id = 2; - // the user ID to query permissions for (if not provided, the current user is + // The user ID to query permissions for (if not provided, the current user is // assumed). optional uint64 as = 4; - // the permission node to check for. - string check_for = 3; + // The permission node(s) to check for. + repeated string check_for = 3; } // Used in the `QueryHasPermission` endpoint. message QueryHasPermissionResponse { - // the permissions for the given node. - bool ok = 1; + // The permissions for the given node(s). + map ok = 1; } // Used in the `SetPermissions` endpoint. message SetPermissionsRequest { - // the guild ID to set permissions for. + // The guild ID to set permissions for. uint64 guild_id = 1; - // the channel ID to set permissions for. Only set if the role is for a + // The channel ID to set permissions for. Only set if the role is for a // channel. optional uint64 channel_id = 2; - // the role ID to set permissions for. + // The role ID to set permissions for. uint64 role_id = 3; - // the permission list to give. + // The permission list to give. // // There is no "perms_to_take" because not given permissions are by // default not allowed. @@ -75,27 +73,33 @@ message SetPermissionsResponse {} // Used in the `GetPermissions` endpoint. message GetPermissionsRequest { - // the guild ID to get permissions for. + // The guild ID to get permissions for. uint64 guild_id = 1; - // the channel ID to get permissions for. Only applicable for roles in a + // The channel ID(s) to get permissions for. Only applicable for roles in a // channel. - optional uint64 channel_id = 2; - // the role ID to get permissions for. + repeated uint64 channel_ids = 2; + // The role ID to get permissions for. uint64 role_id = 3; } // Used in the `GetPermissions` endpoint. message GetPermissionsResponse { - // the permissions list for the given role. - repeated Permission perms = 1; + // Permissions of a role for a channel or guild. + message Permissions { + // The permissions. + repeated Permission perms = 1; + } + + // The guild / channel id -> permissions list map for the given role. + map perms = 1; } // Used in the `MoveRole` endpoint. message MoveRoleRequest { - // the guild ID to move the role in. + // The guild ID to move the role in. uint64 guild_id = 1; - // the role ID to move. + // The role ID to move. uint64 role_id = 2; - // the new position of the role. + // The new position of the role. harmonytypes.v1.ItemPosition new_position = 3; } // Used in the `MoveRole` endpoint. @@ -103,39 +107,39 @@ message MoveRoleResponse {} // Used in the `GetGuildRoles` endpoint. message GetGuildRolesRequest { - // the guild ID to get roles for. + // The guild ID to get roles for. uint64 guild_id = 1; } // Used in the `GetGuildRoles` endpoint. message GetGuildRolesResponse { - // the list of roles in the guild. + // The list of roles in the guild. repeated RoleWithId roles = 1; } // Used in the `AddGuildRole` endpoint. message AddGuildRoleRequest { - // the guild ID to add the role to. + // The guild ID to add the role to. uint64 guild_id = 1; - // the role name. + // The role name. string name = 2; - // the role color. + // The role color. int32 color = 3; - // whether the role is hoisted or not. + // Whether the role is hoisted or not. bool hoist = 4; - // whether the role is mentionable or not. + // Whether the role is mentionable or not. bool pingable = 5; } // Used in the `AddGuildRole` endpoint. message AddGuildRoleResponse { - // the ID of the newly created role. + // The ID of the newly created role. uint64 role_id = 1; } // Used in the `DeleteGuildRole` endpoint. message DeleteGuildRoleRequest { - // the guild ID to delete the role from. + // The guild ID to delete the role from. uint64 guild_id = 1; - // the role ID to delete. + // The role ID to delete. uint64 role_id = 2; } // Used in the `DeleteGuildRole` endpoint. @@ -143,17 +147,17 @@ message DeleteGuildRoleResponse {} // Used in the `ModifyGuildRole` endpoint. message ModifyGuildRoleRequest { - // the ID of the guild where the role is located + // The ID of the guild where the role is located. uint64 guild_id = 1; - // the ID of the role to modify + // The ID of the role to modify. uint64 role_id = 2; - // the new name of the role + // The new name of the role. optional string new_name = 3; - // the new color of the role + // The new color of the role. optional int32 new_color = 4; - // the new hoist status of the role + // The new hoist status of the role. optional bool new_hoist = 5; - // the new pingable status of the role + // The new pingable status of the role. optional bool new_pingable = 6; } // Used in the `ModifyGuildRole` endpoint. @@ -161,13 +165,13 @@ message ModifyGuildRoleResponse {} // Used in the `ManageUserRoles` endpoint. message ManageUserRolesRequest { - // the ID of the guild where the user is being managed + // The ID of the guild where the user is being managed. uint64 guild_id = 1; - // the ID of the user to modify + // The ID of the user to modify. uint64 user_id = 2; - // the IDs of the roles to add + // The IDs of the roles to add. repeated uint64 give_role_ids = 3; - // the IDs of the roles to remove + // The IDs of the roles to remove. repeated uint64 take_role_ids = 4; } // Used in the `ManageUserRoles` endpoint. @@ -175,13 +179,19 @@ message ManageUserRolesResponse {} // Used in the `GetUserRoles` endpoint. message GetUserRolesRequest { - // the ID of the guild where the user is located + // The ID of the guild where the user(s) are located. uint64 guild_id = 1; - // the ID of the user to get roles for - uint64 user_id = 2; + // The ID(s) of the user to get roles for. + repeated uint64 user_ids = 2; } // Used in the `GetUserRoles` endpoint. message GetUserRolesResponse { - // a list of IDs of the roles the user has - repeated uint64 roles = 1; + // Contains role IDs for a user in a guild. + message UserRoles { + // A list of IDs of the roles the user has. + repeated uint64 roles = 1; + } + + // User ID -> user role IDs map for the requested user(s). + map user_roles = 1; } diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 1b85768..9ebbeca 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -10,8 +10,6 @@ import "chat/v1/permissions.proto"; import "emote/v1/stream.proto"; import "profile/v1/stream.proto"; -option go_package = "github.com/harmony-development/legato/gen/chat/v1"; - // Request type for use in the `StreamEvents` endpoint. // By default, this endpoint will subscribe to all events. // Any guilds joined in the future will be added to the subscription as well. diff --git a/stable/emote/v1/types.proto b/stable/emote/v1/types.proto index 25fab8a..16a8765 100644 --- a/stable/emote/v1/types.proto +++ b/stable/emote/v1/types.proto @@ -42,12 +42,18 @@ message GetEmotePacksResponse { // Used in the `GetEmotes` endpoint. message GetEmotePackEmotesRequest { // The ID of the pack. - uint64 pack_id = 1; + repeated uint64 pack_id = 1; } // Used in the `GetEmotes` endpoint. message GetEmotePackEmotesResponse { - // The list of emotes in the pack. - repeated Emote emotes = 1; + // An emote pack's emotes. + message EmotePackEmotes { + // The list of emotes in the pack. + repeated Emote emotes = 1; + } + + // The requested emote packs' emotes. + map pack_emotes = 1; } // Used in the `AddEmoteToPack` endpoint. diff --git a/stable/harmonytypes/v1/types.proto b/stable/harmonytypes/v1/types.proto index caa7348..48a7d1f 100644 --- a/stable/harmonytypes/v1/types.proto +++ b/stable/harmonytypes/v1/types.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package protocol.harmonytypes.v1; -option go_package = "github.com/harmony-development/legato/gen/harmonytypes/v1"; - import "google/protobuf/descriptor.proto"; // Metadata for methods. These are set in individual RPC endpoints and are @@ -40,16 +38,6 @@ message Metadata { map extension = 2; } -// Error type that will be returned by servers. -message Error { - // The identifier of this error, can be used as an i18n key. - string identifier = 1; - // A (usually english) human message for this error. - string human_message = 2; - // More details about this message. Is dependent on the endpoint. - bytes more_details = 3; -} - // Token that will be used for authentication. message Token { // Ed25519 signature of the following serialized protobuf data, signed diff --git a/stable/mediaproxy/v1/mediaproxy.proto b/stable/mediaproxy/v1/mediaproxy.proto index ba7d09d..a84c58e 100644 --- a/stable/mediaproxy/v1/mediaproxy.proto +++ b/stable/mediaproxy/v1/mediaproxy.proto @@ -3,8 +3,6 @@ syntax = "proto3"; package protocol.mediaproxy.v1; import "harmonytypes/v1/types.proto"; -option go_package = "github.com/harmony-development/legato/gen/mediaproxy/v1"; - // Object representing the metadata of a website. message SiteMetadata { // Title of the website. @@ -37,17 +35,33 @@ message MediaMetadata { // Used in the `FetchLinkMetadata` endpoint. message FetchLinkMetadataRequest { // URL to fetch metadata from. - string url = 1; + repeated string url = 1; } // Used in the `FetchLinkMetadata` endpoint. message FetchLinkMetadataResponse { - // Data of the metadata. - oneof data { - // Site metadata for the URL. - SiteMetadata is_site = 1; - // Media metadata for the URL. - MediaMetadata is_media = 2; + // Fetched metadata for a link. + message Metadata { + // Data of the metadata. + oneof data { + // Site metadata for the URL. + SiteMetadata is_site = 1; + // Media metadata for the URL. + MediaMetadata is_media = 2; + } + } + + // Error data for a link. + message Error { + // Error status (usually HTTP, eg. `500 Internal Server Error`). + string status = 1; + // Error message, if the requested URL's server has provided one. + string message = 2; } + + // Fetched metadata for the requested URL(s). + map metadata = 1; + // URL(s) that errored out while trying to fetch metadata for them. + map errors = 2; } // Used in the `InstantView` endpoint. @@ -66,13 +80,13 @@ message InstantViewResponse { } // Used in the `CanInstantView` endpoint. message CanInstantViewRequest { - // URL to query if server can instant view the website. - string url = 1; + // URL(s) to query if server can instant view the website. + repeated string url = 1; } // Used in the `CanInstantView` endpoint. message CanInstantViewResponse { - // Whether the server generate an instant view for the URL queried. - bool can_instant_view = 1; + // Whether the server generate an instant view for the URL(s) queried. + map can_instant_view = 1; } // Harmony service for fetching metadata and generating instant view for URLs. diff --git a/stable/profile/v1/types.proto b/stable/profile/v1/types.proto index b66364a..d68ddef 100644 --- a/stable/profile/v1/types.proto +++ b/stable/profile/v1/types.proto @@ -44,14 +44,14 @@ message Profile { // Used in `GetProfile` endpoint. message GetProfileRequest { - // The id of the user to get. - uint64 user_id = 1; + // The ID(s) of the user(s) to get. + repeated uint64 user_id = 1; } // Used in `GetProfile` endpoint. message GetProfileResponse { - // The user's profile - Profile profile = 1; + // The users' profile(s). + map profile = 1; } // Used in `UpdateProfile` endpoint. diff --git a/stable/sync/v1/sync.proto b/stable/sync/v1/sync.proto index 4e1f790..e232395 100644 --- a/stable/sync/v1/sync.proto +++ b/stable/sync/v1/sync.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package protocol.sync.v1; -option go_package = "github.com/harmony-development/legato/gen/sync/v1"; - // Authentication data that will be sent in a `harmonytypes.v1.Token`. message AuthData { // The server ID of the server initiating the transaction. For Pull, From 35109fc00555ac65838c664b300dc7860d70ae41 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 12 Feb 2022 01:20:41 +0300 Subject: [PATCH 14/68] feat: add image resolution to embeds, fix ids --- stable/Ids.md | 12 +++++++-- stable/chat/v1/guilds.proto | 4 +-- stable/chat/v1/messages.proto | 47 ++++++++++++++++++++++----------- stable/profile/v1/appdata.proto | 2 +- stable/rest/rest.md | 5 ++-- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/stable/Ids.md b/stable/Ids.md index 6dfdadf..fa0651f 100644 --- a/stable/Ids.md +++ b/stable/Ids.md @@ -25,7 +25,7 @@ This must be unique in a channel. A `uint64` ID. Represents an emote pack. This must be unique in a server. -## File ID +## Local File ID A `string` ID. Represents a file on a server. This must be unique in a server. @@ -40,4 +40,12 @@ Represents a file on a server. - The `server` part is the domain of the server and must always be provided. - The `id` part is a file ID and must always be provided. -- The `port` part is the port and must always be provided. \ No newline at end of file +- The `port` part is the port and must always be provided. + +## File ID + +This is an ID that represents a file on a server. +It can be one of the following: + +- A local file ID, +- A HMC. \ No newline at end of file diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 288ac84..222c543 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -113,7 +113,7 @@ enum LeaveReason { message CreateGuildRequest { // The name of the guild. string name = 1; - // The picture HMC of the guild. + // The picture file ID of the guild. optional string picture = 2; // Metadata of the guild. optional harmonytypes.v1.Metadata metadata = 3; @@ -128,7 +128,7 @@ message CreateGuildResponse { message CreateRoomRequest { // The name of the guild. string name = 1; - // The picture HMC of the guild. + // The picture file ID of the guild. optional string picture = 2; // Metadata of the guild. optional harmonytypes.v1.Metadata metadata = 3; diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 0992d66..19df1bb 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -11,7 +11,7 @@ message Overrides { optional string username = 1; // The overridden avatar. // - // This can be a HMC, a file ID, or an external image URL. + // This can be a file ID or an external image URL. optional string avatar = 2; // The reason for overriding username and avatar. oneof reason { @@ -159,32 +159,47 @@ message Embed { PRESENTATION_ROW = 2; } + // Data for displaying an image in embed. + // + // Servers should fill in the `width` and `height` fields. + message Image { + // File ID or external image URL of an image. + string id = 1; + // Width of the image in pixels. + uint32 width = 2; + // Height of the image in pixels. + uint32 height = 3; + } + + // How to present this field. + Presentation presentation = 1; + // Title of this field. - string title = 1; + string title = 2; // Subtitle of this field. - optional string subtitle = 2; + optional string subtitle = 3; // Body text of this field (eg. a description). - optional FormattedText body = 3; - // File ID of an image to display on this field. - optional string image_url = 4; - // How to present this field. - Presentation presentation = 5; + optional FormattedText body = 4; + + // An image to display on this field. + optional Image image = 5; + // Actions to show on this field. repeated Action actions = 6; } + // Embed heading for the header. + optional EmbedHeading header = 1; // Title of this embed. - string title = 1; + string title = 2; // Body text of this embed. - optional FormattedText body = 2; - // Color of this embed. - optional int32 color = 3; - // Embed heading for the header. - optional EmbedHeading header = 4; + optional FormattedText body = 3; + // Fields of this embed. + repeated EmbedField fields = 4; // Embed heading for the footer. optional EmbedHeading footer = 5; - // Fields of this embed. - repeated EmbedField fields = 6; + // Color of this embed. + optional int32 color = 6; } /* diff --git a/stable/profile/v1/appdata.proto b/stable/profile/v1/appdata.proto index 2a61226..4bacfbe 100644 --- a/stable/profile/v1/appdata.proto +++ b/stable/profile/v1/appdata.proto @@ -23,7 +23,7 @@ message ProfileOverride { optional string username = 1; // The avatar for this override. // - // This can be a HMC, a file ID, or an external image URL. + // This can be a file ID or an external image URL. optional string avatar = 2; // The tags for this override. repeated OverrideTag tags = 3; diff --git a/stable/rest/rest.md b/stable/rest/rest.md index 5b6f579..74ead0d 100644 --- a/stable/rest/rest.md +++ b/stable/rest/rest.md @@ -46,9 +46,8 @@ Expects authentication: no The `file_id` should be one of the following: -- An attachment ID returned from POST `/_harmony/media/upload` -- A URI-encoded URL of an image -- A URI-encoded HMC URL. +- A URI-encoded file ID. +- A URI-encoded URL of an image. ### Responses From cd89e8e14125dcfadd6cc8405e728c629dbd015e Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 12 Feb 2022 01:34:12 +0300 Subject: [PATCH 15/68] feat(mediaproxy): add image resolution to site / media metadatas --- stable/mediaproxy/v1/mediaproxy.proto | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/stable/mediaproxy/v1/mediaproxy.proto b/stable/mediaproxy/v1/mediaproxy.proto index a84c58e..75c894a 100644 --- a/stable/mediaproxy/v1/mediaproxy.proto +++ b/stable/mediaproxy/v1/mediaproxy.proto @@ -5,6 +5,16 @@ import "harmonytypes/v1/types.proto"; // Object representing the metadata of a website. message SiteMetadata { + // Information for a thumbnail image. + message ThumbnailImage { + // URL of the thumbnail. + string url = 1; + // Width of the image, in pixels. + optional uint32 width = 2; + // Height of the image, in pixels. + optional uint32 height = 3; + } + // Title of the website. string site_title = 1; // Page title of the website page. @@ -15,11 +25,20 @@ message SiteMetadata { string description = 4; // URL of the website. string url = 5; - // A thumbnail image of the website. - string image = 6; + // A thumbnail image for the website. + repeated ThumbnailImage thumbnail = 6; } + // Object represeting the metadata of a media. message MediaMetadata { + // Extra information for an image media. + message ImageInfo { + // Width of the image, in pixels. + uint32 width = 1; + // Height of the image, in pixels. + uint32 height = 2; + } + // Mimetype of the media. string mimetype = 1; // Filename of the media. @@ -30,6 +49,11 @@ message MediaMetadata { // (for HTTP requests). // If this is not included, then it means the size could not be determined. optional uint32 size = 3; + // Extra information specific to types of media. + oneof info { + // Information for an image media. + ImageInfo image = 4; + } } // Used in the `FetchLinkMetadata` endpoint. From e467d470dd0f3805cb5993c02f90c67037070c56 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 14 Feb 2022 13:52:01 +0300 Subject: [PATCH 16/68] refactor(chat): rename QueryHasPermission -> HasPermission --- stable/chat/v1/chat.proto | 2 +- stable/chat/v1/permissions.proto | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index c937e6e..fb6f9ea 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -242,7 +242,7 @@ service ChatService { } // Endpoint to query if a user has a permission. - rpc QueryHasPermission(QueryHasPermissionRequest) returns (QueryHasPermissionResponse) { + rpc HasPermission(QueryHasPermissionRequest) returns (QueryHasPermissionResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; // This permissions node is only required if you're trying // to see if someone besides yourself has a permission. diff --git a/stable/chat/v1/permissions.proto b/stable/chat/v1/permissions.proto index e90d11c..2818fcc 100644 --- a/stable/chat/v1/permissions.proto +++ b/stable/chat/v1/permissions.proto @@ -34,8 +34,8 @@ message RoleWithId { Role role = 2; } -// Used in the `QueryHasPermission` endpoint. -message QueryHasPermissionRequest { +// Used in the `HasPermission` endpoint. +message HasPermissionRequest { // The guild ID to query permissions for. uint64 guild_id = 1; // The channel ID to query permissions for. If not set, it will query @@ -47,8 +47,8 @@ message QueryHasPermissionRequest { // The permission node(s) to check for. repeated string check_for = 3; } -// Used in the `QueryHasPermission` endpoint. -message QueryHasPermissionResponse { +// Used in the `HasPermission` endpoint. +message HasPermissionResponse { // The permissions for the given node(s). map ok = 1; } From 7514d4fed2bdb5dcca2270d3408ab1abeb60dd48 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 14 Feb 2022 13:59:13 +0300 Subject: [PATCH 17/68] refactor: move PhotoInfo to harmonytypes as ImageInfo, use it in places --- stable/chat/v1/messages.proto | 50 +++------------------------ stable/harmonytypes/v1/types.proto | 24 +++++++++++++ stable/mediaproxy/v1/mediaproxy.proto | 16 ++------- 3 files changed, 31 insertions(+), 59 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 19df1bb..83fda8d 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -165,10 +165,8 @@ message Embed { message Image { // File ID or external image URL of an image. string id = 1; - // Width of the image in pixels. - uint32 width = 2; - // Height of the image in pixels. - uint32 height = 3; + // Image information. + harmonytypes.v1.ImageInfo info = 2; } // How to present this field. @@ -202,46 +200,6 @@ message Embed { optional int32 color = 6; } -/* - An extremely low-quality WebP thumbnail. - - The resolution is usually no larger than 64x64. -*/ -message Minithumbnail { - // The width of the minithumbnail, in pixels. - uint32 width = 1; - // The height of the minithumbnail, in pixels. - uint32 height = 2; - // The data of the minithumbnail. - bytes data = 3; -} - -/* - Contains data about a photo. - - Photos are constrained to the following rules: - - - width+height <= 10_000 - - width <= height*20 - - height <= width*20 - - Photos are preferably no more than 10MB - in size, and servers may compress as necessary. - - Photos are always WebP images, lossless or lossy - depending on if the server wants to compress the image. -*/ -message PhotoInfo { - // The height of the photo, in pixels. - uint32 height = 1; - // The width of the photo, in pixels. - uint32 width = 2; - // The photo's caption. - FormattedText caption = 3; - // A thumbnail representing the photo. - Minithumbnail minithumbnail = 4; -} - // Object representing a generic message attachment. message Attachment { // File ID of this attachment. @@ -255,7 +213,7 @@ message Attachment { // Extra info. oneof info { // Photo info. - PhotoInfo photo = 5; + harmonytypes.v1.ImageInfo photo = 5; } } @@ -577,7 +535,7 @@ message SendMessageRequest { // Information a user can add to a photo attachment. message PhotoInfo { // The photo's caption. - FormattedText caption = 1; + optional string caption = 1; // Whether to use the original image, instead of compressing the image. // // Compression can be forced by servers, so this option may not work on diff --git a/stable/harmonytypes/v1/types.proto b/stable/harmonytypes/v1/types.proto index 48a7d1f..c9ab194 100644 --- a/stable/harmonytypes/v1/types.proto +++ b/stable/harmonytypes/v1/types.proto @@ -70,3 +70,27 @@ message ItemPosition { // Whether the position is before or after the given ID Position position = 2; } + +// An extremely low-quality WebP thumbnail. +// +// The resolution is usually no larger than 64x64. +message Minithumbnail { + // The width of the minithumbnail, in pixels. + uint32 width = 1; + // The height of the minithumbnail, in pixels. + uint32 height = 2; + // The data of the minithumbnail. + bytes data = 3; +} + +// Contains data about an image. +message ImageInfo { + // The height of the image, in pixels. + uint32 height = 1; + // The width of the image, in pixels. + uint32 width = 2; + // The image's caption. + optional string caption = 3; + // A thumbnail for the image. + optional Minithumbnail minithumbnail = 4; +} diff --git a/stable/mediaproxy/v1/mediaproxy.proto b/stable/mediaproxy/v1/mediaproxy.proto index 75c894a..38dd4fd 100644 --- a/stable/mediaproxy/v1/mediaproxy.proto +++ b/stable/mediaproxy/v1/mediaproxy.proto @@ -9,10 +9,8 @@ message SiteMetadata { message ThumbnailImage { // URL of the thumbnail. string url = 1; - // Width of the image, in pixels. - optional uint32 width = 2; - // Height of the image, in pixels. - optional uint32 height = 3; + // Image information. + harmonytypes.v1.ImageInfo info = 2; } // Title of the website. @@ -31,14 +29,6 @@ message SiteMetadata { // Object represeting the metadata of a media. message MediaMetadata { - // Extra information for an image media. - message ImageInfo { - // Width of the image, in pixels. - uint32 width = 1; - // Height of the image, in pixels. - uint32 height = 2; - } - // Mimetype of the media. string mimetype = 1; // Filename of the media. @@ -52,7 +42,7 @@ message MediaMetadata { // Extra information specific to types of media. oneof info { // Information for an image media. - ImageInfo image = 4; + harmonytypes.v1.ImageInfo image = 4; } } From 42d1d0211b1babf416e82b004b9319cf251786d0 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 14 Feb 2022 19:55:31 +0300 Subject: [PATCH 18/68] refactor(emote): add emote rpc shouldnt use emote itself --- stable/chat/v1/chat.proto | 2 +- stable/emote/v1/types.proto | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index fb6f9ea..6df2d26 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -242,7 +242,7 @@ service ChatService { } // Endpoint to query if a user has a permission. - rpc HasPermission(QueryHasPermissionRequest) returns (QueryHasPermissionResponse) { + rpc HasPermission(HasPermissionRequest) returns (HasPermissionResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; // This permissions node is only required if you're trying // to see if someone besides yourself has a permission. diff --git a/stable/emote/v1/types.proto b/stable/emote/v1/types.proto index 16a8765..f6cf74b 100644 --- a/stable/emote/v1/types.proto +++ b/stable/emote/v1/types.proto @@ -60,8 +60,10 @@ message GetEmotePackEmotesResponse { message AddEmoteToPackRequest { // The ID of the pack. uint64 pack_id = 1; - // The emote to add. - Emote emote = 2; + // The file ID of the image to use for the emote. + string image_id = 2; + // The name of the emote. + string name = 3; } // Used in the `AddEmoteToPack` endpoint. message AddEmoteToPackResponse {} From a2f1964f889559cf7b606870e787664dd9ee58cd Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 14 Feb 2022 20:13:39 +0300 Subject: [PATCH 19/68] refactor(chat): use repeated Permission in HasPermissions, document GetPermissions response behaviour --- stable/chat/v1/permissions.proto | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stable/chat/v1/permissions.proto b/stable/chat/v1/permissions.proto index 2818fcc..5096668 100644 --- a/stable/chat/v1/permissions.proto +++ b/stable/chat/v1/permissions.proto @@ -49,8 +49,8 @@ message HasPermissionRequest { } // Used in the `HasPermission` endpoint. message HasPermissionResponse { - // The permissions for the given node(s). - map ok = 1; + // The permissions for the requested node(s). + repeated Permission perms = 1; } // Used in the `SetPermissions` endpoint. @@ -90,6 +90,10 @@ message GetPermissionsResponse { } // The guild / channel id -> permissions list map for the given role. + // + // This will always contain the guild's permissions. On top of that, + // if any channels were specified in the request, those channels' + // permissions will also be added here. map perms = 1; } From d923771213dc9371abed469dd3721fb009a8c7fb Mon Sep 17 00:00:00 2001 From: Bluskript Date: Tue, 15 Feb 2022 01:40:16 -0500 Subject: [PATCH 20/68] remove deprecated is_bot field --- stable/profile/v1/types.proto | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stable/profile/v1/types.proto b/stable/profile/v1/types.proto index d68ddef..e39965d 100644 --- a/stable/profile/v1/types.proto +++ b/stable/profile/v1/types.proto @@ -36,10 +36,8 @@ message Profile { optional string user_avatar = 2; // the status of the user. UserStatus user_status = 3; - // whether the user is a bot or not. - bool is_bot = 4 [ deprecated = true ]; // what kind of account the user is, e.g. full, guest, bot. - AccountKind account_kind = 5; + AccountKind account_kind = 4; } // Used in `GetProfile` endpoint. @@ -66,7 +64,7 @@ message UpdateProfileRequest { // // Deprecated; see bot service and guest handling // in auth. - optional bool new_is_bot = 4 [ deprecated = true ]; + optional bool new_is_bot = 4 [deprecated = true]; } // Used in `UpdateProfile` endpoint. From 8084e429e402ca683e66cf34780da064aff85bfe Mon Sep 17 00:00:00 2001 From: Bluskript Date: Tue, 15 Feb 2022 03:00:33 -0500 Subject: [PATCH 21/68] move embeds and attachments out of extras --- stable/chat/v1/messages.proto | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 83fda8d..eb2e22f 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -222,17 +222,9 @@ message Attachment { // `InviteRejected`, `InviteAccepted` and `RoomUpgradedToGuild`, can only // be used by servers themselves. Servers should reject messages with this // content if they are sent by a user. +// +// Text should be displayed before embeds, and embeds should be displayed before attachments. message Content { - // Attachment content. - message Attachments { - // Attachments. - repeated Attachment attachments = 1; - } - // Embed content. - message Embeds { - // Embeds. - repeated Embed embeds = 1; - } // Represents a user rejecting an invite. message InviteRejected { // User ID of the invitee. @@ -257,13 +249,13 @@ message Content { string text = 1; // Text formatting of the text content. repeated Format text_formats = 2; + // Embed content. + repeated Embed embeds = 3; + // Attachment content. + repeated Attachment attachments = 4; // Extra content data, in addition to the text content. oneof extra { - // Embed content. - Embeds embeds = 3; - // Attachment content. - Attachments attachments = 4; // A user rejected an invite. InviteRejected invite_rejected = 5; // A user accepted an invite. @@ -288,17 +280,17 @@ message Reaction { // A format for text. message Format { // Bold text. - message Bold { } + message Bold {} // Italic text. - message Italic { } + message Italic {} // Underlined text. - message Underline { } + message Underline {} // Monospace text. - message Monospace { } + message Monospace {} // Superscript text. - message Superscript { } + message Superscript {} // Subscript text. - message Subscript { } + message Subscript {} // A larger codeblock, with a programming language specified. // // Clients should ideally not bound the width of codeblock messages, @@ -603,7 +595,6 @@ message SendMessageRequest { optional Overrides overrides = 6; // The message this new message is a reply to. optional uint64 in_reply_to = 7; - // The metadata of this new message. optional harmonytypes.v1.Metadata metadata = 5; } From ff630bba6296feddc856c6854ac3025c432c7238 Mon Sep 17 00:00:00 2001 From: Bluskript Date: Tue, 15 Feb 2022 06:58:59 -0500 Subject: [PATCH 22/68] improve consistency: rename photo to image, add id field to mediaproxy --- stable/chat/v1/messages.proto | 14 +++++++------- stable/mediaproxy/v1/mediaproxy.proto | 14 ++++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index eb2e22f..e3754b2 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -212,8 +212,8 @@ message Attachment { uint32 size = 4; // Extra info. oneof info { - // Photo info. - harmonytypes.v1.ImageInfo photo = 5; + // Image info. + harmonytypes.v1.ImageInfo image = 5; } } @@ -524,9 +524,9 @@ message TriggerActionResponse {} // Used in the `SendMessage` endpoint. message SendMessageRequest { - // Information a user can add to a photo attachment. - message PhotoInfo { - // The photo's caption. + // Information a user can add to a image attachment. + message ImageInfo { + // The image's caption. optional string caption = 1; // Whether to use the original image, instead of compressing the image. // @@ -543,8 +543,8 @@ message SendMessageRequest { string name = 2; // Extra information. oneof info { - // Photo info. - PhotoInfo photo = 3; + // Image info. + ImageInfo image = 3; } } diff --git a/stable/mediaproxy/v1/mediaproxy.proto b/stable/mediaproxy/v1/mediaproxy.proto index 38dd4fd..a8cc1f3 100644 --- a/stable/mediaproxy/v1/mediaproxy.proto +++ b/stable/mediaproxy/v1/mediaproxy.proto @@ -29,20 +29,22 @@ message SiteMetadata { // Object represeting the metadata of a media. message MediaMetadata { - // Mimetype of the media. + // Mimetype of the media. string mimetype = 1; // Filename of the media. - string filename = 2; + string name = 2; + // File ID of the media. + string id = 3; // Sıze of the media. // // This should (usually) be the size taken from the `Content-Length` header // (for HTTP requests). // If this is not included, then it means the size could not be determined. - optional uint32 size = 3; + optional uint32 size = 4; // Extra information specific to types of media. oneof info { // Information for an image media. - harmonytypes.v1.ImageInfo image = 4; + harmonytypes.v1.ImageInfo image = 5; } } @@ -80,7 +82,7 @@ message FetchLinkMetadataResponse { // Used in the `InstantView` endpoint. message InstantViewRequest { - // URL to get instant view for. + // URL to get instant view for. string url = 1; } // Used in the `InstantView` endpoint. @@ -94,7 +96,7 @@ message InstantViewResponse { } // Used in the `CanInstantView` endpoint. message CanInstantViewRequest { - // URL(s) to query if server can instant view the website. + // URL(s) to query if server can instant view the website. repeated string url = 1; } // Used in the `CanInstantView` endpoint. From 6b61f2efc1c876252cc5fd2fd5e15d9d9e574037 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 20 Feb 2022 13:07:47 +0300 Subject: [PATCH 23/68] fix(chat): make sendmessage.content consistent with content --- stable/chat/v1/messages.proto | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index e3754b2..dfca006 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -550,34 +550,23 @@ message SendMessageRequest { // Content that can be sent by a user. message Content { - // Attachment content. - message Attachments { - // Attachments. - repeated Attachment attachments = 1; - } - - // Embed content. - message Embeds { - // Embeds. - repeated Embed embeds = 1; - } - // Text content of the message to be sent. // - // If this is empty, then `extra` must be specified. + // If this is empty, then either `attachments` + // or `embeds` must be specified. string text = 1; // Text formats for the text content. repeated Format text_formats = 2; - - // Extra content of the message to be sent. + // Attachments to be sent. // - // If this is empty, then `text` must be specified. - oneof extra { - // Attachment content. - Attachments attachments = 3; - // Embed content. - Embeds embeds = 4; - } + // If this is empty, then either `embeds` or `text` + // must be specified. + repeated Attachment attachments = 3; + // Embeds to be sent. + // + // If this is empty, then either `attachemnts` + // or `text` must be specified. + repeated Embed embeds = 4; } // Guild ID of the guild where the channel is. From af88d1098c3d821fb5e8d90fca4704d170d8460d Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 20 Feb 2022 13:47:38 +0300 Subject: [PATCH 24/68] feat(chat): seperate ImageInfos again --- stable/chat/v1/messages.proto | 33 ++++++++++++++++++++++++--- stable/harmonytypes/v1/types.proto | 24 ------------------- stable/mediaproxy/v1/mediaproxy.proto | 19 +++++++++++---- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index dfca006..89d10f9 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -165,8 +165,10 @@ message Embed { message Image { // File ID or external image URL of an image. string id = 1; - // Image information. - harmonytypes.v1.ImageInfo info = 2; + // The width of the image, in pixels. + uint32 width = 2; + // The height of the image, in pixels. + uint32 height = 3; } // How to present this field. @@ -200,6 +202,31 @@ message Embed { optional int32 color = 6; } + +// An extremely low-quality WebP thumbnail. +// +// The resolution is usually no larger than 64x64. +message Minithumbnail { + // The width of the minithumbnail, in pixels. + uint32 width = 1; + // The height of the minithumbnail, in pixels. + uint32 height = 2; + // The data of the minithumbnail. + bytes data = 3; +} + +// Contains data about an image. +message ImageInfo { + // The width of the image, in pixels. + uint32 width = 1; + // The height of the image, in pixels. + uint32 height = 2; + // A thumbnail for the image. + Minithumbnail minithumbnail = 3; + // The image's caption. + optional string caption = 4; +} + // Object representing a generic message attachment. message Attachment { // File ID of this attachment. @@ -213,7 +240,7 @@ message Attachment { // Extra info. oneof info { // Image info. - harmonytypes.v1.ImageInfo image = 5; + ImageInfo image = 5; } } diff --git a/stable/harmonytypes/v1/types.proto b/stable/harmonytypes/v1/types.proto index c9ab194..48a7d1f 100644 --- a/stable/harmonytypes/v1/types.proto +++ b/stable/harmonytypes/v1/types.proto @@ -70,27 +70,3 @@ message ItemPosition { // Whether the position is before or after the given ID Position position = 2; } - -// An extremely low-quality WebP thumbnail. -// -// The resolution is usually no larger than 64x64. -message Minithumbnail { - // The width of the minithumbnail, in pixels. - uint32 width = 1; - // The height of the minithumbnail, in pixels. - uint32 height = 2; - // The data of the minithumbnail. - bytes data = 3; -} - -// Contains data about an image. -message ImageInfo { - // The height of the image, in pixels. - uint32 height = 1; - // The width of the image, in pixels. - uint32 width = 2; - // The image's caption. - optional string caption = 3; - // A thumbnail for the image. - optional Minithumbnail minithumbnail = 4; -} diff --git a/stable/mediaproxy/v1/mediaproxy.proto b/stable/mediaproxy/v1/mediaproxy.proto index a8cc1f3..6c642ca 100644 --- a/stable/mediaproxy/v1/mediaproxy.proto +++ b/stable/mediaproxy/v1/mediaproxy.proto @@ -1,16 +1,17 @@ syntax = "proto3"; package protocol.mediaproxy.v1; -import "harmonytypes/v1/types.proto"; // Object representing the metadata of a website. message SiteMetadata { - // Information for a thumbnail image. + // Information pertaining to a thumbnail image. message ThumbnailImage { // URL of the thumbnail. string url = 1; - // Image information. - harmonytypes.v1.ImageInfo info = 2; + // Width of the image, in pixels. + uint32 width = 2; + // Height of the image, in pixels. + uint32 height = 3; } // Title of the website. @@ -29,6 +30,14 @@ message SiteMetadata { // Object represeting the metadata of a media. message MediaMetadata { + // Information pertaining to an image. + message ImageInfo { + // Width of the image, in pixels. + uint32 width = 1; + // Height of the image, in pixels. + uint32 height = 2; + } + // Mimetype of the media. string mimetype = 1; // Filename of the media. @@ -44,7 +53,7 @@ message MediaMetadata { // Extra information specific to types of media. oneof info { // Information for an image media. - harmonytypes.v1.ImageInfo image = 5; + ImageInfo image = 5; } } From 828cefe4ccd101583c976031d2c5082569282f52 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 20 Feb 2022 14:28:14 +0300 Subject: [PATCH 25/68] fix(mediaproxy): fix import --- stable/mediaproxy/v1/mediaproxy.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/stable/mediaproxy/v1/mediaproxy.proto b/stable/mediaproxy/v1/mediaproxy.proto index 6c642ca..b74ab98 100644 --- a/stable/mediaproxy/v1/mediaproxy.proto +++ b/stable/mediaproxy/v1/mediaproxy.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package protocol.mediaproxy.v1; +import "harmonytypes/v1/types.proto"; // Object representing the metadata of a website. message SiteMetadata { From 40c9d52dc221106e001f137ef197c16755c2d90e Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 20 Feb 2022 14:42:13 +0300 Subject: [PATCH 26/68] feat: remove is_bot --- stable/profile/v1/stream.proto | 9 +++------ stable/profile/v1/types.proto | 5 ----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/stable/profile/v1/stream.proto b/stable/profile/v1/stream.proto index c1eaaf1..76507d2 100644 --- a/stable/profile/v1/stream.proto +++ b/stable/profile/v1/stream.proto @@ -17,11 +17,8 @@ message ProfileUpdated { optional string new_avatar = 3; // New status for this user. optional UserStatus new_status = 4; - // New is bot or not for this user. - // Deprecated, prefer new_account_kind if set. - optional bool new_is_bot = 5 [ deprecated = true ]; - // The new account kind for this account - optional AccountKind new_account_kind = 6; + // The new account kind for this account. + optional AccountKind new_account_kind = 5; } // Describes an emote service event. @@ -29,6 +26,6 @@ message StreamEvent { // The event type. oneof event { // Send the profile updated event. - ProfileUpdated profile_updated = 14; + ProfileUpdated profile_updated = 1; } } diff --git a/stable/profile/v1/types.proto b/stable/profile/v1/types.proto index e39965d..86797c5 100644 --- a/stable/profile/v1/types.proto +++ b/stable/profile/v1/types.proto @@ -60,11 +60,6 @@ message UpdateProfileRequest { optional string new_user_avatar = 2; // New status of the user. optional UserStatus new_user_status = 3; - // New whether the user is a bot or not. - // - // Deprecated; see bot service and guest handling - // in auth. - optional bool new_is_bot = 4 [deprecated = true]; } // Used in `UpdateProfile` endpoint. From 0c42f2f043c0063a7b644a9873088ed58aa2c28f Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 21 Feb 2022 08:51:38 +0300 Subject: [PATCH 27/68] feat(chat): make GetPermissions return guild perms seperately --- stable/chat/v1/permissions.proto | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/stable/chat/v1/permissions.proto b/stable/chat/v1/permissions.proto index 5096668..262f0c1 100644 --- a/stable/chat/v1/permissions.proto +++ b/stable/chat/v1/permissions.proto @@ -88,13 +88,14 @@ message GetPermissionsResponse { // The permissions. repeated Permission perms = 1; } + + // The permissions for the guild. + Permissions guild_perms = 1; - // The guild / channel id -> permissions list map for the given role. + // The channel id -> permissions list map for the given role. // - // This will always contain the guild's permissions. On top of that, - // if any channels were specified in the request, those channels' - // permissions will also be added here. - map perms = 1; + // This will contain permissions for any requested channels. + map channel_perms = 2; } // Used in the `MoveRole` endpoint. From 858ed82d67fa5ad37d2eab23102a57e1c8957921 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 10:57:17 +0300 Subject: [PATCH 28/68] docs: fix ID documentations --- stable/chat/v1/messages.proto | 5 +++-- stable/emote/v1/types.proto | 4 ++-- stable/profile/v1/types.proto | 29 +++++++++++++++-------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 89d10f9..45fb526 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -161,7 +161,8 @@ message Embed { // Data for displaying an image in embed. // - // Servers should fill in the `width` and `height` fields. + // Servers should fill in the `width` and `height` fields, if + // the provided `id` is not external. message Image { // File ID or external image URL of an image. string id = 1; @@ -564,7 +565,7 @@ message SendMessageRequest { // Attachment info that can be sent by a user. message Attachment { - // The file ID of the attachment. + // The local file ID of the attachment. string id = 1; // Name of the attachment. string name = 2; diff --git a/stable/emote/v1/types.proto b/stable/emote/v1/types.proto index f6cf74b..c890a58 100644 --- a/stable/emote/v1/types.proto +++ b/stable/emote/v1/types.proto @@ -14,7 +14,7 @@ message EmotePack { // Data for a single emote. message Emote { - // The HMC of the emote. Must point to an image. + // The HMC or external URL of the emote. Must point to an image. string image_id = 1; // The name of the emote. string name = 2; @@ -60,7 +60,7 @@ message GetEmotePackEmotesResponse { message AddEmoteToPackRequest { // The ID of the pack. uint64 pack_id = 1; - // The file ID of the image to use for the emote. + // The file ID or external URL of the image to use for the emote. string image_id = 2; // The name of the emote. string name = 3; diff --git a/stable/profile/v1/types.proto b/stable/profile/v1/types.proto index 86797c5..1aa935b 100644 --- a/stable/profile/v1/types.proto +++ b/stable/profile/v1/types.proto @@ -4,39 +4,39 @@ package protocol.profile.v1; // The possible statuses a user can have. enum UserStatus { - // User is offline (not connected to the server). + // The user is offline (not connected to the server). USER_STATUS_OFFLINE_UNSPECIFIED = 0; - // User is online (this is the default value if ommitted). + // The user is online (this is the default value if omitted). USER_STATUS_ONLINE = 1; - // User is away. + // The user is away. USER_STATUS_IDLE = 2; - // User does not want to be disturbed. + // The user does not want to be disturbed. USER_STATUS_DO_NOT_DISTURB = 3; - // User is on mobile. + // The user is on mobile. USER_STATUS_MOBILE = 4; - // User is streaming + // The user is streaming. USER_STATUS_STREAMING = 5; } -// The possible kinds of an account +// The possible kinds of an account. enum AccountKind { - // The account is a full-fledged account controlled by a human + // The account is a full-fledged account controlled by a human. ACCOUNT_KIND_FULL_UNSPECIFIED = 0; - // The account is an account controlled by a bot + // The account is an account controlled by a bot. ACCOUNT_KIND_BOT = 1; - // The account is a guest account controlled by a human + // The account is a guest account controlled by a human. ACCOUNT_KIND_GUEST = 2; } // Data for a single profile, without the user's ID. message Profile { - // the name of the user. + // The name of the user. string user_name = 1; - // the user's avatar. This must be a file ID that points to an image. + // The user's avatar. This must be a file ID. optional string user_avatar = 2; - // the status of the user. + // The status of the user. UserStatus user_status = 3; - // what kind of account the user is, e.g. full, guest, bot. + // What kind of account the user is, e.g. full, guest, bot. AccountKind account_kind = 4; } @@ -57,6 +57,7 @@ message UpdateProfileRequest { // New name of the user. optional string new_user_name = 1; // New user avatar. The avatar will be removed if the string is empty. + // This must be a local file ID. optional string new_user_avatar = 2; // New status of the user. optional UserStatus new_user_status = 3; From 1c923b59c78ebee833c749ee229450198e0cea45 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 13:11:35 +0300 Subject: [PATCH 29/68] refactor(chat): rework guild kinds --- stable/chat/v1/chat.proto | 13 ++++---- stable/chat/v1/guilds.proto | 59 +++++++++++++++---------------------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 6df2d26..bf8defd 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -24,11 +24,10 @@ service ChatService { // Endpoint to create a "direct message" guild. // // - The inviter and the invitee that join the created guild will both be owners. - // - The guild should be created on the server that inviter is on. + // - The guild should be created on the server that the inviter is on. // - The server should send a guild invite to the invitee (specified in the request), - // using the `UserInvited` postbox event if the invitee is on another server, - // otherwise see the below item. - // - The server should process this as follows: adding the invite to their pending + // using the `UserInvited` postbox event if the invitee is on another server. + // - The receiving server should process this as follows: adding the invite to their pending // invite list and sending an `InviteReceived` event over their event stream if // the invitee is on this server. // - The invitee may or may not use the invite. Only the invitee may use the invite. @@ -81,8 +80,10 @@ service ChatService { // server. // // The "notification" is sending a `InviteRejected` stream event to the - // inviter. If the guild's kind is `DirectMessage`, the server should also - // set the `rejected` field of the guild's kind to `true`. + // inviter. + // + // The server should increase the invite's used count by one to let the + // inviter know that their invite was rejected. rpc RejectPendingInvite(RejectPendingInviteRequest) returns (RejectPendingInviteResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 222c543..1138182 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -4,43 +4,30 @@ package protocol.chat.v1; import "harmonytypes/v1/types.proto"; -// The kind of a guild. -message GuildKind { - // A "normal" guild as in a guild that allows multiple channels. - message Normal {} - // A "room" guild as in a guild that only has one channel. - // - // - Clients should not show a channel list for guilds of this type. - message Room {} - // A "direct message" guild as in a guild that has at most two members, - // and has only one channel. - // - // - Clients should not show a channel list for guilds of this type. - // - Clients should show this guild in the guild list with the profile picture - // and the username of the other user. - // - Servers should "upgrade" this guild to a "room" guild if another - // user joins the guild. A name should be crafted using the algorithm - // described below: - // - Get at most 3 members' usernames, by their - // - Concat them with ", " as a seperator. - message DirectMessage { - // Whether this direct message was rejected by the invitee or not. - bool rejected = 1; - } - - // The kind. If this is empty, assume it is `Normal`. - oneof kind { - // A "normal" guild. - Normal normal = 1; - // A "room" guild. - Room room = 2; - // A "direct message" guild. - DirectMessage direct_message = 3; - } -} - // Object representing a guild without the ID part. message Guild { + // The kind of a guild. + enum Kind { + // A "normal" guild as in a guild that allows multiple channels. + KIND_NORMAL_UNSPECIFIED = 0; + // A "room" guild as in a guild that only has one channel. + // + // - Clients should not show a channel list for guilds of this type. + KIND_ROOM = 1; + // A "direct message" guild as in a guild that has at most two members, + // and has only one channel. + // + // - Clients should not show a channel list for guilds of this type. + // - Clients should show this guild in the guild list with the profile picture + // and the username of the other user. + // - Servers should "upgrade" this guild to a "room" guild if another + // user joins the guild. A name should be crafted using the algorithm + // described below: + // - Get at most 3 members' usernames, by their + // - Concat them with ", " as a seperator. + KIND_DIRECT_MESSAGE = 2; + } + // The name of the guild. // // This will be empty if the guild kind is "direct message". See @@ -52,7 +39,7 @@ message Guild { // User ID of the owners of the guild. repeated uint64 owner_ids = 3; // The kind of this guild. - GuildKind kind = 4; + Kind kind = 4; // Metadata of the guild. optional harmonytypes.v1.Metadata metadata = 5; } From 45d166264c17e204821bcc4b123929225550cffe Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 13:12:04 +0300 Subject: [PATCH 30/68] feat(profile): extend user status by allowing it to contain activities --- stable/profile/v1/profile.proto | 5 ++ stable/profile/v1/stream.proto | 15 ++++-- stable/profile/v1/types.proto | 90 +++++++++++++++++++++++++++------ 3 files changed, 91 insertions(+), 19 deletions(-) diff --git a/stable/profile/v1/profile.proto b/stable/profile/v1/profile.proto index 6873274..e03e404 100644 --- a/stable/profile/v1/profile.proto +++ b/stable/profile/v1/profile.proto @@ -17,6 +17,11 @@ service ProfileService { option (harmonytypes.v1.metadata).requires_authentication = true; } + // Updates the user's status. + rpc UpdateStatus(UpdateStatusRequest) returns (UpdateStatusResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } + // Gets app data for a user (this can be used to store user preferences which // is synchronized across devices). rpc GetAppData(GetAppDataRequest) returns (GetAppDataResponse) { diff --git a/stable/profile/v1/stream.proto b/stable/profile/v1/stream.proto index 76507d2..d0b24ec 100644 --- a/stable/profile/v1/stream.proto +++ b/stable/profile/v1/stream.proto @@ -15,10 +15,17 @@ message ProfileUpdated { optional string new_username = 2; // New avatar for this user. optional string new_avatar = 3; +} + +// Event sent when a user's status is updated. +// +// Servers should sent this event only to users that can "see" (eg. they are +// in the same guild) the user this event was triggered by. +message StatusUpdated { + // User ID of the user that had it's status updated. + uint64 user_id = 1; // New status for this user. - optional UserStatus new_status = 4; - // The new account kind for this account. - optional AccountKind new_account_kind = 5; + UserStatus new_status = 2; } // Describes an emote service event. @@ -27,5 +34,7 @@ message StreamEvent { oneof event { // Send the profile updated event. ProfileUpdated profile_updated = 1; + // Send the status updated event. + StatusUpdated status_updated = 2; } } diff --git a/stable/profile/v1/types.proto b/stable/profile/v1/types.proto index 1aa935b..9871c44 100644 --- a/stable/profile/v1/types.proto +++ b/stable/profile/v1/types.proto @@ -2,20 +2,72 @@ syntax = "proto3"; package protocol.profile.v1; -// The possible statuses a user can have. -enum UserStatus { - // The user is offline (not connected to the server). - USER_STATUS_OFFLINE_UNSPECIFIED = 0; - // The user is online (this is the default value if omitted). - USER_STATUS_ONLINE = 1; - // The user is away. - USER_STATUS_IDLE = 2; - // The user does not want to be disturbed. - USER_STATUS_DO_NOT_DISTURB = 3; - // The user is on mobile. - USER_STATUS_MOBILE = 4; - // The user is streaming. - USER_STATUS_STREAMING = 5; +// The status information for a user. +message UserStatus { + // Information about an action the user can use + // in the context of an activity. + message Action { + // URL to open when this action is clicked. + string url = 1; + // Name of this action. This must be provided if + // an icon isn't provided. + optional string name = 2; + // Icon for this action. + // This must be a file ID that points to an image. + // + // This must be provided if a name isn't provided. + optional string icon = 3; + } + + // Information about an activity the user is performing. + message Activity { + // When the user started performing this + // activity, in seconds since UNIX epoch. + uint64 started = 1; + // Title of this activity. + string title = 2; + // Details about this activity. + optional string details = 3; + // An image that relates to the activity. + // This must be a file ID that points to an image. + optional string image = 4; + // A color that relates to the activity. + optional uint32 color = 5; + // Actions for this activity. + repeated Action actions = 6; + } + + // The possible status kinds a user can have. + enum Kind { + // The user is offline (not connected to the server). + KIND_OFFLINE_UNSPECIFIED = 0; + // The user is online. + KIND_ONLINE = 1; + // The user is away. + KIND_IDLE = 2; + // The user does not want to be disturbed. + KIND_DO_NOT_DISTURB = 3; + } + + // The possible platforms a user can be on. + enum Platform { + // The user is on a desktop platform. + PLATFORM_DESKTOP_UNSPECIFIED = 0; + // The user is on a mobile platform. + PLATFORM_MOBILE = 1; + } + + // The kind of the status. + Kind kind = 1; + // The message for the status. This is independent of the + // activities being performed by the user. + string message = 2; + // The activities this user is performing, if any. + // + // The first activity in this list has the most priority. + repeated Activity activities = 3; + // The platform the user is on. + Platform platform = 4; } // The possible kinds of an account. @@ -59,13 +111,19 @@ message UpdateProfileRequest { // New user avatar. The avatar will be removed if the string is empty. // This must be a local file ID. optional string new_user_avatar = 2; - // New status of the user. - optional UserStatus new_user_status = 3; } // Used in `UpdateProfile` endpoint. message UpdateProfileResponse {} +// Used in `UpdateStatus` endpoint. +message UpdateStatusRequest { + // The new user status to use. + UserStatus new_status = 1; +} +// Used in `UpdateStatus` endpoint. +message UpdateStatusResponse {} + // Used in `GetAppData` endpoint. message GetAppDataRequest { // The app id. From 5c39069666d5cd942d45b4e6a532c82e628fb9b2 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 14:04:23 +0300 Subject: [PATCH 31/68] refactor(chat): rework embeds --- stable/chat/v1/messages.proto | 82 ++++++++++++++--------------------- 1 file changed, 33 insertions(+), 49 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 45fb526..85f382d 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -132,75 +132,59 @@ message Action { // Object representing a message embed. message Embed { // Object representing an embed heading. - message EmbedHeading { + message Heading { // Text of the heading. string text = 1; - // Subtext of the heading. - optional string subtext = 2; // URL of the heading. // // If this is provided, clients should make it so that // interacting with the heading opens this URL, for example // clicking on it. - optional string url = 3; - // Icon of the heading. - optional string icon = 4; + optional string url = 2; + // Icon of the heading. This must be a file ID that points + // to an image. + optional string icon = 3; } - // Object representing an embed field. - message EmbedField { - // Type representing how to present an embed field. - enum Presentation { - // Show the field as data. - PRESENTATION_DATA_UNSPECIFIED = 0; - // Show the field as a captioned image. - PRESENTATION_CAPTIONED_IMAGE = 1; - // Show the field as a row. - PRESENTATION_ROW = 2; - } - - // Data for displaying an image in embed. - // - // Servers should fill in the `width` and `height` fields, if - // the provided `id` is not external. - message Image { - // File ID or external image URL of an image. - string id = 1; - // The width of the image, in pixels. - uint32 width = 2; - // The height of the image, in pixels. - uint32 height = 3; - } - - // How to present this field. - Presentation presentation = 1; - - // Title of this field. - string title = 2; - // Subtitle of this field. - optional string subtitle = 3; - // Body text of this field (eg. a description). - optional FormattedText body = 4; - - // An image to display on this field. - optional Image image = 5; + // A field for the embed. Fields usually contain + // small information and are not meant to be used + // for huge chunks of text. + message Field { + // Title of this field (what is it?). + string title = 1; + // Body of this field. + string body = 2; + } - // Actions to show on this field. - repeated Action actions = 6; + // Data for displaying an image in embed. + // + // Servers should fill in the `width` and `height` fields, if + // the provided `id` is not external. + message Image { + // File ID or external image URL of an image. + string id = 1; + // The width of the image, in pixels. + uint32 width = 2; + // The height of the image, in pixels. + uint32 height = 3; } // Embed heading for the header. - optional EmbedHeading header = 1; + optional Heading header = 1; // Title of this embed. string title = 2; // Body text of this embed. optional FormattedText body = 3; // Fields of this embed. - repeated EmbedField fields = 4; + repeated Field fields = 4; + // An image to display on this embed. + optional Image image = 5; + // Actions to show on this field. + repeated Action actions = 6; // Embed heading for the footer. - optional EmbedHeading footer = 5; + optional Heading footer = 7; // Color of this embed. - optional int32 color = 6; + optional int32 color = 8; } From 0fcff77828d8feda7170200eb7a2436fb2257549 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 14:27:57 +0300 Subject: [PATCH 32/68] refactor: move ImageInfo's under their Attachment's, improve some comments --- stable/chat/v1/messages.proto | 51 ++++++++++++++++---------------- stable/chat/v1/permissions.proto | 9 ++---- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 85f382d..31886fb 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -200,20 +200,20 @@ message Minithumbnail { bytes data = 3; } -// Contains data about an image. -message ImageInfo { - // The width of the image, in pixels. - uint32 width = 1; - // The height of the image, in pixels. - uint32 height = 2; - // A thumbnail for the image. - Minithumbnail minithumbnail = 3; - // The image's caption. - optional string caption = 4; -} - // Object representing a generic message attachment. message Attachment { + // Contains data about an image. + message ImageInfo { + // The width of the image, in pixels. + uint32 width = 1; + // The height of the image, in pixels. + uint32 height = 2; + // A thumbnail for the image. + Minithumbnail minithumbnail = 3; + // The image's caption. + optional string caption = 4; + } + // File ID of this attachment. string id = 1; // Filename of this attachment. @@ -536,19 +536,19 @@ message TriggerActionResponse {} // Used in the `SendMessage` endpoint. message SendMessageRequest { - // Information a user can add to a image attachment. - message ImageInfo { - // The image's caption. - optional string caption = 1; - // Whether to use the original image, instead of compressing the image. - // - // Compression can be forced by servers, so this option may not work on - // every homeserver. - bool use_original = 2; - } - // Attachment info that can be sent by a user. message Attachment { + // Information a user can add to a image attachment. + message ImageInfo { + // The image's caption. + optional string caption = 1; + // Whether to use the original image, instead of compressing the image. + // + // Compression can be forced by servers, so this option may not work on + // every homeserver. + bool use_original = 2; + } + // The local file ID of the attachment. string id = 1; // Name of the attachment. @@ -588,9 +588,8 @@ message SendMessageRequest { // Content of the new message. Content content = 3; // Echo ID of the new message. This can be used by clients to - // determine whether a message has been broadcasted properly - // to other clients. Note that this does not mean the broadcast - // reached other clients. + // determine whether a message has been broadcasted to other clients. + // Note that this does not mean the broadcast reached other clients. optional uint64 echo_id = 4; // The overrides of this new message. optional Overrides overrides = 6; diff --git a/stable/chat/v1/permissions.proto b/stable/chat/v1/permissions.proto index 262f0c1..6e38dbe 100644 --- a/stable/chat/v1/permissions.proto +++ b/stable/chat/v1/permissions.proto @@ -62,10 +62,7 @@ message SetPermissionsRequest { optional uint64 channel_id = 2; // The role ID to set permissions for. uint64 role_id = 3; - // The permission list to give. - // - // There is no "perms_to_take" because not given permissions are by - // default not allowed. + // The list of permissions to set. repeated Permission perms_to_give = 4; } // Used in the `SetPermissions` endpoint. @@ -75,8 +72,8 @@ message SetPermissionsResponse {} message GetPermissionsRequest { // The guild ID to get permissions for. uint64 guild_id = 1; - // The channel ID(s) to get permissions for. Only applicable for roles in a - // channel. + // The channel ID(s) to get permissions for. + // Only applicable for roles in a channel. repeated uint64 channel_ids = 2; // The role ID to get permissions for. uint64 role_id = 3; From 22fcfd7535912b7063786c8368a00e81bd00a744 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 14:29:40 +0300 Subject: [PATCH 33/68] feat: remove localization format --- stable/chat/v1/messages.proto | 8 -------- 1 file changed, 8 deletions(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 31886fb..3a69c57 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -360,12 +360,6 @@ message Format { // The kind of colour modification to apply. Kind kind = 1; } - // Replace a part of the text with the text matching the i18n code. - // If i18n code was not found, keep the original text. - message Localization { - // i18n code for the text. - string i18n_code = 1; - } // Where the format begins to apply to. uint32 start = 1; @@ -400,8 +394,6 @@ message Format { Emoji emoji = 14; // A text format for coloured text. Color color = 15; - // A text format for localization. - Localization localization = 16; } } From 9c3798e69280eb3a4d2c2c6df70afd42f0d2f9f5 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 14:53:56 +0300 Subject: [PATCH 34/68] feat(chat): rework reactions --- stable/chat/v1/chat.proto | 7 ++-- stable/chat/v1/messages.proto | 41 ++++++++++++++++------ stable/chat/v1/stream.proto | 64 +++++++++++++++++++++++++++-------- 3 files changed, 86 insertions(+), 26 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index bf8defd..4686a58 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -401,8 +401,11 @@ service ChatService { // Endpoint to remove a reaction from a message. // - // Servers should only remove a reaction if the user making the request - // added the reaction before. + // Servers should only remove a reaction if the user making the + // request added the reaction before. + // + // Servers should delete the reaction from the message if it's + // reaction count reaches zero. rpc RemoveReaction(RemoveReactionRequest) returns (RemoveReactionResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; option (harmonytypes.v1.metadata).requires_permission_node = diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 3a69c57..ea680d3 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -277,16 +277,33 @@ message Content { } } +// The kind of this reaction. +enum ReactionKind { + // A reaction that uses an image. + // + // The `data` field of the reaction should be interpreted + // as a file ID that points to an image. + REACTION_KIND_IMAGE_UNSPECIFIED = 0; + // A reaction that uses text. For example, this + // can be used to send unicode emojis. + // + // The `data` field of the reaction should be interpreted + // as text to display. + REACTION_KIND_TEXT = 1; +} + // Object representing a reaction. message Reaction { - // Emote data for this reaction. + // The kind of the reaction. + ReactionKind kind = 1; + // The reaction's data. This is interpreted using the `kind`. // - // - Emote's image ID is used as an identifier for unique reactions. - // - Emotes with the same names should be "deduplicated" by a client, - // by suffixing their names with `~1`, `~2` and so on. - emote.v1.Emote emote = 1; + // This is used as a unique identifier for reactions. + string data = 2; + // The name of the reaction. + string name = 3; // How many times this reaction has been used. - uint32 count = 2; + uint32 count = 4; } // A format for text. @@ -656,8 +673,12 @@ message AddReactionRequest { uint64 channel_id = 2; // Message ID of the message we want to add a reaction to. uint64 message_id = 3; - // The emote we want to react with. - emote.v1.Emote emote = 4; + // The kind of the reaction we want to react with. + ReactionKind reaction_kind = 4; + // The data of the reaction we want to react with. + string reaction_data = 5; + // The name of the reaction we want to react with. + string reaction_name = 6; } // Used in `AddReaction` endpoint. message AddReactionResponse {} @@ -670,8 +691,8 @@ message RemoveReactionRequest { uint64 channel_id = 2; // Message ID of the message we want to remove a reaction. uint64 message_id = 3; - // The emote we want to remove the react of. - emote.v1.Emote emote = 4; + // The data of the reaction we want to remove. + string reaction_data = 4; } // Used in `RemoveReaction` endpoint. message RemoveReactionResponse {} diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 9ebbeca..515e86e 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -372,21 +372,53 @@ message StreamEvent { uint64 message_id = 3; } - // Sent when a message's reaction is changed. + // Sent when a new reaction is added to a message. This is only sent if + // such a reaction wasn't on the message, otherwise see `ReactionAdded`. // // Should only be sent to users who have the "message.view" permission for - // the guild channel where the reaction was updated. - message ReactionUpdated { + // the guild channel where the reaction was added. + message NewReactionAdded { // Guild ID of the guild where this event occured. uint64 guild_id = 1; // Channel ID of the channel where this event occured. uint64 channel_id = 2; - // Message ID of the message that had a reaction updated. + // Message ID of the message that had a reaction added. uint64 message_id = 3; - // The reaction. + // The reaction that was added. chat.v1.Reaction reaction = 4; } + // Sent when an existing reaction is added to a message. This is only sent + // such a reaction was on the message, otherwise see `NewReactionAdded`. + // + // Should only be sent to users who have the "message.view" permission for + // the guild channel where the reaction was added. + message ReactionAdded { + // Guild ID of the guild where this event occured. + uint64 guild_id = 1; + // Channel ID of the channel where this event occured. + uint64 channel_id = 2; + // Message ID of the message that had a reaction added. + uint64 message_id = 3; + // The data of the reaction that was added. + string reaction_data = 4; + } + + // Sent when an existing reaction is removed from a message. + // + // Should only be sent to users who have the "message.view" permission for + // the guild channel where the reaction was removed. + message ReactionRemoved { + // Guild ID of the guild where this event occured. + uint64 guild_id = 1; + // Channel ID of the channel where this event occured. + uint64 channel_id = 2; + // Message ID of the message that had a reaction removed. + uint64 message_id = 3; + // The data of the reaction that was removed. + string reaction_data = 4; + } + // Sent when there's a new owner. message OwnerAdded { // Guild ID of the guild where this event occured. @@ -512,21 +544,25 @@ message StreamEvent { MessagePinned message_pinned = 24; // Send the message unpinned event. MessageUnpinned message_unpinned = 25; - // Send the reaction updated event. - ReactionUpdated reaction_updated = 26; // Send the owner added event. - OwnerAdded owner_added = 27; + OwnerAdded owner_added = 26; // Send the owner removed event. - OwnerRemoved owner_removed = 28; + OwnerRemoved owner_removed = 27; // Send the guild invite received event. - InviteReceived invite_received = 29; + InviteReceived invite_received = 28; // Send the guild invite rejected event. - InviteRejected invite_rejected = 30; + InviteRejected invite_rejected = 29; // Send the invite created event. - InviteCreated invite_created = 31; + InviteCreated invite_created = 30; // Send the invite deleted event. - InviteDeleted invite_deleted = 32; + InviteDeleted invite_deleted = 31; // Send the invite used event. - InviteUsed invite_used = 33; + InviteUsed invite_used = 32; + // Send the new reaction added event. + NewReactionAdded new_reaction_added = 33; + // Send the reaction added event. + ReactionAdded reaction_added = 34; + // Send the reaction removed event. + ReactionRemoved reaction_removed = 35; } } From 593ba50c75134ecfc353d7ca173893c4907381ba Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 26 Feb 2022 15:40:12 +0300 Subject: [PATCH 35/68] feat(chat): rework UpdateMessageText into UpdateMessageContent --- stable/chat/v1/chat.proto | 4 ++-- stable/chat/v1/messages.proto | 12 ++++++------ stable/chat/v1/stream.proto | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 4686a58..e03c94d 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -171,8 +171,8 @@ service ChatService { "channels.manage.move"; } - // Endpoint to change the text of a message. - rpc UpdateMessageText(UpdateMessageTextRequest) returns (UpdateMessageTextResponse) { + // Endpoint to change the content of a message. + rpc UpdateMessageContent(UpdateMessageContentRequest) returns (UpdateMessageContentResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; option (harmonytypes.v1.metadata).requires_permission_node = "messages.send"; diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index ea680d3..59ead8a 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -613,19 +613,19 @@ message SendMessageResponse { uint64 message_id = 1; } -// Used in the `UpdateMessageText` endpoint. -message UpdateMessageTextRequest { +// Used in the `UpdateMessageContent` endpoint. +message UpdateMessageContentRequest { // Guild ID of the guild where the channel is. uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; - // Message ID of the message you want to edit the text of. + // Message ID of the message you want to change the content of. uint64 message_id = 3; // New content for this message. - FormattedText new_content = 4; + SendMessageRequest.Content new_content = 4; } -// Used in the `UpdateMessageText` endpoint. -message UpdateMessageTextResponse {} +// Used in the `UpdateMessageContent` endpoint. +message UpdateMessageContentResponse {} // Used in the `PinMessage` endpoint. message PinMessageRequest { diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 515e86e..66bc899 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -72,7 +72,7 @@ message StreamEvent { Message message = 5; } - // Event sent when a message's text content is updated. + // Event sent when a message's content is updated. // // This event will only be sent to users that have "messages.view" permission // for the channel the message was updated in. @@ -83,10 +83,10 @@ message StreamEvent { uint64 channel_id = 2; // Message ID of the message that was updated. uint64 message_id = 3; - // When this message was edited, in milliseconds since unix epoch + // When this message was edited, in seconds since unix epoch. uint64 edited_at = 4; // New message content. - chat.v1.FormattedText new_content = 5; + chat.v1.Content new_content = 5; } // Event sent when a message is deleted. From d963c675f7515b1ff66fac87b8959d463d9b52db Mon Sep 17 00:00:00 2001 From: Jan Blackquill Date: Tue, 22 Feb 2022 00:30:48 -0500 Subject: [PATCH 36/68] feat: remove voice --- staging/voice/v1/voice.proto | 188 ----------------------------------- 1 file changed, 188 deletions(-) delete mode 100644 staging/voice/v1/voice.proto diff --git a/staging/voice/v1/voice.proto b/staging/voice/v1/voice.proto deleted file mode 100644 index c1d65c9..0000000 --- a/staging/voice/v1/voice.proto +++ /dev/null @@ -1,188 +0,0 @@ -syntax = "proto3"; - -import "harmonytypes/v1/types.proto"; - -package protocol.voice.v1; - -option go_package = "github.com/harmony-development/legato/gen/voice/v1"; - -// Data containing all the necessary information to -// create a consumer for a user in a voice channel. -// -// This corresponds to https://mediasoup.org/documentation/v3/mediasoup-client/api/#ConsumerOptions on client: -// - `consumer_id` -> `id` -// - `producer_id` -> `producerId` -// - `rtp_parameters` -> `rtpParameters` -// - and `kind` should be set to "audio". -message UserConsumerOptions { - // User ID of the user. - uint64 user_id = 1; - // Producer ID of the producer being consumed. - string producer_id = 2; - // Consumer ID for the user's producer consumer. - string consumer_id = 3; - // RTP paramaters for the user's audio track. Corresponds to `RtpParameters` in mediasoup's TypeScript API. - string rtp_parameters = 4; -} - -// Object containing all the necessary information about transport options required -// from the server to establish transport connection on the client. -// -// This corresponds to https://mediasoup.org/documentation/v3/mediasoup-client/api/#TransportOptions on client: -// - `id` -> `id` -// - `ice_parameters` -> `iceParameters` -// - `dtls_parameters` -> `dtlsParameters` -// - `ice_candidates` -> `iceCandidates` -message TransportOptions { - // The transport ID. - string id = 1; - // DTLS paramaters in JSON. Corresponds to `DtlsParameters` in mediasoup's TypeScript API. - string dtls_parameters = 2; - // ICE candidates in JSON. Corresponds to `IceCandidate` in mediasoup's TypeScript API. - repeated string ice_candidates = 3; - // ICE paramaters in JSON. Corresponds to `IceParameters` in mediasoup's TypeScript API. - string ice_parameters = 4; -} - -// Used in `StreamMessage` endpoint. -message StreamMessageRequest { - // IDs that will be used to know which channel this WS will operate in. - message Initialize { - // Guild ID of the guild where the channel is. - uint64 guild_id = 1; - // Channel ID of the voice channel to initialize for. - uint64 channel_id = 2; - } - - // Data needed to prepare for joining a channel. - message PrepareForJoinChannel { - // RTP capabilities in JSON. - string rtp_capabilities = 1; - } - - // Data needed to join a channel. - // - // This takes one RTP paramaters for one track, which will be - // assumed to be Audio. - // - // It also takes DTLS paramaters for connecting both producer and consumer. - message JoinChannel { - // RTP paramaters in JSON. Corresponds to `RtpParameters` in mediasoup's TypeScript API. - string rtp_paramaters = 1; - // DTLS paramaters for producer transport, in JSON. Corresponds to `DtlsParameters` in mediasoup's TypeScript API. - string producer_dtls_paramaters = 2; - // DTLS paramaters for consumer transport, in JSON. Corresponds to `DtlsParameters` in mediasoup's TypeScript API. - string consumer_dtls_paramaters = 3; - } - - // Message to resume a consumer. - message ResumeConsumer { - // ID of the consumer to resume. - string consumer_id = 1; - } - - // Message for this response. - oneof message { - // Sent to initialize the WS and receive necessary information. - Initialize initialize = 1; - // Sent to prepare for joining channel. - PrepareForJoinChannel prepare_for_join_channel = 2; - // Sent to join a channel. - JoinChannel join_channel = 3; - // Sent to resume a consumer. - ResumeConsumer resume_consumer = 4; - } -} -// Used in `StreamMessage` endpoint. -message StreamMessageResponse { - // Initialization data for client. - message Initialized { - // Server RTP capabilities in JSON. Corresponds to `RtpCapabilities` in mediasoup's TypeScript API. - string rtp_capabilities = 1; - } - - // RTP capabilities validated. - message PreparedForJoinChannel { - // Consumer transport options. - TransportOptions consumer_transport_options = 1; - // Producer transport options. - TransportOptions producer_transport_options = 2; - } - - // Producer for voice created; consumer and producer transports are connected. - message JoinedChannel { - // Consumer options for users that were already in the room. - repeated UserConsumerOptions other_users = 1; - } - - // Data for the user that joined the room and it's producer. - message UserJoined { - // Consumer options for this user. - UserConsumerOptions data = 1; - } - - // Data for the user that left the room and the producer. - message UserLeft { - // ID of the user that left. - uint64 user_id = 1; - } - - // Message for this response. - oneof message { - // Sent when connection is started. - Initialized initialized = 1; - // Sent when preparing to join a channel is successful. - PreparedForJoinChannel prepared_for_join_channel = 2; - // Sent when joining a channel is successful. - JoinedChannel joined_channel = 3; - // Sent when another user joins the channel. - UserJoined user_joined = 4; - // Sent when another user leaves the channel. - UserLeft user_left = 5; - } -} - -// Harmony service for facilitating voice operations using WebRTC. -// -// # Usage (for client) -// -// 0. Call StreamMessage to be able to send RTC commands to server. -// 1. Send Initialize over stream with guild_id and channel_id of the request set to the channel you want to join. -// 2. Init device by using the RTP capabilities sent in the response message, which should be Initialized. -// 3. Send PrepareForJoinChannel over stream with client rtp capabilities. -// 4. Wait for PreparedForJoinChannel, which contains transport options. -// 5. Connect both transports using the transport options on client. -// 6. Send JoinChannel over stream containing RTP paramaters for your Audio track -// and DTLS paramaters for both consumer and producer. -// 7. Wait for JoinedChannel, which confirms you have successfully joined the voice channel; -// handle other_users which will be described in 8 (UserJoined handling). -// 8. Handle UserJoined and UserLeft events appropiately -// - For UserJoined; use the received consumer ID, producer ID and RTP parameters on your -// consumer transport to consume the producer, afterwards send ResumeConsumer message -// with the consumer ID, then if that's successful add the track to a `user ID -> Track` map. -// - For UserLeft, remove the user track from the `user ID -> Track` map. -// -// ## How this looks for servers -// -// 0. Receives StreamMessage, starts the socket. -// 1. Waits for Initialize. -// 2. Sends Initialized over stream with it's RTP capabilities. -// 3. Receives PrepareForJoinChannel with client RTP capabilities. -// 4. Sends PreparedForJoinChannel over stream with consumer and producer transport options. -// 5. Receives JoinChannel, checks for DTLS parameters for consumer and producer transports -// and uses the RTP paramaters to create a producer for the client. -// 6. Sends JoinedChannel over stream with the created producer ID and all other users' data (UserData). -// 7. When another user does 1 to 7, sends UserJoined over stream to all other users; -// when a user leaves the channel (when their stream ends), sends UserLeft to all other users. -// 8. When receiving a ResumeConsumer message, unpauses the consumer corresponding to the consumer ID. -// -service VoiceService { - // Endpoint to stream messages between client and server. - // - // - One StreamMessage stream corresponds to being in one voice channel. - // - It's recommended that users should not be able to be in more than one voice channel, - // but this limitation is left up to the server implementation. - rpc StreamMessage(stream StreamMessageRequest) returns (stream StreamMessageResponse) { - option (harmonytypes.v1.metadata).requires_authentication = true; - } -} From f67cbf858ab83ae3b00d944f1fd0d73c2002a502 Mon Sep 17 00:00:00 2001 From: Jan Blackquill Date: Tue, 22 Feb 2022 01:19:46 -0500 Subject: [PATCH 37/68] feat: add webrtc service --- stable/webrtc/v1/webrtc.proto | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 stable/webrtc/v1/webrtc.proto diff --git a/stable/webrtc/v1/webrtc.proto b/stable/webrtc/v1/webrtc.proto new file mode 100644 index 0000000..2fabf15 --- /dev/null +++ b/stable/webrtc/v1/webrtc.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; + +package protocol.webrtc.v1; + +// A TURN server +message TurnServer { + // The hostname of the server + string uri = 1; + // The username to provide for the server + string username = 2; + // The password for the server + string password = 3; + // The port for the server + uint32 port = 4; +} + +// An ICE candidate +message IceCandidate { + // The MID, or Media Stream ID. + string sdp_mid = 1; + // The index of the m-line describing the media associated with this candidate. + string sdp_mline_index = 2; + // The candidate, in textual form, for passing to a WebRTC library. + // A blank candidate indicates no further candidates are coming. + string candidate = 3; +} + +// An incoming message from the WebRTC service +message WebRTCResponse { + // An event from the current session + oneof event { + // There is a new TURN server you should use for initiating calls + TurnServer turn_server = 1; + // There is a new remote ICE candidate + IceCandidate ice_candidate = 2; + // The remote has an SDP offer for you + SDP sdp_offer = 3; + // The remote has an SDP answer for you + SDP sdp_answer = 4; + } +} + +// The initialisation message for the WebRTC rpc. This should be sent first. +message Init { + // The "session" you want to connect to. + // + // Various APIs in Harmony will give you session IDs, + // which should be used in this API. + uint64 session_id = 1; +} + +// A session description for WebRTC +message SDP { + // The SDP + string sdp = 1; +} + +// The request for WebRTC. +message WebRTCRequest { + // The request + oneof request { + // Initialise the stream + Init init = 1; + // Send an SDP as an offer + SDP sdp_offer = 2; + // Send an SDP as an answer + SDP sdp_answer = 3; + } +} + +// The WebRTC Service manages WebRTC sessions between two or more parties. +service WebRTCService { + // WebRTC opens a stream + rpc WebRTC(stream WebRTCRequest) returns (stream WebRTCResponse) {} +} \ No newline at end of file From 31ea1893982b2f8c8c27246b06a3cad9a8ca7986 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 03:19:32 +0300 Subject: [PATCH 38/68] feat(profile): add user notes app data type --- stable/profile/v1/appdata.proto | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/stable/profile/v1/appdata.proto b/stable/profile/v1/appdata.proto index 4bacfbe..988c9a9 100644 --- a/stable/profile/v1/appdata.proto +++ b/stable/profile/v1/appdata.proto @@ -36,9 +36,14 @@ message ProfileOverride { } } -// The message used for the 'h.overrides' app ID -// of appdata. +// The message used for the 'h.overrides' app ID of appdata. message AppDataOverrides { // The list of overrides. repeated ProfileOverride overrides = 1; +} + +// The message used for the 'h.user_notes' app ID of appdata. +message AppDataUserNotes { + // The user ID -> note map. + map notes = 1; } \ No newline at end of file From 9c39c99090c29939d7300b62e34e9eaa4fc2961f Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 04:08:05 +0300 Subject: [PATCH 39/68] feat: bot tokens (#99) Co-authored-by: spiral --- stable/auth/v1/auth.proto | 4 + stable/chat/v1/chat.proto | 36 +++++---- stable/chat/v1/guilds.proto | 64 +--------------- stable/chat/v1/messages.proto | 87 +++++++++------------ stable/chat/v1/private_channel.proto | 68 +++++++++++++++++ stable/chat/v1/stream.proto | 109 ++++++++++++++++++++------- stable/sync/v1/sync.proto | 47 ++++++++++-- staging/bots/v1/bots.proto | 34 +++++++-- 8 files changed, 279 insertions(+), 170 deletions(-) create mode 100644 stable/chat/v1/private_channel.proto diff --git a/stable/auth/v1/auth.proto b/stable/auth/v1/auth.proto index bbbdcf0..96fb232 100644 --- a/stable/auth/v1/auth.proto +++ b/stable/auth/v1/auth.proto @@ -281,6 +281,10 @@ message CheckLoggedInResponse {} // TODO: finish // The service containing authorization/entication methods. +// +// It is important to note that bots are exempt from AuthService +// - a persistent authorization token is generated on bot creation. +// This is handled in BotsService. service AuthService { // Federate with a foreignserver, obtaining a token // you can use to call LoginFederated on it. diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index e03c94d..3b35c6d 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -6,6 +6,7 @@ import "chat/v1/channels.proto"; import "chat/v1/messages.proto"; import "chat/v1/permissions.proto"; import "chat/v1/stream.proto"; +import "chat/v1/private_channel.proto"; package protocol.chat.v1; @@ -16,29 +17,32 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } - // Endpoint to create a "room" guild. - rpc CreateRoom(CreateRoomRequest) returns (CreateRoomResponse) { - option (harmonytypes.v1.metadata).requires_authentication = true; - } - - // Endpoint to create a "direct message" guild. + // Endpoint to create a private channel. // - // - The inviter and the invitee that join the created guild will both be owners. - // - The guild should be created on the server that the inviter is on. - // - The server should send a guild invite to the invitee (specified in the request), - // using the `UserInvited` postbox event if the invitee is on another server. + // - The server should send an invite to the invitee(s) (specified in the request), + // using the `UserInvited` postbox event if the invitee(s) are on another server. // - The receiving server should process this as follows: adding the invite to their pending // invite list and sending an `InviteReceived` event over their event stream if - // the invitee is on this server. - // - The invitee may or may not use the invite. Only the invitee may use the invite. - rpc CreateDirectMessage(CreateDirectMessageRequest) returns (CreateDirectMessageResponse) { + // the invitee(s) are on this server. + // - The invitee(s) may or may not use the invite. Only the invitee(s) may use the invite. + rpc CreatePrivateChannel(CreatePrivateChannelRequest) returns (CreatePrivateChannelResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } - // Endpoint to upgrade a "room" guild to a "normal" guild. - rpc UpgradeRoomToGuild(UpgradeRoomToGuildRequest) returns (UpgradeRoomToGuildResponse) { + // Endpoint to modify the member list of a private channel. + // + // - This is only possible if the channel's `is_locked` property is set to false. + // - The server should send an invite to the added members (if any). + // This should follow the same invite sending logic in `CreatePrivateChannel`. + rpc UpdatePrivateChannelMembers(UpdatePrivateChannelMembersRequest) returns (UpdatePrivateChannelMembersResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } + + // Endpoint to delete a private channel. + // + // Only the user who created the private channel can delete it. + rpc DeletePrivateChannel(DeletePrivateChannelRequest) returns (DeletePrivateChannelResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; - option (harmonytypes.v1.metadata).requires_owner = true; } // Endpoint to create an invite. diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 1138182..558c605 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -6,28 +6,6 @@ import "harmonytypes/v1/types.proto"; // Object representing a guild without the ID part. message Guild { - // The kind of a guild. - enum Kind { - // A "normal" guild as in a guild that allows multiple channels. - KIND_NORMAL_UNSPECIFIED = 0; - // A "room" guild as in a guild that only has one channel. - // - // - Clients should not show a channel list for guilds of this type. - KIND_ROOM = 1; - // A "direct message" guild as in a guild that has at most two members, - // and has only one channel. - // - // - Clients should not show a channel list for guilds of this type. - // - Clients should show this guild in the guild list with the profile picture - // and the username of the other user. - // - Servers should "upgrade" this guild to a "room" guild if another - // user joins the guild. A name should be crafted using the algorithm - // described below: - // - Get at most 3 members' usernames, by their - // - Concat them with ", " as a seperator. - KIND_DIRECT_MESSAGE = 2; - } - // The name of the guild. // // This will be empty if the guild kind is "direct message". See @@ -38,10 +16,8 @@ message Guild { optional string picture = 2; // User ID of the owners of the guild. repeated uint64 owner_ids = 3; - // The kind of this guild. - Kind kind = 4; // Metadata of the guild. - optional harmonytypes.v1.Metadata metadata = 5; + optional harmonytypes.v1.Metadata metadata = 4; } // Object representing a guild with the ID part. @@ -111,36 +87,6 @@ message CreateGuildResponse { uint64 guild_id = 1; } -// Request type used in `CreateRoom` endpoint. -message CreateRoomRequest { - // The name of the guild. - string name = 1; - // The picture file ID of the guild. - optional string picture = 2; - // Metadata of the guild. - optional harmonytypes.v1.Metadata metadata = 3; -} -// Used in the `CreateRoom` endpoint. -message CreateRoomResponse { - // Guild ID of the guild that was created. - uint64 guild_id = 1; -} - -// Used in the `CreateDirectMessage` endpoint. -message CreateDirectMessageRequest { - // The user name of the user to DM with. - string user_name = 1; - // The server ID of the server the user is on. - // - // Should be left unspecified if it's a user on the homeserver. - optional string server_id = 2; -} -// Used in the `CreateDirectMessage` endpoint. -message CreateDirectMessageResponse { - // Guild ID of the just created "direct message" guild. - uint64 guild_id = 1; -} - // Used in the `CreateInvite` endpoint. message CreateInviteRequest { // Guild ID of the guild to create an invite in. @@ -213,14 +159,6 @@ message UpdateGuildInformationRequest { // Used in the `UpdateGuildInformation` endpoint. message UpdateGuildInformationResponse {} -// Used in the `UpgradeRoomToGuild` endpoint. -message UpgradeRoomToGuildRequest { - // Guild ID of the "room" guild to upgrade to a "normal" guild. - uint64 guild_id = 1; -} -// Used in the `UpgradeRoomToGuild` endpoint. -message UpgradeRoomToGuildResponse {} - // Used in the `DeleteGuild` endpoint. message DeleteGuildRequest { // Guild ID of the guild you want to delete. diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 59ead8a..8c18516 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -30,37 +30,11 @@ message Overrides { } } -// The payload sent to the bot when an action is triggered. -message ActionPayload { - // The payload data for a button action. - message Button { - // The data from the Button action. - bytes data = 1; - } - // The payload for a dropdown action. - message Dropdown { - // The user choice from the dropdown. - bytes choice = 1; - } - // The payload for a text input action. - message Input { - // The user input. - string input = 1; - // The bot-provided data. - bytes data = 2; - } - // The payload data. - oneof payload { - // Payload for a button. - Button button = 1; - // Payload for a dropdown. - Dropdown dropdown = 2; - // Payload for a text input. - Input input = 3; - } -} - -// Actions are interactive elements that can exist within an embed. +// Actions are interactive elements that can exist within a message. +// They can be only sent by bots; servers should ignore actions created by users. +// +// Servers MUST verify that the action data sent by an user is valid for that action +// before sending it to the bot. message Action { // The action type. This is primarily used to change the look of the action to // the user (example: Destructive actions will have a red background). @@ -78,14 +52,11 @@ message Action { // The text to show on the button. string text = 1; - // Action data, which should be used in the call to perform the action. - bytes data = 2; - // An external URL that the button links to. // // This makes it so that tapping this button will open said URL instead // of triggering the action. - optional string url = 3; + optional string url = 2; } // A dropdown menu that users can click on to trigger an action. @@ -111,21 +82,24 @@ message Action { string label = 1; // Whether this text input should be a multiline one or not. bool multiline = 2; - // Contextual data allowing the bot to discern what the user input is for. - bytes data = 3; + // The default text that should be pre-filled in the text field. + optional string default = 3; } // Type of the action. Type action_type = 1; + // Contextual info allowing the bot to discern what the action is for. + // The info of an action cannot be the same with the info of another action in the same message. + bytes info = 2; // The kind of the action. oneof kind { // Button action. - Button button = 2; + Button button = 3; // Dropdown action. - Dropdown dropdown = 3; + Dropdown dropdown = 4; // Input action. - Input input = 4; + Input input = 5; } } @@ -440,6 +414,8 @@ message Message { Content content = 7; // The reactions of the message. repeated Reaction reactions = 8; + // Bot actions to show on this message. + repeated Action actions = 9; } // Object representing a message with it's ID. @@ -463,7 +439,7 @@ message GetChannelMessagesRequest { } // Guild ID of the guild that has the channel. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel to get messages from. uint64 channel_id = 2; // The ID of the message that will be used as an "anchor" point to figure out @@ -505,7 +481,7 @@ message GetChannelMessagesResponse { // Used in the `GetMessage` endpoint. message GetMessageRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message you want to get. @@ -520,7 +496,7 @@ message GetMessageResponse { // Used in the `DeleteMessage` endpoint. message DeleteMessageRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message you want to delete. @@ -532,13 +508,16 @@ message DeleteMessageResponse {} // Used in the `TriggerAction` endpoint. message TriggerActionRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message you want to trigger an action in. uint64 message_id = 3; - // Payload of action data. - ActionPayload payload = 4; + // Data that alllows the bot to discern which action the user is trying to trigger. + // A server MUST verify that this info refers to a valid action for the target message. + bytes info = 4; + // Payload of action data. Ignored if this is a button action. + optional bytes payload = 5; } // Used in the `TriggerAction` endpoint. message TriggerActionResponse {} @@ -591,7 +570,7 @@ message SendMessageRequest { } // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel you want to send a message in. uint64 channel_id = 2; // Content of the new message. @@ -604,6 +583,8 @@ message SendMessageRequest { optional Overrides overrides = 6; // The message this new message is a reply to. optional uint64 in_reply_to = 7; + // Actions to send on this message. Ignored if the message is not sent by a bot. + repeated Action actions = 8; // The metadata of this new message. optional harmonytypes.v1.Metadata metadata = 5; } @@ -616,7 +597,7 @@ message SendMessageResponse { // Used in the `UpdateMessageContent` endpoint. message UpdateMessageContentRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message you want to change the content of. @@ -630,7 +611,7 @@ message UpdateMessageContentResponse {} // Used in the `PinMessage` endpoint. message PinMessageRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message we want to pin. @@ -642,7 +623,7 @@ message PinMessageResponse {} // Used in the `UnpinMessage` endpoint. message UnpinMessageRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message we want to unpin. @@ -654,7 +635,7 @@ message UnpinMessageResponse {} // Used in the `GetPinnedMessages` endpoint. message GetPinnedMessagesRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel we want to get pins of. uint64 channel_id = 2; } @@ -668,7 +649,7 @@ message GetPinnedMessagesResponse { // Used in `AddReaction` endpoint. message AddReactionRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message we want to add a reaction to. @@ -686,7 +667,7 @@ message AddReactionResponse {} // Used in `RemoveReaction` endpoint. message RemoveReactionRequest { // Guild ID of the guild where the channel is. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where the message is. uint64 channel_id = 2; // Message ID of the message we want to remove a reaction. diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto new file mode 100644 index 0000000..b30096a --- /dev/null +++ b/stable/chat/v1/private_channel.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; + +package protocol.chat.v1; + +// PrivateChannel is a private channel between a list of users, independent of a guild. +// It should be possible to use this channel for both text and voice communications. +message PrivateChannel { + // The list of users that have access to this channel. + repeated uint64 members = 1; + // Whether it is possible to add or remove users to/from this channel. + // + // If a channel is locked, the number of recipients is two (this is a direct message channel). + // It should not be possible to have multiple direct message channels between the same two users. + bool is_locked = 2; +} + +// An entry in the list of private channels. +message PrivateChannelListEntry { + // The channel ID of this channel list entry. + uint64 channel_id = 1; + // The server ID of the homeserver of this private channel. + string server_id = 2; +} + +// Request type used in `CreatePrivateChannel` endpoint. +message CreatePrivateChannelRequest { + // The list of users that have access to this channel. + // + // These users will be sent an invite. + repeated uint64 members = 1; + // Whether it is possible to add or remove users to/from this channel. + bool is_locked = 2; +} +// Response type used in `CreatePrivateChannel` endpoint. +message CreatePrivateChannelResponse { + // The channel ID of the newly created private channel. + uint64 channel_id = 1; +} + +// Request type used in `UpdatePrivateChannelMembers` endpoint. +message UpdatePrivateChannelMembersRequest { + // The channel ID of the private channel to update the member list for. + uint64 channel_id = 1; + // The list of member IDs of members to add to the private channel. + // + // These users will be sent an invite. + repeated uint64 added_members = 2; + // The list of member IDs of members to remove from the private channel. + repeated uint64 removed_members = 3; +} +// Request type used in `UpdatePrivateChannelMembers` endpoint. +message UpdatePrivateChannelMembersResponse {} + +// Request type used in `DeletePrivateChannel` endpoint. +message DeletePrivateChannelRequest { + // The channel ID of the private channel to delete. + uint64 channel_id = 1; +} +// Response type used in `DeletePrivateChannel` endpoint. +message DeletePrivateChannelResponse {} + +// Request type used in `GetPrivateChannels` endpoint. +message GetPrivateChannelsRequest {} +// Response type used in `GetPrivateChannels` endpoint. +message GetPrivateChannelsResponse { + // The list of private channels that the user is in. + repeated PrivateChannelListEntry channels = 1; +} \ No newline at end of file diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 66bc899..3a55150 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -7,36 +7,44 @@ import "chat/v1/channels.proto"; import "chat/v1/guilds.proto"; import "chat/v1/messages.proto"; import "chat/v1/permissions.proto"; +import "chat/v1/private_channel.proto"; import "emote/v1/stream.proto"; import "profile/v1/stream.proto"; // Request type for use in the `StreamEvents` endpoint. // By default, this endpoint will subscribe to all events. -// Any guilds joined in the future will be added to the subscription as well. -// Use the UnsubscribeFromAll event for unsubscribing from all current subscriptions and disable the automatic guild subscriptions +// Any guilds / private channels joined in the future will be added to the subscription as well. +// Use the UnsubscribeFromAll event for unsubscribing from all current subscriptions and disable the automatic guild subscriptions. message StreamEventsRequest { - // Event source for guilds' events. + // Message to use for subscribing to a guild. message SubscribeToGuild { - // the guild id to subscribe to + // The guild ID to subscribe to. uint64 guild_id = 1; } - // Event source for actions' events. + // Message to use for subscribing to a private channel. + message SubscribeToPrivateChannel { + // The channel ID to subscribe to. + uint64 channel_id = 1; + } + // Message to use for subscribing to actions. message SubscribeToActions {} - // Event source for homeserver events. + // Message to use for subscribing to homeserver events. message SubscribeToHomeserverEvents {} - // Event to unsubscribe from all events. + // Message to use for unsubscribing from all events. message UnsubscribeFromAll {} // Describes which event source to subscribe to. oneof request { - // Subscribe to the guild event source. + // Subscribe to guild events. SubscribeToGuild subscribe_to_guild = 1; - // Subscribe to the action event source. - SubscribeToActions subscribe_to_actions = 2; - // Subscribe to the homeserver event source. - SubscribeToHomeserverEvents subscribe_to_homeserver_events = 3; + // Subscribe to private channel events. + SubscribeToPrivateChannels subscribe_to_private_channels = 2; + // Subscribe to action events. + SubscribeToActions subscribe_to_actions = 3; + // Subscribe to homeserver events. + SubscribeToHomeserverEvents subscribe_to_homeserver_events = 4; // Unsubscribe from all events. - UnsubscribeFromAll unsubscribe_from_all = 4; + UnsubscribeFromAll unsubscribe_from_all = 5; } } @@ -63,7 +71,8 @@ message StreamEvent { // ID that is sent by your client it can use to confirm that the message is sent. optional uint64 echo_id = 1; // Guild ID of the guild where this event happened. - uint64 guild_id = 2; + // Null if the event happened in a private channel. + optional uint64 guild_id = 2; // Channel ID of the channel where this event happened. uint64 channel_id = 3; // Message ID of the message that was updated. @@ -78,7 +87,8 @@ message StreamEvent { // for the channel the message was updated in. message MessageUpdated { // Guild ID of the guild where this event happened. - uint64 guild_id = 1; + // Null if the event happened in a private channel. + optional uint64 guild_id = 1; // Channel ID of the channel where this event happened. uint64 channel_id = 2; // Message ID of the message that was updated. @@ -95,7 +105,7 @@ message StreamEvent { // for the channel the message was deleted in. message MessageDeleted { // Guild ID of the guild where this event happened. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event happened. uint64 channel_id = 2; // Message ID of the message that was deleted. @@ -105,7 +115,7 @@ message StreamEvent { // Event sent when a new channel is created. message ChannelCreated { // Guild ID of the guild where this event happened. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event happened. uint64 channel_id = 2; // Name of this channel. @@ -208,16 +218,16 @@ message StreamEvent { message GuildAddedToList { // Guild ID of the guild where this event happened. uint64 guild_id = 1; - // The homeserver this guild is on. - string homeserver = 2; + // The server ID of the homeserver this guild is on. + string server_id = 2; } // Event sent when you leave a guild. message GuildRemovedFromList { // Guild ID of the guild where this event happened. uint64 guild_id = 1; - // The homeserver this guild is on. - string homeserver = 2; + // The server ID homeserver this guild is on. + string server_id = 2; } // Event sent when an action is performed. @@ -230,8 +240,10 @@ message StreamEvent { uint64 message_id = 3; // User ID of the user that triggered the action uint64 user_id = 4; + // The custom info set by the bot + optional bytes info = 5; // The action data payload - ActionPayload payload = 5; + optional bytes payload = 6; } // Event sent when a role's position in the role list is changed. @@ -326,7 +338,7 @@ message StreamEvent { // User ID of the user that sent the typing notification. uint64 user_id = 1; // Guild ID of the guild where this event happened. - uint64 guild_id = 2; + optional uint64 guild_id = 2; // Channel ID of the channel where this event happened. uint64 channel_id = 3; } @@ -352,7 +364,7 @@ message StreamEvent { // the guild channel where the message was pinned. message MessagePinned { // Guild ID of the guild where this event occured. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event occured. uint64 channel_id = 2; // Message ID of the message that was pinned. @@ -365,7 +377,7 @@ message StreamEvent { // the guild channel where the message was unpinned. message MessageUnpinned { // Guild ID of the guild where this event occured. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event occured. uint64 channel_id = 2; // Message ID of the message that was unpinned. @@ -379,7 +391,7 @@ message StreamEvent { // the guild channel where the reaction was added. message NewReactionAdded { // Guild ID of the guild where this event occured. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event occured. uint64 channel_id = 2; // Message ID of the message that had a reaction added. @@ -492,6 +504,41 @@ message StreamEvent { uint64 user_id = 3; } + // Sent when a private channel is deleted. + message PrivateChannelDeleted { + // The channel ID of the private channel that was deleted. + uint64 channel_id = 1; + } + + // Sent when a private channel is added to an user's private channel list. + message PrivateChannelAddedToList { + // The channel ID of the private channel that was added. + uint64 channel_id = 1; + // The server ID of the homeserver of this private channel. + string server_id = 2; + } + // Sent when a private channel is removed from an user's private channel list. + message PrivateChannelRemovedFromList { + // The channel ID of the private channel that was removed. + uint64 channel_id = 1; + // The server ID of the homeserver of this private channel. + string server_id = 2; + } + // Sent when a user joins a private channel. + message UserJoinedPrivateChannel { + // The channel ID of the private channel. + uint64 channel_id = 1; + // The user ID of the user who joined the private channel. + uint64 user_id = 2; + } + // Sent when a user leaves a private channel. + message UserLeftPrivateChannel { + // The channel ID of the private channel. + uint64 channel_id = 1; + // The user ID of the user who left the private channel. + uint64 user_id = 2; + } + // Which event to send. oneof event { // Send the guild added to list event. @@ -564,5 +611,15 @@ message StreamEvent { ReactionAdded reaction_added = 34; // Send the reaction removed event. ReactionRemoved reaction_removed = 35; + // Send the private channel deleted event. + PrivateChannelDeleted private_channel_deleted = 36; + // Send the private channel added to list event. + PrivateChannelAddedToList private_channel_added_to_list = 37; + // Send the private channel removed from list event. + PrivateChannelRemovedFromList private_channel_removed_from_list = 38; + // Send the user joined private channel event. + UserJoinedPrivateChannel user_joined_private_channel = 39; + // Send the user left private channel event. + UserLeftPrivateChannel user_left_private_channel = 40; } } diff --git a/stable/sync/v1/sync.proto b/stable/sync/v1/sync.proto index e232395..4a98f3b 100644 --- a/stable/sync/v1/sync.proto +++ b/stable/sync/v1/sync.proto @@ -31,24 +31,53 @@ message Event { // Guild ID of the guild where the user will be. uint64 guild_id = 2; } + + // Event sent when an user is removed from a private channel. + message UserRemovedFromChannel { + // User ID of the user that was removed. + uint64 user_id = 1; + // Channel ID of the channel where the user was. + uint64 channel_id = 2; + } + // Event sent when an user is added to a private channel. + message UserAddedToChannel { + // User ID of the user that was added. + uint64 user_id = 1; + // Channel ID of the channel where the user will be. + uint64 channel_id = 2; + } + // Event sent when a user is invited to a guild. message UserInvited { // User ID of the invitee. uint64 user_id = 1; // User ID of the user that invited. uint64 inviter_id = 2; + + // The location where the user is being invited to. + oneof location { // The unique identifier of a user's invite to another // user to join a given guild. - string invite_id = 3; + uint64 guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } } // Event sent when a user rejects a guild invitation. message UserRejectedInvite { - // Guild ID of the guild the invitee rejected an invite for. - uint64 guild_id = 1; // User ID of the invitee that rejected the invitation. - uint64 user_id = 2; + uint64 user_id = 1; // Invite ID of the invite that was rejected. - string invite_id = 3; + string invite_id = 2; + + // The location where the user was invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + uint64 guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } } // The kind and data of this event. @@ -57,10 +86,14 @@ message Event { UserRemovedFromGuild user_removed_from_guild = 1; // User added to a guild. UserAddedToGuild user_added_to_guild = 2; + // User removed from a private channel. + UserRemovedFromChannel user_removed_from_channel = 3; + // User added to a private channel. + UserAddedToChannel user_added_to_channel = 4; // User invited to a guild. - UserInvited user_invited = 3; + UserInvited user_invited = 5; // User rejected a guild invitation. - UserRejectedInvite user_rejected_invite = 4; + UserRejectedInvite user_rejected_invite = 6; } } diff --git a/staging/bots/v1/bots.proto b/staging/bots/v1/bots.proto index 54f8860..e23982a 100644 --- a/staging/bots/v1/bots.proto +++ b/staging/bots/v1/bots.proto @@ -49,6 +49,8 @@ message CreateBotRequest { message CreateBotResponse { // The newly generated ID of the bot. uint64 bot_id = 1; + // The authentication token of the bot, used instead of a session token from AuthService + string token = 2; } // Request type for EditBot. @@ -66,7 +68,18 @@ message EditBotRequest { // Response type for EditBot. message EditBotResponse {} -// Request type for DeleteBot. +// Request type for RefreshToken +message RefreshTokenRequest { + // The ID of the bot to refresh the token of + uint64 bot_id = 1; +} +// Response type for RefreshToken +message RefreshTokenResponse { + // The new authentication token for the bot + string new_token = 1; +} + +// Request type for DeleteBot message DeleteBotRequest { // The ID of the bot to delete. uint64 bot_id = 1; @@ -95,11 +108,18 @@ message PoliciesResponse { // Request type for AddBot. message AddBotRequest { - // The guild to add the bot to. - uint64 guild_id = 1; // The bot's invite code. - string invite_code = 2; + string invite_code = 1; + + // The location where the bot is being added to. + oneof location { + // The guild to add the bot to. + uint64 guild_id = 2; + // The private channel to add the bot to. + uint64 channel_id = 3; + } } + // Response type for AddBot. message AddBotResponse {} @@ -113,7 +133,11 @@ service BotsService { rpc CreateBot(CreateBotRequest) returns (CreateBotResponse); // Modifies a bot account that you own. rpc EditBot(EditBotRequest) returns (EditBotResponse); - // Deletes a bot account that you own. + // Refreshes the authentication token for a bot that you own + // + // This invalidates the current authentication token and returns a new one. + rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse); + // Deletes a bot account that you own rpc DeleteBot(DeleteBotRequest) returns (DeleteBotResponse); // Server policies for bot accounts that the client // may display in its UI or restrict actions to prevent From 94b11120a829fc163e3892c95f18bead2154d764 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 04:09:16 +0300 Subject: [PATCH 40/68] feat: separate private channels from guilds (#100) Co-authored-by: spiral From d9f35a336d30dfb0734c964d3ca618c7d15a5d86 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 04:10:10 +0300 Subject: [PATCH 41/68] feat: refactor actions (#101) Co-authored-by: spiral From ac35c0163cef8bc42e6e8c771ff9ec907a479d89 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 04:45:14 +0300 Subject: [PATCH 42/68] fix(chat): message name typo --- stable/chat/v1/stream.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 3a55150..1cb829a 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -38,7 +38,7 @@ message StreamEventsRequest { // Subscribe to guild events. SubscribeToGuild subscribe_to_guild = 1; // Subscribe to private channel events. - SubscribeToPrivateChannels subscribe_to_private_channels = 2; + SubscribeToPrivateChannel subscribe_to_private_channel = 2; // Subscribe to action events. SubscribeToActions subscribe_to_actions = 3; // Subscribe to homeserver events. From 6ad5b1d63c2d32a091e71f84baf398eddebc8ed8 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 20:47:14 +0300 Subject: [PATCH 43/68] fix(chat): add missing get private channel list rpc --- stable/chat/v1/chat.proto | 5 +++++ stable/chat/v1/private_channel.proto | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 3b35c6d..42e1012 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -64,6 +64,11 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } + // Endpoint to get your private channel list. + rpc GetPrivateChannelList(GetPrivateChannelListRequest) returns (GetPrivateChannelListResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } + // Endpoint to invite a user to a guild. rpc InviteUserToGuild(InviteUserToGuildRequest) returns (InviteUserToGuildResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index b30096a..f02ebc8 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -59,10 +59,10 @@ message DeletePrivateChannelRequest { // Response type used in `DeletePrivateChannel` endpoint. message DeletePrivateChannelResponse {} -// Request type used in `GetPrivateChannels` endpoint. -message GetPrivateChannelsRequest {} -// Response type used in `GetPrivateChannels` endpoint. -message GetPrivateChannelsResponse { +// Request type used in `GetPrivateChannelList` endpoint. +message GetPrivateChannelListRequest {} +// Response type used in `GetPrivateChannelList` endpoint. +message GetPrivateChannelListResponse { // The list of private channels that the user is in. repeated PrivateChannelListEntry channels = 1; } \ No newline at end of file From a2d408269d8a42d4fe068d67694e18982c90cc87 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 2 Apr 2022 22:54:45 +0300 Subject: [PATCH 44/68] fix(chat): remove unused import --- stable/chat/v1/stream.proto | 1 - 1 file changed, 1 deletion(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 1cb829a..8cf523d 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -7,7 +7,6 @@ import "chat/v1/channels.proto"; import "chat/v1/guilds.proto"; import "chat/v1/messages.proto"; import "chat/v1/permissions.proto"; -import "chat/v1/private_channel.proto"; import "emote/v1/stream.proto"; import "profile/v1/stream.proto"; From 90a1fc053915a8100726c38f6040ddee695455ea Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 3 Apr 2022 05:30:34 +0300 Subject: [PATCH 45/68] fix(chat): fix a few fields that need to be optional --- stable/chat/v1/stream.proto | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 8cf523d..8151ffc 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -114,7 +114,7 @@ message StreamEvent { // Event sent when a new channel is created. message ChannelCreated { // Guild ID of the guild where this event happened. - optional uint64 guild_id = 1; + uint64 guild_id = 1; // Channel ID of the channel where this event happened. uint64 channel_id = 2; // Name of this channel. @@ -232,7 +232,7 @@ message StreamEvent { // Event sent when an action is performed. message ActionPerformed { // Guild ID of the guild where this event happened. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event happened. uint64 channel_id = 2; // Message ID where this event happened. @@ -406,7 +406,7 @@ message StreamEvent { // the guild channel where the reaction was added. message ReactionAdded { // Guild ID of the guild where this event occured. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event occured. uint64 channel_id = 2; // Message ID of the message that had a reaction added. @@ -421,7 +421,7 @@ message StreamEvent { // the guild channel where the reaction was removed. message ReactionRemoved { // Guild ID of the guild where this event occured. - uint64 guild_id = 1; + optional uint64 guild_id = 1; // Channel ID of the channel where this event occured. uint64 channel_id = 2; // Message ID of the message that had a reaction removed. From ffb8ca8e2fdb7e4be78f5cf7075167be6d5b33a1 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 3 Apr 2022 05:35:26 +0300 Subject: [PATCH 46/68] fix(chat): typing request should have an optional guild id --- stable/chat/v1/channels.proto | 10 ---------- stable/chat/v1/messages.proto | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/stable/chat/v1/channels.proto b/stable/chat/v1/channels.proto index 4ae3e0f..8bc8281 100644 --- a/stable/chat/v1/channels.proto +++ b/stable/chat/v1/channels.proto @@ -123,13 +123,3 @@ message DeleteChannelRequest { } // Used in the `DeleteChannel` endpoint. message DeleteChannelResponse {} - -// Used in `Typing` endpoint. -message TypingRequest { - // The guild id of the channel the user is typing in. - uint64 guild_id = 1; - // The channel id of the channel the user is typing in. - uint64 channel_id = 2; -} -// Used in `Typing` endpoint. -message TypingResponse {} \ No newline at end of file diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index 8c18516..cdde4d5 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -677,3 +677,13 @@ message RemoveReactionRequest { } // Used in `RemoveReaction` endpoint. message RemoveReactionResponse {} + +// Used in `Typing` endpoint. +message TypingRequest { + // The guild id of the channel the user is typing in. + optional uint64 guild_id = 1; + // The channel id of the channel the user is typing in. + uint64 channel_id = 2; +} +// Used in `Typing` endpoint. +message TypingResponse {} \ No newline at end of file From 6bbbadc0af51e2f349613041d0c0a3f3b196ff36 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 05:19:48 +0300 Subject: [PATCH 47/68] fix: fix location.guild_invite_id to be string, remove invite_id from UserRejectedInvite, add location to PendingInvite --- stable/chat/v1/guilds.proto | 15 +++++++++++---- stable/sync/v1/sync.proto | 22 ++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 558c605..1c55f76 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -46,12 +46,19 @@ message InviteWithId { // A pending invite. message PendingInvite { - // Invite ID of the invite. - string invite_id = 1; // Server ID of the server the inviter is on. - optional string server_id = 2; + optional string server_id = 1; // User ID of the inviter. - uint64 inviter_id = 3; + uint64 inviter_id = 2; + + // The location where the user is being invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } } // Object representing a guild list entry. diff --git a/stable/sync/v1/sync.proto b/stable/sync/v1/sync.proto index 4a98f3b..5b0bf95 100644 --- a/stable/sync/v1/sync.proto +++ b/stable/sync/v1/sync.proto @@ -54,11 +54,11 @@ message Event { // User ID of the user that invited. uint64 inviter_id = 2; - // The location where the user is being invited to. + // The location where the user is being invited to. oneof location { - // The unique identifier of a user's invite to another - // user to join a given guild. - uint64 guild_invite_id = 3; + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 3; // The channel ID of the private channel that the user was invited to. uint64 channel_id = 4; } @@ -67,17 +67,15 @@ message Event { message UserRejectedInvite { // User ID of the invitee that rejected the invitation. uint64 user_id = 1; - // Invite ID of the invite that was rejected. - string invite_id = 2; // The location where the user was invited to. oneof location { - // The unique identifier of a user's invite to another - // user to join a given guild. - uint64 guild_invite_id = 3; - // The channel ID of the private channel that the user was invited to. - uint64 channel_id = 4; - } + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 2; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 3; + } } // The kind and data of this event. From f424aa01af7147d8fdf0be3f00a97e3c9ef336cd Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 06:24:07 +0300 Subject: [PATCH 48/68] fix: Invite* events should also use location --- stable/chat/v1/stream.proto | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 8151ffc..34ec7d3 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -446,24 +446,34 @@ message StreamEvent { uint64 user_id = 1; } - // Sent when a guild invite is received. + // Sent when an invite is received. message InviteReceived { - // ID of the invite received. - string invite_id = 1; // Server ID of the server the inviter is on. - optional string server_id = 2; + optional string server_id = 1; // User ID of the inviter. - uint64 inviter_id = 3; - } - - // Sent when a guild invite is rejected by the invitee. + uint64 inviter_id = 2; + // The location where the user was invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } + } + + // Sent when an invite is rejected by the invitee. message InviteRejected { - // Guild ID of the guild that this occured for. - uint64 guild_id = 1; - // ID of the invite rejected. - string invite_id = 2; // User ID of the invitee. - uint64 user_id = 3; + uint64 user_id = 1; + // The location where the user was invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 2; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 3; + } } // Sent when an invite is created in a guild. From 63b855ff345a4fa8a73193b71dfb5f1c5bab4a4b Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 06:34:41 +0300 Subject: [PATCH 49/68] feat(chat): add GetOutgoingPendingInvites to let users fetch the invites they have sent that haven't been rejected --- stable/chat/v1/chat.proto | 5 +++++ stable/chat/v1/guilds.proto | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 42e1012..8ad5021 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -76,6 +76,11 @@ service ChatService { "invites.manage.create"; } + // Endpoint to get your outgoing pending invites. + rpc GetOutgoingPendingInvites(GetOutgoingPendingInvitesRequest) returns (GetOutgoingPendingInvitesResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + }; + // Endpoint to get your pending invites. rpc GetPendingInvites(GetPendingInvitesRequest) returns (GetPendingInvitesResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 1c55f76..78a4bc3 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -61,6 +61,23 @@ message PendingInvite { } } +// An outgoing pending invite. +message OutgoingPendingInvite { + // Server ID of the server the invitee is on. + optional string server_id = 1; + // User ID of the invitee. + uint64 invitee_id = 2; + + // The location where the user is being invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } +} + // Object representing a guild list entry. message GuildListEntry { // Guild ID of this guild entry. @@ -282,7 +299,15 @@ message GetPendingInvitesRequest {} // Used in `GetPendingInvites` endpoint. message GetPendingInvitesResponse { // The pending invite(s). - repeated PendingInvite pending_invites = 1; + repeated PendingInvite invites = 1; +} + +// Used in `GetOutgoingPendingInvites` endpoint. +message GetOutgoingPendingInvitesRequest {} +// Used in `GetOutgoingPendingInvites` endpoint. +message GetOutgoingPendingInvitesResponse { + // The pending invite(s). + repeated OutgoingPendingInvite invites = 1; } // Used in `RejectPendingInvite` endpoint. From fb9028f4413867a21fcfd2c7a074cd14cff69b99 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 06:40:02 +0300 Subject: [PATCH 50/68] feat(chat): add DeleteOutgoingInvite to delete and cancel an outgoing invite --- stable/chat/v1/chat.proto | 9 +++++++-- stable/chat/v1/guilds.proto | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 8ad5021..d754a96 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -77,9 +77,14 @@ service ChatService { } // Endpoint to get your outgoing pending invites. - rpc GetOutgoingPendingInvites(GetOutgoingPendingInvitesRequest) returns (GetOutgoingPendingInvitesResponse) { + rpc GetOutgoingInvites(GetOutgoingInvitesRequest) returns (GetOutgoingInvitesResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; - }; + } + + // Endpoint to delete (cancel) an outgoing invite. + rpc DeleteOutgoingInvite(DeleteOutgoingInviteRequest) returns (DeleteOutgoingInviteResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } // Endpoint to get your pending invites. rpc GetPendingInvites(GetPendingInvitesRequest) returns (GetPendingInvitesResponse) { diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 78a4bc3..5d3aaff 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -61,8 +61,8 @@ message PendingInvite { } } -// An outgoing pending invite. -message OutgoingPendingInvite { +// An outgoing invite. +message OutgoingInvite { // Server ID of the server the invitee is on. optional string server_id = 1; // User ID of the invitee. @@ -302,14 +302,22 @@ message GetPendingInvitesResponse { repeated PendingInvite invites = 1; } -// Used in `GetOutgoingPendingInvites` endpoint. -message GetOutgoingPendingInvitesRequest {} -// Used in `GetOutgoingPendingInvites` endpoint. -message GetOutgoingPendingInvitesResponse { +// Used in `GetOutgoingInvites` endpoint. +message GetOutgoingInvitesRequest {} +// Used in `GetOutgoingInvites` endpoint. +message GetOutgoingInvitesResponse { // The pending invite(s). - repeated OutgoingPendingInvite invites = 1; + repeated OutgoingInvite invites = 1; } +// Used in `DeleteOutgoingInvite` endpoint. +message DeleteOutgoingInviteRequest { + // The outgoing invite to delete. + OutgoingInvite invite = 1; +} +// Used in `DeleteOutgoingInvite` endpoint. +message DeleteOutgoingInviteResponse {} + // Used in `RejectPendingInvite` endpoint. message RejectPendingInviteRequest { // Invite ID of the pending invite to reject. From 14be6dd7ec3330f7fa14d5e36228e7872cb2d158 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 06:49:15 +0300 Subject: [PATCH 51/68] fix(chat): Reject/Ignore pending invite requests should use PendingInvite --- stable/chat/v1/guilds.proto | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 5d3aaff..4419584 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -320,20 +320,16 @@ message DeleteOutgoingInviteResponse {} // Used in `RejectPendingInvite` endpoint. message RejectPendingInviteRequest { - // Invite ID of the pending invite to reject. - string invite_id = 1; - // Server ID of the pending invite to reject. - optional string server_id = 2; + // The pending invite to reject. + PendingInvite invite = 1; } // Used in `RejectPendingInvite` endpoint. message RejectPendingInviteResponse {} // Used in `IgnorePendingInvite` endpoint. message IgnorePendingInviteRequest { - // ID of the pending invite to ignore. - string invite_id = 1; - // Server ID of the pending invite to reject. - optional string server_id = 2; + // The pending invite to ignore. + PendingInvite invite = 1; } // Used in `IgnorePendingInvite` endpoint. message IgnorePendingInviteResponse {} From cc41fa80f225f3352c3b6b32b3849f6752373a7f Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 06:56:32 +0300 Subject: [PATCH 52/68] feat(chat): allow specifying pack_id optionally in Emoji format --- stable/chat/v1/messages.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stable/chat/v1/messages.proto b/stable/chat/v1/messages.proto index cdde4d5..8461989 100644 --- a/stable/chat/v1/messages.proto +++ b/stable/chat/v1/messages.proto @@ -327,8 +327,10 @@ message Format { } // An emoji. message Emoji { - // The emote data of the emoji. + // The emote data of the emote. emote.v1.Emote emote = 1; + // The (optional) pack ID of this emote. + optional uint64 pack_id = 2; } // Colour modification. message Color { From abd8124d298821187224211542177bd96b936771 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 07:13:25 +0300 Subject: [PATCH 53/68] refactor(chat): Invite* events should use Pending/Outgoing Invite --- stable/chat/v1/stream.proto | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 34ec7d3..8b1221b 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -448,32 +448,14 @@ message StreamEvent { // Sent when an invite is received. message InviteReceived { - // Server ID of the server the inviter is on. - optional string server_id = 1; - // User ID of the inviter. - uint64 inviter_id = 2; - // The location where the user was invited to. - oneof location { - // The unique identifier of a user's invite to another - // user to join a given guild. - string guild_invite_id = 3; - // The channel ID of the private channel that the user was invited to. - uint64 channel_id = 4; - } + // Invite that was received. + PendingInvite invite = 1; } // Sent when an invite is rejected by the invitee. message InviteRejected { - // User ID of the invitee. - uint64 user_id = 1; - // The location where the user was invited to. - oneof location { - // The unique identifier of a user's invite to another - // user to join a given guild. - string guild_invite_id = 2; - // The channel ID of the private channel that the user was invited to. - uint64 channel_id = 3; - } + // Invite that was rejected. + OutgoingInvite invite = 1; } // Sent when an invite is created in a guild. From 317b784ca5b57fb18e5c60a71b6833558f749d3b Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 07:14:15 +0300 Subject: [PATCH 54/68] refactor(chat): make more server_ids optional --- stable/chat/v1/stream.proto | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 8b1221b..a106703 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -218,7 +218,7 @@ message StreamEvent { // Guild ID of the guild where this event happened. uint64 guild_id = 1; // The server ID of the homeserver this guild is on. - string server_id = 2; + optional string server_id = 2; } // Event sent when you leave a guild. @@ -226,7 +226,7 @@ message StreamEvent { // Guild ID of the guild where this event happened. uint64 guild_id = 1; // The server ID homeserver this guild is on. - string server_id = 2; + optional string server_id = 2; } // Event sent when an action is performed. @@ -506,14 +506,14 @@ message StreamEvent { // The channel ID of the private channel that was added. uint64 channel_id = 1; // The server ID of the homeserver of this private channel. - string server_id = 2; + optional string server_id = 2; } // Sent when a private channel is removed from an user's private channel list. message PrivateChannelRemovedFromList { // The channel ID of the private channel that was removed. uint64 channel_id = 1; // The server ID of the homeserver of this private channel. - string server_id = 2; + optional string server_id = 2; } // Sent when a user joins a private channel. message UserJoinedPrivateChannel { From 848b617132fbd442aea0077f00a2a45d722f183c Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 6 Apr 2022 07:49:30 +0300 Subject: [PATCH 55/68] feat(sync): add inviter_id to user rejected invite --- stable/sync/v1/sync.proto | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stable/sync/v1/sync.proto b/stable/sync/v1/sync.proto index 5b0bf95..b31a1e3 100644 --- a/stable/sync/v1/sync.proto +++ b/stable/sync/v1/sync.proto @@ -67,14 +67,16 @@ message Event { message UserRejectedInvite { // User ID of the invitee that rejected the invitation. uint64 user_id = 1; + // User ID of the inviter. + uint64 inviter_id = 2; // The location where the user was invited to. oneof location { // The unique identifier of a user's invite to another // user to join a given guild. - string guild_invite_id = 2; + string guild_invite_id = 3; // The channel ID of the private channel that the user was invited to. - uint64 channel_id = 3; + uint64 channel_id = 4; } } From c9647917e45c2047ab123b777aea2142fbd868f5 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 07:02:28 +0300 Subject: [PATCH 56/68] feat: remove outgoing invites, add join private channel --- stable/chat/v1/chat.proto | 18 +++++++-------- stable/chat/v1/guilds.proto | 33 ---------------------------- stable/chat/v1/private_channel.proto | 10 ++++++++- 3 files changed, 17 insertions(+), 44 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index d754a96..121840d 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -44,6 +44,14 @@ service ChatService { rpc DeletePrivateChannel(DeletePrivateChannelRequest) returns (DeletePrivateChannelResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } + + // Endpoint to join a private channel. + // + // - If the invite used is in a user's "pending invites" list, it should be + // removed from there. + rpc JoinPrivateChannel(JoinPrivateChannelRequest) returns (JoinPrivateChannelResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } // Endpoint to create an invite. rpc CreateInvite(CreateInviteRequest) returns (CreateInviteResponse) { @@ -76,16 +84,6 @@ service ChatService { "invites.manage.create"; } - // Endpoint to get your outgoing pending invites. - rpc GetOutgoingInvites(GetOutgoingInvitesRequest) returns (GetOutgoingInvitesResponse) { - option (harmonytypes.v1.metadata).requires_authentication = true; - } - - // Endpoint to delete (cancel) an outgoing invite. - rpc DeleteOutgoingInvite(DeleteOutgoingInviteRequest) returns (DeleteOutgoingInviteResponse) { - option (harmonytypes.v1.metadata).requires_authentication = true; - } - // Endpoint to get your pending invites. rpc GetPendingInvites(GetPendingInvitesRequest) returns (GetPendingInvitesResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 4419584..748122e 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -61,23 +61,6 @@ message PendingInvite { } } -// An outgoing invite. -message OutgoingInvite { - // Server ID of the server the invitee is on. - optional string server_id = 1; - // User ID of the invitee. - uint64 invitee_id = 2; - - // The location where the user is being invited to. - oneof location { - // The unique identifier of a user's invite to another - // user to join a given guild. - string guild_invite_id = 3; - // The channel ID of the private channel that the user was invited to. - uint64 channel_id = 4; - } -} - // Object representing a guild list entry. message GuildListEntry { // Guild ID of this guild entry. @@ -302,22 +285,6 @@ message GetPendingInvitesResponse { repeated PendingInvite invites = 1; } -// Used in `GetOutgoingInvites` endpoint. -message GetOutgoingInvitesRequest {} -// Used in `GetOutgoingInvites` endpoint. -message GetOutgoingInvitesResponse { - // The pending invite(s). - repeated OutgoingInvite invites = 1; -} - -// Used in `DeleteOutgoingInvite` endpoint. -message DeleteOutgoingInviteRequest { - // The outgoing invite to delete. - OutgoingInvite invite = 1; -} -// Used in `DeleteOutgoingInvite` endpoint. -message DeleteOutgoingInviteResponse {} - // Used in `RejectPendingInvite` endpoint. message RejectPendingInviteRequest { // The pending invite to reject. diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index f02ebc8..36ccb77 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -65,4 +65,12 @@ message GetPrivateChannelListRequest {} message GetPrivateChannelListResponse { // The list of private channels that the user is in. repeated PrivateChannelListEntry channels = 1; -} \ No newline at end of file +} + +// Request type used in `JoinPrivateChannel` endpoint. +message JoinPrivateChannelRequest { + // The channel ID of the private channel to join. + uint64 channel_id = 1; +} +// Response type used in `JoinPrivateChannel` endpoint. +message JoinPrivateChannelResponse {} \ No newline at end of file From 724cf955ee44b356a44ed59096565ca353af3bb2 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 07:12:48 +0300 Subject: [PATCH 57/68] fix(chat): remove outgoing invite usage --- stable/chat/v1/stream.proto | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index a106703..2fa734c 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -448,14 +448,34 @@ message StreamEvent { // Sent when an invite is received. message InviteReceived { - // Invite that was received. - PendingInvite invite = 1; + // The user ID of the inviter. + uint64 inviter_id = 1; + // The server ID of the server the inviter is on. + optional server_id = 2; + // The location where the user was invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } } // Sent when an invite is rejected by the invitee. message InviteRejected { - // Invite that was rejected. - OutgoingInvite invite = 1; + // The user ID of the invitee. + uint64 invitee_id = 1; + // The server ID of the server the invitee is on. + optional server_id = 2; + // The location where the user was invited to. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 3; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 4; + } } // Sent when an invite is created in a guild. From 0981d9771bcdf3c8ddafa8c323166e9469760463 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 07:16:53 +0300 Subject: [PATCH 58/68] fix(chat): add field names --- stable/chat/v1/stream.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index 2fa734c..f404a61 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -451,7 +451,7 @@ message StreamEvent { // The user ID of the inviter. uint64 inviter_id = 1; // The server ID of the server the inviter is on. - optional server_id = 2; + optional string server_id = 2; // The location where the user was invited to. oneof location { // The unique identifier of a user's invite to another @@ -467,7 +467,7 @@ message StreamEvent { // The user ID of the invitee. uint64 invitee_id = 1; // The server ID of the server the invitee is on. - optional server_id = 2; + optional string server_id = 2; // The location where the user was invited to. oneof location { // The unique identifier of a user's invite to another From 87a935934aef68c7839793e99b84d40f1d293623 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 20:22:37 +0300 Subject: [PATCH 59/68] refactor(chat): make pending invite endpoints not use pending invite object --- stable/chat/v1/guilds.proto | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 748122e..aea464f 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -46,7 +46,7 @@ message InviteWithId { // A pending invite. message PendingInvite { - // Server ID of the server the inviter is on. + // Server ID of the server where the inviter is on. optional string server_id = 1; // User ID of the inviter. uint64 inviter_id = 2; @@ -287,16 +287,32 @@ message GetPendingInvitesResponse { // Used in `RejectPendingInvite` endpoint. message RejectPendingInviteRequest { - // The pending invite to reject. - PendingInvite invite = 1; + // Server ID of the server where the inviter is on. + optional string server_id = 1; + // The location of the pending invite to ignore. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 2; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 3; + } } // Used in `RejectPendingInvite` endpoint. message RejectPendingInviteResponse {} // Used in `IgnorePendingInvite` endpoint. message IgnorePendingInviteRequest { - // The pending invite to ignore. - PendingInvite invite = 1; + // Server ID of the server where the inviter is on. + optional string server_id = 1; + // The location of the pending invite to ignore. + oneof location { + // The unique identifier of a user's invite to another + // user to join a given guild. + string guild_invite_id = 2; + // The channel ID of the private channel that the user was invited to. + uint64 channel_id = 3; + } } // Used in `IgnorePendingInvite` endpoint. message IgnorePendingInviteResponse {} From ca3ebacf5789c71fcda67c2dfa80258589e6c0a4 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 20:29:19 +0300 Subject: [PATCH 60/68] docs(chat): document when a pending invite is unique --- stable/chat/v1/guilds.proto | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index aea464f..1f593ff 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -36,7 +36,7 @@ message Invite { uint32 use_count = 2; } -// Invite with ID. +// Object representing an invite with the ID part. message InviteWithId { // ID of the invite. string invite_id = 1; @@ -45,6 +45,10 @@ message InviteWithId { } // A pending invite. +// +// A pending invite's `server_id` and `location` determines whether +// it is unique or not. If two pending invites have the same `server_id` +// and `location`, these are considered as the same pending invite. message PendingInvite { // Server ID of the server where the inviter is on. optional string server_id = 1; From db389661e997d6bd82c8d8fe75852b70befdc384 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 21:43:20 +0300 Subject: [PATCH 61/68] feat(chat): add leave private channel endpoint --- stable/chat/v1/chat.proto | 5 +++++ stable/chat/v1/private_channel.proto | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 121840d..773928d 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -53,6 +53,11 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } + // Endpoint to leave a private channel. + rpc LeavePrivateChannel(LeavePrivateChannelRequest) returns (LeavePrivateChannelResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } + // Endpoint to create an invite. rpc CreateInvite(CreateInviteRequest) returns (CreateInviteResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index 36ccb77..ee38d4a 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -73,4 +73,12 @@ message JoinPrivateChannelRequest { uint64 channel_id = 1; } // Response type used in `JoinPrivateChannel` endpoint. -message JoinPrivateChannelResponse {} \ No newline at end of file +message JoinPrivateChannelResponse {} + +// Request type used in `LeavePrivateChannel` endpoint. +message LeavePrivateChannelRequest { + // The channel ID of the private channel to leave. + uint64 channel_id = 1; +} +// Response type used in `LeavePrivateChannel` endpoint. +message LeavePrivateChannelResponse {} \ No newline at end of file From 64ea59e6046932eca19e0d06775cb04fa59437cc Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Thu, 7 Apr 2022 22:45:32 +0300 Subject: [PATCH 62/68] refactor(chat): rename is_locked to is_dm, let create private channel join the user to dm if already joined before --- stable/chat/v1/chat.proto | 7 ++++++- stable/chat/v1/private_channel.proto | 11 ++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 773928d..5466dc0 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -19,6 +19,11 @@ service ChatService { // Endpoint to create a private channel. // + // If creating a direct message channel (`is_dm` is `true`), and you were in + // a DM channel with the user specified in `members` before, this method will + // join you to that same DM channel. + // + // // - The server should send an invite to the invitee(s) (specified in the request), // using the `UserInvited` postbox event if the invitee(s) are on another server. // - The receiving server should process this as follows: adding the invite to their pending @@ -31,7 +36,7 @@ service ChatService { // Endpoint to modify the member list of a private channel. // - // - This is only possible if the channel's `is_locked` property is set to false. + // - This is only possible if the channel's `is_dm` property is set to `false`. // - The server should send an invite to the added members (if any). // This should follow the same invite sending logic in `CreatePrivateChannel`. rpc UpdatePrivateChannelMembers(UpdatePrivateChannelMembersRequest) returns (UpdatePrivateChannelMembersResponse) { diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index ee38d4a..5aaa263 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -7,11 +7,11 @@ package protocol.chat.v1; message PrivateChannel { // The list of users that have access to this channel. repeated uint64 members = 1; - // Whether it is possible to add or remove users to/from this channel. + // Whether this is a direct message (1:1) channel or not. // - // If a channel is locked, the number of recipients is two (this is a direct message channel). + // If a channel is a direct message, the number of recipients is two. // It should not be possible to have multiple direct message channels between the same two users. - bool is_locked = 2; + bool is_dm = 2; } // An entry in the list of private channels. @@ -27,9 +27,10 @@ message CreatePrivateChannelRequest { // The list of users that have access to this channel. // // These users will be sent an invite. + // If `is_dm` is `true`, this must only have one member specified. repeated uint64 members = 1; - // Whether it is possible to add or remove users to/from this channel. - bool is_locked = 2; + // Whether this is a direct message (1:1) channel or not. + bool is_dm = 2; } // Response type used in `CreatePrivateChannel` endpoint. message CreatePrivateChannelResponse { From 772798bb1098ecdae7539c53085cddf63d28a83e Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Fri, 8 Apr 2022 02:03:02 +0300 Subject: [PATCH 63/68] refactor(chat): make another server id optional --- stable/chat/v1/guilds.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stable/chat/v1/guilds.proto b/stable/chat/v1/guilds.proto index 1f593ff..753cc78 100644 --- a/stable/chat/v1/guilds.proto +++ b/stable/chat/v1/guilds.proto @@ -70,7 +70,7 @@ message GuildListEntry { // Guild ID of this guild entry. uint64 guild_id = 1; // Server ID of the homeserver of this guild. - string server_id = 2; + optional string server_id = 2; } // A reason for why a user has left a guild. From b265a914c50f89e9148bf381e40aef131ba36eec Mon Sep 17 00:00:00 2001 From: Blusk Date: Sun, 10 Apr 2022 16:11:56 -0400 Subject: [PATCH 64/68] add private channel data to get rpc, add optional name --- stable/chat/v1/chat.proto | 8 ++++++-- stable/chat/v1/private_channel.proto | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 5466dc0..022bc83 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -35,7 +35,7 @@ service ChatService { } // Endpoint to modify the member list of a private channel. - // + // // - This is only possible if the channel's `is_dm` property is set to `false`. // - The server should send an invite to the added members (if any). // This should follow the same invite sending logic in `CreatePrivateChannel`. @@ -43,13 +43,17 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } + rpc UpdatePrivateChannelName(UpdatePrivateChannelNameRequest) returns (UpdatePrivateChannelNameResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } + // Endpoint to delete a private channel. // // Only the user who created the private channel can delete it. rpc DeletePrivateChannel(DeletePrivateChannelRequest) returns (DeletePrivateChannelResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } - + // Endpoint to join a private channel. // // - If the invite used is in a user's "pending invites" list, it should be diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index 5aaa263..ec37b08 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -8,10 +8,12 @@ message PrivateChannel { // The list of users that have access to this channel. repeated uint64 members = 1; // Whether this is a direct message (1:1) channel or not. - // + // // If a channel is a direct message, the number of recipients is two. // It should not be possible to have multiple direct message channels between the same two users. bool is_dm = 2; + // The name of the channel. + optional string name = 3; } // An entry in the list of private channels. @@ -20,6 +22,8 @@ message PrivateChannelListEntry { uint64 channel_id = 1; // The server ID of the homeserver of this private channel. string server_id = 2; + // The data for this channel. + PrivateChannel data = 3; } // Request type used in `CreatePrivateChannel` endpoint. @@ -31,6 +35,8 @@ message CreatePrivateChannelRequest { repeated uint64 members = 1; // Whether this is a direct message (1:1) channel or not. bool is_dm = 2; + // The name of the channel. + optional string name = 3; } // Response type used in `CreatePrivateChannel` endpoint. message CreatePrivateChannelResponse { @@ -52,6 +58,16 @@ message UpdatePrivateChannelMembersRequest { // Request type used in `UpdatePrivateChannelMembers` endpoint. message UpdatePrivateChannelMembersResponse {} +// Request type used in `UpdatePrivateChannelName` endpoint. +message UpdatePrivateChannelNameRequest { + // The channel ID of the private channel to update the name for. + uint64 channel_id = 1; + // The new name of the private channel. + optional string name = 2; +} +// Response type used in `UpdatePrivateChannelName` endpoint. +message UpdatePrivateChannelNameResponse {} + // Request type used in `DeletePrivateChannel` endpoint. message DeletePrivateChannelRequest { // The channel ID of the private channel to delete. From b47c27f330dd3e78d9f84133bf710d1265ea3fc0 Mon Sep 17 00:00:00 2001 From: Blusk Date: Sun, 10 Apr 2022 16:54:37 -0400 Subject: [PATCH 65/68] separate private channel fetching and its data --- stable/chat/v1/chat.proto | 4 ++++ stable/chat/v1/private_channel.proto | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 022bc83..3851fca 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -91,6 +91,10 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } + rpc GetPrivateChannelData(GetPrivateChannelDataRequest) returns (GetPrivateChannelDataResponse) { + option (harmonytypes.v1.metadata).requires_authentication = true; + } + // Endpoint to invite a user to a guild. rpc InviteUserToGuild(InviteUserToGuildRequest) returns (InviteUserToGuildResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index ec37b08..21297d4 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -20,10 +20,20 @@ message PrivateChannel { message PrivateChannelListEntry { // The channel ID of this channel list entry. uint64 channel_id = 1; - // The server ID of the homeserver of this private channel. - string server_id = 2; - // The data for this channel. - PrivateChannel data = 3; + // The server ID of the homeserver of this private channel. If local, this is not set. + optional string server_id = 2; +} + +// Request type used in `GetPrivateChannelData` endpoint. +message GetPrivateChannelDataRequest { + // The IDs of the channels to get data for. + repeated uint64 channel_ids = 1; +} + +// Response type used in `GetPrivateChannelData` endpoint. +message GetPrivateChannelDataResponse { + // The list of private channels. + repeated PrivateChannel channels = 1; } // Request type used in `CreatePrivateChannel` endpoint. From 598e41334be9cd0c997d7d128f811cee4e282188 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 11 Apr 2022 01:26:51 +0300 Subject: [PATCH 66/68] refactor(chat): GetPrivateChannelData -> GetPrivateChannel --- stable/chat/v1/chat.proto | 3 ++- stable/chat/v1/private_channel.proto | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index 3851fca..f611737 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -91,7 +91,8 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } - rpc GetPrivateChannelData(GetPrivateChannelDataRequest) returns (GetPrivateChannelDataResponse) { + // Endpoint to get private channel data. + rpc GetPrivateChannel(GetPrivateChannelRequest) returns (GetPrivateChannelResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index 21297d4..8defcf9 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -24,16 +24,16 @@ message PrivateChannelListEntry { optional string server_id = 2; } -// Request type used in `GetPrivateChannelData` endpoint. -message GetPrivateChannelDataRequest { +// Request type used in `GetPrivateChannel` endpoint. +message GetPrivateChannelRequest { // The IDs of the channels to get data for. repeated uint64 channel_ids = 1; } -// Response type used in `GetPrivateChannelData` endpoint. -message GetPrivateChannelDataResponse { +// Response type used in `GetPrivateChannel` endpoint. +message GetPrivateChannelResponse { // The list of private channels. - repeated PrivateChannel channels = 1; + map channels = 1; } // Request type used in `CreatePrivateChannel` endpoint. From e438b775cf4506db56a1020392b4268f5fe81834 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Mon, 11 Apr 2022 01:51:28 +0300 Subject: [PATCH 67/68] refactor(chat): dont use optional name in UpdatePrivateChannelNameRequest --- stable/chat/v1/private_channel.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index 8defcf9..9b13ccb 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -73,7 +73,9 @@ message UpdatePrivateChannelNameRequest { // The channel ID of the private channel to update the name for. uint64 channel_id = 1; // The new name of the private channel. - optional string name = 2; + // + // If this is an empty string, then the channel name will be unset. + string name = 2; } // Response type used in `UpdatePrivateChannelName` endpoint. message UpdatePrivateChannelNameResponse {} From a1319c7bdc38bff1e8797384bbee35051602690f Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 30 Apr 2022 20:31:58 +0300 Subject: [PATCH 68/68] feat(chat): consolidate UpdatePrivateChannel\* RPCs into one, add PrivateChannelUpdated stream event --- stable/chat/v1/chat.proto | 10 +++------- stable/chat/v1/private_channel.proto | 27 +++++++++++---------------- stable/chat/v1/stream.proto | 20 ++++++++++++++++---- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/stable/chat/v1/chat.proto b/stable/chat/v1/chat.proto index f611737..9f0fc9d 100644 --- a/stable/chat/v1/chat.proto +++ b/stable/chat/v1/chat.proto @@ -34,16 +34,12 @@ service ChatService { option (harmonytypes.v1.metadata).requires_authentication = true; } - // Endpoint to modify the member list of a private channel. + // Endpoint to update (add / remove members, change name) a private channel. // - // - This is only possible if the channel's `is_dm` property is set to `false`. + // - Changing members is only possible if the channel's `is_dm` property is set to `false`. // - The server should send an invite to the added members (if any). // This should follow the same invite sending logic in `CreatePrivateChannel`. - rpc UpdatePrivateChannelMembers(UpdatePrivateChannelMembersRequest) returns (UpdatePrivateChannelMembersResponse) { - option (harmonytypes.v1.metadata).requires_authentication = true; - } - - rpc UpdatePrivateChannelName(UpdatePrivateChannelNameRequest) returns (UpdatePrivateChannelNameResponse) { + rpc UpdatePrivateChannel(UpdatePrivateChannelRequest) returns (UpdatePrivateChannelResponse) { option (harmonytypes.v1.metadata).requires_authentication = true; } diff --git a/stable/chat/v1/private_channel.proto b/stable/chat/v1/private_channel.proto index 9b13ccb..13d63c2 100644 --- a/stable/chat/v1/private_channel.proto +++ b/stable/chat/v1/private_channel.proto @@ -5,7 +5,7 @@ package protocol.chat.v1; // PrivateChannel is a private channel between a list of users, independent of a guild. // It should be possible to use this channel for both text and voice communications. message PrivateChannel { - // The list of users that have access to this channel. + // The list of users that are in this channel. repeated uint64 members = 1; // Whether this is a direct message (1:1) channel or not. // @@ -38,7 +38,7 @@ message GetPrivateChannelResponse { // Request type used in `CreatePrivateChannel` endpoint. message CreatePrivateChannelRequest { - // The list of users that have access to this channel. + // The list of users that will have access to this channel. // // These users will be sent an invite. // If `is_dm` is `true`, this must only have one member specified. @@ -54,31 +54,26 @@ message CreatePrivateChannelResponse { uint64 channel_id = 1; } -// Request type used in `UpdatePrivateChannelMembers` endpoint. -message UpdatePrivateChannelMembersRequest { - // The channel ID of the private channel to update the member list for. +// Request type used in `UpdatePrivateChannel` endpoint. +message UpdatePrivateChannelRequest { + // The channel ID of the private channel to update. uint64 channel_id = 1; + // The list of member IDs of members to add to the private channel. // // These users will be sent an invite. repeated uint64 added_members = 2; // The list of member IDs of members to remove from the private channel. repeated uint64 removed_members = 3; -} -// Request type used in `UpdatePrivateChannelMembers` endpoint. -message UpdatePrivateChannelMembersResponse {} -// Request type used in `UpdatePrivateChannelName` endpoint. -message UpdatePrivateChannelNameRequest { - // The channel ID of the private channel to update the name for. - uint64 channel_id = 1; // The new name of the private channel. // - // If this is an empty string, then the channel name will be unset. - string name = 2; + // If this is specified and is an empty string, + // then the channel name will be unset. + optional string new_name = 4; } -// Response type used in `UpdatePrivateChannelName` endpoint. -message UpdatePrivateChannelNameResponse {} +// Request type used in `UpdatePrivateChannel` endpoint. +message UpdatePrivateChannelResponse {} // Request type used in `DeletePrivateChannel` endpoint. message DeletePrivateChannelRequest { diff --git a/stable/chat/v1/stream.proto b/stable/chat/v1/stream.proto index f404a61..c0af78c 100644 --- a/stable/chat/v1/stream.proto +++ b/stable/chat/v1/stream.proto @@ -515,6 +515,16 @@ message StreamEvent { uint64 user_id = 3; } + // Sent when a private channel is updated. + message PrivateChannelUpdated { + // The channel ID of the private channel that was deleted. + uint64 channel_id = 1; + // The new name of the private channel. + // + // If this is specified but is empty, then the name was unset. + optional string new_name = 2; + } + // Sent when a private channel is deleted. message PrivateChannelDeleted { // The channel ID of the private channel that was deleted. @@ -624,13 +634,15 @@ message StreamEvent { ReactionRemoved reaction_removed = 35; // Send the private channel deleted event. PrivateChannelDeleted private_channel_deleted = 36; + // Send the private channel updated event. + PrivateChannelUpdated private_channel_updated = 37; // Send the private channel added to list event. - PrivateChannelAddedToList private_channel_added_to_list = 37; + PrivateChannelAddedToList private_channel_added_to_list = 38; // Send the private channel removed from list event. - PrivateChannelRemovedFromList private_channel_removed_from_list = 38; + PrivateChannelRemovedFromList private_channel_removed_from_list = 39; // Send the user joined private channel event. - UserJoinedPrivateChannel user_joined_private_channel = 39; + UserJoinedPrivateChannel user_joined_private_channel = 40; // Send the user left private channel event. - UserLeftPrivateChannel user_left_private_channel = 40; + UserLeftPrivateChannel user_left_private_channel = 41; } }