SHA256
Server-side DM dialogs state
This commit is contained in:
@@ -66,11 +66,44 @@
|
||||
"ok": true,
|
||||
"payload": {
|
||||
"login": "Alice",
|
||||
"contacts": ["Bob", "Kate"]
|
||||
"dialogs": [
|
||||
{
|
||||
"peerLogin": "Bob",
|
||||
"relationFlag": "close_friend",
|
||||
"lastMessageBlobB64": "U0hpTkVfRE0B...",
|
||||
"lastMessageTimeMs": 1774700000123,
|
||||
"unreadCount": 2,
|
||||
"hasDialog": true
|
||||
},
|
||||
{
|
||||
"peerLogin": "Kate",
|
||||
"relationFlag": "contact",
|
||||
"lastMessageBlobB64": "",
|
||||
"lastMessageTimeMs": 0,
|
||||
"unreadCount": 0,
|
||||
"hasDialog": false
|
||||
},
|
||||
{
|
||||
"peerLogin": "Mira",
|
||||
"relationFlag": "none",
|
||||
"lastMessageBlobB64": "U0hpTkVfRE0B...",
|
||||
"lastMessageTimeMs": 1774700000555,
|
||||
"unreadCount": 1,
|
||||
"hasDialog": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Примечание
|
||||
|
||||
- `dialogs` это серверный inbox-проекционный список диалогов;
|
||||
- `relationFlag` возвращается как `close_friend`, `contact` или `none`;
|
||||
- если один и тот же человек есть и в `contact`, и в `close_friend`, в `dialogs` он приходит как `close_friend`.
|
||||
- `lastMessageBlobB64` содержит полный signed DM block последнего контентного сообщения в base64;
|
||||
- для чатов без сообщений поле `lastMessageBlobB64` пустое.
|
||||
|
||||
---
|
||||
|
||||
## 3. `GetUserConnectionsGraph`
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
- для DM v1 нужно использовать `SendMessagePair`, `ReceiveOutcomingMessage`, `ReceiveIncomingMessage`, `DeleteMessage`, `DeleteConversation`, `GetDirectMessages`;
|
||||
- `DmSyncBatch` предназначен для межсерверной догоняющей синхронизации, не для обычного клиентского UI.
|
||||
- сервер поддерживает материализованный слой диалогов `dm_dialog_state`; `read receipt` обновляет серверный watermark и `unreadCount`, а не только локальный клиентский флаг.
|
||||
- в `dm_dialog_state` сервер также хранит `last_message_blob_b64` для последнего контентного DM в base64, чтобы клиент мог отрисовать список чатов без дополнительного запроса.
|
||||
|
||||
## 1. `UpsertPushToken`
|
||||
|
||||
@@ -147,6 +149,12 @@
|
||||
|
||||
`sourceServerLogin` необязателен. Если поле есть, сервер использует его как подсказку, чтобы не отправлять событие обратно серверу-источнику.
|
||||
|
||||
### Примечание
|
||||
|
||||
- входящий `type=3` не только сохраняется как событие прочтения, но и обновляет серверный watermark диалога;
|
||||
- если подтверждение прочтения приходит не по порядку, сервер сохраняет наибольший watermark и пересчитывает `unreadCount` по фактическому состоянию сообщений;
|
||||
- это нужно, чтобы разные устройства не расходились по счётчику непрочитанных.
|
||||
|
||||
## 5. `DeleteMessage`
|
||||
|
||||
Принимает один signed DM-блок `type=5` или `type=6`.
|
||||
@@ -359,7 +367,7 @@
|
||||
|
||||
- все DM-типы `1..8` используют `SHiNE_DM`
|
||||
- `GetUser` может lazy-import пользователя из Solana PDA, поэтому именно через него клиент обычно получает `clientKey` адресата для E2EE
|
||||
- сервер не расшифровывает DM и не использует ciphertext как preview текста
|
||||
- сервер не расшифровывает DM; в списке диалогов он отдаёт последний signed block как `lastMessageBlobB64`, а не извлекает plaintext preview
|
||||
- сервер хранит последнюю применённую версию контентного сообщения по правилу `revisionTimeMs`, а при равенстве — по `reencryptedAtMs`
|
||||
- если сервер уже знает tombstone удаления переписки и получает старое сообщение до этой границы, он перерассылает известный `DeleteConversation` на `access_servers` обеих сторон
|
||||
- HTTP endpoints для DM-файлов сейчас отсутствуют
|
||||
|
||||
Reference in New Issue
Block a user