twonly-app/memories.md
otsmr 96f8bc39d0
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
start with cloud backup
2026-07-19 20:24:14 +02:00

4.1 KiB

Memories API Documentation

The Memories feature allows users to back up their media to the server in an end-to-end encrypted format. The client-server communication happens primarily via the existing WebSocket connection using Protocol Buffers (client_to_server.proto and server_to_client.proto), while the actual binary file uploads/downloads use Amazon S3 presigned URLs via HTTP PUT/GET.

1. Checking Storage Quota

Before allowing a user to upload a memory, the client should query the user's current storage usage to ensure they haven't exceeded their limit.

Request:

// client_to_server.proto
message GetMemoriesUsage {}

Response:

// server_to_client.proto
message MemoriesUsage {
  int64 max_bytes = 1;
  int64 current_bytes = 2;
  int64 count = 3;
}

If current_bytes + the new file size > max_bytes, the client should block the upload and optionally prompt the user to upgrade their plan or free up space.

2. Uploading a Memory

Uploading a memory is a three-step process: requesting presigned URLs, performing the actual HTTP uploads, and finally confirming the upload.

Step 2.1: Request Upload URLs

The client requests permission to upload a new memory item, declaring its size and original capture date.

Request:

// client_to_server.proto
message RequestMemoriesUpload {
  int64 size = 1;          // Size of the FULL media file in bytes
  int64 original_date = 2; // Unix timestamp (in milliseconds/seconds depending on your app's standard) of when the media was originally created
}

Response:

// server_to_client.proto
message MemoriesUploadUrls {
  string media_id = 1;              // Unique identifier generated by the server for this memory
  string thumbnail_upload_url = 2;  // S3 presigned URL for uploading the encrypted thumbnail
  string full_upload_url = 3;       // S3 presigned URL for uploading the encrypted full media
}

Step 2.2: Perform HTTP Uploads

Using the URLs returned in Step 2.1, the client encrypts the thumbnail and the full media locally, and performs an HTTP PUT request to the respective URLs.

Note: The upload URLs are usually valid only for a short time (e.g. 15-60 minutes). Ensure you upload the data promptly.

Step 2.3: Confirm the Upload

After both the thumbnail and the full media are successfully uploaded via HTTP, the client must notify the server so it can mark the memory as fully uploaded and available.

Request:

// client_to_server.proto
message ConfirmMemoriesUpload {
  string media_id = 1; // The media_id obtained in Step 2.1
}

(The server will respond with an empty Ok::None(true) acknowledgment upon success).

3. Retrieving Memories (Pagination)

To display a gallery or timeline of backed-up memories, the client requests a paginated list of media items. The endpoint returns a descending list (newest first) based on the original date.

Request:

// client_to_server.proto
message GetMemoriesList {
  int64 offset_date = 1; // Unix timestamp to fetch memories older than this date (for pagination). Use MAX_INT64 for the first page.
  int64 limit = 2;       // Maximum number of items to return in this batch (e.g. 50)
}

Response:

// server_to_client.proto
message MemoriesList {
  repeated MediaItem items = 1;
}

message MediaItem {
  string media_id = 1;
  int64 original_date = 2;
  string thumbnail_download_url = 3; // S3 presigned URL to download the encrypted thumbnail
}

The client can immediately use the thumbnail_download_url to fetch and decrypt the thumbnail for the gallery view.

4. Downloading Full Media

When a user taps on a memory to view it in full screen, the client requests a temporary download URL for the full-resolution file.

Request:

// client_to_server.proto
message GetMemoriesUrl {
  string media_id = 1;
}

Response:

// server_to_client.proto
message MemoriesUrl {
  string full_download_url = 1; // S3 presigned URL to download the encrypted full media
}

The client can then perform an HTTP GET request to full_download_url, decrypt the payload locally, and display the full-resolution image or video.