К содержанию
Playerok · Разработчикам

Плагины для Playerok

API ctx.playerok, разрешения, события playerok.*, выдача товара плагином и единый баланс.

Содержание

Плагин для Playerok работает с аккаунтом продавца через API Lovsel: читает сделки, чаты и товары, пишет покупателям, выдаёт товар и реагирует на события площадки. Плагин не получает cookies, токен и прокси продавца — запросы к Playerok выполняет Lovsel. Возвраты денег, публикация и платное продвижение из плагина недоступны: эти действия выполняет продавец в кабинете.

Общие правила создания плагина — структура файла, страницы, формы, операции, публикация — в руководстве «Как создать плагин». Здесь — только то, что относится к Playerok.

Манифест

python
MANIFEST = {
    "id": "studio.playerok-helper",
    "name": "Помощник Playerok",
    "version": "1.0.0",
    "author": "Studio",
    "description": "Пишет покупателям Playerok после оплаты и подтверждения.",
    "permissions": ["orders.read", "chats.read", "chats.write", "storage"],
    "marketplaces": ["playerok"],        # ["funpay", "playerok"] — плагин для нескольких площадок
}
  • Плагин с ["playerok"] не запускается, пока у пользователя не подключён Playerok, и включается сам после подключения.
  • Старые плагины GGsel и FunPay совместимыми с Playerok не становятся: площадку нужно объявить явно.
  • Плагин получает события только объявленных площадок и не может обратиться к ctx.ggsel или ctx.funpay, если они не объявлены.

Разрешения

РазрешениеМетоды ctx.playerok
orders.readorders(), order(), delivery()
chats.readchats(), messages()
chats.writesend_message(), deliver()
products.readitems()
products.writeset_item_price()
reviews.readreviews()
balance.readbalance()

Каждый метод проверяет разрешение, объявленную площадку, принадлежность объекта подключённому аккаунту и активную подписку пользователя. Без них — PermissionDenied или KeyError с понятным текстом.

API ctx.playerok

Метод или свойствоЧто возвращаетОбращается к Playerok
ctx.playerok.connectedПодключён ли Playerok и объявлена ли площадка.нет
ctx.playerok.usernameНик продавца.нет
ctx.playerok.orders(limit=500, status="")Продажи текущего аккаунта, новые первыми.нет
ctx.playerok.order(order_id, refresh=False)Сделка; refresh=True — перечитать с Playerok.при refresh
ctx.playerok.chats(limit=100)Чаты: kind — buyer, support или system.нет
ctx.playerok.messages(chat_id, limit=50)Свежая переписка чата.да
ctx.playerok.send_message(chat_id, text)Сообщение в чат (до 2000 символов).да
ctx.playerok.deliver(order_id, text, mark_sent=True)Выдача товара сообщением в чат сделки.да
ctx.playerok.delivery(order_id)Состояние выдачи по сделке или None.нет
ctx.playerok.items(status="")Свои товары со статусами.нет
ctx.playerok.set_item_price(item_id, price)Новая цена в рублях (целое). Остальные поля не меняются.да
ctx.playerok.reviews(limit=100)Отзывы к сделкам.нет
ctx.playerok.balance()Баланс аккаунта на Playerok (не Lovsel).нет

Поля сделки: id (строка), title, amount, currency, status (paid, sent, success, refunded, waiting), raw_status (как на Playerok: PAID, SENT, CONFIRMED…), has_problem, is_automated, item_id, buyer, buyer_id, chat_id, obtaining_fields (данные покупателя), buyer_comment, created_at, marketplace. ID сделок, чатов и товаров Playerok — строки, а не числа.

Выдача товара плагином

deliver() использует ту же операцию выдачи, что и встроенная автовыдача: одна сделка — одна выдача.

python
@app.on("playerok.new_order")
def on_order(ctx, event):
    order = event["order"]
    if order["raw_status"] != "PAID":
        return
    result = ctx.playerok.deliver(order["id"], "Ваш код: " + take_code(ctx))
    if result["status"] == "busy":
        return                       # сделку выдаёт встроенная автовыдача или другой плагин
    if result["status"] == "unknown":
        ctx.log("Playerok не ответил — Lovsel сверит чат сам, повторять не нужно", "warning")
  • busy — сделку уже обслуживает другая выдача. Если продавец выбрал схему «Автовыдача Lovsel», плагин может выдать только сделку, к которой не подходит ни одно правило; при схеме «Плагины» встроенные правила не срабатывают.
  • bad_state — сделка не ждёт выдачи (уже отправлена, возврат, Playerok выдал товар сам).
  • unknown — Playerok не ответил на отправку: сообщение могло дойти. Не отправляйте товар повторно — выдача ждёт сверки и решения продавца.

События

СобытиеКогдаДанные
playerok.new_orderНовая продажа после подключенияorder
playerok.order_statusСтатус сделки изменилсяorder, old_status, old_raw_status
playerok.deal_problemПроблема открыта или решенаorder, opened
playerok.new_chatПервое сообщение в новом чатеchat_id, buyer, buyer_id, chat_type, message, order
playerok.new_messageСообщение покупателя или поддержкито же, плюс from (buyer или support)
playerok.new_reviewНовый отзывorder, chat_id, review (id, stars, text)
playerok.deliveryТовар по сделке отправленorder, mechanism, status

Во всех событиях event["marketplace"] == "playerok". Свои сообщения продавца, служебные уведомления площадки и старые события до подключения плагинам не приходят. Одно и то же событие не доставляется дважды при сверке и перезапуске, но обработчик всё равно должен быть идемпотентным: храните в ctx.storage, что уже сделано.

Единый баланс

ctx.wallet работает и для сделок Playerok: ctx.wallet.reserve(order_id, amount, marketplace="playerok"). Сделка должна существовать в Lovsel, площадка — быть объявленной в манифесте. Идемпотентность и изоляция операций — по пользователю, плагину, площадке, сделке и ключу, как для других площадок. Баланс Playerok и баланс Lovsel — разные деньги: закупки плагина оплачиваются только с баланса Lovsel. Подробнее — «Единый баланс в плагинах».

Проверка без сервера

python
from lovsel_sdk.testing import load_plugin

plugin = load_plugin("my_plugin.py", playerok={
    "orders": [{"id": "deal-1", "title": "Ключ", "amount": 199, "status": "PAID", "buyer": "anna",
                "chat_id": "chat-1", "item_id": "item-1"}],
    "chats": [{"id": "chat-1", "buyer": "anna"}],
})
plugin.emit("playerok.new_order", {"order": plugin.ctx.playerok.order("deal-1")})
assert plugin.playerok_sent[0]["chat_id"] == "chat-1"

Полный пример — docs/examples/playerok_greetings.py: приветствие после оплаты, благодарность после подтверждения и уведомление о плохом отзыве. Он ничего не создаёт на Playerok и не тратит деньги.