Примеры
1. Создание виджета через ИИ Claude
Для виджетов OkoCRM подготовлен Skill
для ИИ Claude — отдельный документ с правилами создания виджета, описанием Widget API
и Settings API. Подключите его в проект Claude и опишите задачу в свободной форме —
Claude сгенерирует config.json, script.js, шаблоны и стили
по правилам платформы.
Подключение SKILL
SKILL доступен по адресу:
https://<ВАШ_АККАУНТ>.okocrm.com/skills/widget-creator/SKILL.md
Где <ВАШ_АККАУНТ> — поддомен вашего аккаунта в OkoCRM.
Загрузите файл в Claude (через Claude Projects, Claude Code или Claude Desktop) —
он будет использован моделью как инструкция при генерации.
Шаблон запроса
Чтобы Claude сгенерировал виджет корректно, опишите вводные данные подробнее. Далее пример, на основе SKILL:
Создай виджет OkoCRM по правилам подключённого SKILL.
Название: Калькулятор маржи
ID (slug): margin-calc
Назначение: Считает прибыль и маржинальность по сумме сделки и проценту маржи.
Показывает результат в модальном окне при клике на иконку
в карточке сделки.
Сущности: lead
Внешние API: не используются
Настройки (settings.fields): не используются
Расширенные настройки (more_settings):
- margin_percent (number, обязательное) — процент маржи по умолчанию
- currency (text) — код валюты для отображения (RUB, USD, EUR)
- show_in_sidebar (checkbox) — показывать ли иконку в сайдбаре
Поведение:
1. На lead.opened — отрисовать иконку в карточке сделки.
2. На клик по иконке (lead.main) — открыть модалку с расчётом:
прибыль = budget * margin_percent / 100,
маржинальность = margin_percent %.
3. На more_settings.opened — отрисовать форму расширенных настроек.
Чек-лист перед отправкой
- SKILL подключён в проект / контекст Claude;
- указаны название и уникальный ID (slug);
- описано назначение виджета — что он делает с точки зрения пользователя;
- перечислены сущности (lead, contact, company), с которыми работает виджет;
- перечислены внешние API (с примерами URL и форматом ответа), если они нужны;
- перечислены поля настроек (
settings.fields) — имя, тип, обязательность; - указано, нужны ли расширенные настройки (
more_settings); - описано поведение — какие события слушать и что отрисовывать.
2. Пример: «Калькулятор полей»
Задача
Виджет margin-calc: добавляет иконку в карточку сделки. По клику
открывается модалка, в которой по сумме сделки entity.budget и проценту
маржи (из настроек виджета) рассчитываются и показываются:
- прибыль:
budget × margin_percent / 100; - маржинальность:
margin_percent%; - себестоимость:
budget − прибыль.
Структура
margin-calc/
config.json
script.js
logo.png
templates/
modal.hbs
more_settings.hbs
styles/
modal.css
more_settings.css
config.json
{
"id": "margin-calc",
"author": "OkoCRM Team",
"version": "1.0.0",
"settings": {
"links": [
{ "title": "Документация", "url": "https://okocrm.com/widgets/margin-calc" }
],
"text": "Калькулятор маржи и прибыли по сумме сделки. Откройте сделку и нажмите иконку виджета.",
"fields": []
},
"icons": {
"lead.main": "logo.png",
"sidebar": "logo.png"
}
}
script.js
import u from 'umbrellajs';
import _ from 'lodash';
export default async function (widgetApi, settingsApi) {
// 1. Иконка в сайдбаре — можно вызвать сразу при инициализации
widgetApi.renderStaticPosition('sidebar');
// 2. На открытие карточки сделки — отрисовать иконку в карточке
widgetApi.subscribe('lead.opened', (event) => {
const entity = event.detail.entity;
widgetApi.renderStaticPosition('lead.main');
// Сохраним последнюю открытую сделку, чтобы использовать в модалке
currentEntity = entity;
});
let currentEntity = null;
// 3. На клик по иконке виджета в карточке сделки — показать расчёт
widgetApi.subscribe('lead.main', async () => {
const settings = settingsApi.getSettings();
const margin = _.toNumber(settings.margin_percent) || 0;
const more = settings.setting || {};
const currency = more.currency || 'RUB';
if (!currentEntity || !currentEntity.id) {
widgetApi.createNotice({
text: 'Сначала сохраните сделку',
variant: 'error'
});
return;
}
const budget = _.toNumber(currentEntity.budget) || 0;
const profit = budget * margin / 100;
const cost = budget - profit;
const template = await widgetApi.getTemplate('modal');
const html = template({
title: currentEntity.name,
currency,
budget: budget.toLocaleString('ru-RU'),
margin,
profit: profit.toLocaleString('ru-RU'),
cost: cost.toLocaleString('ru-RU')
});
widgetApi.linkStyle('modal');
await widgetApi.createModal({ content: html, isLoading: false });
});
// 4. На открытие расширенных настроек — отрисовать форму
widgetApi.subscribe('more_settings.opened', async () => {
const settings = settingsApi.getSettings();
const more = settings.setting || {};
const template = await widgetApi.getTemplate('more_settings');
const content = template({
currency: more.currency || 'RUB',
show_in_sidebar: more.show_in_sidebar === '1'
});
widgetApi.linkStyle('more_settings');
await widgetApi.renderTemplatePosition('more_settings', content);
});
}
templates/modal.hbs
<div class="widget-margin-calc-modal">
<h3 class="widget-margin-calc-modal__title">Расчёт по сделке «{{title}}»</h3>
<dl class="widget-margin-calc-modal__list">
<dt>Сумма сделки</dt>
<dd>{{budget}} {{currency}}</dd>
<dt>Маржинальность</dt>
<dd>{{margin}} %</dd>
<dt>Прибыль</dt>
<dd><strong>{{profit}} {{currency}}</strong></dd>
<dt>Себестоимость</dt>
<dd>{{cost}} {{currency}}</dd>
</dl>
</div>
templates/more_settings.hbs
В more_settings не добавляем <form>
и кнопку submit — обвязка и сабмит уже встроены в форму платформы. Имена полей
начинаются с setting.
<div class="widget-margin-calc-more">
<label class="widget-margin-calc-more__row">
<input
type="number"
class="input input--with-border"
name="setting[margin_percent]"
value="1"
/>
<span>Процент маржи по умолчанию</span>
</label>
<label class="widget-margin-calc-more__row">
<span>Валюта отображения</span>
<select
class="select-base select-base--with-border"
name="setting[currency]"
>
<option value="RUB" {{#if (or (and currency) (and (eq currency "RUB")))}}selected{{/if}}>RUB</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
</select>
</label>
<label class="widget-margin-calc-more__row">
<input
type="checkbox"
class="checkbox"
name="setting[show_in_sidebar]"
value="1"
{{#if show_in_sidebar}}checked{{/if}}
/>
<span>Показывать иконку в сайдбаре</span>
</label>
</div>
styles/modal.css
.widget-margin-calc-modal {
padding: 16px 20px;
min-width: 320px;
}
.widget-margin-calc-modal__title {
margin: 0 0 12px;
font-size: 16px;
}
.widget-margin-calc-modal__list {
display: grid;
grid-template-columns: 1fr auto;
gap: 8px 16px;
margin: 0;
}
.widget-margin-calc-modal__list dt {
color: #555;
}
.widget-margin-calc-modal__list dd {
margin: 0;
text-align: right;
}
styles/more_settings.css
.widget-margin-calc-more {
display: flex;
flex-direction: column;
gap: 12px;
}
.widget-margin-calc-more__row {
display: flex;
align-items: center;
gap: 8px;
}
.widget-margin-calc-more__row span {
flex: 1;
}