Пример: данные из внешнего API на портале¶
Сквозной пример настройки цепочки: Lua-скрипт вызывает внешний REST API, получает данные, а портальный виджет Smart Html отображает результат. В качестве примера — виджет с текущими курсами валют ЦБ РФ.
Общая схема¶
Lua-скрипт (HTTP:send_http_request)
↓ получает JSON от внешнего API
Смарт-пакет (Выполнить смарт-скрипт → HTTP-ответ)
↓ оборачивает результат в публикацию
Публикация пакета действий
↓ отдаёт данные по URL /app/v1.2/api/publications/action/{алиас}
JS-вставка на портале (AJAX-запрос к публикации)
↓ получает JSON, рендерит в DOM
Виджет Smart Html (отображает результат)
Каждый шаг можно проверить независимо от остальных.
Шаг 1. Lua-скрипт¶
Создайте глобальный смарт-скрипт: Администрирование → Общие смарты → вкладка Lua → Создать.
Скрипт вызывает API Центробанка и возвращает курсы валют в формате JSON:
-- Запрос к API ЦБ РФ
local json_res = HTTP:send_http_request(
'get',
'https://www.cbr-xml-daily.ru/daily_json.js',
{}, {}, '', {}
)
-- Извлекаем тело ответа
local content = json_res['HttpResponse']['ResponseContent']
local data = UTILS:json_decode(content)
-- Формируем результат — массив с нужными валютами
local currencies = {}
local codes = {'USD', 'EUR', 'CNY', 'GBP'}
for _, code in ipairs(codes) do
local cur = data['Valute'][code]
if cur then
table.insert(currencies, {
code = code,
name = cur['Name'],
value = cur['Value'],
previous = cur['Previous']
})
end
end
-- RESULT должен быть строкой JSON
RESULT = UTILS:json_encode({
date = data['Date'],
currencies = currencies
})
Проверка: нажмите Выполнить в редакторе скрипта. В области результата должен появиться JSON с курсами валют. Запомните ID скрипта — он понадобится на следующем шаге.
ℹ️ Функция
HTTP:send_http_requestвыполняется синхронно. Таймаут Lua-скрипта — 5 минут. Если внешний API отвечает медленно, это влияет на время загрузки виджета.
Шаг 2. Смарт-пакет¶
Создайте глобальный смарт-пакет: Администрирование → Общие смарты → вкладка Пакеты действий → Создать.
ℹ️ Включите флажок Для публикаций в настройках пакета — без него пакет не будет доступен при создании публикации.
Добавьте в пакет два действия в следующем порядке:
Действие 1: Выполнить смарт-скрипт
В параметре «Lua скрипт» выберите скрипт, созданный на шаге 1.
Действие 2: HTTP-ответ
В параметре «Тело HTTP-ответа» укажите смарт-выражение в режиме TSQL, которое возвращает результат предыдущего действия:
SELECT @eventParam1
Здесь @eventParam1 — результат первого действия в пакете (Lua-скрипт записал JSON в RESULT).
ℹ️ Действие «HTTP-ответ» должно быть последним в пакете. Без него публикация не вернёт данные.
Шаг 3. Публикация¶
Создайте публикацию: Администрирование → Публикации → Добавить публикацию.
| Параметр | Значение |
|---|---|
| Тип публикации | Пакет действий |
| Объект | Смарт-пакет, созданный на шаге 2 |
| Тип запроса | GET |
| Алиас | currency-rates |
| Активность | Включена |
После сохранения система сформирует URL:
/app/v1.2/api/publications/action/currency-rates
Проверка: откройте URL в браузере (будучи авторизованным в системе). Должен вернуться JSON с курсами валют.
Настройте доступ: укажите группы пользователей, которым разрешён доступ к публикации, либо включите флажок «Виден всем».
Шаг 4. Виджет Smart Html на портале¶
Создайте портальный блок: Администрирование → Порталы → выберите портал → добавьте блок типа Smart Html.
В настройках блока → Открыть дополнительные настройки → в шаблоне (левая часть) вставьте HTML-разметку:
<div id="currency-widget">
<div class="currency-loading">Загрузка курсов валют...</div>
</div>
Смарт-выражения для этого блока добавлять не нужно — данные поступят через JS-вставку и публикацию, а не через стандартный механизм смарт-выражений.
Запомните ID блока — он понадобится на следующем шаге.
Шаг 5. JS-вставка на портале¶
Добавьте JS-вставку к порталу. В ней — AJAX-запрос к публикации и рендер результата в DOM виджета:
(window.firstForma.portal.block(BLOCK_ID)).onLoaded(function () {
var container = document.getElementById('currency-widget');
fetch('/app/v1.2/api/publications/action/currency-rates')
.then(function (response) { return response.json(); })
.then(function (data) {
var html = '<table style="width:100%; border-collapse:collapse;">';
html += '<tr style="border-bottom:2px solid #eee;">';
html += '<th style="text-align:left; padding:8px;">Валюта</th>';
html += '<th style="text-align:right; padding:8px;">Курс</th>';
html += '<th style="text-align:right; padding:8px;">Изменение</th>';
html += '</tr>';
data.currencies.forEach(function (cur) {
var diff = (cur.value - cur.previous).toFixed(4);
var color = diff >= 0 ? '#2e7d32' : '#c62828';
var arrow = diff >= 0 ? '▲' : '▼';
html += '<tr style="border-bottom:1px solid #f5f5f5;">';
html += '<td style="padding:8px;">' + cur.code + ' — ' + cur.name + '</td>';
html += '<td style="text-align:right; padding:8px; font-weight:bold;">'
+ cur.value.toFixed(4) + ' ₽</td>';
html += '<td style="text-align:right; padding:8px; color:' + color + ';">'
+ arrow + ' ' + diff + '</td>';
html += '</tr>';
});
html += '</table>';
container.innerHTML = html;
})
.catch(function () {
container.innerHTML = '<div style="color:#c62828;">Ошибка загрузки курсов валют</div>';
});
});
Замените BLOCK_ID на ID портального блока, созданного на шаге 4.
Шаг 6. Проверка¶
Каждый шаг можно проверить независимо:
| Шаг | Как проверить |
|---|---|
| Lua-скрипт | Кнопка «Выполнить» в редакторе скрипта — JSON в области результата |
| Публикация | Открыть URL /app/v1.2/api/publications/action/currency-rates в браузере |
| Виджет на портале | Открыть портал — виджет показывает таблицу с курсами |
Типичные ошибки:
- Пустой ответ публикации — проверьте, что в пакете включён флажок «Для публикаций» и что «HTTP-ответ» — последнее действие.
- 403 при обращении к публикации — проверьте настройки доступа (группы или «Виден всем») и флажок «Активность».
- Ошибка в Lua — внешний API может быть недоступен с сервера 1Формы. Проверьте сетевую доступность и firewall.
- Данные не появляются в виджете — убедитесь, что ID блока в JS-вставке соответствует ID портального блока.
Полезные ссылки¶
Смарт-скрипты (Lua, JavaScript, Python)