Перейти к основному содержимому

Quick Start

В этом руководстве — /ping бот, который отвечает «pong». От нуля до работающего deployment за 5 минут.

Шаг 1. Создать бота

Открыть Settings

В UI Reason Space: правый верхний угол → аватарка → SettingsБоты.

Создать

Кнопка Создать бота. Имя: Echo, username: echo_bot. После создания UI покажет BOT_TOKEN вида bot_xxxxxxxx….

Токен показывается один раз. Сохраните его сразу — повторно получить нельзя. Если потеряется — кнопка Rotate на странице бота.

Пригласить в Space

На странице бота → Пригласить в Space. Выберите space, отметьте:

  • Scopes: commands (право регистрировать slash-команды и принимать событие command.invoked). Для отправки сообщений в канал добавьте messages.send.
  • Channels: text-канал, где будут вызывать /ping

Scope commands запрашивается именно здесь, при invite, — не в коде бота. Сама регистрация набора команд (PUT /api/bot/commands) — глобальная и от scope не зависит. Но без commands ваш бот не появится в каталоге команд канала (GET /api/chat/{space}/{channel}/commands), а юзеры не смогут вызвать его команды (invoke → 403). Полный список — Scopes.

Шаг 2. Установить SDK

pip install 'reasonspace-bot[server]'

Extra [server] подтягивает uvicorn, нужный для встроенного bot.run() (Шаг 5). Без него bot.run() бросит RuntimeError. В основные зависимости SDK входят только httpx и starlette.

Шаг 3. Написать бота

Бот регистрирует свой набор slash-команд (bulk-overwrite через PUT /api/bot/commands) и обрабатывает вызов команды на событии command.invoked. Имя команды передаётся без слэша.

import asyncio

from reasonspace_bot import Bot, CommandInvokedEvent

bot = Bot() # читает BOT_TOKEN + WEBHOOK_SECRET из env

@bot.command("ping") # имя без слэша; ловит /ping в чате
async def on_ping(event: CommandInvokedEvent) -> None:
# Эфемерный ответ — виден только тому, кто вызвал команду.
await bot.respond(event, "🏓 pong")

async def setup() -> None:
# Декларируем ВЕСЬ набор команд бота (idempotent overwrite).
await bot.client.register_commands([
{"name": "ping", "description": "Проверка связи", "options": []},
])

if __name__ == "__main__":
asyncio.run(setup())
bot.run(port=8765)

@bot.command("ping") — имя без /, без параметров scope= и description=. Хендлер получает CommandInvokedEvent (поля command, channel_id, actor_user_id, options, interaction_token), а эфемерный ответ инвокеру отправляется через await bot.respond(event, content) — под капотом это POST /api/bot/interactions/respond. Подробнее — Команды.

Шаг 4. Создать webhook

На странице бота → WebhooksСоздать:

  • URL: http://localhost:8765/webhook (или туннель, если бот не на той же машине)
  • Events: ☑ command.invoked

UI покажет WEBHOOK_SECRET — также один раз. Сохраните.

Шаг 5. Запустить

export BOT_TOKEN=bot_xxxxxxxxxxxx
export WEBHOOK_SECRET=whsec_xxxxxxxxxxxx
export REASONSPACE_API=https://api.reasonspace.ru # опционально

python bot.py
# → INFO Uvicorn running on http://0.0.0.0:8765

Зайдите в Reason Space → в канал, куда пригласили бота → вызовите /ping → бот ответит 🏓 pong эфемерно (ответ увидите только вы).

E2E: Reason Space шифрует chat-сообщения end-to-end, и бот не может прочитать обычный текст из ленты. Обычные сообщения юзеров боту как webhook не доставляются — единственный inbound-канал юзер→бот — это slash-команды. Текст приходит только как структурированные options команды внутри события command.invoked (по явному opt-in юзера, привязаны к схеме команды и не попадают в ленту/модерацию). См. Privacy и Команды.

Дальше