Skip to content

Запрос списка участников чата/группы.#75

Open
Gorily wants to merge 2 commits into
MaxApiTeam:dev/2.4.0from
Gorily:feature/get-chat-members
Open

Запрос списка участников чата/группы.#75
Gorily wants to merge 2 commits into
MaxApiTeam:dev/2.4.0from
Gorily:feature/get-chat-members

Conversation

@Gorily

@Gorily Gorily commented Jul 16, 2026

Copy link
Copy Markdown

Описание

Добавляет возможность получения списка участников чата или группы.

При работе с библиотекой оказалось, что chat = await client.get_chat(channel_id) и последующий chat.participants выдают только 1 участника. Проверил в протоколе - действительно, данные не передаются. Написал метод по получению всех участников.

Тип изменений

  • Исправление бага
  • Новая функциональность
  • Улучшение документации
  • Рефакторинг

Связанные задачи / Issue

Ссылка на issue, если есть: #

Тестирование

Покажите пример кода, который проверяет изменения:

import pymax

# пример использования нового функционала
chat = await client.get_chat(channel_id)
members, marker = await client.get_chat_members(channel_id)
all_members = list(members)
while marker:
    page, marker = await client.get_chat_members(channel_id, marker)
    all_members.extend(page)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added the ability to retrieve chat members.
  * Supports optional pagination to load additional participants, returning both the current member page and a next-page marker when more results are available.
  * Returned participants are provided as fully integrated member objects for use across the client.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds chat-member retrieval support with a Pydantic request payload, API service method, pagination marker handling, member model binding, and a client-facing chat mixin wrapper.

Changes

Chat member retrieval

Layer / File(s) Summary
Member request and API service
src/pymax/api/chats/payloads.py, src/pymax/api/chats/enums.py, src/pymax/api/chats/service.py
Adds GetChatMembersPayload, the MARKER response key, and ChatService.get_chat_members with pagination and bound Member models.
Chat mixin wrapper
src/pymax/infra/chat.py
Exposes get_chat_members with an optional pagination marker and delegates to the chat API service.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ChatMixin
  participant ChatService
  participant ChatAPI
  ChatMixin->>ChatService: get_chat_members(chat_id, marker)
  ChatService->>ChatAPI: CHAT_MEMBERS with GetChatMembersPayload
  ChatAPI-->>ChatService: members and next marker
  ChatService-->>ChatMixin: bound Member models and next marker
Loading

Suggested reviewers: ink-developer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed Заголовок кратко и точно описывает добавление запроса списка участников чата или группы.
Description check ✅ Passed Описание в целом соответствует шаблону: есть цель, тип изменений и пример тестирования с кодом.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pymax/infra/chat.py`:
- Around line 214-228: Update get_chat_members to follow pagination until all
member pages are retrieved, using each response’s next-page marker to request
subsequent pages and combining the results into one list. Preserve the existing
chat_id and optional marker as the starting point, and return the complete
member collection through the public wrapper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7176c637-8ae3-44bc-ac3d-88ae3988785c

📥 Commits

Reviewing files that changed from the base of the PR and between 8c40b71 and 8ec73c3.

📒 Files selected for processing (3)
  • src/pymax/api/chats/payloads.py
  • src/pymax/api/chats/service.py
  • src/pymax/infra/chat.py

Comment thread src/pymax/infra/chat.py Outdated
Comment on lines +214 to +228
async def get_chat_members(self, chat_id: int, marker: int | None = None) -> list[Member]:
"""Возвращает участников чата по ID.

Args:
chat_id: ID чата.
marker: Маркер пагинации. Если ``None``, запрашивается первая
страница.

Returns:
Список участников.

Raises:
PyMaxError: Если сервер не вернул участников.
"""
return await self._app.api.chats.get_chat_members(chat_id, marker)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Make the public wrapper complete pagination.

This wrapper exposes a method described as retrieving chat members, but it forwards a single-page request and provides no next-page marker. Users cannot obtain members beyond the first 50 through the documented API.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pymax/infra/chat.py` around lines 214 - 228, Update get_chat_members to
follow pagination until all member pages are retrieved, using each response’s
next-page marker to request subsequent pages and combining the results into one
list. Preserve the existing chat_id and optional marker as the starting point,
and return the complete member collection through the public wrapper.

@ink-developer

Copy link
Copy Markdown
Collaborator

Спасибо за PR

Проблема в том, что по моему CHAT_MEMBERS по мимо самих юзеров еще и маркер возвращает. И соответственно человек не сможет получить больше юзеров кроме первых 50

Нужно возвращать либо tuple[list[Member], int] или полноценную модель

@Gorily

Gorily commented Jul 16, 2026

Copy link
Copy Markdown
Author

Нужно возвращать либо tuple[list[Member], int] или полноценную модель

А как насчет варианта самим проходится и отдавать всех подписчиков?
Примерно так:

async def get_chat_members(self, chat_id: int, marker: int | None = None) -> list[Member]:
    members: list[Member] = []
    next_marker = marker or 0

    while True:
        frame = GetChatMembersPayload(chat_id=chat_id, marker=next_marker)
        response = await self.app.invoke(Opcode.CHAT_MEMBERS, frame.to_payload())
        members.extend(parse_payload_list(response, ChatPayloadKey.MEMBERS, Member))

        next_marker = payload_item(response, ChatPayloadKey.MARKER, int)
        if next_marker is None:
            break

    return bind_api_model(self.app, members)

@Gorily

Gorily commented Jul 16, 2026

Copy link
Copy Markdown
Author

Или как вы предложили:

    async def get_chat_members(
        self,
        chat_id: int,
        marker: int | None = None,
    ) -> tuple[list[Member], int]:
        frame = GetChatMembersPayload(chat_id=chat_id, marker=marker or 0)
        response = await self.app.invoke(Opcode.CHAT_MEMBERS, frame.to_payload())

        members = bind_api_model(
            self.app,
            parse_payload_list(response, ChatPayloadKey.MEMBERS, Member),
        )
        next_marker = payload_item(response, ChatPayloadKey.MARKER, int) or 0
        return members, next_marker

Вариант с моделью выглядит как излишний, тут частная ситуация.

@ink-developer

Copy link
Copy Markdown
Collaborator

Пользователей может быть слишком много или юзеру нужно ограниченное количество
Лучше все же отдавать маркер

@ink-developer
ink-developer changed the base branch from main to dev/2.4.0 July 17, 2026 17:32
@ink-developer

Copy link
Copy Markdown
Collaborator

Так, еще одна проблема, нету параметра count (Хотя в пейлоаде он есть)
Можно его просто сделать опциональным и по дефолту 50

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants