syntax = "proto3"; package memos.api.v1; import "api/v1/attachment_service.proto"; import "api/v1/common.proto"; import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v1"; service MemoService { // CreateMemo creates a memo. rpc CreateMemo(CreateMemoRequest) returns (Memo) { option (google.api.http) = { post: "/api/v1/memos" body: "memo" }; option (google.api.method_signature) = "memo"; } // ListMemos lists memos with pagination and filter. rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) { option (google.api.http) = {get: "/api/v1/memos"}; option (google.api.method_signature) = ""; } // GetMemo gets a memo. rpc GetMemo(GetMemoRequest) returns (Memo) { option (google.api.http) = {get: "/api/v1/{name=memos/*}"}; option (google.api.method_signature) = "name"; } // UpdateMemo updates a memo. rpc UpdateMemo(UpdateMemoRequest) returns (Memo) { option (google.api.http) = { patch: "/api/v1/{memo.name=memos/*}" body: "memo" }; option (google.api.method_signature) = "memo,update_mask"; } // DeleteMemo deletes a memo. rpc DeleteMemo(DeleteMemoRequest) returns (google.protobuf.Empty) { option (google.api.http) = {delete: "/api/v1/{name=memos/*}"}; option (google.api.method_signature) = "name"; } // SetMemoAttachments sets attachments for a memo. rpc SetMemoAttachments(SetMemoAttachmentsRequest) returns (google.protobuf.Empty) { option (google.api.http) = { patch: "/api/v1/{name=memos/*}/attachments" body: "*" }; option (google.api.method_signature) = "name"; } // ListMemoAttachments lists attachments for a memo. rpc ListMemoAttachments(ListMemoAttachmentsRequest) returns (ListMemoAttachmentsResponse) { option (google.api.http) = {get: "/api/v1/{name=memos/*}/attachments"}; option (google.api.method_signature) = "name"; } // SetMemoRelations sets relations for a memo. rpc SetMemoRelations(SetMemoRelationsRequest) returns (google.protobuf.Empty) { option (google.api.http) = { patch: "/api/v1/{name=memos/*}/relations" body: "*" }; option (google.api.method_signature) = "name"; } // ListMemoRelations lists relations for a memo. rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) { option (google.api.http) = {get: "/api/v1/{name=memos/*}/relations"}; option (google.api.method_signature) = "name"; } // CreateMemoComment creates a comment for a memo. rpc CreateMemoComment(CreateMemoCommentRequest) returns (Memo) { option (google.api.http) = { post: "/api/v1/{name=memos/*}/comments" body: "comment" }; option (google.api.method_signature) = "name,comment"; } // ListMemoComments lists comments for a memo. rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) { option (google.api.http) = {get: "/api/v1/{name=memos/*}/comments"}; option (google.api.method_signature) = "name"; } // ListMemoReactions lists reactions for a memo. rpc ListMemoReactions(ListMemoReactionsRequest) returns (ListMemoReactionsResponse) { option (google.api.http) = {get: "/api/v1/{name=memos/*}/reactions"}; option (google.api.method_signature) = "name"; } // UpsertMemoReaction upserts a reaction for a memo. rpc UpsertMemoReaction(UpsertMemoReactionRequest) returns (Reaction) { option (google.api.http) = { post: "/api/v1/{name=memos/*}/reactions" body: "*" }; option (google.api.method_signature) = "name"; } // DeleteMemoReaction deletes a reaction for a memo. rpc DeleteMemoReaction(DeleteMemoReactionRequest) returns (google.protobuf.Empty) { option (google.api.http) = {delete: "/api/v1/{name=memos/*/reactions/*}"}; option (google.api.method_signature) = "name"; } // CreateMemoShare creates a share link for a memo. Requires authentication as the memo creator. rpc CreateMemoShare(CreateMemoShareRequest) returns (MemoShare) { option (google.api.http) = { post: "/api/v1/{parent=memos/*}/shares" body: "memo_share" }; option (google.api.method_signature) = "parent,memo_share"; } // ListMemoShares lists all share links for a memo. Requires authentication as the memo creator. rpc ListMemoShares(ListMemoSharesRequest) returns (ListMemoSharesResponse) { option (google.api.http) = {get: "/api/v1/{parent=memos/*}/shares"}; option (google.api.method_signature) = "parent"; } // DeleteMemoShare revokes a share link. Requires authentication as the memo creator. rpc DeleteMemoShare(DeleteMemoShareRequest) returns (google.protobuf.Empty) { option (google.api.http) = {delete: "/api/v1/{name=memos/*/shares/*}"}; option (google.api.method_signature) = "name"; } // GetMemoByShare resolves a share token to its memo. No authentication required. // Returns NOT_FOUND if the token is invalid or expired. rpc GetMemoByShare(GetMemoByShareRequest) returns (Memo) { option (google.api.http) = {get: "/api/v1/shares/{share_id}"}; } // GetLinkMetadata gets metadata for a link. rpc GetLinkMetadata(GetLinkMetadataRequest) returns (LinkMetadata) { option (google.api.http) = {get: "/api/v1/memos/-/linkMetadata"}; } // BatchGetLinkMetadata gets metadata for links. rpc BatchGetLinkMetadata(BatchGetLinkMetadataRequest) returns (BatchGetLinkMetadataResponse) { option (google.api.http) = { post: "/api/v1/memos/-/linkMetadata:batchGet" body: "*" }; } } enum Visibility { VISIBILITY_UNSPECIFIED = 0; PRIVATE = 1; PROTECTED = 2; PUBLIC = 3; } message Reaction { option (google.api.resource) = { type: "memos.api.v1/Reaction" pattern: "memos/{memo}/reactions/{reaction}" name_field: "name" singular: "reaction" plural: "reactions" }; // The resource name of the reaction. // Format: memos/{memo}/reactions/{reaction} string name = 1 [ (google.api.field_behavior) = OUTPUT_ONLY, (google.api.field_behavior) = IDENTIFIER ]; // The resource name of the creator. // Format: users/{user} string creator = 2 [ (google.api.field_behavior) = OUTPUT_ONLY, (google.api.resource_reference) = {type: "memos.api.v1/User"} ]; // The resource name of the content. // For memo reactions, this should be the memo's resource name. // Format: memos/{memo} string content_id = 3 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Required. The type of reaction (e.g., "👍", "❤️", "😄"). string reaction_type = 4 [(google.api.field_behavior) = REQUIRED]; // Output only. The creation timestamp. google.protobuf.Timestamp create_time = 5 [(google.api.field_behavior) = OUTPUT_ONLY]; } message Memo { option (google.api.resource) = { type: "memos.api.v1/Memo" pattern: "memos/{memo}" name_field: "name" singular: "memo" plural: "memos" }; // The resource name of the memo. // Format: memos/{memo}, memo is the user defined id or uuid. string name = 1 [(google.api.field_behavior) = IDENTIFIER]; // The state of the memo. State state = 2 [(google.api.field_behavior) = REQUIRED]; // The name of the creator. // Format: users/{user} string creator = 3 [ (google.api.field_behavior) = OUTPUT_ONLY, (google.api.resource_reference) = {type: "memos.api.v1/User"} ]; // The creation timestamp. // If not set on creation, the server will set it to the current time. google.protobuf.Timestamp create_time = 4 [(google.api.field_behavior) = OPTIONAL]; // The last update timestamp. // If not set on creation, the server will set it to the current time. google.protobuf.Timestamp update_time = 5 [(google.api.field_behavior) = OPTIONAL]; reserved 6; reserved "display_time"; // Required. The content of the memo in Markdown format. string content = 7 [(google.api.field_behavior) = REQUIRED]; // The visibility of the memo. Visibility visibility = 9 [(google.api.field_behavior) = REQUIRED]; // Output only. The tags extracted from the content. repeated string tags = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; // Whether the memo is pinned. bool pinned = 11 [(google.api.field_behavior) = OPTIONAL]; // Optional. The attachments of the memo. repeated Attachment attachments = 12 [(google.api.field_behavior) = OPTIONAL]; // Optional. The relations of the memo. repeated MemoRelation relations = 13 [(google.api.field_behavior) = OPTIONAL]; // Output only. The reactions to the memo. repeated Reaction reactions = 14 [(google.api.field_behavior) = OUTPUT_ONLY]; // Output only. The computed properties of the memo. Property property = 15 [(google.api.field_behavior) = OUTPUT_ONLY]; // Output only. The name of the parent memo. // Format: memos/{memo} optional string parent = 16 [ (google.api.field_behavior) = OUTPUT_ONLY, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Output only. The snippet of the memo content. Plain text only. string snippet = 17 [(google.api.field_behavior) = OUTPUT_ONLY]; // Optional. The location of the memo. optional Location location = 18 [(google.api.field_behavior) = OPTIONAL]; // Computed properties of a memo. message Property { bool has_link = 1; bool has_task_list = 2; bool has_code = 3; bool has_incomplete_tasks = 4; // The title extracted from the first H1 heading, if present. string title = 5; } } message Location { // A placeholder text for the location. string placeholder = 1 [(google.api.field_behavior) = OPTIONAL]; // The latitude of the location. double latitude = 2 [(google.api.field_behavior) = OPTIONAL]; // The longitude of the location. double longitude = 3 [(google.api.field_behavior) = OPTIONAL]; } message CreateMemoRequest { // Required. The memo to create. Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; // Optional. The memo ID to use for this memo. // If empty, a unique ID will be generated. string memo_id = 2 [(google.api.field_behavior) = OPTIONAL]; } message ListMemosRequest { // Optional. The maximum number of memos to return. // The service may return fewer than this value. // If unspecified, at most 50 memos will be returned. // The maximum value is 1000; values above 1000 will be coerced to 1000. int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; // Optional. A page token, received from a previous `ListMemos` call. // Provide this to retrieve the subsequent page. string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; // Optional. The state of the memos to list. // Default to `NORMAL`. Set to `ARCHIVED` to list archived memos. State state = 3 [(google.api.field_behavior) = OPTIONAL]; // Optional. The order to sort results by. // Default to "create_time desc". // Supports comma-separated list of fields following AIP-132. // Example: "pinned desc, create_time desc" or "update_time asc" // Supported fields: pinned, create_time, update_time, name string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; // Optional. Filter to apply to the list results. // Filter is a CEL expression to filter memos. // Refer to `Shortcut.filter`. string filter = 5 [(google.api.field_behavior) = OPTIONAL]; // Optional. If true, show deleted memos in the response. bool show_deleted = 6 [(google.api.field_behavior) = OPTIONAL]; } message ListMemosResponse { // The list of memos. repeated Memo memos = 1; // A token that can be sent as `page_token` to retrieve the next page. // If this field is omitted, there are no subsequent pages. string next_page_token = 2; } message GetMemoRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; } message UpdateMemoRequest { // Required. The memo to update. // The `name` field is required. Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; // Required. The list of fields to update. google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; } message DeleteMemoRequest { // Required. The resource name of the memo to delete. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Optional. If set to true, the memo will be deleted even if it has associated data. bool force = 2 [(google.api.field_behavior) = OPTIONAL]; } message SetMemoAttachmentsRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Required. The attachments to set for the memo. repeated Attachment attachments = 2 [(google.api.field_behavior) = REQUIRED]; } message ListMemoAttachmentsRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Optional. The maximum number of attachments to return. int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; // Optional. A page token for pagination. string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; } message ListMemoAttachmentsResponse { // The list of attachments. repeated Attachment attachments = 1; // A token for the next page of results. string next_page_token = 2; } message MemoRelation { // The memo in the relation. Memo memo = 1 [(google.api.field_behavior) = REQUIRED]; // The related memo. Memo related_memo = 2 [(google.api.field_behavior) = REQUIRED]; // The type of the relation. enum Type { TYPE_UNSPECIFIED = 0; REFERENCE = 1; COMMENT = 2; } Type type = 3 [(google.api.field_behavior) = REQUIRED]; // Memo reference in relations. message Memo { // The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Output only. The snippet of the memo content. Plain text only. string snippet = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; } } message SetMemoRelationsRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Required. The relations to set for the memo. repeated MemoRelation relations = 2 [(google.api.field_behavior) = REQUIRED]; } message ListMemoRelationsRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Optional. The maximum number of relations to return. int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; // Optional. A page token for pagination. string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; } message ListMemoRelationsResponse { // The list of relations. repeated MemoRelation relations = 1; // A token for the next page of results. string next_page_token = 2; } message CreateMemoCommentRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Required. The comment to create. Memo comment = 2 [(google.api.field_behavior) = REQUIRED]; // Optional. The comment ID to use. string comment_id = 3 [(google.api.field_behavior) = OPTIONAL]; } message ListMemoCommentsRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Optional. The maximum number of comments to return. int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; // Optional. A page token for pagination. string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; // Optional. The order to sort results by. string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; } message ListMemoCommentsResponse { // The list of comment memos. repeated Memo memos = 1; // A token for the next page of results. string next_page_token = 2; // The total count of comments. int32 total_size = 3; } message ListMemoReactionsRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Optional. The maximum number of reactions to return. int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; // Optional. A page token for pagination. string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; } message ListMemoReactionsResponse { // The list of reactions. repeated Reaction reactions = 1; // A token for the next page of results. string next_page_token = 2; // The total count of reactions. int32 total_size = 3; } message UpsertMemoReactionRequest { // Required. The resource name of the memo. // Format: memos/{memo} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Required. The reaction to upsert. Reaction reaction = 2 [(google.api.field_behavior) = REQUIRED]; } message DeleteMemoReactionRequest { // Required. The resource name of the reaction to delete. // Format: memos/{memo}/reactions/{reaction} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Reaction"} ]; } // MemoShare is an access grant that permits read-only access to a memo via an opaque bearer token. message MemoShare { option (google.api.resource) = { type: "memos.api.v1/MemoShare" pattern: "memos/{memo}/shares/{share}" singular: "share" plural: "shares" }; // The resource name of the share. Format: memos/{memo}/shares/{share} // The {share} segment is the opaque token used in the share URL. string name = 1 [(google.api.field_behavior) = IDENTIFIER]; // Output only. When this share link was created. google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; // Optional. When set, the share link stops working after this time. // If unset, the link never expires. optional google.protobuf.Timestamp expire_time = 3 [(google.api.field_behavior) = OPTIONAL]; } message CreateMemoShareRequest { // Required. The resource name of the memo to share. // Format: memos/{memo} string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; // Required. The share to create. MemoShare memo_share = 2 [(google.api.field_behavior) = REQUIRED]; } message ListMemoSharesRequest { // Required. The resource name of the memo. // Format: memos/{memo} string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/Memo"} ]; } message ListMemoSharesResponse { // The list of share links. repeated MemoShare memo_shares = 1; } message DeleteMemoShareRequest { // Required. The resource name of the share to delete. // Format: memos/{memo}/shares/{share} string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = {type: "memos.api.v1/MemoShare"} ]; } message GetMemoByShareRequest { // Required. The share token extracted from the share URL (/s/{share_id}). string share_id = 1 [(google.api.field_behavior) = REQUIRED]; } message GetLinkMetadataRequest { // Required. The link URL. string url = 1 [(google.api.field_behavior) = REQUIRED]; } message BatchGetLinkMetadataRequest { // Required. The link URLs. repeated string urls = 1 [(google.api.field_behavior) = REQUIRED]; } message BatchGetLinkMetadataResponse { // The link metadata list, in the same order as the input URLs. repeated LinkMetadata link_metadata = 1; } message LinkMetadata { // The original link URL. string url = 1; // The link title. string title = 2; // The link description. string description = 3; // The link image URL. string image = 4; }