Sellor Plugin SDK
Плагин Sellor — самостоятельное приложение на Python, которое общается с платформой только через Broker API. Схема манифеста — sellor.plugin/v1.
Быстрый старт
pip install sellor-plugin-sdk
sellor-plugin init thanks-bot # шаблон плагина
cd thanks-bot
sellor-plugin doctor . # проверка манифеста и схемы настроек
sellor-plugin pack . # сборка thanks-bot-1.0.0.slpkg
export SELLOR_SDK_TOKEN=sdk_… # выдаётся в кабинете разработчика
sellor-plugin publish . --upload Если PyPI недоступен, SDK 1.0.0 ставится с зеркала: pip install https://sellor.net/sdk/sellor_plugin_sdk-1.0.0-py3-none-any.whl. Исходники — отдельным архивом.
SDK-токен нужен только для загрузки пакета. Он не устанавливает плагин и не даёт доступа к данным продавцов.
Структура плагина
thanks-bot/
├─ sellor.plugin.json # манифест: права, события, схема настроек, цена
├─ main.py # точка входа, объявленная в runner.entrypoint
├─ requirements.txt # опционально, только чистый Python
└─ README.mdМанифест
{
"schema": "sellor.plugin/v1",
"slug": "thanks-bot",
"name": "Спасибо за покупку",
"version": "1.0.0",
"summary": "Пишет покупателю после выполненного заказа.",
"description": "Полное описание для страницы плагина.",
"category": "Заказы",
"accent": "amber",
"icon": "star",
"marketplaces": ["FunPay", "Playerok"],
"permissions": ["orders:read", "chats:send", "logs:write"],
"events": ["order.completed"],
"runner": { "mode": "managed", "entrypoint": "main.py", "python": ">=3.11" },
"settings": [
{ "key": "reply", "label": "Текст ответа", "type": "textarea",
"default": "Спасибо за отзыв!", "required": true }
],
"support": { "contact": "@your_handle", "refund": "Возврат в течение 14 дней." },
"pricing": { "model": "subscription", "amountCents": 30000, "periodDays": 30, "trialDays": 3 },
"sdk": "2026-07-26"
}- slug — латиница, цифры и дефис. Вместе с витриной образует адрес плагина.
- version — SemVer. Повторно загрузить ту же версию нельзя.
- runner.mode —
managed(внутри Sellor Connector) илиstandalone(свой сервер). - pricing.model —
free,one_timeилиsubscription; минимальная платная цена 10 ₽. - support.contact обязателен: покупатель должен знать, куда писать.
Схема настроек
Схема из манифеста рендерится дважды: на публичной странице плагина в блоке «Как выглядит в Sellor» и в панели продавца при установке. Значения приходят в рантайм уже приведёнными к типам — валидировать их повторно не нужно.
| Тип | Поле | Правила |
|---|---|---|
text | Однострочное поле | Строка до 500 символов. |
textarea | Многострочное поле | Строка до 8 000 символов, для шаблонов сообщений. |
number | Число | Целое в диапазоне min…max, значения за пределами обрезаются. |
toggle | Переключатель | Булево значение. |
select | Выбор из списка | Нужен непустой options: [{ value, label }]. |
tags | Список строк | До 40 значений, каждое до 120 символов. |
secret | Секрет | Хранится зашифрованным, покупателю и в конфиге не возвращается — только через secrets:read. |
Права
Права запрашиваются в манифесте и показываются покупателю до установки. Broker API проверяет их на каждом вызове. Доверенные права включаются только после ручного ревью.
| Право | Что даёт | Ревью |
|---|---|---|
chats:read | Чтение чатов и сообщенийПлагин видит переписку выбранных аккаунтов. | автоматически |
chats:send | Отправка сообщений покупателямПлагин может писать покупателям от вашего имени. | автоматически |
orders:read | Чтение заказовПлагин видит список и статусы заказов. | автоматически |
orders:refund | Возврат заказовПлагин может вернуть деньги покупателю. | вручную |
lots:read | Чтение лотовПлагин видит названия, цены и остатки лотов. | автоматически |
lots:write | Изменение лотовПлагин может менять цену и активность лотов. | вручную |
reviews:read | Чтение отзывовПлагин видит новые отзывы и оценки. | автоматически |
balance:read | Чтение балансаПлагин видит баланс подключённых аккаунтов. | автоматически |
storage:write | Собственное хранилище плагинаПлагин хранит своё состояние между запусками. | автоматически |
secrets:read | Доступ к своим секретамПлагин читает ключи, которые вы сами ему выдали. | автоматически |
logs:write | Запись в журналПлагин пишет строки в журнал запусков. | автоматически |
net:external | Запросы к внешним сервисамПлагин обращается к сторонним API со своего процесса. | вручную |
События
События появляются, когда Sellor Connector присылает свежий снимок аккаунта. Каждое событие уникально по ключу дедупликации — повторной доставки одного и того же сообщения или заказа не будет. Событие живёт 6 часов.
| Событие | Когда приходит | Статус |
|---|---|---|
message.created | Новое сообщение в чате | доставляется |
chat.unread | Непрочитанный диалог | доставляется |
order.created | Новый заказ | доставляется |
order.processing | Заказ в работе | доставляется |
order.completed | Заказ выполнен | доставляется |
order.refunded | Возврат по заказу | доставляется |
review.created | Новый отзыв | доставляется |
lot.updated | Изменение лота | доставляется |
balance.changed | Изменение баланса | доставляется |
schedule.tick | Событие по расписанию | доставляется |
Событие со статусом «готовится» пока не порождается платформой: коннектор не собирает эти данные. Манифест с таким событием загрузку не пройдёт — плагин просто молчал бы у покупателя.
Python-рантайм
from sellor_sdk import Plugin
plugin = Plugin()
@plugin.on("order.completed")
async def thank_buyer(ctx, event):
order = event.payload["order"]
if not order.get("chatId"):
raise ctx.skip("у заказа нет диалога")
if await ctx.storage.seen(f"thanked:{order['id']}"):
raise ctx.skip("уже благодарили за этот заказ")
await ctx.chat.send(
account_id=event.account_id,
chat_id=order["chatId"],
text=ctx.render(ctx.config["reply"], buyer=order["buyer"]),
)
await ctx.log.info(f"поблагодарили за заказ {order['id']}")
if __name__ == "__main__":
plugin.run()ctx.config— значения настроек установки, уже приведённые к типам.ctx.storage—get/set/delete, состояние между запусками.ctx.secrets.get(key)— секреты установки, требуетsecrets:read.ctx.orders / ctx.lots / ctx.chats / ctx.balance— чтение рабочих данных.ctx.skip(reason)— подтвердить событие без действия, чтобы оно не пришло снова.
Broker API
Все запросы идут с заголовком Authorization: Bearer blk_…. Токен привязан к одной установке; продавец может ротировать его в панели в любой момент.
| Метод | Путь | Назначение |
|---|---|---|
| GET | /api/broker/v1/handshake | Манифест установки, права, конфиг, аккаунты. |
| GET | /api/broker/v1/events?limit=20 | Забрать события. Без ack событие вернётся через 2 минуты. |
| POST | /api/broker/v1/events/{id}/ack | Подтвердить обработку: { ok, detail }. |
| POST | /api/broker/v1/actions/chat.send | Отправить сообщение: { accountId, chatId, text }. Нужно chats:send. |
| POST | /api/broker/v1/actions/chat.markRead | Пометить диалог прочитанным. Нужно chats:read. |
| POST | /api/broker/v1/actions/account.sync | Запросить внеочередную синхронизацию аккаунта. |
| GET | /api/broker/v1/orders?limit=50 | Заказы подключённых аккаунтов. Нужно orders:read. |
| GET | /api/broker/v1/lots?limit=100 | Лоты подключённых аккаунтов. Нужно lots:read. |
| GET | /api/broker/v1/balance | Баланс аккаунтов. Нужно balance:read. |
| GET | /api/broker/v1/chats/{chatId}/messages | История диалога. Нужно chats:read. |
| GET/PUT/DELETE | /api/broker/v1/storage/{key} | Хранилище плагина: 500 ключей, 100 КБ на значение. |
| GET | /api/broker/v1/secrets/{key} | Расшифрованный секрет установки. Нужно secrets:read. |
| POST | /api/broker/v1/logs | Запись в журнал: { level, message }. Нужно logs:write. |
| POST | /api/broker/v1/heartbeat | Отметка «раннер жив», раз в 30–60 секунд. |
Публикация
- Откройте витрину разработчика в панели Sellor и выпустите SDK-токен — он показывается один раз.
- Соберите пакет:
sellor-plugin pack .. Контрольная сумма считается по содержимому. - Загрузите:
sellor-plugin publish . --upload. Версия попадает в очередь ревью. - Ревью проверяет права, схему настроек, секреты, разницу пакета и правила поддержки и возврата.
- После одобрения плагин появляется в публичном каталоге, а обновления уходят покупателям.
Уже опубликованный плагин продолжает работать на прежней версии, пока новая не пройдёт ревью — обновление не может внезапно сломать покупателям автоматизацию.
Открыть кабинет разработчика