Avito — крупнейшая российская площадка объявлений. Плагин avito даёт агентам OpenClaw нативные инструменты для управления объявлениями, автозагрузкой, мессенджером и статистикой продавца через официальный Avito API для бизнеса (OAuth 2.0, developers.avito.ru). Это отдельный контур от Avito Ads API (рекламные кампании) — тот вынесен в отдельный плагин avito-ads (уже начат: Фазы 1a/1c реализованы, отдельная вики-страница пока не написана).
poreklame.tech подключает AI-агента к вашему аккаунту Avito: он видит список и статус ваших объявлений, подсказывает категории и требования Авито при подготовке новых объявлений, следит за балансом кошелька и рекомендованными бюджетами продвижения. Прямая публикация и редактирование объявлений через API невозможны — это ограничение самого Avito, не плагина: единственный официальный программный способ завести или обновить объявление — фид Автозагрузки (XML/YML), который агент помогает подготовить, а загружает пока вручную человек в личном кабинете.
(Технический контур: 17 нативных инструментов, OAuth 2.0, rate-limit 1 запрос/3с для защиты от бана по IP. В проде читающий доступ у роли «Авитолог» (Ирина): объявления/категории/автозагрузка-отчёт/продвижение-цены/баланс — 9 тулов. Мессенджер — тарифицируется «Максимальным» тарифом и относится к роли Ивана, пока никому не выдан. Автозагрузка (запуск/отчёт) упирается в отсутствие OAuth-скоупа у приложения на стороне Avito — см. «Известные проблемы».)
| Параметр | Значение |
|---|---|
| ID плагина | avito |
| Тип | Source plugin (TypeScript → ESM) |
| Расположение (рантайм) | ~/.openclaw/source-plugins/avito/ |
| Источник правды (код) | golden-image репо, source-plugins/avito/, ветка dev |
| API Base URL | https://api.avito.ru |
| Аутентификация | OAuth 2.0 (client_credentials, сейчас; authorization_code — код готов, не тестировался) |
| Rate Limit | 1 запрос / 3 секунды (глобальная очередь) |
| Количество инструментов | 17 (в прошлой версии страницы было 18 — с тех пор Фаза 4а добавила VAS+Баланс [+6, итого 24], а аудит 22.07 снял 9 фантомов и добавил 2 category-тула: 24 − 9 + 2 = 17) |
| Статус | загружен и работает (Registered 17 tools). Роль «Авитолог» (Ирина) — 9 read-тулов в tools.allow. Мессенджер (5) и продвижение-покупка (2) не выданы никому. |
source-plugins/avito/
├── openclaw.plugin.json # Манифест + contracts.tools (17 имён)
├── package.json
├── tsconfig.json
├── .env.example # Пустые AVITO_CLIENT_ID / AVITO_CLIENT_SECRET
├── SPEC.md # Копия спеки, версионируется вместе с кодом
├── src/
│ ├── types.ts # AvitoClientConfig, AvitoTokenResponse
│ ├── config.ts # parseConfig + resolveCredentials (секреты только из env)
│ ├── auth.ts # OAuth2: client_credentials + authorization_code/refresh
│ ├── client.ts # HTTP-клиент + rate limiter + retry
│ └── index.ts # Регистрация 17 инструментов
├── scripts/
│ └── generate-autoload-feed.mjs # Генератор XML-фида Автозагрузки (не тул плагина, см. ниже)
├── data/
│ └── first-ad.json # Данные черновика для генератора (не в манифесте тулов)
└── dist/ # Собранный JS (не в git)
Golden-image репо — источник правды, не ~/.openclaw напрямую.
~/work/golden-image/source-plugins/avito/ (клон https://git.poreklame.tech/poreklameadmin/golden-image.git, ветка dev).npm install && npx tsc — чистая сборка.dev.rsync -av --itemize-changes ~/work/golden-image/source-plugins/avito/src/ ~/.openclaw/source-plugins/avito/src/ (и отдельно openclaw.plugin.json, SPEC.md) — не одной командой с общим списком файлов и каталогом src/ с завершающим слэшем: так src/*.ts рассыпаются плашмя в корень рантайм-копии вместо src/, и следующая сборка молча компилирует старый код. Каждый путь — отдельным вызовом rsync.npx tsc в рантайм-копии (dist/ там не версионируется).openclaw daemon restart --safe — source-плагины не hot-reload. Конфиг-изменения плагина (plugins.entries.avito.config.*, например rateLimitMs) подхватываются на лету; agents.list[].tools.allow/deny — НЕТ (кэшируется гейтвеем при старте процесса, см. «Известные проблемы» №7 и «Правила изменения профилей» ниже) — после правки ACL нужен отдельный systemctl restart openclaw.service.Напрямую редактировать ~/.openclaw/source-plugins/avito/ — нельзя (временное исключение до провижинера было только для самой первой ручной копии; дальше — только через golden-image + rsync).
client_credentials (сервер-сервер) — активный режим, работает.authorization_code + refresh — код написан по спеке, не тестировался живьём (нет consent-флоу в ЛК на момент реализации).agentTokens из ранней спеки сознательно не реализован).rateLimitMs: 3000 (защита от бана по IP — Avito банит жёстко).User-Agent: poreklame.tech avito-plugin/0.1 — обязателен.getCategoryTree/getCategoryFields) — см. «Инструменты».⚠️ Архитектурный факт API, подтверждён 22.07.2026. Реальный Avito Seller API не поддерживает создание, полное обновление, удаление объявлений или загрузку/удаление изображений через JSON REST — сверено с исчерпывающим открытым референсом avito-mcp@1.3.2 (148 тулов, 18 доменов, MIT — ни в одном домене такого эндпоинта нет) и подтверждено живым пробным
POST /core/v1/accounts/441951247/items, вернувшим чистый404 {"message":"no Route matched with those values"}. Единственный официальный программный способ опубликовать/изменить объявление — фид Автозагрузки (XML/YML: настройка профиля + запуск загрузки) или ручная публикация на сайте.
| Инструмент | Метод | Эндпоинт | Статус |
|---|---|---|---|
avito_list_items |
GET | /core/v1/items |
✅ Подтверждено — 200, {"resources": []} |
avito_get_item |
GET | /core/v1/accounts/:accountId/items/:itemId/ |
⚠️ Путь исправлен 22.07 (был плоский, без account-scope) — новый путь подтверждён живьём: 422 с телом про поле item_id на заведомо неверном id (маршрут распознан). С реальным itemId не проверялся — на аккаунте 0 объявлений |
avito_get_category_tree |
GET | /autoload/v1/user-docs/tree |
✅ Добавлено 22.07, подтверждено живьём — 200. Официальный справочник категорий Авито (для подготовки фида Автозагрузки). Требует Bearer (не анонимный статический файл). Кэшируется в памяти процесса |
avito_get_category_fields |
GET | /autoload/v1/user-docs/node/:nodeSlug/fields |
✅ Добавлено 22.07, подтверждено живьём на slug ii_resheniya_neiroseti — 200. Поля конкретной категории: обязательность, enum-значения, чекбоксы, зависимости — то, что дерево категорий не показывает. Кэшируется по slug |
Убрано 22.07 — 6 тулов, эндпоинтов для которых не существует в реальном API (код в client.ts/index.ts не удалён, помечен PHANTOM, но reg() закомментирован и имена сняты из contracts.tools — агенты их не видят): avito_create_item, avito_update_item, avito_delete_item, avito_upload_image, avito_delete_image, avito_get_item_stats. Детали и вердикт по каждому — source-plugins/avito/SPEC.md, раздел «Модуль 1» и §10.
| Инструмент | Метод | Эндпоинт | Статус |
|---|---|---|---|
avito_get_autoload_report |
GET | /autoload/v3/reports/last_completed_report |
⚠️ Путь исправлен 22.07 (Автозагрузка НЕ аккаунт-скоупится путём — прошлая гипотеза 0594cf3 была неверной). Живая проверка после фикса: 401 {"message":"Forbidden"} — не 404, маршрут распознан, но приложению не хватает OAuth-скоупа на домен Автозагрузки. См. «Известные проблемы» №1 |
avito_start_autoload |
POST | /autoload/v1/upload |
⚠️ Путь исправлен 22.07 (реальный эндпоинт — без тела, без accountId, лимит 1 запуск/час). Не вызывался живьём (write); учитывая 401 у соседнего GET того же домена, скорее всего тоже упрётся в авторизацию |
Убрано 22.07: avito_get_autoload_errors — прямого аналога нет (реальные ошибки автозагрузки требуют report_id + фильтр sections, другая форма вызова, не путь-фикс). Не переделан в рамках аудита — судейское решение, см. SPEC.md §10.
| Инструмент | Метод | Эндпоинт | Статус |
|---|---|---|---|
avito_list_chats |
GET | /messenger/v2/accounts/:accountId/chats |
✅ Подтверждено живьём — 200, {"chats":[],"meta":{"has_more":false}} (аккаунт без чатов) |
avito_get_chat |
GET | /messenger/v2/accounts/:accountId/chats/:chatId |
Маршрут подтверждён (404 «chat not found» на фиктивном id — не route-404). Не тестировался с реальным chatId |
avito_list_messages |
GET | /messenger/v3/accounts/:accountId/chats/:chatId/messages/ |
⚠️ Путь исправлен 22.07 (было v2 без trailing slash). Живая проверка с фиктивным chatId дала пустой 404 без тела — не различает route-404 от chat-404 так чётко, как list/get chat. Остаётся неподтверждённым до появления реального чата |
avito_send_message |
POST | /messenger/v1/accounts/:accountId/chats/:chatId/messages |
Маршрут подтверждён (400 на фиктивном chat_id). DESTRUCTIVE — не вызывать без явного подтверждения текста и получателя. Не выдан ни одному агенту |
avito_mark_read |
POST | /messenger/v1/accounts/:accountId/chats/:chatId/read |
Маршрут подтверждён (400 на фиктивном chat_id). Не выдан ни одному агенту |
Весь модуль относится к роли Ивана (мессенджер с покупателями), не к Ирине (Авитолог) — см. «Выдача тулов агентам».
avito_get_account_stats и avito_get_items_stats были построены на путях, которых в реальном API никогда не существовало (GET /stats/v1/accounts/:id, GET /stats/v1/items/:id) — сняты полностью. Реальная статистика по объявлениям — батч POST /stats/v1|v2/accounts/:accountId/items с телом itemIds — не реализована (вне рамок аудита 22.07). Код методов client.ts оставлен с пометкой PHANTOM.
Пути сняты с открытого референса avito-mcp@1.3.2 (MIT), код написан заново под паттерн плагина. Не аккаунт-скоупятся путём — OAuth-токен скоупит их на аккаунт вызывающего.
| Инструмент | Метод | Эндпоинт | Статус |
|---|---|---|---|
avito_list_vas_services |
POST | /promotion/v1/items/services/dict |
✅ Подтверждено живьём — 200, 16 услуг (bbip, highlight, xl, пакеты x2_1…x20_7) |
avito_get_vas_prices |
POST | /promotion/v1/items/services/bbip/suggests/get |
Маршрут подтверждён (validation/business-логика на пустом/фиктивном itemIds, не route-404). Живой 200 не получен — на аккаунте 0 объявлений |
avito_apply_vas |
PUT | /promotion/v1/items/services/bbip/orders/create |
⚠️ ПЛАТНЫЙ. Не вызывался — списывает деньги. Draft-режим: не выдан никому, появится у Ирины отдельным решением после обкатки |
avito_apply_vas_batch |
PUT | /promotion/v1/items/services/bbip/orders/create |
Тот же эндпоинт, пакетно (до 100 объявлений). Тот же статус, что и avito_apply_vas |
| Инструмент | Метод | Эндпоинт | Статус |
|---|---|---|---|
avito_get_balance |
GET | /core/v1/accounts/:accountId/balance/ |
✅ Подтверждено живьём — 200, {"bonus":0,"real":0} |
avito_list_balance_operations |
POST | /core/v1/accounts/operations_history/ |
✅ Подтверждено живьём — 200. Ограничения API: dateTimeFrom не более года назад, диапазон не более 7 дней |
{
"plugins": {
"entries": {
"avito": {
"enabled": true,
"config": {
"apiBaseUrl": "https://api.avito.ru",
"authType": "client_credentials",
"rateLimitMs": 3000
}
}
},
"load": {
"paths": ["/home/openclaw/.openclaw/source-plugins/avito"]
}
}
}
clientId/clientSecret никогда не хранятся в конфиге — только в env (AVITO_CLIENT_ID, AVITO_CLIENT_SECRET), в ~/.openclaw/.env и в ~/.openclaw/gateway.systemd.env (последний — реальный EnvironmentFile systemd-юнита, без него процесс их не увидит). Права на оба файла — 600.
См. Супервизия гейтвея OpenClaw — прямые записи в openclaw.json через exec запрещены даже если gateway config.patch падает; чинить вызов, не обходить канал. config.patch — правильный канал, но см. «Известные проблемы» №7: для tools.allow он меняет только диск, не живой процесс.
Ирина (Авитолог) — канонический профиль из 9 read-тулов в agents.list[id=irina].tools.allow:
avito_list_items, avito_get_item, avito_get_category_tree, avito_get_category_fields, avito_get_autoload_report, avito_list_vas_services, avito_get_vas_prices, avito_get_balance, avito_list_balance_operations.
Не выдано никому:
avito_list_chats, avito_get_chat, avito_list_messages, avito_send_message, avito_mark_read. Роль — Иван, профиль пока не создан/не наполнен.avito_apply_vas / avito_apply_vas_batch — draft-режим (тратят деньги), появятся у Ирины отдельным решением после обкатки.avito_ads_* (плагин avito-ads, 5 read-тулов) — отдельный контур, Ирине не выданы; выдача — отдельным решением после приёмки ads-контура.Полная методология — Инструментальные профили ролей (Tool Allow-List Standard). Ниже — то, что конкретно всплыло на инциденте с профилем Ирины 23.07:
agents/<роль>/ в golden-image (AGENTS.md, SOUL.md, IDENTITY.md и т.п.). Клиентский конфиг (openclaw.json, tools.allow) приводится в соответствие канону, а не наоборот.~/.openclaw/workspace-<agent>/ — деплой-цель, не источник правды; агент не редактирует собственный устав.avito-ads) не конфигурируют чужих агентов — они регистрируют свои тулы в манифесте; кому их выдавать — решает владелец роли (для Ирины и мессенджера — Иван/Роман), не разработчик соседнего плагина.tools.allow/tools.deny кэшируются гейтвеем при старте процесса. config.patch пишет на диск немедленно, но не влияет на уже запущенный процесс — несмотря на сообщение CLI «Change will apply without restarting the gateway» (это сообщение верно для plugins.entries.*.config, но НЕ для agents.list[].tools.*). После правки ACL обязателен systemctl restart openclaw.service — это требует sudo, которого у пользователя openclaw нет; рестарт делает владелец инфраструктуры./context detail живой сессии агента (видно фактический список загруженных тулов), не самоотчёт агента и не факт успешного config.patch.401, не «temporarily unavailable»; Статистика — снята полностьюПосле фикса путей 22.07 (Автозагрузка не аккаунт-скоупится путём, см. №2) живая проверка avito_get_autoload_report/GET /autoload/v2/reports дала:
{"code":401,"message":"authorization required"}
— маршрут распознан (не 404), но текущему client_credentials-приложению не хватает OAuth-скоупа на домен Автозагрузки. Прежняя формулировка «temporarily unavailable» (22.07 до второго аудита) была реакцией на неверный путь, а не тарифным/скоуп-гейтом, как считалось изначально. Требует уточнения у Avito support/кабинета разработчика.
Статистика (avito_get_account_stats, avito_get_items_stats) была построена на путях, которых в реальном API не существует вовсе — не «закрыта скоупом», а сняты из манифеста полностью, см. таблицу тулов выше.
Исходная спека описывала плоские пути (/autoload/v1/reports, /messenger/v1/chats) — на реальном API 404 no Route matched/404 page not found. Исправлено в 0594cf3 (20.07) добавлением accountId в пути Автозагрузки/Мессенджера/Статистики.
22.07 полный аудит всех 24 тулов против исчерпывающего открытого референса avito-mcp@1.3.2 (148 тулов, 18 доменов, MIT) показал, что фикс 0594cf3 сам был частично неверен: Автозагрузка вообще не аккаунт-скоупится путём (гипотеза по аналогии с Мессенджером не подтвердилась). Из 24 тулов: 11 совпали с референсом, 4 расходились путём (исправлены — avito_get_item, avito_get_autoload_report, avito_start_autoload, avito_list_messages), 9 оказались эндпоинтами, которых в реальном API нет вообще (сняты из манифеста) — включая архитектурный факт: программного создания объявления не существует, см. раздел «Инструменты» → «Объявления». Коммит: 6d3b904. Полная таблица аудита — SPEC.md §10.
avito_list_messages — путь исправлен, но всё ещё не подтверждёнПуть сверен с референсом и исправлен на v3 с trailing slash 22.07, но на аккаунте по-прежнему нет ни одного чата, поэтому живая проверка с фиктивным chatId дала неинформативный пустой 404 (не различает route-404 от chat-404, в отличие от avito_get_chat). Нужна повторная проверка, когда на аккаунте появится реальный чат.
Спека называла тул статистики объявления так же, как тул из модуля «Объявления» (avito_get_item_stats). Переименован в avito_get_items_stats во избежание коллизии — оба тула сняты полностью 22.07 (путь вымышлен у обоих), коллизия имён более не актуальна, оставлено для истории.
avito_start_autoload — путь теперь реальный, но заблокирован тем же 401Путь исправлен 22.07 на POST /autoload/v1/upload (без тела, без accountId, сверено с референсом). Не вызывался живьём (write + trigger) — по соседним GET-эндпоинтам того же домена (см. №1) вероятная причина отказа та же: отсутствие OAuth-скоупа на Автозагрузку, не путь-баг.
authType: authorization_code не тестировался живьёмКод полного OAuth2 authorization_code flow (обмен code → token, refresh) написан по спеке, но в проде используется только client_credentials. Нужны будут AVITO_REDIRECT_URI, AVITO_AUTHORIZATION_CODE, AVITO_REFRESH_TOKEN в env (см. .env.example).
config.patch на agents.list[].tools.allow для Ирины прошёл успешно (22.07, 22:55) и CLI сообщил «Change will apply without restarting the gateway» — но правка не действовала до ручного systemctl restart openclaw.service (сделан владельцем инфраструктуры, у пользователя openclaw нет sudo на это). Причина: tools.allow/tools.deny читаются гейтвеем один раз при старте процесса и кэшируются в памяти; config.patch меняет только файл на диске. Сообщение CLI вводит в заблуждение для этого конкретного пути конфига (верно для plugins.entries.*.config, неверно для agents.list[].tools.*). См. «Правила изменения профилей» выше и Tool Allow-List Standard §4 (верификация обязательна через /context detail, не через самоотчёт).
cd ~/work/golden-image/source-plugins/avito # НЕ ~/.openclaw напрямую
npm install
npx tsc
src/client.ts (endpoint запроса).src/index.ts через reg({...}).contracts.tools в openclaw.plugin.json.npx tsc, коммит + push в dev (golden-image).rsync в ~/.openclaw/source-plugins/avito/ — отдельными вызовами для src/ и для каждого файла манифеста/спеки (см. «Workflow разработки» — общий вызов с каталогом и файлами вперемешку рассыпает src/*.ts не туда), npx tsc там же.openclaw daemon restart --safe.tools.invoke — доказать код 200 (или зафиксировать причину, если не 200), а не полагаться на предположения о путях API.config.patch на его tools.allow + отдельный systemctl restart openclaw.service (см. «Известные проблемы» №7) + верификация через /context detail этого агента.Раз OAuth-скоуп на Автозагрузку не выдан (№1/№5 выше), загрузка фида через API не производится — только генерация + локальная валидация; финальная загрузка в Avito — вручную человеком в личном кабинете.
scripts/generate-autoload-feed.mjs — генератор ОДНОЙ категории: «ИИ-решения, нейросети» (Услуги > Деловые услуги > IT, дизайн, тексты, slug ii_resheniya_neiroseti). Намеренно не универсальный движок по произвольной категории. Схема обязательных полей и фиксированных значений таксономии снята живьём через avito_get_category_fields.data/first-ad.json — данные объявления (текст живёт здесь, не в коде), помечен "_draft": true — плейсхолдер, не согласованный текст/фото. Реальный текст и фото — отдельное согласование с заказчиком.Images/ImageUrls/ImageNames в живом ответе API все помечены обязательными; генератор реализует общепринятый вложенный формат <Images><Image url="..."/></Images>, ждёт подтверждения через xmlcheck-проверку (детали которой заказчик даёт отдельно).output/<id>.xml (в .gitignore, не коммитится).Для живых проверок использовался собственный аккаунт компании (Avito ID 441951247, Poreklame(dot)Tech, тариф «Расширенный») — узнаётся через GET /core/v1/accounts/self (не входит в тулы плагина, использован только как ручная диагностика). На аккаунте пока нет объявлений и чатов — часть тулов не может быть проверена «в бою» до появления реальных данных.
| Дата | Событие |
|---|---|
| 2026-07-20 | Фаза 1 (Объявления, 8 тулов): реализация, живой тест avito_list_items — 200 |
| 2026-07-20 | Код перенесён в golden-image репо (https://git.poreklame.tech/poreklameadmin/golden-image, ветка dev) — источник правды |
| 2026-07-20 | Фазы 2+3 (Автозагрузка 3 + Мессенджер 5 + Статистика 2 = 10 тулов): реализация по спеке v0.1 |
| 2026-07-20 | Живые тесты выявили неверные пути в спеке (плоские вместо аккаунт-скоупнутых) — фикс в 0594cf3, avito_list_chats подтверждён 200 |
| 2026-07-20 | Спека синхронизирована с фактическими путями (181adc8) |
| 2026-07-21 | Фаза 4а — Продвижение (VAS, 4 тула) + Баланс (2 тула): 9d89e0f/c4057ed. Живые тесты: dict/get_balance/list_balance_operations — 200; apply_vas/apply_vas_batch не вызывались (реальные деньги) |
| 2026-07-22 | Полный аудит 24 тулов против исчерпывающего референса avito-mcp@1.3.2 — 6d3b904: 4 путь-бага исправлены, 9 тулов оказались построены на несуществующих эндпоинтах (сняты из манифеста, код оставлен с пометкой PHANTOM). Подтверждён живьём чистый 404 no Route matched на пробном создании объявления — программного способа создать объявление в реальном API нет. Добавлен avito_get_category_tree |
| 2026-07-22 | Добавлен avito_get_category_fields — b184751, 17 тулов. Рестарт гейтвея подтвердил Registered 17 tools. Живая проверка вскрыла: после фикса путей Автозагрузка отдаёт 401 (нет OAuth-скоупа), не route-баг |
| 2026-07-22 | Генератор фида Автозагрузки для категории «ИИ-решения, нейросети» — c6991c6: scripts/generate-autoload-feed.mjs + data/first-ad.json (draft), ждёт фото и согласованный текст |
| 2026-07-22/23 | Правка tools.allow Ирины (9 read-тулов) через config.patch не подействовала на живой процесс без ручного рестарта (кэш ACL при старте гейтвея) — инцидент 23.07 разобран, введены «Правила изменения профилей» (см. выше) и подтверждена привязка Ирины ровно к каноническим 9 тулам |
https://git.poreklame.tech/poreklameadmin/golden-image (ветка dev, путь source-plugins/avito/)source-plugins/avito/SPEC.md (в golden-image, актуальна после b184751)source-plugins/avito/scripts/generate-autoload-feed.mjs + data/first-ad.json (в golden-image)developers.avito.ru (JS SPA, не парсится напрямую — пути проверялись живыми запросами)~/.openclaw/.env, ~/.openclaw/gateway.systemd.env (chmod 600, не в git)