Per-channel доступ
Reason Space permission-model — это двумерная решётка:
scopes →
┌───────────┬───────────┬───────────┐
│ messages │ voice │ moderation│
│ .send │ .join │ .messages │
├───────────┼───────────┼───────────┤
#general │ ✅ │ ❌ │ ❌ │
├───────────┼───────────┼───────────┤
#music │ ✅ │ ✅ │ ❌ │
├───────────┼───────────┼───────────┤
#private │ ❌ │ ❌ │ ❌ │ (бот не в allowed_channels)
└───────────┴───────────┴───────────┘
Запрос на канал, которого нет в allowed_channel_ids — 403 channel_denied + audit.
При invite
Owner выбирает каналы через UI:
Settings → Боты → выбрать бот → Пригласить в Space →
→ Step 2: «На каких каналах работает бот?»
☑ #general
☑ #music
☐ #private (приватный, бот не имеет доступа)
В БД это bot_memberships.allowed_channel_ids: uuid[].
Изменение
Owner может в любой момент добавить / убрать каналы:
curl -X PATCH https://api.reasonspace.ru/api/spaces/{space_id}/bots/{bot_user_id} \
-H "Authorization: Bearer <owner_jwt>" \
-H "Content-Type: application/json" \
-d '{
"channel_ids": ["<new uuid>", "<another>"]
}'
→ Бот сразу теряет / получает доступ.
Что значит «канал доступен»
| Scope | Что бот может в канале |
|---|---|
messages.read | Читать сообщения этого канала |
messages.send | Отправлять в этот канал |
messages.react | Реагировать на сообщения в этом канале |
voice.join | Подключаться к этому voice-каналу (если он voice-типа) |
Cross-channel ничего не работает: даже с messages.send бот не может
отправить в #private, если его там нет.
Voice-каналы
Voice-каналы — это тоже allowed_channel_ids. Если хочешь чтобы music-бот
играл в #voice-1, добавь его в этот канал. Если в #voice-2 тоже —
добавь и его.
Лимит
Отдельного лимита на число каналов в membership на стороне bot-API нет —
ограничение только естественное: бот может работать лишь в тех каналах,
которые реально существуют в этом space. При invite / изменении каждый
channel_id проверяется на принадлежность space (иначе 400), но
количество не ограничивается.