# 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`.