messages.proto 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. syntax = "proto3";
  2. package chatto.api.v1;
  3. import "google/protobuf/field_mask.proto";
  4. import "buf/validate/validate.proto";
  5. import "chatto/api/v1/link_previews.proto";
  6. import "chatto/api/v1/message_types.proto";
  7. import "chatto/api/v1/reactions.proto";
  8. // Description supplied for one attachment in a new message.
  9. message MessageAttachmentDescriptionInput {
  10. // Required. Asset ID included in attachment_asset_ids on the same request.
  11. string asset_id = 1 [(buf.validate.field).string = {
  12. min_len: 1
  13. max_bytes: 15
  14. }];
  15. // Plain-text description with at most 1,000 Unicode characters. Trim outer
  16. // whitespace before sending. Chatto also trims outer whitespace, preserves
  17. // internal line breaks, and omits an empty result.
  18. string description = 2 [(buf.validate.field).string.max_len = 1000];
  19. }
  20. // Request to create a message in a room or thread.
  21. message CreateMessageRequest {
  22. // Field 8 was `link_preview`, a client-provided metadata message used before
  23. // CreateMessage accepted only server-issued link preview tokens.
  24. reserved 8;
  25. reserved "link_preview";
  26. // Field 9 was `attachments`, inline attachment bytes accepted before
  27. // AssetUploadService moved uploads into a dedicated chunked API.
  28. reserved 9;
  29. reserved "attachments";
  30. // Field 7 was `mention_confirmation_token`, used by a server-enforced large
  31. // mention confirmation flow before role mention confirmation became a
  32. // client-only composer affordance.
  33. reserved 7;
  34. reserved "mention_confirmation_token";
  35. // Required. Room where the message should be created.
  36. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  37. // Message body text. Required unless attachment_asset_ids is non-empty.
  38. string body = 2;
  39. // Completed room-scoped asset IDs uploaded by the caller and not yet attached
  40. // to a message. The server attaches them exclusively and atomically to this
  41. // message. At most 10 IDs may be supplied.
  42. repeated string attachment_asset_ids = 3 [(buf.validate.field).repeated = {
  43. max_items: 10
  44. items: {
  45. string: {
  46. min_len: 1
  47. max_bytes: 15
  48. }
  49. }
  50. }];
  51. // Event ID of the thread root message when posting a thread reply.
  52. string thread_root_event_id = 4;
  53. // Event ID this message replies to for attribution.
  54. string in_reply_to = 5;
  55. // True to also echo a thread reply into the main room timeline.
  56. bool also_send_to_channel = 6;
  57. // Short-lived token returned by FetchLinkPreview for the selected URL. The
  58. // server resolves the token to cached, server-fetched metadata during post.
  59. string link_preview_token = 10;
  60. // True to establish the new root message as a thread immediately. Requires
  61. // message.post (which includes thread posting). Cannot be combined with
  62. // thread_root_event_id.
  63. bool create_thread = 11;
  64. // Optional descriptions for assets in attachment_asset_ids. Asset IDs must
  65. // be unique in this list. At most one description can target each asset.
  66. repeated MessageAttachmentDescriptionInput attachment_descriptions = 12 [(buf.validate.field).repeated = {
  67. max_items: 10
  68. }];
  69. }
  70. // Result of creating a message.
  71. message CreateMessageResponse {
  72. // Field 2 was `mention_confirmation`, used by a server-enforced large
  73. // mention confirmation flow before role mention confirmation became a
  74. // client-only composer affordance.
  75. reserved 2;
  76. reserved "mention_confirmation";
  77. // Field 3 was `includes`, used before create responses were narrowed to the
  78. // generated message.
  79. reserved 3;
  80. reserved "includes";
  81. // Renderable message created by the request.
  82. Message message = 1;
  83. }
  84. // Request to patch a message. update_mask selects fields to apply or reset.
  85. // Fields outside the mask stay unchanged.
  86. message UpdateMessageRequest {
  87. // Required. Room containing the message.
  88. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  89. // Required. Event ID of the message to edit.
  90. string event_id = 2 [(buf.validate.field).string.min_len = 1];
  91. // New message body text. Select body in update_mask to change it.
  92. optional string body = 3 [(buf.validate.field).string.max_len = 10000];
  93. // For thread replies, whether a channel echo should exist after saving.
  94. // Select also_send_to_channel in update_mask to change it.
  95. optional bool also_send_to_channel = 4;
  96. // Editable fields to apply or reset: body, also_send_to_channel.
  97. // Omit to infer populated fields; * selects all editable fields. An explicit
  98. // empty mask is invalid. Unselected values are ignored. Selected absent values
  99. // reset the field to its default, subject to field validation.
  100. google.protobuf.FieldMask update_mask = 5;
  101. }
  102. // Result of editing a message.
  103. message UpdateMessageResponse {
  104. reserved 1;
  105. reserved "updated";
  106. // Field 3 was `includes`, used before update responses were narrowed to the
  107. // edited message.
  108. reserved 3;
  109. reserved "includes";
  110. // Renderable message after the edit.
  111. Message message = 2;
  112. }
  113. // Request to retract a message.
  114. message DeleteMessageRequest {
  115. // Required. Room containing the message.
  116. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  117. // Required. Event ID of the message to retract.
  118. string event_id = 2 [(buf.validate.field).string.min_len = 1];
  119. }
  120. // Result of retracting a message.
  121. message DeleteMessageResponse {
  122. reserved 1;
  123. reserved "deleted";
  124. }
  125. // Request to remove one attachment from a message.
  126. message DeleteAttachmentRequest {
  127. // Required. Room containing the message.
  128. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  129. // Required. Event ID of the message containing the attachment.
  130. string event_id = 2 [(buf.validate.field).string.min_len = 1];
  131. // Required. Attachment ID to remove from the message.
  132. string attachment_id = 3 [(buf.validate.field).string.min_len = 1];
  133. }
  134. // Result of removing one attachment from a message.
  135. message DeleteAttachmentResponse {
  136. reserved 1;
  137. reserved "deleted";
  138. }
  139. // Request to set or clear one attachment description.
  140. message SetAttachmentDescriptionRequest {
  141. // Required. Room containing the message.
  142. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  143. // Required. Message event containing the attachment, or its channel echo.
  144. string event_id = 2 [(buf.validate.field).string.min_len = 1];
  145. // Required. Attachment asset ID in the current message body.
  146. string attachment_id = 3 [(buf.validate.field).string.min_len = 1];
  147. // Replacement description with at most 1,000 Unicode characters. Trim outer
  148. // whitespace before sending. Chatto also trims outer whitespace and preserves
  149. // internal line breaks. An empty result clears the description.
  150. string description = 4 [(buf.validate.field).string.max_len = 1000];
  151. }
  152. // Result of setting or clearing an attachment description.
  153. message SetAttachmentDescriptionResponse {
  154. // Renderable message after the description change.
  155. Message message = 1;
  156. }
  157. // Request to remove the accepted link preview from a message.
  158. message DeleteLinkPreviewRequest {
  159. // Required. Room containing the message.
  160. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  161. // Required. Event ID of the message containing the link preview.
  162. string event_id = 2 [(buf.validate.field).string.min_len = 1];
  163. // Required. URL of the link preview to remove.
  164. string url = 3 [(buf.validate.field).string.min_len = 1];
  165. }
  166. // Result of removing a link preview from a message.
  167. message DeleteLinkPreviewResponse {
  168. reserved 1;
  169. reserved "deleted";
  170. }
  171. // Request to read one visible message.
  172. message GetMessageRequest {
  173. // Field 3 was `thumbnail`, used before custom attachment URL hydration moved
  174. // to AssetService.
  175. reserved 3;
  176. reserved "thumbnail";
  177. // Required. Room containing the message.
  178. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  179. // Required. Message event ID.
  180. string event_id = 2 [(buf.validate.field).string.min_len = 1];
  181. }
  182. // Response containing one renderable message.
  183. message GetMessageResponse {
  184. // Field 2 was `includes`, used before message read responses were narrowed
  185. // to messages.
  186. reserved 2;
  187. reserved "includes";
  188. // Renderable message.
  189. Message message = 1;
  190. }
  191. // Request to read many visible messages in one room.
  192. message BatchGetMessagesRequest {
  193. // Field 3 was `thumbnail`, used before custom attachment URL hydration moved
  194. // to AssetService.
  195. reserved 3;
  196. reserved "thumbnail";
  197. // Required. Room containing the messages.
  198. string room_id = 1 [(buf.validate.field).string.min_len = 1];
  199. // Required. Message event IDs. Missing, retracted, non-message, and
  200. // wrong-room event IDs are omitted from the response.
  201. repeated string event_ids = 2 [(buf.validate.field).repeated = {
  202. min_items: 1
  203. max_items: 100
  204. items: {
  205. string: {min_len: 1}
  206. }
  207. }];
  208. }
  209. // Response containing renderable messages.
  210. message BatchGetMessagesResponse {
  211. // Field 2 was `includes`, used before message read responses were narrowed
  212. // to messages.
  213. reserved 2;
  214. reserved "includes";
  215. // Renderable messages in first-seen request order.
  216. repeated Message messages = 1;
  217. }
  218. // Creates messages in room and thread timelines.
  219. service MessageService {
  220. // Lists all users with the requested reaction. Requires room membership and
  221. // permission to read the message. A missing reaction returns an empty page;
  222. // a missing or hidden message returns NOT_FOUND or PERMISSION_DENIED.
  223. rpc ListReactionUsers(ListReactionUsersRequest) returns (ListReactionUsersResponse);
  224. // Fetches and caches metadata for a composer URL. Authentication is required
  225. // to avoid exposing the preview fetcher as an unauthenticated network proxy.
  226. // Successful responses include a short-lived token accepted by CreateMessage.
  227. rpc FetchLinkPreview(FetchLinkPreviewRequest) returns (FetchLinkPreviewResponse);
  228. // Creates a message for the current user. The user must be a room member and
  229. // must have message.post for room messages. Thread replies require read
  230. // access and either message.post, message.post-in-thread, or
  231. // message.post-in-interactions with an existing interaction relationship.
  232. // Echoing a thread reply also requires message.echo and
  233. // message.post. The room's Threading Mode may automatically establish a root
  234. // thread or reject a thread placement that the mode does not allow.
  235. rpc CreateMessage(CreateMessageRequest) returns (CreateMessageResponse);
  236. // Edits a message body. Authors can edit their own messages within the edit
  237. // window. Effective message.manage permits edits at any time. Only the
  238. // message author can change channel echo state. Disabled rooms reject
  239. // creation of a new channel echo while allowing an existing echo to be
  240. // removed. Room membership is also required.
  241. // Edits require message.read or a matching thread relationship with
  242. // message.read-interactions.
  243. rpc UpdateMessage(UpdateMessageRequest) returns (UpdateMessageResponse);
  244. // Retracts a message. Authors can delete their own messages. Non-authors need
  245. // message.manage.
  246. rpc DeleteMessage(DeleteMessageRequest) returns (DeleteMessageResponse);
  247. // Removes one attachment from the author's own message.
  248. rpc DeleteAttachment(DeleteAttachmentRequest) returns (DeleteAttachmentResponse);
  249. // Sets or clears one attachment description. Authors can change descriptions
  250. // within the message edit window. Effective message.manage permits changes
  251. // at any time and to other users' messages. Room membership and message read
  252. // access are required.
  253. rpc SetAttachmentDescription(SetAttachmentDescriptionRequest) returns (SetAttachmentDescriptionResponse);
  254. // Removes the accepted link preview from the author's own message.
  255. rpc DeleteLinkPreview(DeleteLinkPreviewRequest) returns (DeleteLinkPreviewResponse);
  256. // Reads one renderable message, including current body, attachment metadata,
  257. // link preview, reactions, thread metadata, and pin state. Authentication
  258. // and room membership are required. Reads also require
  259. // message.read or a matching thread relationship with
  260. // message.read-interactions. Returns
  261. // NOT_FOUND when the event does not exist, is not a message, has been
  262. // retracted, or belongs to a different room.
  263. rpc GetMessage(GetMessageRequest) returns (GetMessageResponse);
  264. // Reads many renderable messages and their current pin state in one room.
  265. // Authentication and room membership are required. Reads also
  266. // require message.read or a matching thread relationship with
  267. // message.read-interactions. Missing,
  268. // retracted, non-message, wrong-room, and inaccessible event IDs are omitted.
  269. // Results preserve first-seen request order, and repeated event IDs are
  270. // de-duplicated.
  271. rpc BatchGetMessages(BatchGetMessagesRequest) returns (BatchGetMessagesResponse);
  272. // Adds a reaction to a message. The user must be a room member and have
  273. // message.react. Reactions also require message.read or a matching thread
  274. // relationship with message.read-interactions.
  275. rpc AddReaction(AddReactionRequest) returns (AddReactionResponse);
  276. // Removes a reaction from a message. The user must be a room member and have
  277. // message.react. Reactions also require message.read or a matching thread
  278. // relationship with message.read-interactions.
  279. rpc RemoveReaction(RemoveReactionRequest) returns (RemoveReactionResponse);
  280. }