Metadata-Version: 2.4
Name: sellor-plugin-sdk
Version: 1.0.0
Summary: SDK и CLI для разработки плагинов Sellor
Author: Sellor
License: MIT
Project-URL: Homepage, https://sellor.net/developers
Project-URL: Documentation, https://sellor.net/developers/docs
Keywords: sellor,funpay,playerok,g2g,plugins
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# Sellor Plugin SDK

SDK и CLI для разработки плагинов [Sellor](https://sellor.net). Плагин — самостоятельный
процесс: он не исполняется внутри backend Sellor и общается с платформой только через
Broker API по токену конкретной установки.

Полная документация: <https://sellor.net/developers/docs>

## Установка

```bash
pip install sellor-plugin-sdk
```

Зависимостей нет — только стандартная библиотека Python 3.11+.

## Путь от идеи до публикации

```bash
sellor-plugin init review-bot      # шаблон плагина
cd review-bot
sellor-plugin doctor .             # проверка манифеста, прав и схемы настроек
sellor-plugin pack .               # детерминированный review-bot-0.1.0.slpkg

export SELLOR_SDK_TOKEN=sdk_...    # выпускается в кабинете разработчика
sellor-plugin publish . --upload   # версия уходит на ревью
```

`sellor-plugin doctor` повторяет серверные правила: если он молчит, загрузка не упадёт
на валидации манифеста.

## Структура плагина

```
review-bot/
├─ sellor.plugin.json   манифест: права, события, схема настроек, цена
├─ main.py              точка входа из runner.entrypoint
└─ README.md
```

## Обработчики

```python
from sellor_sdk import Plugin

plugin = Plugin()


@plugin.on("review.created")
async def reply_to_review(ctx, event):
    review = event.payload["review"]
    if review["rating"] < 4 and not ctx.config["answerLow"]:
        raise ctx.skip("низкая оценка, отвечаем вручную")

    await ctx.chat.send(
        account_id=event.account_id,
        chat_id=review["chatId"],
        text=ctx.render(ctx.config["reply"], buyer=review["buyer"]),
    )
    await ctx.log.info(f"ответили на отзыв {review['id']}")


if __name__ == "__main__":
    plugin.run()
```

Что даёт `ctx`:

| Объект | Назначение |
| --- | --- |
| `ctx.config` | значения настроек установки, уже приведённые к типам схемы |
| `ctx.chat.send / mark_read / history` | работа с диалогами, требует `chats:*` |
| `ctx.orders() / ctx.lots() / ctx.balance()` | чтение рабочих данных |
| `ctx.storage.get / set / delete / seen` | состояние между запусками, требует `storage:write` |
| `ctx.secrets.get(key)` | расшифрованные секреты установки, требует `secrets:read` |
| `ctx.log.info / warn / error` | журнал, видимый продавцу в панели |
| `ctx.render(template, **vars)` | подстановка `{buyer}`, `{order}` и других переменных |
| `raise ctx.skip(reason)` | подтвердить событие без действия |

Необработанное исключение помечает событие как неуспешное; событие с ключом дедупликации
повторно не приходит, поэтому идемпотентность удобно держать через `ctx.storage.seen(...)`.

## Запуск установленного плагина

```bash
export SELLOR_BROKER_TOKEN=blk_...   # выдаётся продавцу при установке
python main.py
```

Broker-токен привязан к одной установке. Продавец может ротировать его в панели —
старый перестаёт работать немедленно, и раннер завершится с сообщением «Доступ отозван».

## Границы

- Плагин не получает `golden_key`, cookie площадок и доступ к базе Sellor.
- Права из манифеста проверяются на каждом вызове Broker API.
- Права `orders:refund`, `lots:write` и `net:external` считаются доверенными
  и включаются только после ручного ревью пакета.
- Публикация в общедоступный каталог — всегда после ревью; уже опубликованная версия
  продолжает работать у покупателей, пока новая проверяется.
