Сначала запустите один сценарий
Для первого результата не нужен собственный модуль. Соберите сценарий, проверьте его, опубликуйте и только затем подключайте реальное событие.
Создайте сценарий
Объявите типизированные входы и соберите все ветки от «Запуска» до результата.
Проверьте
Тестовый запуск покажет входы, результаты шагов и точное место ошибки.
Опубликуйте
Публикация создаёт неизменяемую ревизию. Следующие изменения останутся в новом черновике.
Подключите событие
Выберите точную версию модуля, событие, условия запуска и сопоставьте его поля со входами.
Запустите и следите
Включите подключение и отслеживайте события, повторы, очередь доставки и метрики исполнения.
Создайте аккаунт и проверьте встроенный сценарий до разработки интеграции.
Что именно вы встраиваете?
Публичный Edge SDK поддерживает два типа расширений. Marketplace-модуль описывает площадку целиком; adapter-driver добавляет операции одного специализированного API.
Marketplace-модуль
Для площадки с заказами, сообщениями, каталогом и действиями от имени продавца.
- принимает события
- может публиковать каталоги
- credentials остаются в Edge
Managed adapter
Для специализированного API с HMAC, TOTP, сессиями, IP allowlist или локальными secrets.
- объявляет операции
- подписанный manifest
- блоки видит только владелец
Как добавить свой маркетплейс
Модуль переводит API конкретной площадки в версионированные события, действия и каталоги Buywell. SDK берёт на себя протокол Edge, доставку, heartbeat и package manifest.
1. Опишите контракт
Выберите стабильный extension ID и semver. Объявите Pydantic-модели событий и действий с одинаковым смыслом полей на RU и EN.
2. Подключите provider
В on_start запустите клиент площадки. Передавайте только ожидаемые события через session.emit_event и задавайте детерминированный event_id для дедупликации.
3. Добавьте действия
Каждый action получает типизированный input и возвращает только output своей схемы. Повторная доставка использует один idempotency key.
4. Соберите пакет
Локальный builder генерирует Manifest v2, фиксирует файлы и зависимости, считает digest и подписывает детерминированный архив.
5. Проверьте в Edge
Установите пакет в dev mode, подключите тестовый аккаунт, проверьте health, событие, повторную доставку и обновление с предыдущей версии.
Установите публичный SDK
В репозитории Edge находятся daemon, CLI, сборщик пакетов и тот же Python SDK, которым пользуются официальные интеграции.
github.com/moreveal/buywell-edge ↗git clone https://github.com/moreveal/buywell-edge.git
cd buywell-edge
python3.12 -m venv .venv
. .venv/bin/activate
pip install -e '.[test]'
# From your extension repository:
buywell-edge module build extension:extension --source .import asyncio
from pydantic import BaseModel
from buywell_edge_sdk import contract_field, module
class PaidOrder(BaseModel):
order_id: str = contract_field(
label={"ru": "Номер заказа", "en": "Order ID"},
)
buyer: str = contract_field(
label={"ru": "Покупатель", "en": "Buyer"},
)
extension = module(
extension_id="example.market",
version="1.0.0",
display_name={"ru": "Пример", "en": "Example"},
publisher="Example",
entrypoint="extension:extension",
network_domains=["api.example.com"],
)
@extension.event(
"commerce.purchase.created",
"1.0.0",
payload_model=PaidOrder,
identity_fields=["order_id"],
display_name={"ru": "Заказ оплачен", "en": "Order paid"},
)
async def paid_order_contract(_context):
return {}
async def forward_order(session, order):
await session.emit_event(
"commerce.purchase.created",
"1.0.0",
PaidOrder(order_id=order.id, buyer=order.buyer).model_dump(),
{"shopId": order.shop_id},
event_id=f"example:{order.id}:paid",
)Не реализуйте WebSocket Buywell, leases, outbox и heartbeat внутри расширения — это ответственность Edge.
Не кладите токены площадки в пакет, manifest или workflow. Configuration secrets принадлежат локальному подключению.
Trigger selectors фильтруют запуск; binding fields и catalogs поставляют типизированные значения. Это разные контракты.
Изменение публичного события, action или поля требует новой версии контракта. Обновление внутреннего provider-кода — не всегда.
Как сделать подписанный adapter-driver
Используйте managed adapter, когда запрос нельзя честно описать обычным облачным HTTP-адаптером. Драйвер выполняется рядом с пользователем, а его блоки появляются только после проверки подписи и live-подключения.
- HMAC или нестандартная подпись каждого запроса
- TOTP, refresh-сессия или device identity
- IP allowlist на стороне поставщика
- локальная библиотека или pinned upstream
- секреты не должны покидать устройство пользователя
from pydantic import BaseModel, SecretStr
from buywell_edge_sdk import adapter_driver, contract_field
class Settings(BaseModel):
api_key: SecretStr
class ReserveRequest(BaseModel):
item_id: str = contract_field(
label={"ru": "ID товара", "en": "Item ID"},
)
class ReserveResult(BaseModel):
reserved: bool = contract_field(
label={"ru": "Зарезервировано", "en": "Reserved"},
)
driver = adapter_driver(
extension_id="adapter.example-supplier",
version="1.0.0",
display_name={"ru": "Поставщик", "en": "Supplier"},
publisher="Example",
entrypoint="driver:driver",
config_model=Settings,
network_domains=["api.example.com"],
)
@driver.operation(
"adapter.example-supplier/reserve",
"1.0.0",
input_model=ReserveRequest,
output_model=ReserveResult,
display_name={"ru": "Зарезервировать", "en": "Reserve"},
)
async def reserve(context, value):
# Sign the provider request here with context.secrets["api_key"].
return ReserveResult(reserved=True)Secrets локальны
SecretStr и secret metadata попадают в configuration.secretFields и не становятся входами сценария.
Сеть ограничена
Пакет заранее объявляет network_domains. Разрешение не выводится из пользовательского URL.
Контракт подписан
Edge передаёт manifest, digest и Ed25519-подпись; Buywell проверяет их до регистрации операций.
Видимость изолирована
Операции создаются только для аккаунта с этим подтверждённым подключением и исчезают вместе с ним.
Pydantic-модели становятся схемами операций, contract_field задаёт локализованные подписи UI. Подписанные секции managedAdapter и adapterOperations создают блоки только для этого аккаунта; дублировать cloud-definition не нужно.
Смотрите на рабочие реализации
Официальные расширения используют тот же публичный SDK и тот же формат пакета, что и сторонние разработчики.
moreveal/buywell-runtimes
Репозиторий buywell-runtimes — источник истины для исходников официальных интеграций и их неизменяемых release-пакетов.
FunPay Cardinal
Заказы, статусы, сообщения, ответы, формы покупателя и каталог.
Открыть исходники ↗Marketplace moduleGGSel Seller
Покупки, сообщения, ответы, формы и каталог товаров продавца.
Открыть исходники ↗Marketplace modulePlayerok Universal
Продажи, сообщения, контекстные ответы, формы и каталоги категорий.
Открыть исходники ↗Managed adapterNSGifts
Подпись запросов, TOTP, IP allowlist, диагностика и live-каталог остатков.
Открыть исходники ↗buywell-automationControl plane, контракты сценариев, валидация, редактор и выполнение.
buywell-edgeПользовательский daemon, CLI, сборщик пакетов, публичный SDK и binary releases.
buywell-runtimesОфициальные реализации площадок, тесты, pinned upstreams и package releases.
Git остаётся источником истины
Версия, которую уже получил пользователь, неизменяема. Новый код публикуется новой версией, а старые workflow продолжают ссылаться на прежний контракт.
Исходники
Зафиксируйте реализацию, схемы, RU/EN guides, changelog и точные зависимости в публичном или проверяемом git commit.
Проверки
Прогоните unit tests, contract tests, self-test и тест обновления. Builder не должен получать файлы вне source tree.
Release
Создайте tag и release assets из этого commit. Опубликованный архив, digest и версия больше не перезаписываются.
Доставка
Официальный каталог указывает точный release URL и SHA-256. Edge скачивает, проверяет и переключает подключение атомарно.
Миграция
Новая версия устанавливается рядом. Смена контракта и перенос опубликованных сценариев всегда явные; скрытой миграции нет.
1.0.0неизменяема1.1.0новый пакетНовые интеграции, релизы Edge и runtime, изменения продукта и заметки о миграциях.
Полный справочник Manifest
Ниже — сгенерированный из текущего валидатора справочник полей и проверяемые примеры. Для Edge-пакетов предпочитайте типизированные декларации SDK ручному JSON.
Всё, что может объявить manifest.json
Каждый пример на этой странице проверяется тем же контрактом, который используется при установке пакета. Начните с компактного примера, а затем сверяйте события, источники данных, блоки и правила совместимости со справочником полей.
Для Buywell Edge Python SDK генерирует Manifest v2, схемы, список файлов, digest и подпись из типизированных деклараций. Подписанный adapter-driver сам поставляет управляемый адаптер и поля операций при подключении Edge; Buywell проверяет подпись до показа пользовательских блоков. Существующие модули могут сохранить весь manifest v1 как контракт совместимости.
{
"schemaVersion": 1,
"protocolVersion": "1.0.0",
"module": {
"id": "example.delivery",
"version": "1.0.0",
"displayName": "Example Delivery",
"description": "A minimal module package example.",
"publisher": "Example developer",
"supportedPlatforms": [
"Example Platform"
]
},
"nodes": [
{
"type": "example.delivery/send-message",
"version": "1.0.0",
"kind": "action",
"displayName": "Send message",
"localization": {
"ru": {
"displayName": "Отправить сообщение"
},
"en": {
"displayName": "Send message"
}
},
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
},
"required": [
"message"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"configSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"requiredEventContext": [
{
"eventType": "commerce.purchase.created",
"eventVersion": "1.0.0",
"source": "scope",
"path": "conversationId"
}
],
"ui": {
"category": "Messages",
"icon": "message"
}
}
],
"events": [
{
"type": "commerce.purchase.created",
"version": "1.0.0",
"displayName": "Purchase received",
"localization": {
"ru": {
"displayName": "Получена покупка"
},
"en": {
"displayName": "Purchase received"
}
},
"payloadSchema": {
"type": "object",
"properties": {
"purchaseId": {
"type": "string"
},
"recipient": {
"type": "string"
}
},
"required": [
"purchaseId",
"recipient"
],
"additionalProperties": false
},
"scopeSchema": {
"type": "object",
"properties": {
"conversationId": {
"type": "string"
},
"orderUrl": {
"type": "string"
}
},
"required": [
"conversationId",
"orderUrl"
],
"additionalProperties": false
},
"selectors": [],
"bindingFields": [
{
"id": "recipient",
"source": "payload",
"path": "recipient",
"valueSchema": {
"type": "string"
},
"displayName": "Recipient",
"localization": {
"ru": {
"displayName": "Получатель"
},
"en": {
"displayName": "Recipient"
}
},
"recommended": true,
"availability": "always"
}
],
"identityFields": [
"purchaseId"
],
"buyerForm": {
"returnUrl": {
"source": "scope",
"path": "orderUrl",
"allowedOrigins": [
"https://shop.example"
]
}
},
"ui": {
"category": "Sales",
"icon": "cart"
}
}
],
"abstractions": [
{
"abstractionId": "messaging.send-in-context",
"abstractionVersion": "1.0.0",
"nodeType": "example.delivery/send-message",
"nodeVersion": "1.0.0"
}
],
"package": {
"branding": {
"icon": "assets/icon.png"
},
"artifact": {
"path": "edge/driver.py",
"filename": "driver.py"
},
"guides": {
"installation": {
"ru": "guides/install.ru.md",
"en": "guides/install.en.md"
},
"readme": {
"ru": "guides/README.ru.md",
"en": "guides/README.en.md"
},
"changelog": {
"ru": "guides/CHANGELOG.ru.md",
"en": "guides/CHANGELOG.en.md"
}
},
"compatibility": {
"environments": [
"Example Runtime 1.x"
]
},
"release": {
"critical": false
}
}
}За что отвечает каждое поле и какие значения принимает
Корень manifest7 полей
Идентичность пакета, его содержимое и публичные возможности.
schemaVersion1обязательное полеМожно опустить: при разборе и в каноническом manifest становится 1. · по умолчанию: 1
protocolVersion"1.0.0"обязательное полеМожно опустить: при разборе и в каноническом manifest становится 1.0.0. · по умолчанию: "1.0.0"
moduleobjectобязательное полеИдентичность, издатель и поддерживаемые площадки. · лишние поля запрещены
nodesarrayобязательное полеБлоки, принадлежащие пакету. · максимум элементов: 100
eventsarrayВерсионируемые события модуля. · максимум элементов: 100
abstractionsarrayРеализации платформенно-нейтральных контрактов. · максимум элементов: 100
packageobjectФайлы архива, совместимость и сведения о релизе. · лишние поля запрещены
module10 полей
Назначение, допустимые значения и ограничения этой части manifest.
module.idstringобязательное полеСтрочные сегменты через точку или дефис, например example.delivery. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
module.versionstringобязательное полеФормат x.y.z с опциональным prerelease. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
module.displayNamestringобязательное полеОсновное название; localization может заменить его в RU/EN. · минимальная длина: 1 · максимальная длина: 120
module.descriptionstringКраткое пользовательское описание. · максимальная длина: 2000
module.publisherstringобязательное полеИмя издателя пакета. · минимальная длина: 1 · максимальная длина: 160
module.supportedPlatformsarrayобязательное полеЧеловекочитаемые названия поддерживаемых площадок. · минимум элементов: 1 · максимум элементов: 50
module.documentationobjectОпциональные HTTPS/HTTP homepageUrl, supportUrl и sourceUrl. · лишние поля запрещены
module.documentation.homepageUrlstringСсылка на страницу модуля или его издателя. · максимальная длина: 2048 · format: uri
module.documentation.supportUrlstringСсылка, по которой пользователь может получить поддержку модуля. · максимальная длина: 2048 · format: uri
module.documentation.sourceUrlstringСсылка на исходный код модуля, если издатель его публикует. · максимальная длина: 2048 · format: uri
nodes[]31 полей
Назначение, допустимые значения и ограничения этой части manifest.
nodes[].typestringобязательное полеОбязан начинаться с точного namespace module.id/. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)*\/[a-z][a-z0-9.-]*$
nodes[].versionstringобязательное полеВерсия контракта блока. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
nodes[].kind"action" | "condition"обязательное полеCondition требует branches; action запрещает branches.
nodes[].displayNamestringобязательное полеdisplayName обязателен; description и RU/EN localization опциональны. · минимальная длина: 1 · максимальная длина: 120
nodes[].descriptionstringdisplayName обязателен; description и RU/EN localization опциональны. · максимальная длина: 2000
nodes[].localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
nodes[].localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
nodes[].localization.ru.displayNamestringdisplayName обязателен; description и RU/EN localization опциональны. · минимальная длина: 1 · максимальная длина: 120
nodes[].localization.ru.descriptionstringdisplayName обязателен; description и RU/EN localization опциональны. · максимальная длина: 2000
nodes[].localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
nodes[].localization.en.displayNamestringdisplayName обязателен; description и RU/EN localization опциональны. · минимальная длина: 1 · максимальная длина: 120
nodes[].localization.en.descriptionstringdisplayName обязателен; description и RU/EN localization опциональны. · максимальная длина: 2000
nodes[].inputSchemavalueобязательное полеВходы действия или условия.
nodes[].outputSchemavalueобязательное полеПо умолчанию закрытые пустые объекты. · по умолчанию: {"type":"object","properties":{},"required":[],"additionalProperties":false}
nodes[].configSchemavalueобязательное полеПо умолчанию закрытые пустые объекты. · по умолчанию: {"type":"object","properties":{},"required":[],"additionalProperties":false}
nodes[].requiredEventContextarrayСуществующие eventType@version и payload/scope paths. · максимум элементов: 100
nodes[].requiredEventContext[].eventTypestringобязательное полеУказывает событие, контекст которого необходим блоку для выполнения. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
nodes[].requiredEventContext[].eventVersionstringобязательное полеЗакрепляет точную версию требуемого события. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
nodes[].requiredEventContext[].source"payload" | "scope"обязательное полеПуть обязан существовать в соответствующей схеме.
nodes[].requiredEventContext[].pathstringобязательное полеЕдинственный Edge-драйвер внутри архива. · минимальная длина: 1 · максимальная длина: 512
nodes[].branchesarrayТолько для condition; каждая ветка содержит id и label. · минимум элементов: 2 · максимум элементов: 20
nodes[].branches[].idstringобязательное полеСтрочные сегменты через точку или дефис, например example.delivery. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
nodes[].branches[].labelstringобязательное полеЧеловекочитаемое название выхода блока-условия в редакторе. · минимальная длина: 1 · максимальная длина: 120
nodes[].retryPolicyobjectmaxAttempts, initialBackoffMs и maxBackoffMs в допустимых пределах. · лишние поля запрещены
nodes[].retryPolicy.maxAttemptsintegerобязательное полеОграничивает общее число попыток выполнения блока. · ≥ 1 · ≤ 10
nodes[].retryPolicy.initialBackoffMsintegerобязательное полеЗадаёт паузу перед первой повторной попыткой блока. · ≥ 0 · ≤ 300000
nodes[].retryPolicy.maxBackoffMsintegerобязательное полеОграничивает максимальную паузу между повторными попытками блока. · ≥ 0 · ≤ 3600000
nodes[].uiobjectобязательное полеcategory, #RRGGBB color и icon. · по умолчанию: {"category":"Other"} · лишние поля запрещены
nodes[].ui.categorystringобязательное полеОпределяет раздел библиотеки блоков, в котором показывается блок. · по умолчанию: "Other" · минимальная длина: 1 · максимальная длина: 80
nodes[].ui.colorstringЗадаёт акцентный цвет блока в редакторе. · формат: ^#[0-9A-Fa-f]{6}$
nodes[].ui.iconstringPNG, JPEG или WebP с совпадающим расширением. · минимальная длина: 1 · максимальная длина: 80
events[]111 полей
Назначение, допустимые значения и ограничения этой части manifest.
events[].typestringобязательное полеВерсионируемая идентичность события. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].versionstringобязательное полеВерсионируемая идентичность события. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].displayNamestringобязательное полеdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
events[].localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
events[].localization.ru.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].localization.ru.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
events[].localization.en.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].localization.en.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].payloadSchemavalueобязательное полеТело события; каждый identityFields path обязан существовать и быть required.
events[].scopeSchemavalueобязательное полеКонтекст выполнения. По умолчанию закрытый пустой объект. · по умолчанию: {"type":"object","properties":{},"required":[],"additionalProperties":false}
events[].selectorsarrayобязательное полеПоля фильтра запуска; по умолчанию []. · по умолчанию: [] · максимум элементов: 100
events[].selectors[].idstringобязательное полеСтрочные сегменты через точку или дефис, например example.delivery. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].selectors[].displayNamestringобязательное полеdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].selectors[].source"payload" | "scope"обязательное полеПуть обязан существовать в соответствующей схеме.
events[].selectors[].pathstringобязательное полеЕдинственный Edge-драйвер внутри архива. · минимальная длина: 1 · максимальная длина: 512
events[].selectors[].operatorsarrayобязательное полеexists, equals, not-equals, in, contains, starts-with, ends-with или matches. · минимум элементов: 1 · максимум элементов: 8
events[].selectors[].localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
events[].selectors[].localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
events[].selectors[].localization.ru.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].selectors[].localization.ru.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].selectors[].localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
events[].selectors[].localization.en.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].selectors[].localization.en.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingFieldsarrayТипизированные payload/scope значения, доступные как источники входов. · максимум элементов: 200
events[].bindingFields[].idstringобязательное полеСтрочные сегменты через точку или дефис, например example.delivery. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingFields[].source"payload" | "scope"обязательное полеПуть обязан существовать в соответствующей схеме.
events[].bindingFields[].pathstringобязательное полеЕдинственный Edge-драйвер внутри архива. · минимальная длина: 1 · максимальная длина: 512
events[].bindingFields[].valueSchemavalueобязательное полеТип должен совпадать с типом объявленного пути.
events[].bindingFields[].displayNamestringобязательное полеdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingFields[].descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingFields[].localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
events[].bindingFields[].localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
events[].bindingFields[].localization.ru.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingFields[].localization.ru.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingFields[].localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
events[].bindingFields[].localization.en.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingFields[].localization.en.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingFields[].categorystringГруппирует доступное значение в выборе источника данных. · минимальная длина: 1 · максимальная длина: 80
events[].bindingFields[].orderintegerОпределяет порядок значения среди других доступных данных события. · ≥ 0 · ≤ 10000
events[].bindingFields[].recommendedbooleanПодсказки UI и правила обращения с данными.
events[].bindingFields[].nullablebooleanПодсказки UI и правила обращения с данными.
events[].bindingFields[].availability"always" | "when-present"обязательное полеПо умолчанию always. · по умолчанию: "always"
events[].bindingFields[].sensitivebooleanПодсказки UI и правила обращения с данными.
events[].bindingFields[].keyedobjectДля объектного path объявляет guardPath и guardParameter параметризованного строкового значения. · лишние поля запрещены
events[].bindingFields[].keyed.guardPathstringобязательное полеПроверяет контекст перед чтением параметризованного ключа объектного поля. · минимальная длина: 1 · максимальная длина: 512
events[].bindingFields[].keyed.guardParameterstringобязательное полеНазывает параметр биндинга, значение которого должно совпасть с guardPath. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogsarrayОбъявляет каталоги категорий, товаров или других областей, из которых пользователь может выбрать контекст события. · максимум элементов: 20
events[].bindingCatalogs[].idstringобязательное полеСтрочные сегменты через точку или дефис, например example.delivery. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].bindingCatalogs[].versionstringобязательное полеВерсионируемая идентичность события. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].bindingCatalogs[].displayNamestringобязательное полеdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingCatalogs[].localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
events[].bindingCatalogs[].localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
events[].bindingCatalogs[].localization.ru.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingCatalogs[].localization.ru.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingCatalogs[].localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
events[].bindingCatalogs[].localization.en.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingCatalogs[].localization.en.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingCatalogs[].scopeobjectобязательное полеОписывает селектор и параметр, которые связывают выбор из каталога с контекстом события. · лишние поля запрещены
events[].bindingCatalogs[].scope.displayNamestringобязательное полеdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingCatalogs[].scope.localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
events[].bindingCatalogs[].scope.localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
events[].bindingCatalogs[].scope.localization.ru.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingCatalogs[].scope.localization.ru.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingCatalogs[].scope.localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
events[].bindingCatalogs[].scope.localization.en.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].bindingCatalogs[].scope.localization.en.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].bindingCatalogs[].scope.selectorIdstringобязательное полеСсылается на селектор события с оператором equals, который ограничивает выбранную область. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogs[].scope.guardParameterstringобязательное полеНазывает параметр, которым выбранное значение каталога передаётся в keyed-поля. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogs[].valueFieldIdstringобязательное полеСсылается на keyed-поле, содержащее внутреннее значение элемента каталога. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogs[].choiceFieldIdstringобязательное полеСсылается на keyed-поле, содержащее отображаемый пользователю вариант каталога. · формат: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].identityFieldsarrayобязательное полеПути payload, образующие идентичность события. · минимум элементов: 1 · максимум элементов: 20
events[].buyerFormobjectОбъявляет безопасный возврат в магазин для публичной формы покупателя. · лишние поля запрещены
events[].buyerForm.returnUrlobjectобязательное полеОписывает источник адреса возврата и разрешённые магазины. · лишние поля запрещены
events[].buyerForm.returnUrl.source"payload" | "scope"обязательное полеВыбирает payload или scope как источник адреса возврата.
events[].buyerForm.returnUrl.pathstringобязательное полеУказывает гарантированный строковый путь с адресом возврата. · минимальная длина: 1 · максимальная длина: 512
events[].buyerForm.returnUrl.allowedOriginsarrayобязательное полеОграничивает возврат точным списком разрешённых HTTPS origins. · минимум элементов: 1 · максимум элементов: 20
events[].inputResolversarrayВерсионируемые immediate/deferred источники данных; messaging.collect-input включает канал чата и может сочетаться с buyerForm. · максимум элементов: 50
events[].inputResolvers[].idstringобязательное полеСтрочные сегменты через точку или дефис, например example.delivery. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].inputResolvers[].versionstringобязательное полеВерсионируемая идентичность события. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].inputResolvers[].abstractionIdstringОпциональная точная абстракция Buywell; оба поля объявляются вместе. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].inputResolvers[].abstractionVersionstringОпциональная точная абстракция Buywell; оба поля объявляются вместе. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].inputResolvers[].displayNamestringобязательное полеdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].inputResolvers[].descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].inputResolvers[].outputSchemavalueобязательное полеТочный тип возвращаемого значения.
events[].inputResolvers[].parameterSchemavalueДля абстракции обязана точно совпадать с её версионированным контрактом.
events[].inputResolvers[].mode"immediate" | "deferred"обязательное полеProduction исполняет deferred; immediate не активируется как удалённая задача.
events[].inputResolvers[].localizationobjectdisplayName обязателен; description и RU/EN localization опциональны. · лишние поля запрещены
events[].inputResolvers[].localization.ruobjectНепустая UTF-8 Markdown-инструкция. · лишние поля запрещены
events[].inputResolvers[].localization.ru.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].inputResolvers[].localization.ru.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].inputResolvers[].localization.enobjectОпциональный перевод; без него используется RU. · лишние поля запрещены
events[].inputResolvers[].localization.en.displayNamestringdisplayName обязателен; description опционален и ограничен 2000 символами. · минимальная длина: 1 · максимальная длина: 120
events[].inputResolvers[].localization.en.descriptionstringdisplayName обязателен; description опционален и ограничен 2000 символами. · максимальная длина: 2000
events[].inputResolvers[].requiredContextarrayКаждый payload/scope path существует и гарантирован required. · максимум элементов: 50
events[].inputResolvers[].requiredContext[].source"payload" | "scope"обязательное полеПуть обязан существовать в соответствующей схеме.
events[].inputResolvers[].requiredContext[].pathstringобязательное полеЕдинственный Edge-драйвер внутри архива. · минимальная длина: 1 · максимальная длина: 512
events[].inputResolvers[].timeoutMsintegerОпциональный лимит ожидания. · ≥ 100 · ≤ 300000
events[].inputResolvers[].retryobjectmaxAttempts 1…10 и initialBackoffMs 0…300000. · лишние поля запрещены
events[].inputResolvers[].retry.maxAttemptsintegerобязательное полеОграничивает число попыток получить отложенные данные. · ≥ 1 · ≤ 10
events[].inputResolvers[].retry.initialBackoffMsintegerобязательное полеЗадаёт паузу перед повторным получением отложенных данных. · ≥ 0 · ≤ 300000
events[].inputResolvers[].sensitivebooleanПодсказки UI и правила обращения с данными.
events[].inputResolvers[].uiobjectcategory по умолчанию Other; icon опционален. · лишние поля запрещены
events[].inputResolvers[].ui.categorystringГруппирует источник данных в интерфейсе редактора. · минимальная длина: 1 · максимальная длина: 80
events[].inputResolvers[].ui.orderintegerОпределяет порядок источника данных в интерфейсе. · ≥ 0 · ≤ 10000
events[].inputResolvers[].ui.recommendedbooleanПодсказки UI и правила обращения с данными.
events[].uiobjectобязательное полеcategory по умолчанию Other; icon опционален. · по умолчанию: {"category":"Other"} · лишние поля запрещены
events[].ui.categorystringобязательное полеОпределяет раздел, в котором событие показывается при выборе запуска. · по умолчанию: "Other" · минимальная длина: 1 · максимальная длина: 80
events[].ui.iconstringPNG, JPEG или WebP с совпадающим расширением. · минимальная длина: 1 · максимальная длина: 80
abstractions[]4 полей
Назначение, допустимые значения и ограничения этой части manifest.
abstractions[].abstractionIdstringобязательное полеУказывает стабильный идентификатор нейтрального действия, которое реализует модуль. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
abstractions[].abstractionVersionstringобязательное полеЗакрепляет точную версию контракта выбранного нейтрального действия. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
abstractions[].nodeTypestringобязательное полеСсылка на существующий блок этого же module.id. · формат: ^[a-z0-9]+(?:[.-][a-z0-9]+)*\/[a-z][a-z0-9.-]*$
abstractions[].nodeVersionstringобязательное полеСсылка на существующий блок этого же module.id. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
package25 полей
Назначение, допустимые значения и ограничения этой части manifest.
package.brandingobjectОписывает визуальные материалы модуля, поставляемые внутри архива. · лишние поля запрещены
package.branding.iconstringобязательное полеPNG, JPEG или WebP с совпадающим расширением. · минимальная длина: 1 · максимальная длина: 240
package.artifactobjectобязательное полеУказывает исполняемый Edge-драйвер этой версии модуля. · лишние поля запрещены
package.artifact.pathstringобязательное полеЕдинственный Edge-драйвер внутри архива. · минимальная длина: 1 · максимальная длина: 240
package.artifact.filenamestringИмя файла для скачивания; не является URL. · минимальная длина: 1 · максимальная длина: 180
package.guidesobjectобязательное полеСобирает инструкции по установке и дальнейшему обслуживанию модуля. · лишние поля запрещены
package.guides.installationobjectобязательное полеСодержит обязательную русскую инструкцию установки и опциональный английский перевод. · лишние поля запрещены
package.guides.installation.rustringобязательное полеНепустая UTF-8 Markdown-инструкция. · минимальная длина: 1 · максимальная длина: 240
package.guides.installation.enstringОпциональный перевод; без него используется RU. · минимальная длина: 1 · максимальная длина: 240
package.guides.readmeobjectСодержит локализованное описание возможностей модуля для раздела «О модуле». · лишние поля запрещены
package.guides.readme.rustringобязательное полеУказывает обязательный русский Markdown-файл описания, когда readme объявлен. · минимальная длина: 1 · максимальная длина: 240
package.guides.readme.enstringУказывает опциональный английский перевод readme; без него используется русский файл. · минимальная длина: 1 · максимальная длина: 240
package.guides.changelogobjectСодержит локализованную историю пользовательских изменений по версиям. · лишние поля запрещены
package.guides.changelog.rustringобязательное полеУказывает обязательный русский Markdown-файл истории изменений, когда changelog объявлен. · минимальная длина: 1 · максимальная длина: 240
package.guides.changelog.enstringУказывает опциональный английский перевод changelog; без него используется русский файл. · минимальная длина: 1 · максимальная длина: 240
package.guides.updateUrlstringВедёт к инструкции по обновлению модуля. · максимальная длина: 2048 · format: uri
package.guides.rollbackUrlstringВедёт к инструкции по возврату на предыдущую версию. · максимальная длина: 2048 · format: uri
package.guides.troubleshootingUrlstringВедёт к инструкции по диагностике типичных проблем. · максимальная длина: 2048 · format: uri
package.guides.removalUrlstringВедёт к инструкции по безопасному удалению модуля. · максимальная длина: 2048 · format: uri
package.compatibilityobjectобязательное полеОписывает версии сервиса и окружения, в которых пакет может работать. · лишние поля запрещены
package.compatibility.minimumBuywellVersionstringМинимальная совместимая версия сервиса. · формат: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
package.compatibility.environmentsarrayобязательное полеПоддерживаемые окружения Buywell Edge. · минимум элементов: 1 · максимум элементов: 30
package.releaseobjectобязательное полеСодержит сведения о важности релиза и ссылку на список изменений. · по умолчанию: {"critical":false} · лишние поля запрещены
package.release.criticalbooleanобязательное полеПо умолчанию false. · по умолчанию: false
package.release.changelogUrlstringОпциональная история изменений. · максимальная длина: 2048 · format: uri
Нейтральные действия, которые может реализовать модуль
Абстракция позволяет сценарию запросить понятное действие без привязки к одной площадке. Совместимый модуль связывает это действие со своим блоком.
messaging.send-in-context@1.0.0actionОтправить сообщение
Отправить сообщение в текущий диалог.
- Блок сценария
abstract/send-in-context@1.0.0- Входы
message*- Известные реализации
example.delivery/send-message@1.0.0
Расширенный нейтральный manifest1 события · 2 блока
Этот пример показывает события, фильтры, данные сценария, резолверы, действия и условия, выполняемые через Buywell Edge.
{
"schemaVersion": 1,
"protocolVersion": "1.0.0",
"module": {
"id": "example.delivery",
"version": "1.1.0",
"displayName": "Example Delivery",
"description": "A complete production-compatible manifest example.",
"publisher": "Example developer",
"supportedPlatforms": [
"Example Platform"
]
},
"nodes": [
{
"type": "example.delivery/send-message",
"version": "1.0.0",
"kind": "action",
"displayName": "Send message",
"localization": {
"ru": {
"displayName": "Отправить сообщение"
},
"en": {
"displayName": "Send message"
}
},
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
},
"required": [
"message"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"configSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"requiredEventContext": [
{
"eventType": "commerce.purchase.created",
"eventVersion": "1.0.0",
"source": "scope",
"path": "conversationId"
}
],
"ui": {
"category": "Messages",
"icon": "message"
}
},
{
"type": "example.delivery/has-recipient",
"version": "1.0.0",
"kind": "condition",
"displayName": "Recipient is present",
"localization": {
"ru": {
"displayName": "Получатель указан"
},
"en": {
"displayName": "Recipient is present"
}
},
"inputSchema": {
"type": "object",
"properties": {
"recipient": {
"type": "string"
}
},
"required": [
"recipient"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"configSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"branches": [
{
"id": "yes",
"label": "Yes"
},
{
"id": "no",
"label": "No"
}
],
"ui": {
"category": "Checks",
"icon": "question"
}
}
],
"events": [
{
"type": "commerce.purchase.created",
"version": "1.0.0",
"displayName": "Purchase received",
"localization": {
"ru": {
"displayName": "Получена покупка"
},
"en": {
"displayName": "Purchase received"
}
},
"payloadSchema": {
"type": "object",
"properties": {
"purchaseId": {
"type": "string"
},
"recipient": {
"type": "string"
},
"categoryId": {
"type": "string"
},
"customFields": {
"type": "object",
"additionalProperties": true
}
},
"required": [
"purchaseId",
"recipient"
],
"additionalProperties": false
},
"scopeSchema": {
"type": "object",
"properties": {
"conversationId": {
"type": "string"
},
"orderUrl": {
"type": "string"
}
},
"required": [
"conversationId",
"orderUrl"
],
"additionalProperties": false
},
"selectors": [
{
"id": "category-id",
"displayName": "Category",
"source": "payload",
"path": "categoryId",
"operators": [
"equals"
]
},
{
"id": "recipient",
"displayName": "Recipient",
"source": "payload",
"path": "recipient",
"operators": [
"exists",
"equals",
"contains"
],
"localization": {
"ru": {
"displayName": "Получатель"
},
"en": {
"displayName": "Recipient"
}
}
}
],
"bindingFields": [
{
"id": "recipient",
"source": "payload",
"path": "recipient",
"valueSchema": {
"type": "string"
},
"displayName": "Recipient",
"localization": {
"ru": {
"displayName": "Получатель"
},
"en": {
"displayName": "Recipient"
}
},
"recommended": true,
"availability": "always"
},
{
"id": "custom-field",
"source": "payload",
"path": "customFields",
"valueSchema": {
"type": "string"
},
"displayName": "Custom field",
"localization": {
"ru": {
"displayName": "Дополнительное поле"
},
"en": {
"displayName": "Custom field"
}
},
"availability": "when-present",
"keyed": {
"guardPath": "categoryId",
"guardParameter": "categoryId"
}
}
],
"bindingCatalogs": [
{
"id": "example.categories",
"version": "1.0.0",
"displayName": "Category fields",
"scope": {
"displayName": "Category",
"selectorId": "category-id",
"guardParameter": "categoryId"
},
"valueFieldId": "custom-field",
"choiceFieldId": "custom-field"
}
],
"identityFields": [
"purchaseId"
],
"buyerForm": {
"returnUrl": {
"source": "scope",
"path": "orderUrl",
"allowedOrigins": [
"https://shop.example"
]
}
},
"inputResolvers": [
{
"id": "commerce.recipient-profile",
"version": "1.0.0",
"displayName": "Recipient profile",
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"mode": "deferred",
"localization": {
"ru": {
"displayName": "Профиль получателя"
},
"en": {
"displayName": "Recipient profile"
}
},
"requiredContext": [
{
"source": "scope",
"path": "conversationId"
}
],
"timeoutMs": 30000,
"retry": {
"maxAttempts": 3,
"initialBackoffMs": 1000
},
"ui": {
"category": "Customer data",
"order": 20
}
}
],
"ui": {
"category": "Sales",
"icon": "cart"
}
}
],
"abstractions": [
{
"abstractionId": "messaging.send-in-context",
"abstractionVersion": "1.0.0",
"nodeType": "example.delivery/send-message",
"nodeVersion": "1.0.0"
}
],
"package": {
"branding": {
"icon": "assets/icon.png"
},
"artifact": {
"path": "edge/driver.py",
"filename": "driver.py"
},
"guides": {
"installation": {
"ru": "guides/install.ru.md",
"en": "guides/install.en.md"
},
"readme": {
"ru": "guides/README.ru.md",
"en": "guides/README.en.md"
},
"changelog": {
"ru": "guides/CHANGELOG.ru.md",
"en": "guides/CHANGELOG.en.md"
}
},
"compatibility": {
"environments": [
"Example Runtime 1.x"
]
},
"release": {
"critical": false
}
}
}