Jelajahi Sumber

Track Chatto 0.4.9

Chatto HQ jumped from 0.4.3 to 0.4.9. Per the version-tracks-Chatto
policy, chattolib bumps to match.

Upstream proto deltas:

- Additive: Message.deleted_at (Timestamp). Surfaced on the Message
  dataclass and its parser.
- Additive: GetSystemInfoResponse.asset_cleanup (AdminAssetCleanupStatus)
  with a new AdminAssetCleanupHealth enum. Passes through the existing
  raw-dict admin_get_system_info() return; no client code change.
- Metadata-only: DeleteAvatar, DeleteCustomStatus, DismissNotification,
  Unsubscribe, and GetServer now advertise idempotency_level. No wire
  change.
- Server-side validation: CreateMessageRequest.attachment_asset_ids
  now capped at 10 items with per-item length limits. Server-enforced;
  no client change.

Live-verified against chat.chatto.run (0.4.9) with the RoboChatto
account: login, me(), list_rooms(), get_motd() all decode correctly.
ruff + mypy --strict + pytest all clean.
TheCodemancer 3 bulan lalu
induk
melakukan
eae1a44b2e

+ 28 - 0
.beans/chattolib-5ggo--update-chattolib-to-chatto-049.md

@@ -0,0 +1,28 @@
+---
+# chattolib-5ggo
+title: Update chattolib to Chatto 0.4.9
+status: completed
+type: task
+priority: high
+created_at: 2026-07-12T23:46:37Z
+updated_at: 2026-07-12T23:48:14Z
+---
+
+Chatto HQ is now serving 0.4.9. Regenerate proto bindings from upstream, diff the API surface for breaking or additive changes, adapt the client if needed, bump chattolib to 0.4.9, run the full check + live-verify, publish, and push.
+
+## Summary of Changes
+Regenerated proto bindings from upstream. Delta from 0.4.3:
+
+**Additive fields**
+- `Message.deleted_at` (google.protobuf.Timestamp) — surface added to the `Message` dataclass and its `.parse()` classmethod.
+- `GetSystemInfoResponse.asset_cleanup` (AdminAssetCleanupStatus) with a new AdminAssetCleanupHealth enum. Passes through the existing raw-dict `admin_get_system_info()` return; no code change needed.
+
+**Metadata-only**
+- Several RPCs now advertise `idempotency_level`: `DeleteAvatar`, `DeleteCustomStatus`, `DismissNotification`, `Unsubscribe`, `GetServer`. No wire change.
+
+**Server-side validation tightening**
+- `CreateMessageRequest.attachment_asset_ids` now capped at 10 items with per-item length constraints. Server-enforced; no client change.
+
+Bumped `pyproject.toml` from `0.4.3` to `0.4.9`. `ruff` + `mypy --strict` + `pytest` (48 passed, 4 skipped) all clean.
+
+Live-verified against Chatto HQ (0.4.9): login, viewer, list_rooms, get_motd all decode correctly.

+ 14 - 12
proto/buf/validate/validate.proto

