Библиотеки для сервера: Node.js и Python
Обе библиотеки — тонкие клиенты API партнёра и проверка подписи вебхуков. Зависимостей у них нет. Ключ API передаётся только на сервере: в браузер и мобильное приложение он попадать не должен.
Node.js — @whiteboard-studio/partner
Node 18 и новее (нужен встроенный fetch).
import { WhiteboardPartner, WhiteboardApiError, parseWebhook } from '@whiteboard-studio/partner'
const wb = new WhiteboardPartner({ apiKey: process.env.WB_API_KEY! })Параметры конструктора
| Параметр | По умолчанию | |
|---|---|---|
apiKey | обязательно | ключ вида wbk_… |
baseUrl | https://api.rismik.ru | адрес API |
timeoutMs | 15 000 | сколько ждать ответа |
fetch | глобальный fetch | своя реализация, например для тестов |
Методы
| Метод | Что делает | API |
|---|---|---|
createLesson({ title, externalId?, mode?, subjectMode? }) | создаёт урок; mode: 'full' или 'board_only' | POST /lessons |
getLesson(id) | урок по нашему id | GET /lessons/{id} |
findLesson(externalId) | урок по вашему id или null | GET /lessons?external_id= |
archiveLesson(id) | архивирует урок | DELETE /lessons/{id} |
createLink(lessonId, { id, name, role }, { ttlMinutes? }) | личная ссылка участника; role: 'teacher' или 'student' | POST /lessons/{id}/links |
snapshot(lessonId) | содержимое доски в JSON | GET /lessons/{id}/snapshot |
preview(lessonId) | миниатюра доски, PNG в ArrayBuffer | GET /lessons/{id}/preview |
balance() | остаток минут | GET /balance |
usage({ from?, to? }) | минуты по урокам и дням | GET /usage |
setWebhook(url) | адрес вебхука; возвращает новый секрет | PUT /webhook |
deleteWebhook() | отключает вебхук | DELETE /webhook |
testWebhook() | отправляет событие webhook.test | POST /webhook/test |
Ошибка API — исключение WhiteboardApiError с полями status (HTTP), code (например not_found, minutes_exhausted) и текстом. Коды перечислены в api.md.
Вебхук
// Express: тело нужно сырым — подпись считается по байтам, а не по разобранному JSON.
app.post('/hooks/whiteboard', express.raw({ type: 'application/json' }), (req, res) => {
const event = parseWebhook({ secret: process.env.WB_WEBHOOK_SECRET!, header: req.get('X-Whiteboard-Signature'), body: req.body })
if (!event) return res.sendStatus(400)
queue.push(event) // обработайте позже, ответить нужно быстро
res.sendStatus(204)
})verifyWebhook({ secret, header, body, toleranceSeconds? }) — только проверка, true/false. По умолчанию подпись старше 5 минут не принимается.
Типы TypeScript в комплекте: Lesson, Link, Balance, Usage, WebhookEvent и другие.
Python — whiteboard_partner
Python 3.9 и новее, только стандартная библиотека.
from whiteboard_partner import Client, WhiteboardApiError, parse_webhook
wb = Client(api_key=os.environ["WB_API_KEY"]) # base_url=…, timeout=15.0| Метод | Что делает |
|---|---|
create_lesson(title, external_id=None, mode="full", subject_mode=None) | создаёт урок |
get_lesson(lesson_id) | урок по нашему id |
find_lesson(external_id) | урок по вашему id или None |
archive_lesson(lesson_id) | архивирует урок |
create_link(lesson_id, *, user_id, name, role, ttl_minutes=None) | личная ссылка участника |
snapshot(lesson_id) | содержимое доски (dict) |
preview(lesson_id) | миниатюра, PNG (bytes) |
balance() | остаток минут |
usage(date_from=None, date_to=None) | минуты по урокам и дням |
set_webhook(url) · delete_webhook() · test_webhook() | вебхук |
Ошибка API — WhiteboardApiError с атрибутами status, code, detail.
Вебхук (Django)
def whiteboard_hook(request):
event = parse_webhook(settings.WB_WEBHOOK_SECRET, request.headers.get("X-Whiteboard-Signature"), request.body)
if event is None:
return HttpResponse(status=400)
queue.enqueue(event)
return HttpResponse(status=204)verify_webhook(secret, header, body, tolerance=300) — только проверка.
Пакеты для страницы
Фрейм, события и команды — @whiteboard-studio/embed и компонент для React @whiteboard-studio/embed-react. Они описаны в frame.md.