12 KiB
06. Channels Read API
Человеко-читаемое объяснение
Эти функции — это чтение данных каналов для UI:
-
ListSubscriptionsFeed— отдает данные для экрана списка каналов:- ваши каналы (личный + созданные вами),
- каналы пользователей, на кого вы подписаны,
- отдельные каналы, на которые вы подписаны напрямую.
-
GetChannelMessages— отдает полную ленту одного канала (пока без курсоров, загружается сразу целиком), включая версии сообщений, лайки и ответы. -
GetMessageThread— отдает дерево обсуждения вокруг конкретного сообщения: предки, фокус-сообщение, потомки. -
GetPersonalDiary— отдает виртуальную лентуЛичный дневник, собранную изSTATUS_ACTIONтекущего пользователя. -
GetChannelsCounters— отдает счетчики разделов каналов для пользователя. -
ListGroupChats200— отдает список групповых чатов типа200. -
GetGroupDialog— отдает сообщения конкретного группового чата типа200.
На первом этапе мы не используем курсоры (
nextCursor) и загружаем полные списки.
unreadCountдля канала считается поuser_settings: если для парыownerBlockchainName/channelNameещё нет записи, канал считается полностью прочитанным, а UI при первом открытии записывает текущий курсор чтения.
1) ListSubscriptionsFeed
Request
{
"op": "ListSubscriptionsFeed",
"requestId": "req-1",
"payload": {
"login": "Alice",
"limit": 200
}
}
Response (success)
{
"op": "ListSubscriptionsFeed",
"requestId": "req-1",
"status": 200,
"ok": true,
"payload": {
"login": "Alice",
"ownedChannels": [
{
"channel": {
"ownerLogin": "Alice",
"ownerBlockchainName": "alice-001",
"channelName": "0",
"displayName": "Мой канал",
"channelDescription": "Короткое описание",
"avaAr": "ArweaveTxId...",
"avaSha256": "0123...",
"avaSize": 248193,
"metaUpdatedAtMs": 1760000000000,
"personal": true,
"channelRoot": { "blockNumber": 0, "blockHash": "..." }
},
"messagesCount": 120,
"lastMessage": {
"messageRef": { "blockNumber": 921, "blockHash": "..." },
"text": "последняя версия текста",
"createdAtMs": 1760000000000,
"authorLogin": "Alice",
"authorBlockchainName": "alice-001"
}
}
],
"followedUsersChannels": [
{
"channel": {
"ownerLogin": "Bob",
"ownerBlockchainName": "bob-001",
"channelName": "0",
"personal": true,
"channelRoot": { "blockNumber": 0, "blockHash": "..." }
},
"messagesCount": 540,
"lastMessage": {
"messageRef": { "blockNumber": 922, "blockHash": "..." },
"text": "последняя версия текста",
"createdAtMs": 1760000100000,
"authorLogin": "Bob",
"authorBlockchainName": "bob-001"
}
}
],
"followedChannels": [
{
"channel": {
"ownerLogin": "Carl",
"ownerBlockchainName": "carl-001",
"channelName": "market",
"personal": false,
"channelRoot": { "blockNumber": 456, "blockHash": "..." }
},
"messagesCount": 90,
"lastMessage": {
"messageRef": { "blockNumber": 1002, "blockHash": "..." },
"text": "актуальный текст",
"createdAtMs": 1760001000000,
"authorLogin": "Carl",
"authorBlockchainName": "carl-001"
}
}
]
}
}
2) GetChannelMessages
Request
{
"op": "GetChannelMessages",
"requestId": "req-2",
"payload": {
"channel": {
"ownerBlockchainName": "bob-001",
"channelRootBlockNumber": 123,
"channelRootBlockHash": "..."
},
"limit": 200,
"sort": "asc"
}
}
Response (success)
{
"op": "GetChannelMessages",
"requestId": "req-2",
"status": 200,
"ok": true,
"payload": {
"channel": {
"ownerLogin": "Bob",
"ownerBlockchainName": "bob-001",
"channelName": "news",
"displayName": "Новости Bob",
"channelDescription": "Канал о новостях",
"avaAr": "ArweaveTxId...",
"avaSha256": "0123...",
"avaSize": 248193,
"metaUpdatedAtMs": 1760000000000,
"subscribersCount": 128,
"channelRoot": { "blockNumber": 123, "blockHash": "..." }
},
"metaEvents": [
{
"kind": "created",
"messageRef": { "blockNumber": 123, "blockHash": "..." },
"authorLogin": "Bob",
"authorBlockchainName": "bob-001",
"lineStep": 1,
"createdAtMs": 1760000000000,
"title": "news",
"description": "",
"avaAr": "",
"avaSha256": "",
"avaSize": 0
},
{
"kind": "profile_updated",
"messageRef": { "blockNumber": 130, "blockHash": "..." },
"authorLogin": "Bob",
"authorBlockchainName": "bob-001",
"lineStep": 2,
"createdAtMs": 1760000500000,
"title": "Новости Bob",
"description": "Канал о новостях",
"avaAr": "ArweaveTxId...",
"avaSha256": "0123...",
"avaSize": 248193
}
],
"messages": [
{
"messageRef": { "blockNumber": 140, "blockHash": "..." },
"authorLogin": "Bob",
"authorBlockchainName": "bob-001",
"createdAtMs": 1760000000000,
"text": "текущая версия",
"likesCount": 12,
"repliesCount": 3,
"ratingsCount": 2,
"versionsTotal": 4,
"versions": [
{ "versionIndex": 1, "blockNumber": 140, "blockHash": "...", "text": "v1", "createdAtMs": 1760000000000 },
{ "versionIndex": 2, "blockNumber": 155, "blockHash": "...", "text": "v2", "createdAtMs": 1760001000000 },
{ "versionIndex": 3, "blockNumber": 170, "blockHash": "...", "text": "v3", "createdAtMs": 1760002000000 },
{ "versionIndex": 4, "blockNumber": 199, "blockHash": "...", "text": "v4", "createdAtMs": 1760003000000 }
]
}
]
}
}
3) GetMessageThread
Request
{
"op": "GetMessageThread",
"requestId": "req-3",
"payload": {
"message": {
"blockchainName": "bob-001",
"blockNumber": 333,
"blockHash": "..."
},
"depthUp": 20,
"depthDown": 2,
"limitChildrenPerNode": 50
}
}
Response (success)
{
"op": "GetMessageThread",
"requestId": "req-3",
"status": 200,
"ok": true,
"payload": {
"ancestors": [MessageNode],
"focus": MessageNode,
"descendants": [MessageNodeTree]
}
}
MessageNode (дополнение)
MessageNodeрасширяет формат сообщения изGetChannelMessagesи дополнительно содержит:channelInfo— мета-информация о канале (если применимо);rawBlockB64— сыройblock_bytesтекущего блока в Base64.
- Поле
rawBlockB64присутствует у узлов во всех частях ответаGetMessageThread:focus,ancestors[],descendants[]. - В
GetChannelMessagesполеrawBlockB64не добавляется (лента канала без сырого блока, чтобы не раздувать ответ). - И в
GetChannelMessages, и вGetMessageThreadкаждое сообщение теперь содержит:repliesCount— число дочерних сообщений типаTEXT_REPLY;ratingsCount— число дочерних сообщений типаTEXT_RATING.
- В
descendants[]операцииGetMessageThreadвозвращаются оба типа дочерних текстовых сообщений:TEXT_REPLY;TEXT_RATING. Они идут в одной общей ветке обсуждения и сортируются по времени создания.
4) GetPersonalDiary
Возвращает виртуальный канал Личный дневник для самого пользователя.
- Вызов доступен только владельцу дневника.
- Сообщения в ответе строятся из блоков
STATUS_ACTION. - Поля
targetMsgSubType,targetText,targetAuthorLogin,targetAuthorBlockchainName,targetCreatedAtMsописывают исходный материал, к которому относится действие.
Request
{
"op": "GetPersonalDiary",
"requestId": "req-4",
"payload": {
"login": "Alice",
"limit": 200,
"sort": "asc"
}
}
4) GetChannelsCounters
Request
{
"op": "GetChannelsCounters",
"requestId": "req-4",
"payload": {
"login": "Alice"
}
}
Response (success)
{
"op": "GetChannelsCounters",
"requestId": "req-4",
"status": 200,
"ok": true,
"payload": {
"login": "Alice",
"feedCount": 12,
"dialogs100Count": 3,
"groupChats200Count": 4,
"myChannelsCount": 2
}
}
5) ListGroupChats200
Request
{
"op": "ListGroupChats200",
"requestId": "req-5",
"payload": {
"login": "Alice"
}
}
Response (success)
{
"op": "ListGroupChats200",
"requestId": "req-5",
"status": 200,
"ok": true,
"payload": {
"login": "Alice",
"chats": [
{
"ownerLogin": "Alice",
"ownerBlockchainName": "alice-001",
"channelRootBlockNumber": 123,
"channelRootBlockHash": "...",
"channelName": "team",
"chatTitle": "Team chat",
"membersCount": 3,
"updatedAtMs": 1760000000000
}
]
}
}
6) GetGroupDialog
Request
{
"op": "GetGroupDialog",
"requestId": "req-6",
"payload": {
"login": "Alice",
"group": {
"ownerBlockchainName": "alice-001",
"channelRootBlockNumber": 123
}
}
}
Response (success)
{
"op": "GetGroupDialog",
"requestId": "req-6",
"status": 200,
"ok": true,
"payload": {
"group": {
"ownerLogin": "Alice",
"ownerBlockchainName": "alice-001",
"channelRootBlockNumber": 123,
"channelName": "team",
"chatTitle": "Team chat"
},
"messages": [
{
"authorLogin": "Bob",
"authorBlockchainName": "bob-001",
"blockNumber": 140,
"blockHash": "...",
"createdAtMs": 1760000000000,
"text": "Привет"
}
]
}
}
Reason codes
bad_fieldsuser_not_foundchannel_not_foundmessage_not_foundlimit_too_largechannel_name_already_existsinternal_error
Profile public-channel lists (v18)
ListUserProfileChannels
Returns lightweight public-channel cards for profile counters. mode is owned or following; only channel_type_code=1 is returned.
{
"op": "ListUserProfileChannels",
"requestId": "profile-ch-1",
"payload": { "login": "Alice", "mode": "owned", "limit": 100, "offset": 0 }
}
Channel items contain ownerLogin, slug, displayName, avatarAr, ownerBlockchainName, rootBlockNumber, and rootBlockHashHex.
Qualified likes (v18)
Channel/message responses expose three counters:
likesCount— all active likes;primaryLikesCount— likes from users whose currentaccount_role=primary;shiningLikesCount— likes from users who are currently bothprimaryandshining.
Changing account_role or shine does not alter the raw reaction. The two qualified counters are recalculated from reactions_state; therefore old likes automatically enter or leave qualified counters when the actor's current status changes.