@@ -88,7 +88,7 @@ extend google.protobuf.FieldOptions {
   //
   //
   // ```proto
   // ```proto
   // extend buf.validate.Int32Rules {
   // extend buf.validate.Int32Rules {
-  //   bool is_zero [(buf.validate.predefined).cel = {
+  //   bool is_zero = 1001 [(buf.validate.predefined).cel = {
   //     id: "int32.is_zero",
   //     id: "int32.is_zero",
   //     message: "must be zero",
   //     message: "must be zero",
   //     expression: "!rule || this == 0",
   //     expression: "!rule || this == 0",
@@ -1747,7 +1747,7 @@ message UInt64Rules {
   // message MyUInt64 {
   // message MyUInt64 {
   //   uint64 value = 1 [
   //   uint64 value = 1 [
   //     (buf.validate.field).uint64.example = 1,
   //     (buf.validate.field).uint64.example = 1,
-  //     (buf.validate.field).uint64.example = -10
+  //     (buf.validate.field).uint64.example = 10
   //   ];
   //   ];
   // }
   // }
   // ```
   // ```
@@ -3028,8 +3028,8 @@ message BoolRules {
   // ```proto
   // ```proto
   // message MyBool {
   // message MyBool {
   //   bool value = 1 [
   //   bool value = 1 [
-  //     (buf.validate.field).bool.example = 1,
-  //     (buf.validate.field).bool.example = 2
+  //     (buf.validate.field).bool.example = true,
+  //     (buf.validate.field).bool.example = false
   //   ];
   //   ];
   // }
   // }
   // ```
   // ```
@@ -3239,7 +3239,7 @@ message StringRules {
   // ```proto
   // ```proto
   // message MyString {
   // message MyString {
   //   // must be in list ["apple", "banana"]
   //   // must be in list ["apple", "banana"]
-  //   string value = 1 [(buf.validate.field).string.in = "apple", (buf.validate.field).string.in = "banana"];
+  //   string value = 1 [(buf.validate.field).string = { in: ["apple", "banana"] }];
   // }
   // }
   // ```
   // ```
   repeated string in = 10 [(predefined).cel = {
   repeated string in = 10 [(predefined).cel = {
@@ -3253,7 +3253,7 @@ message StringRules {
   // ```proto
   // ```proto
   // message MyString {
   // message MyString {
   //   // value must not be in list ["orange", "grape"]
   //   // value must not be in list ["orange", "grape"]
-  //   string value = 1 [(buf.validate.field).string.not_in = "orange", (buf.validate.field).string.not_in = "grape"];
+  //   string value = 1 [(buf.validate.field).string = { not_in: ["orange", "grape"] }];
   // }
   // }
   // ```
   // ```
   repeated string not_in = 11 [(predefined).cel = {
   repeated string not_in = 11 [(predefined).cel = {
@@ -4025,7 +4025,7 @@ message BytesRules {
   // ```proto
   // ```proto
   // message MyBytes {
   // message MyBytes {
   //   // value must in ["\x01\x02", "\x02\x03", "\x03\x04"]
   //   // value must in ["\x01\x02", "\x02\x03", "\x03\x04"]
-  //   optional bytes value = 1 [(buf.validate.field).bytes.in = {"\x01\x02", "\x02\x03", "\x03\x04"}];
+  //   optional bytes value = 1 [(buf.validate.field).bytes = { in: ["\x01\x02", "\x02\x03", "\x03\x04"] }];
   // }
   // }
   // ```
   // ```
   repeated bytes in = 8 [(predefined).cel = {
   repeated bytes in = 8 [(predefined).cel = {
@@ -4041,7 +4041,7 @@ message BytesRules {
   // ```proto
   // ```proto
   // message MyBytes {
   // message MyBytes {
   //   // value must not in ["\x01\x02", "\x02\x03", "\x03\x04"]
   //   // value must not in ["\x01\x02", "\x02\x03", "\x03\x04"]
-  //   optional bytes value = 1 [(buf.validate.field).bytes.not_in = {"\x01\x02", "\x02\x03", "\x03\x04"}];
+  //   optional bytes value = 1 [(buf.validate.field).bytes = { not_in: ["\x01\x02", "\x02\x03", "\x03\x04"] }];
   // }
   // }
   // ```
   // ```
   repeated bytes not_in = 9 [(predefined).cel = {
   repeated bytes not_in = 9 [(predefined).cel = {
@@ -4258,8 +4258,10 @@ message EnumRules {
   // }
   // }
   //
   //
   // message MyMessage {
   // message MyMessage {
+  //   MyEnum value = 1 [
   //     (buf.validate.field).enum.example = 1,
   //     (buf.validate.field).enum.example = 1,
   //     (buf.validate.field).enum.example = 2
   //     (buf.validate.field).enum.example = 2
+  //   ];
   // }
   // }
   // ```
   // ```
   repeated int32 example = 5 [(predefined).cel = {
   repeated int32 example = 5 [(predefined).cel = {
@@ -4647,7 +4649,7 @@ message DurationRules {
   // message MyDuration {
   // message MyDuration {
   //   google.protobuf.Duration value = 1 [
   //   google.protobuf.Duration value = 1 [
   //     (buf.validate.field).duration.example = { seconds: 1 },
   //     (buf.validate.field).duration.example = { seconds: 1 },
-  //     (buf.validate.field).duration.example = { seconds: 2 },
+  //     (buf.validate.field).duration.example = { seconds: 2 }
   //   ];
   //   ];
   // }
   // }
   // ```
   // ```
@@ -4727,7 +4729,7 @@ message FieldMaskRules {
   // message MyFieldMask {
   // message MyFieldMask {
   //   google.protobuf.FieldMask value = 1 [
   //   google.protobuf.FieldMask value = 1 [
   //     (buf.validate.field).field_mask.example = { paths: ["a", "b"] },
   //     (buf.validate.field).field_mask.example = { paths: ["a", "b"] },
-  //     (buf.validate.field).field_mask.example = { paths: ["c.a", "d"] },
+  //     (buf.validate.field).field_mask.example = { paths: ["c.a", "d"] }
   //   ];
   //   ];
   // }
   // }
   // ```
   // ```
@@ -4938,7 +4940,7 @@ message TimestampRules {
   // message MyTimestamp {
   // message MyTimestamp {
   //   google.protobuf.Timestamp value = 1 [
   //   google.protobuf.Timestamp value = 1 [
   //     (buf.validate.field).timestamp.example = { seconds: 1672444800 },
   //     (buf.validate.field).timestamp.example = { seconds: 1672444800 },
-  //     (buf.validate.field).timestamp.example = { seconds: 1672531200 },
+  //     (buf.validate.field).timestamp.example = { seconds: 1672531200 }
   //   ];
   //   ];
   // }
   // }
   // ```
   // ```
@@ -5038,7 +5040,7 @@ message Violation {
   //   bool b = 2 [(buf.validate.field).cel = {
   //   bool b = 2 [(buf.validate.field).cel = {
   //     id: "custom_rule",
   //     id: "custom_rule",
   //     expression: "!this ? 'b must be true': ''"
   //     expression: "!this ? 'b must be true': ''"
-  //   }]
+  //   }];
   // }
   // }
   // ```
   // ```
   //
   //

+ 40 - 0
proto/chatto/admin/v1/diagnostics.proto

@@ -2,6 +2,8 @@ syntax = "proto3";
 
 
 package chatto.admin.v1;
 package chatto.admin.v1;
 
 
+import "google/protobuf/timestamp.proto";
+
 // Request to read owner-only server diagnostics.
 // Request to read owner-only server diagnostics.
 message GetSystemInfoRequest {}
 message GetSystemInfoRequest {}
 
 
@@ -11,6 +13,44 @@ message GetSystemInfoResponse {
   AdminSystemInfo system_info = 1;
   AdminSystemInfo system_info = 1;
   // Event-sourced projection health and memory estimates.
   // Event-sourced projection health and memory estimates.
   repeated AdminProjectionState projections = 2;
   repeated AdminProjectionState projections = 2;
+  // Recoverable physical deletion worker health.
+  AdminAssetCleanupStatus asset_cleanup = 3;
+}
+
+// Current health of recoverable message-owned asset deletion.
+message AdminAssetCleanupStatus {
+  // Operator-facing worker state derived from lease and heartbeat state.
+  AdminAssetCleanupHealth health = 1;
+  // Deletion effects currently waiting for a successful retry.
+  int64 pending_count = 2;
+  // Creation time of the oldest pending deletion, when known.
+  google.protobuf.Timestamp oldest_pending_at = 3;
+  // Whether the elected worker is currently running a cleanup pass.
+  bool pass_in_progress = 4;
+  // Completion time of the most recent pass.
+  google.protobuf.Timestamp last_pass_at = 5;
+  // Completion time of the most recent fully successful pass.
+  google.protobuf.Timestamp last_successful_pass_at = 6;
+  // Time of the latest elected-worker heartbeat.
+  google.protobuf.Timestamp updated_at = 7;
+  // Whether the most recent completed pass had one or more failures.
+  bool last_pass_failed = 8;
+  // Global EVT sequence through which deletion facts were inspected.
+  string last_inspected_sequence = 9;
+  // Current latest global EVT sequence matching asset deletion facts.
+  string latest_deletion_sequence = 10;
+}
+
+// Operator-facing state for the elected asset cleanup worker.
+enum AdminAssetCleanupHealth {
+  ADMIN_ASSET_CLEANUP_HEALTH_UNSPECIFIED = 0;
+  ADMIN_ASSET_CLEANUP_HEALTH_INACTIVE = 1;
+  ADMIN_ASSET_CLEANUP_HEALTH_INITIALIZING = 2;
+  ADMIN_ASSET_CLEANUP_HEALTH_HEALTHY = 3;
+  ADMIN_ASSET_CLEANUP_HEALTH_RETRYING = 4;
+  ADMIN_ASSET_CLEANUP_HEALTH_STALLED = 5;
+  // Cleanup diagnostics could not be read; other system diagnostics remain valid.
+  ADMIN_ASSET_CLEANUP_HEALTH_UNAVAILABLE = 6;
 }
 }
 
 
 // Broker and application diagnostics shown on the server admin system page.
 // Broker and application diagnostics shown on the server admin system page.

+ 7 - 2
proto/chatto/api/v1/account.proto

@@ -9,6 +9,7 @@ import "chatto/api/v1/presence.proto";
 import "chatto/api/v1/user_status.proto";
 import "chatto/api/v1/user_status.proto";
 import "chatto/api/v1/users.proto";
 import "chatto/api/v1/users.proto";
 import "chatto/api/v1/viewer.proto";
 import "chatto/api/v1/viewer.proto";
+import "google/protobuf/descriptor.proto";
 
 
 // Request to update the authenticated user's profile. At least one field must
 // Request to update the authenticated user's profile. At least one field must
 // be present.
 // be present.
@@ -119,7 +120,9 @@ service MyAccountService {
   // Uploads and sets the authenticated user's avatar.
   // Uploads and sets the authenticated user's avatar.
   rpc UploadAvatar(UploadAvatarRequest) returns (UploadAvatarResponse);
   rpc UploadAvatar(UploadAvatarRequest) returns (UploadAvatarResponse);
   // Deletes the authenticated user's avatar. The call is idempotent.
   // Deletes the authenticated user's avatar. The call is idempotent.
-  rpc DeleteAvatar(DeleteAvatarRequest) returns (DeleteAvatarResponse);
+  rpc DeleteAvatar(DeleteAvatarRequest) returns (DeleteAvatarResponse) {
+    option idempotency_level = IDEMPOTENT;
+  }
   // Updates or adds the authenticated user's password.
   // Updates or adds the authenticated user's password.
   rpc UpdatePassword(UpdatePasswordRequest) returns (UpdatePasswordResponse);
   rpc UpdatePassword(UpdatePasswordRequest) returns (UpdatePasswordResponse);
   // Updates the authenticated user's display preferences.
   // Updates the authenticated user's display preferences.
@@ -142,7 +145,9 @@ service MyAccountService {
   rpc UpdateCustomStatus(UpdateCustomStatusRequest) returns (UpdateCustomStatusResponse);
   rpc UpdateCustomStatus(UpdateCustomStatusRequest) returns (UpdateCustomStatusResponse);
   // Deletes the current user's custom status. The call is idempotent and returns
   // Deletes the current user's custom status. The call is idempotent and returns
   // the resulting empty status state.
   // the resulting empty status state.
-  rpc DeleteCustomStatus(DeleteCustomStatusRequest) returns (DeleteCustomStatusResponse);
+  rpc DeleteCustomStatus(DeleteCustomStatusRequest) returns (DeleteCustomStatusResponse) {
+    option idempotency_level = IDEMPOTENT;
+  }
   // Issues a short-lived token used to confirm self-deletion.
   // Issues a short-lived token used to confirm self-deletion.
   rpc RequestAccountDeletion(RequestAccountDeletionRequest) returns (RequestAccountDeletionResponse);
   rpc RequestAccountDeletion(RequestAccountDeletionRequest) returns (RequestAccountDeletionResponse);
   // Permanently deletes the authenticated account after token validation.
   // Permanently deletes the authenticated account after token validation.

+ 3 - 0
proto/chatto/api/v1/message_types.proto

@@ -172,4 +172,7 @@ message Message {
   repeated MessageReaction reactions = 19;
   repeated MessageReaction reactions = 19;
   // Aggregated thread state, when known for a thread root message.
   // Aggregated thread state, when known for a thread root message.
   ThreadSummary thread = 20;
   ThreadSummary thread = 20;
+  // Time when the message content was deleted through retraction or account
+  // crypto-shredding. Absent when unavailable body content is not a deletion.
+  google.protobuf.Timestamp deleted_at = 21;
 }
 }

+ 10 - 1
proto/chatto/api/v1/messages.proto

@@ -28,7 +28,16 @@ message CreateMessageRequest {
   // Message body text. Required unless attachment_asset_ids is non-empty.
   // Message body text. Required unless attachment_asset_ids is non-empty.
   string body = 2;
   string body = 2;
   // Existing room-scoped attachment asset IDs to include with the message.
   // Existing room-scoped attachment asset IDs to include with the message.
-  repeated string attachment_asset_ids = 3;
+  // At most 10 IDs may be supplied.
+  repeated string attachment_asset_ids = 3 [(buf.validate.field).repeated = {
+    max_items: 10
+    items: {
+      string: {
+        min_len: 1
+        max_bytes: 15
+      }
+    }
+  }];
   // Event ID of the thread root message when posting a thread reply.
   // Event ID of the thread root message when posting a thread reply.
   string thread_root_event_id = 4;
   string thread_root_event_id = 4;
   // Event ID this message replies to for attribution.
   // Event ID this message replies to for attribution.

+ 4 - 1
proto/chatto/api/v1/notifications.proto

@@ -6,6 +6,7 @@ import "buf/validate/validate.proto";
 import "chatto/api/v1/pagination.proto";
 import "chatto/api/v1/pagination.proto";
 import "chatto/api/v1/rooms.proto";
 import "chatto/api/v1/rooms.proto";
 import "chatto/api/v1/users.proto";
 import "chatto/api/v1/users.proto";
+import "google/protobuf/descriptor.proto";
 import "google/protobuf/timestamp.proto";
 import "google/protobuf/timestamp.proto";
 
 
 // Direct-message notification payload.
 // Direct-message notification payload.
@@ -217,7 +218,9 @@ service NotificationService {
   rpc HasNotifications(HasNotificationsRequest) returns (HasNotificationsResponse);
   rpc HasNotifications(HasNotificationsRequest) returns (HasNotificationsResponse);
   // Dismisses one pending notification. Already-dismissed notifications are
   // Dismisses one pending notification. Already-dismissed notifications are
   // treated as idempotent success.
   // treated as idempotent success.
-  rpc DismissNotification(DismissNotificationRequest) returns (DismissNotificationResponse);
+  rpc DismissNotification(DismissNotificationRequest) returns (DismissNotificationResponse) {
+    option idempotency_level = IDEMPOTENT;
+  }
   // Dismisses all pending notifications.
   // Dismisses all pending notifications.
   rpc DismissAllNotifications(DismissAllNotificationsRequest) returns (DismissAllNotificationsResponse);
   rpc DismissAllNotifications(DismissAllNotificationsRequest) returns (DismissAllNotificationsResponse);
 }
 }

+ 4 - 1
proto/chatto/api/v1/push_notifications.proto

@@ -3,6 +3,7 @@ syntax = "proto3";
 package chatto.api.v1;
 package chatto.api.v1;
 
 
 import "buf/validate/validate.proto";
 import "buf/validate/validate.proto";
+import "google/protobuf/descriptor.proto";
 
 
 // Browser Web Push subscription commands for the current user.
 // Browser Web Push subscription commands for the current user.
 service PushNotificationService {
 service PushNotificationService {
@@ -15,7 +16,9 @@ service PushNotificationService {
   // Removes the caller's browser push subscription by endpoint.
   // Removes the caller's browser push subscription by endpoint.
   //
   //
   // The call is idempotent: removing an unknown endpoint still succeeds.
   // The call is idempotent: removing an unknown endpoint still succeeds.
-  rpc Unsubscribe(UnsubscribePushRequest) returns (UnsubscribePushResponse);
+  rpc Unsubscribe(UnsubscribePushRequest) returns (UnsubscribePushResponse) {
+    option idempotency_level = IDEMPOTENT;
+  }
 }
 }
 
 
 // Request to store a PushSubscription returned by the browser Push API.
 // Request to store a PushSubscription returned by the browser Push API.

+ 4 - 1
proto/chatto/discovery/v1/server.proto

@@ -3,6 +3,7 @@ syntax = "proto3";
 package chatto.discovery.v1;
 package chatto.discovery.v1;
 
 
 import "chatto/api/v1/server.proto";
 import "chatto/api/v1/server.proto";
+import "google/protobuf/descriptor.proto";
 
 
 // Request for public server metadata.
 // Request for public server metadata.
 message GetServerRequest {}
 message GetServerRequest {}
@@ -21,5 +22,7 @@ service ServerDiscoveryService {
   // Returns public server metadata, branding, registration status, and login
   // Returns public server metadata, branding, registration status, and login
   // provider information. This fully public RPC is available before login so
   // provider information. This fully public RPC is available before login so
   // clients can render the first server screen and authentication choices.
   // clients can render the first server screen and authentication choices.
-  rpc GetServer(GetServerRequest) returns (GetServerResponse);
+  rpc GetServer(GetServerRequest) returns (GetServerResponse) {
+    option idempotency_level = NO_SIDE_EFFECTS;
+  }
 }
 }

+ 1 - 1
pyproject.toml

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
 
 
 [project]
 [project]
 name = "chattolib"
 name = "chattolib"
-version = "0.4.3"
+version = "0.4.9"
 description = "Async Python client library for the Chatto webchat Connect API"
 description = "Async Python client library for the Chatto webchat Connect API"
 requires-python = ">=3.11"
 requires-python = ">=3.11"
 license = "MIT"
 license = "MIT"

File diff ditekan karena terlalu besar
+ 1 - 0
src/chattolib/_pb/chatto/admin/v1/diagnostics_pb2.py


+ 8 - 8
src/chattolib/_pb/chatto/api/v1/account_connect.py

@@ -91,7 +91,7 @@ class MyAccountServiceASGIApplication(ConnectASGIApplication[MyAccountService]):
                         service_name="chatto.api.v1.MyAccountService",
                         service_name="chatto.api.v1.MyAccountService",
                         input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                         input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                         output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
                         output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=svc.delete_avatar,
                     function=svc.delete_avatar,
                 ),
                 ),
@@ -171,7 +171,7 @@ class MyAccountServiceASGIApplication(ConnectASGIApplication[MyAccountService]):
                         service_name="chatto.api.v1.MyAccountService",
                         service_name="chatto.api.v1.MyAccountService",
                         input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                         input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                         output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
                         output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=svc.delete_custom_status,
                     function=svc.delete_custom_status,
                 ),
                 ),
@@ -262,7 +262,7 @@ class MyAccountServiceClient(ConnectClient):
                 service_name="chatto.api.v1.MyAccountService",
                 service_name="chatto.api.v1.MyAccountService",
                 input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                 input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                 output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
                 output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
@@ -422,7 +422,7 @@ class MyAccountServiceClient(ConnectClient):
                 service_name="chatto.api.v1.MyAccountService",
                 service_name="chatto.api.v1.MyAccountService",
                 input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                 input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                 output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
                 output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
@@ -528,7 +528,7 @@ class MyAccountServiceWSGIApplication(ConnectWSGIApplication):
                         service_name="chatto.api.v1.MyAccountService",
                         service_name="chatto.api.v1.MyAccountService",
                         input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                         input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                         output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
                         output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=service.delete_avatar,
                     function=service.delete_avatar,
                 ),
                 ),
@@ -608,7 +608,7 @@ class MyAccountServiceWSGIApplication(ConnectWSGIApplication):
                         service_name="chatto.api.v1.MyAccountService",
                         service_name="chatto.api.v1.MyAccountService",
                         input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                         input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                         output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
                         output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=service.delete_custom_status,
                     function=service.delete_custom_status,
                 ),
                 ),
@@ -699,7 +699,7 @@ class MyAccountServiceClientSync(ConnectClientSync):
                 service_name="chatto.api.v1.MyAccountService",
                 service_name="chatto.api.v1.MyAccountService",
                 input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                 input=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarRequest,
                 output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
                 output=chatto_dot_api_dot_v1_dot_account__pb2.DeleteAvatarResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
@@ -859,7 +859,7 @@ class MyAccountServiceClientSync(ConnectClientSync):
                 service_name="chatto.api.v1.MyAccountService",
                 service_name="chatto.api.v1.MyAccountService",
                 input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                 input=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusRequest,
                 output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
                 output=chatto_dot_api_dot_v1_dot_user__status__pb2.DeleteCustomStatusResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,

File diff ditekan karena terlalu besar
+ 1 - 0
src/chattolib/_pb/chatto/api/v1/account_pb2.py


File diff ditekan karena terlalu besar
+ 0 - 0
src/chattolib/_pb/chatto/api/v1/message_types_pb2.py


File diff ditekan karena terlalu besar
+ 0 - 0
src/chattolib/_pb/chatto/api/v1/messages_pb2.py


+ 4 - 4
src/chattolib/_pb/chatto/api/v1/notifications_connect.py

@@ -113,7 +113,7 @@ class NotificationServiceASGIApplication(ConnectASGIApplication[NotificationServ
                         service_name="chatto.api.v1.NotificationService",
                         service_name="chatto.api.v1.NotificationService",
                         input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                         input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                         output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
                         output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=svc.dismiss_notification,
                     function=svc.dismiss_notification,
                 ),
                 ),
@@ -274,7 +274,7 @@ class NotificationServiceClient(ConnectClient):
                 service_name="chatto.api.v1.NotificationService",
                 service_name="chatto.api.v1.NotificationService",
                 input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                 input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                 output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
                 output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
@@ -390,7 +390,7 @@ class NotificationServiceWSGIApplication(ConnectWSGIApplication):
                         service_name="chatto.api.v1.NotificationService",
                         service_name="chatto.api.v1.NotificationService",
                         input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                         input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                         output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
                         output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=service.dismiss_notification,
                     function=service.dismiss_notification,
                 ),
                 ),
@@ -551,7 +551,7 @@ class NotificationServiceClientSync(ConnectClientSync):
                 service_name="chatto.api.v1.NotificationService",
                 service_name="chatto.api.v1.NotificationService",
                 input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                 input=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationRequest,
                 output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
                 output=chatto_dot_api_dot_v1_dot_notifications__pb2.DismissNotificationResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,

File diff ditekan karena terlalu besar
+ 1 - 0
src/chattolib/_pb/chatto/api/v1/notifications_pb2.py


+ 4 - 4
src/chattolib/_pb/chatto/api/v1/push_notifications_connect.py

@@ -45,7 +45,7 @@ class PushNotificationServiceASGIApplication(ConnectASGIApplication[PushNotifica
                         service_name="chatto.api.v1.PushNotificationService",
                         service_name="chatto.api.v1.PushNotificationService",
                         input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                         input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                         output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
                         output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=svc.unsubscribe,
                     function=svc.unsubscribe,
                 ),
                 ),
@@ -96,7 +96,7 @@ class PushNotificationServiceClient(ConnectClient):
                 service_name="chatto.api.v1.PushNotificationService",
                 service_name="chatto.api.v1.PushNotificationService",
                 input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                 input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                 output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
                 output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
@@ -130,7 +130,7 @@ class PushNotificationServiceWSGIApplication(ConnectWSGIApplication):
                         service_name="chatto.api.v1.PushNotificationService",
                         service_name="chatto.api.v1.PushNotificationService",
                         input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                         input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                         output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
                         output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.IDEMPOTENT,
                     ),
                     ),
                     function=service.unsubscribe,
                     function=service.unsubscribe,
                 ),
                 ),
@@ -181,7 +181,7 @@ class PushNotificationServiceClientSync(ConnectClientSync):
                 service_name="chatto.api.v1.PushNotificationService",
                 service_name="chatto.api.v1.PushNotificationService",
                 input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                 input=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushRequest,
                 output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
                 output=chatto_dot_api_dot_v1_dot_push__notifications__pb2.UnsubscribePushResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.IDEMPOTENT,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,

+ 14 - 11
src/chattolib/_pb/chatto/api/v1/push_notifications_pb2.py

@@ -23,9 +23,10 @@ _sym_db = _symbol_database.Default()
 
 
 
 
 from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2
 from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
 
 
 
 
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&chatto/api/v1/push_notifications.proto\x12\rchatto.api.v1\x1a\x1b\x62uf/validate/validate.proto\"\x9c\x01\n\x14SubscribePushRequest\x12\x1c\n\x08\x65ndpoint\x18\x01 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80 \x12\x1a\n\x06p256dh\x18\x02 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80\x02\x12\x18\n\x04\x61uth\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80\x01\x12!\n\nuser_agent\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x04H\x00\x88\x01\x01\x42\r\n\x0b_user_agent\"+\n\x15SubscribePushResponse\x12\x12\n\nsubscribed\x18\x01 \x01(\x08\"6\n\x16UnsubscribePushRequest\x12\x1c\n\x08\x65ndpoint\x18\x01 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80 \"/\n\x17UnsubscribePushResponse\x12\x14\n\x0cunsubscribed\x18\x01 \x01(\x08\x32\xcf\x01\n\x17PushNotificationService\x12V\n\tSubscribe\x12#.chatto.api.v1.SubscribePushRequest\x1a$.chatto.api.v1.SubscribePushResponse\x12\\\n\x0bUnsubscribe\x12%.chatto.api.v1.UnsubscribePushRequest\x1a&.chatto.api.v1.UnsubscribePushResponseb\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&chatto/api/v1/push_notifications.proto\x12\rchatto.api.v1\x1a\x1b\x62uf/validate/validate.proto\x1a google/protobuf/descriptor.proto\"\x9c\x01\n\x14SubscribePushRequest\x12\x1c\n\x08\x65ndpoint\x18\x01 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80 \x12\x1a\n\x06p256dh\x18\x02 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80\x02\x12\x18\n\x04\x61uth\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80\x01\x12!\n\nuser_agent\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x04H\x00\x88\x01\x01\x42\r\n\x0b_user_agent\"+\n\x15SubscribePushResponse\x12\x12\n\nsubscribed\x18\x01 \x01(\x08\"6\n\x16UnsubscribePushRequest\x12\x1c\n\x08\x65ndpoint\x18\x01 \x01(\tB\n\xbaH\x07r\x05\x10\x01\x18\x80 \"/\n\x17UnsubscribePushResponse\x12\x14\n\x0cunsubscribed\x18\x01 \x01(\x08\x32\xd4\x01\n\x17PushNotificationService\x12V\n\tSubscribe\x12#.chatto.api.v1.SubscribePushRequest\x1a$.chatto.api.v1.SubscribePushResponse\x12\x61\n\x0bUnsubscribe\x12%.chatto.api.v1.UnsubscribePushRequest\x1a&.chatto.api.v1.UnsubscribePushResponse\"\x03\x90\x02\x02\x62\x06proto3')
 
 
 _globals = globals()
 _globals = globals()
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -42,14 +43,16 @@ if not _descriptor._USE_C_DESCRIPTORS:
   _globals['_SUBSCRIBEPUSHREQUEST'].fields_by_name['user_agent']._serialized_options = b'\272H\005r\003\030\200\004'
   _globals['_SUBSCRIBEPUSHREQUEST'].fields_by_name['user_agent']._serialized_options = b'\272H\005r\003\030\200\004'
   _globals['_UNSUBSCRIBEPUSHREQUEST'].fields_by_name['endpoint']._loaded_options = None
   _globals['_UNSUBSCRIBEPUSHREQUEST'].fields_by_name['endpoint']._loaded_options = None
   _globals['_UNSUBSCRIBEPUSHREQUEST'].fields_by_name['endpoint']._serialized_options = b'\272H\007r\005\020\001\030\200 '
   _globals['_UNSUBSCRIBEPUSHREQUEST'].fields_by_name['endpoint']._serialized_options = b'\272H\007r\005\020\001\030\200 '
-  _globals['_SUBSCRIBEPUSHREQUEST']._serialized_start=87
-  _globals['_SUBSCRIBEPUSHREQUEST']._serialized_end=243
-  _globals['_SUBSCRIBEPUSHRESPONSE']._serialized_start=245
-  _globals['_SUBSCRIBEPUSHRESPONSE']._serialized_end=288
-  _globals['_UNSUBSCRIBEPUSHREQUEST']._serialized_start=290
-  _globals['_UNSUBSCRIBEPUSHREQUEST']._serialized_end=344
-  _globals['_UNSUBSCRIBEPUSHRESPONSE']._serialized_start=346
-  _globals['_UNSUBSCRIBEPUSHRESPONSE']._serialized_end=393
-  _globals['_PUSHNOTIFICATIONSERVICE']._serialized_start=396
-  _globals['_PUSHNOTIFICATIONSERVICE']._serialized_end=603
+  _globals['_PUSHNOTIFICATIONSERVICE'].methods_by_name['Unsubscribe']._loaded_options = None
+  _globals['_PUSHNOTIFICATIONSERVICE'].methods_by_name['Unsubscribe']._serialized_options = b'\220\002\002'
+  _globals['_SUBSCRIBEPUSHREQUEST']._serialized_start=121
+  _globals['_SUBSCRIBEPUSHREQUEST']._serialized_end=277
+  _globals['_SUBSCRIBEPUSHRESPONSE']._serialized_start=279
+  _globals['_SUBSCRIBEPUSHRESPONSE']._serialized_end=322
+  _globals['_UNSUBSCRIBEPUSHREQUEST']._serialized_start=324
+  _globals['_UNSUBSCRIBEPUSHREQUEST']._serialized_end=378
+  _globals['_UNSUBSCRIBEPUSHRESPONSE']._serialized_start=380
+  _globals['_UNSUBSCRIBEPUSHRESPONSE']._serialized_end=427
+  _globals['_PUSHNOTIFICATIONSERVICE']._serialized_start=430
+  _globals['_PUSHNOTIFICATIONSERVICE']._serialized_end=642
 # @@protoc_insertion_point(module_scope)
 # @@protoc_insertion_point(module_scope)

+ 8 - 4
src/chattolib/_pb/chatto/discovery/v1/server_connect.py

@@ -32,7 +32,7 @@ class ServerDiscoveryServiceASGIApplication(ConnectASGIApplication[ServerDiscove
                         service_name="chatto.discovery.v1.ServerDiscoveryService",
                         service_name="chatto.discovery.v1.ServerDiscoveryService",
                         input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                         input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                         output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
                         output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.NO_SIDE_EFFECTS,
                     ),
                     ),
                     function=svc.get_server,
                     function=svc.get_server,
                 ),
                 ),
@@ -55,6 +55,7 @@ class ServerDiscoveryServiceClient(ConnectClient):
         *,
         *,
         headers: Headers | Mapping[str, str] | None = None,
         headers: Headers | Mapping[str, str] | None = None,
         timeout_ms: int | None = None,
         timeout_ms: int | None = None,
+        use_get: bool = False,
     ) -> chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse:
     ) -> chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse:
         return await self.execute_unary(
         return await self.execute_unary(
             request=request,
             request=request,
@@ -63,10 +64,11 @@ class ServerDiscoveryServiceClient(ConnectClient):
                 service_name="chatto.discovery.v1.ServerDiscoveryService",
                 service_name="chatto.discovery.v1.ServerDiscoveryService",
                 input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                 input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                 output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
                 output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.NO_SIDE_EFFECTS,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
+            use_get=use_get,
         )
         )
 
 
 
 
@@ -85,7 +87,7 @@ class ServerDiscoveryServiceWSGIApplication(ConnectWSGIApplication):
                         service_name="chatto.discovery.v1.ServerDiscoveryService",
                         service_name="chatto.discovery.v1.ServerDiscoveryService",
                         input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                         input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                         output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
                         output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
-                        idempotency_level=IdempotencyLevel.UNKNOWN,
+                        idempotency_level=IdempotencyLevel.NO_SIDE_EFFECTS,
                     ),
                     ),
                     function=service.get_server,
                     function=service.get_server,
                 ),
                 ),
@@ -108,6 +110,7 @@ class ServerDiscoveryServiceClientSync(ConnectClientSync):
         *,
         *,
         headers: Headers | Mapping[str, str] | None = None,
         headers: Headers | Mapping[str, str] | None = None,
         timeout_ms: int | None = None,
         timeout_ms: int | None = None,
+        use_get: bool = False,
     ) -> chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse:
     ) -> chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse:
         return self.execute_unary(
         return self.execute_unary(
             request=request,
             request=request,
@@ -116,8 +119,9 @@ class ServerDiscoveryServiceClientSync(ConnectClientSync):
                 service_name="chatto.discovery.v1.ServerDiscoveryService",
                 service_name="chatto.discovery.v1.ServerDiscoveryService",
                 input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                 input=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerRequest,
                 output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
                 output=chatto_dot_discovery_dot_v1_dot_server__pb2.GetServerResponse,
-                idempotency_level=IdempotencyLevel.UNKNOWN,
+                idempotency_level=IdempotencyLevel.NO_SIDE_EFFECTS,
             ),
             ),
             headers=headers,
             headers=headers,
             timeout_ms=timeout_ms,
             timeout_ms=timeout_ms,
+            use_get=use_get,
         )
         )

+ 10 - 7
src/chattolib/_pb/chatto/discovery/v1/server_pb2.py

@@ -23,19 +23,22 @@ _sym_db = _symbol_database.Default()
 
 
 
 
 from chatto.api.v1 import server_pb2 as chatto_dot_api_dot_v1_dot_server__pb2
 from chatto.api.v1 import server_pb2 as chatto_dot_api_dot_v1_dot_server__pb2
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
 
 
 
 
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n chatto/discovery/v1/server.proto\x12\x13\x63hatto.discovery.v1\x1a\x1a\x63hatto/api/v1/server.proto\"\x12\n\x10GetServerRequest\"s\n\x11GetServerResponse\x12\x33\n\x07profile\x18\x01 \x01(\x0b\x32\".chatto.api.v1.ServerPublicProfile\x12)\n\x05login\x18\x02 \x01(\x0b\x32\x1a.chatto.api.v1.ServerLogin2t\n\x16ServerDiscoveryService\x12Z\n\tGetServer\x12%.chatto.discovery.v1.GetServerRequest\x1a&.chatto.discovery.v1.GetServerResponseb\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n chatto/discovery/v1/server.proto\x12\x13\x63hatto.discovery.v1\x1a\x1a\x63hatto/api/v1/server.proto\x1a google/protobuf/descriptor.proto\"\x12\n\x10GetServerRequest\"s\n\x11GetServerResponse\x12\x33\n\x07profile\x18\x01 \x01(\x0b\x32\".chatto.api.v1.ServerPublicProfile\x12)\n\x05login\x18\x02 \x01(\x0b\x32\x1a.chatto.api.v1.ServerLogin2y\n\x16ServerDiscoveryService\x12_\n\tGetServer\x12%.chatto.discovery.v1.GetServerRequest\x1a&.chatto.discovery.v1.GetServerResponse\"\x03\x90\x02\x01\x62\x06proto3')
 
 
 _globals = globals()
 _globals = globals()
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
 _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'chatto.discovery.v1.server_pb2', _globals)
 _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'chatto.discovery.v1.server_pb2', _globals)
 if not _descriptor._USE_C_DESCRIPTORS:
 if not _descriptor._USE_C_DESCRIPTORS:
   DESCRIPTOR._loaded_options = None
   DESCRIPTOR._loaded_options = None
-  _globals['_GETSERVERREQUEST']._serialized_start=85
-  _globals['_GETSERVERREQUEST']._serialized_end=103
-  _globals['_GETSERVERRESPONSE']._serialized_start=105
-  _globals['_GETSERVERRESPONSE']._serialized_end=220
-  _globals['_SERVERDISCOVERYSERVICE']._serialized_start=222
-  _globals['_SERVERDISCOVERYSERVICE']._serialized_end=338
+  _globals['_SERVERDISCOVERYSERVICE'].methods_by_name['GetServer']._loaded_options = None
+  _globals['_SERVERDISCOVERYSERVICE'].methods_by_name['GetServer']._serialized_options = b'\220\002\001'
+  _globals['_GETSERVERREQUEST']._serialized_start=119
+  _globals['_GETSERVERREQUEST']._serialized_end=137
+  _globals['_GETSERVERRESPONSE']._serialized_start=139
+  _globals['_GETSERVERRESPONSE']._serialized_end=254
+  _globals['_SERVERDISCOVERYSERVICE']._serialized_start=256
+  _globals['_SERVERDISCOVERYSERVICE']._serialized_end=377
 # @@protoc_insertion_point(module_scope)
 # @@protoc_insertion_point(module_scope)

+ 2 - 0
src/chattolib/types.py

@@ -646,6 +646,7 @@ class Message:
     channel_echo_event_id: str = ""
     channel_echo_event_id: str = ""
     reactions: list[MessageReaction] = field(default_factory=list)
     reactions: list[MessageReaction] = field(default_factory=list)
     thread: ThreadSummary | None = None
     thread: ThreadSummary | None = None
+    deleted_at: datetime | None = None
 
 
     @classmethod
     @classmethod
     def parse(cls, data: dict[str, Any] | None) -> Message | None:
     def parse(cls, data: dict[str, Any] | None) -> Message | None:
@@ -667,6 +668,7 @@ class Message:
             channel_echo_event_id=data.get("channelEchoEventId", ""),
             channel_echo_event_id=data.get("channelEchoEventId", ""),
             reactions=[MessageReaction.parse(r) for r in data.get("reactions") or []],
             reactions=[MessageReaction.parse(r) for r in data.get("reactions") or []],
             thread=ThreadSummary.parse(data.get("thread")),
             thread=ThreadSummary.parse(data.get("thread")),
+            deleted_at=parse_datetime(data.get("deletedAt")),
         )
         )
 
 
 
 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini