API виджетов OkoCRM
Виджет получает два аргумента в default export:
widgetApi — для взаимодействия с CRM (события, шаблоны, модалки, HTTP),
и settingsApi — для доступа к настройкам и идентификаторам виджета.
export default async function (widgetApi, settingsApi) {
// ...
}
1. Widget API
События
Подписка на события CRM, отписка и создание собственных событий. В обработчик приходит
нативный объект CustomEvent — данные доступны через event.detail.
// Подписка
widgetApi.subscribe('lead.opened', (event) => {
const entity = event.detail.entity;
});
// Отписка
widgetApi.unsubscribe('lead.opened', handler);
// Создание собственного события
widgetApi.createEvent('my-widget.recalculated', { total: 1000 });
Доступные события:
| Событие | Описание | event.detail |
|---|---|---|
lead.openedcompany.openedcontact.opened |
Открыта карточка сущности | { entity, entityType } |
lead.changedcompany.changedcontact.changed |
Данные сущности изменились | { changed } |
lead.closedcompany.closedcontact.closed |
Карточка сущности закрыта | — |
lead.createdcompany.createdcontact.created |
Сущность создана | данные сущности |
lead.savedcompany.savedcontact.saved |
Сущность сохранена | данные сущности |
lead.maincompany.maincontact.main |
Нажата кнопка виджета в карточке (приватное) | — |
more_settings.opened | Открыты доп. настройки виджета (приватное) | — |
more_settings.closed | Закрыты доп. настройки виджета (приватное) | — |
page.opened | Открыта страница виджета (приватное) | — |
page.closed | Закрыта страница виджета (приватное) | — |
*.main, more_settings.*,
page.*) изолированы для каждого виджета — их получает только тот виджет,
к которому относится действие. Остальные события глобальны.
Объект entity
Доступен через event.detail.entity при событиях *.opened.
Если entity.id равен null или undefined —
сущность ещё не создана (открыто окно создания).
| Поле | Описание |
|---|---|
id | ID сущности |
name | Название сущности |
user_id | ID ответственного пользователя |
responsible | Ответственный { id, name, ... } |
users | Участники сделки [{ id, name, ... }] (только в сделке) |
author | Автор сущности { id, name, ... } |
pipeline_id | ID воронки (только в сделке) |
stages_id | ID этапа воронки (только в сделке) |
city | Город { city_id, name } |
city_id | ID города |
budget | Сумма сделки (только в сделке) |
margin | Маржа сделки (только в сделке) |
tags | Массив тегов [{ id, name }] |
phones | Телефоны [{ id, phone, ... }] (контакт/компания) |
emails | E-mail [{ id, email, ... }] (контакт/компания) |
contacts | Связанные контакты (с собственными phones/emails) |
companies | Связанные компании (с собственными phones/emails) |
Шаблоны
Загрузка скомпилированной Handlebars-функции из файла templates/<name>.hbs:
const template = await widgetApi.getTemplate('modal');
const html = template({ title: 'Заголовок', items: [{ name: 'A' }, { name: 'B' }] });
Доступные хелперы внутри шаблона:
- все методы Lodash с префиксом
_— например,{{_capitalize name}}; - логические
{{and a b}}и{{or a b}}.
Стили
widgetApi.linkStyle('modal'); // подключает styles/modal.css
CSS-классы внутри файла должны быть с префиксом widget-<widget-id>-,
чтобы не конфликтовать со стилями платформы и других виджетов.
Модальные окна
// Создать модалку с готовым HTML
const modal = await widgetApi.createModal({ content: htmlString, isLoading: false });
// Переключить состояние «загрузка»
widgetApi.loadingModal({ id: modal.id, isLoading: true });
// Закрыть модалку
widgetApi.closeModal(modal.id);
Уведомления
widgetApi.createNotice({ text: 'Готово' }); // success
widgetApi.createNotice({ text: 'Ошибка запроса', variant: 'error' }); // error
Отрисовка позиций
Виджет не отрисовывает позиции автоматически — это всегда делается из скрипта виджета в ответ на события.
Статические позиции (иконки) — берутся из config.json →
icons:
// Иконка в карточке сделки (по событию lead.opened)
widgetApi.renderStaticPosition('lead.main');
// Иконка в карточке компании / контакта
widgetApi.renderStaticPosition('company.main');
widgetApi.renderStaticPosition('contact.main');
// Иконка в сайдбаре
widgetApi.renderStaticPosition('sidebar');
Шаблонные позиции (HTML-блоки):
widgetApi.subscribe('more_settings.opened', async () => {
const template = await widgetApi.getTemplate('more_settings');
const content = template({ /* данные */ });
widgetApi.linkStyle('more_settings');
await widgetApi.renderTemplatePosition('more_settings', content);
});
widgetApi.subscribe('page.opened', async () => {
const template = await widgetApi.getTemplate('page');
const content = template();
widgetApi.linkStyle('page');
await widgetApi.renderTemplatePosition('page', content);
});
HTTP-запросы
| Метод | Когда использовать |
|---|---|
fetch(url, options) |
Браузерный Fetch API — сторонние API. |
widgetApi.externalFetch(url, options) |
Сторонний API, которому нужен JWT-токен пользователя — токен передаётся
автоматически в заголовке X-AUTH-TOKEN. |
widgetApi.internalFetch(url, options) |
Публичное API OkoCRM — токен авторизации пользователя уже подставляется в заголовок. |
const response = await widgetApi.internalFetch('/api/v1/leads/123');
const data = await response.json();
Пользователи
const users = await widgetApi.getUsers(); // [{ id, name, ... }, ...]
Работа с DOM и утилиты
Umbrella JS — для DOM, обработки событий и форм внутри отрисованного HTML:
import u from 'umbrellajs';
u('.widget-my-button').on('click', () => {
// ...
});
u('form.widget-my-form').handle('submit', () => {
// ...
});
Lodash — утилиты:
import _ from 'lodash';
const isReady = _.isBoolean(entity.ready);
const total = _.sumBy(entity.contacts, 'budget');
CSS-классы платформы
Чтобы элементы форм выглядели как родные элементы OkoCRM, используйте CSS-классы платформы в шаблонах:
| Элемент | Классы |
|---|---|
<input> (кроме checkbox) |
input, input--with-border, input--with-background |
<textarea> |
textarea, textarea--with-border, textarea--with-background |
<select> |
select-base, select-base--with-border, select-base--with-background |
<input type="checkbox"> |
checkbox — обязателен для всех чекбоксов |
<button> |
button, button--blue, button--white |
2. Widget Settings API
Доступ к настройкам виджета, идентификаторам и токенам пользователя. Передаётся в
script.js вторым аргументом.
export default async function (widgetApi, settingsApi) {
const settings = settingsApi.getSettings();
const userId = settingsApi.getUserId();
}
| Метод | Описание |
|---|---|
getId() | ID интеграции виджета |
getName() | Название виджета |
getUlid() | Уникальный ULID виджета |
getVersion() | Версия виджета |
getUrl() | Базовый URL папки виджета (для построения путей к ресурсам) |
getConfig() | Содержимое config.json |
getSettings() | Объект значений из settings.fields и more_settings, заполненных пользователем |
getSiteId() | ID CRM |
getUserId() | ID текущего пользователя |
getUserToken() | API-токен пользователя |
getJwtToken() | JWT-токен пользователя (используется в externalFetch) |
resetJwtToken() | Сбросить JWT-токен пользователя |
getSettingId() | ID настройки виджета |
getError() | { error, message } — ошибка виджета |
getIndex() | Индекс виджета в списке виджетов CRM |
3. Публичное API OkoCRM
Для чтения и записи бизнес-данных (сделки, контакты, компании, задачи, пользователи,
пользовательские поля и т. д.) используется публичное API OkoCRM. Из виджета — через
widgetApi.internalFetch, токен авторизации подставляется автоматически.
const response = await widgetApi.internalFetch('/api/v1/leads/123');
const lead = await response.json();
Полная документация публичного API: https://okocrm.com/api/