SHA256
250 lines
6.0 KiB
Markdown
250 lines
6.0 KiB
Markdown
# API для разработчиков: связи пользователей
|
|
|
|
Документ описывает операции чтения и записи пользовательских связей.
|
|
|
|
Текущие операции:
|
|
|
|
- `GetFriendsLists`
|
|
- `ListContacts`
|
|
- `GetUserConnectionsGraph`
|
|
- `AddCloseFriend`
|
|
|
|
## 1. `GetFriendsLists`
|
|
|
|
### Запрос
|
|
|
|
```json
|
|
{
|
|
"op": "GetFriendsLists",
|
|
"requestId": "friends-001",
|
|
"payload": {
|
|
"login": "alice"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Успешный ответ
|
|
|
|
```json
|
|
{
|
|
"op": "GetFriendsLists",
|
|
"requestId": "friends-001",
|
|
"status": 200,
|
|
"ok": true,
|
|
"payload": {
|
|
"login": "Alice",
|
|
"out_friends": ["Bob"],
|
|
"in_friends": ["Kate"]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 2. `ListContacts`
|
|
|
|
`ListContacts` использует текущую авторизованную сессию. В payload нет дополнительных полей.
|
|
|
|
### Запрос
|
|
|
|
```json
|
|
{
|
|
"op": "ListContacts",
|
|
"requestId": "contacts-001",
|
|
"payload": {
|
|
}
|
|
}
|
|
```
|
|
|
|
### Успешный ответ
|
|
|
|
```json
|
|
{
|
|
"op": "ListContacts",
|
|
"requestId": "contacts-001",
|
|
"status": 200,
|
|
"ok": true,
|
|
"payload": {
|
|
"login": "Alice",
|
|
"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`
|
|
|
|
### Запрос
|
|
|
|
```json
|
|
{
|
|
"op": "GetUserConnectionsGraph",
|
|
"requestId": "graph-001",
|
|
"payload": {
|
|
"login": "alice"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Успешный ответ
|
|
|
|
```json
|
|
{
|
|
"op": "GetUserConnectionsGraph",
|
|
"requestId": "graph-001",
|
|
"status": 200,
|
|
"ok": true,
|
|
"payload": {
|
|
"login": "Alice",
|
|
"outFriends": ["Bob"],
|
|
"inFriends": ["Kate"],
|
|
"outContacts": [],
|
|
"inContacts": [],
|
|
"outFollows": [],
|
|
"inFollows": [],
|
|
"outSpouses": [],
|
|
"inSpouses": [],
|
|
"outParents": [],
|
|
"inParents": [],
|
|
"outChildren": [],
|
|
"inChildren": [],
|
|
"outSiblings": [],
|
|
"inSiblings": [],
|
|
"outKnownPersons": [],
|
|
"inKnownPersons": [],
|
|
"outShineConfirmed": [],
|
|
"inShineConfirmed": [],
|
|
"outShineSeen": [],
|
|
"inShineSeen": [],
|
|
"parents": [],
|
|
"children": [],
|
|
"siblings": [],
|
|
"spouses": [],
|
|
"allUsers": [
|
|
{
|
|
"login": "Bob",
|
|
"official": false,
|
|
"shine": true,
|
|
"officialLabel": "",
|
|
"shineLabel": "shine",
|
|
"avatar": { "ar": "..." }
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Примечание
|
|
|
|
Поля `known_person`, `shine_confirmed`, `shine_seen` в UI считаются недопроверенной зоной проекта; при изменениях этой логики нужна ручная end-to-end проверка.
|
|
|
|
---
|
|
|
|
## 4. `AddCloseFriend`
|
|
|
|
`AddCloseFriend` использует текущую авторизованную сессию как источник `login`.
|
|
|
|
### Запрос
|
|
|
|
```json
|
|
{
|
|
"op": "AddCloseFriend",
|
|
"requestId": "close-friend-001",
|
|
"payload": {
|
|
"toLogin": "bob"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Успешный ответ
|
|
|
|
```json
|
|
{
|
|
"op": "AddCloseFriend",
|
|
"requestId": "close-friend-001",
|
|
"status": 200,
|
|
"ok": true,
|
|
"payload": {
|
|
"login": "Alice",
|
|
"toLogin": "Bob",
|
|
"relation": "close_friend"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Profile relation lists (v18)
|
|
|
|
### `ListUserProfileRelations`
|
|
|
|
Lightweight paged lists used by clickable counters in a user profile. Supported `listType` values:
|
|
|
|
- `friends`
|
|
- `close_friends`
|
|
- `primary_received`
|
|
- `primary_given`
|
|
- `shine_received`
|
|
- `shine_given`
|
|
|
|
Request:
|
|
|
|
```json
|
|
{
|
|
"op": "ListUserProfileRelations",
|
|
"requestId": "profile-rel-1",
|
|
"payload": { "login": "Alice", "listType": "friends", "limit": 100, "offset": 0 }
|
|
}
|
|
```
|
|
|
|
Each item contains a ready-to-render user card: `login`, `firstName`, `lastName`, `avatarAr`, `accountRole`, `shineStatus`, effective `relationType`, `primaryConfirmed`, `shineConfirmed`, plus received primary/shine confirmation counters.
|
|
|
|
Effective relation priority is `close_friend > friend > contact > none`. Effective `70/80` confirmations are filtered by current voting/status rules; raw blockchain connections are not deleted when temporarily ineffective.
|
|
|
|
### Voting rules
|
|
|
|
- new `80` requires the actor to have `account_role=primary`;
|
|
- `80` cannot be added to a target with `account_role=non_voting`;
|
|
- new `70` requires actor `account_role=primary` and `shine=shining` (legacy `shine=yes` is normalized to `shining`);
|
|
- `70` cannot be added to a target with `shine=not_interested`;
|
|
- a `non_voting` target may still receive `70` if its shine status allows it;
|
|
- old raw `70/80` remain in `connections_state`, but are excluded from effective lists/counts while either side is ineligible. They become effective again automatically if statuses permit later.
|
|
|
|
### `ListContacts` additions (v18)
|
|
|
|
Every dialog item now also carries `firstName`, `lastName`, `avatarAr`, `accountRole`, and `shineStatus`. `relationFlag` priority is now `close_friend > friend > contact > none`.
|