This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
Шаблоны
Шаблоны позволяют генерировать как однострочные команды, так и целые блоки текста.
Эти механизмы являются основой построения взаимодействий SHM.
Шаблоны рендерятся локально (сервером SHM), результат рендера может быть отправлен/выполнен с помощью Транспорта.
Шаблоны служат:
Введение
Синтаксис: {{ ОБЪЕКТ.ДАННЫЕ }}
Например, с помощью объекта user можно получить доступ к данным пользователя:
user.id - идентификатор пользователя
user.login - логин пользователя
user.balance - баланс пользователя
Используя эти функции мы можем написать такой шаблон:
Уважаемый клиент.
Ваш логин: {{ user.login }}
Ваш баланс: {{ user.balance }} руб.
В шаблонах поддерживаются условия и циклы, примеры использования вы можете увидеть здесь: Прогноз оплаты
Больше информации о шаблонизаторе Вы можете узнать здесь
Объекты и функции
Ниже приведен список методов для работы с SHM через шаблоны.
Достуность тех или иных методов зависит от контекста применения шаблона.
Подробнее о доступности методов описано здесь.
Пользователь
| Метод |
Описание |
| user.id() |
Идентификатор пользователя (получить/установить) |
| user.switch( USER_ID ) |
Переключение пользователя на указанного (смена контекста) |
| user.login |
Логин пользователя |
| user.balance |
Баланс пользователя |
| user.credit |
Кредитный лимит пользователя |
| user.dogovor |
Договор пользователя |
| user.full_name |
ФИО пользователя |
| user.settings |
Получить settings пользователя |
| user.get_bonus |
Получить кол-во бонусов |
| user.income_percent |
Получить процент партнерских бонусов |
| user.add_bonus( КОЛ-ВО, КОММЕНТ ) |
Начисление бонусов |
| user.set_settings({ 'foo' => 1 }) |
Сохранить в settings пользователя произвольные данные |
| user.services |
Ссылка на услуги пользователя |
| user.gen_session.id |
Специальная функция для генерации идентификатора сессии |
| user.set_new_passwd |
Смена пароля пользователя. Вернет новый пароль |
| user.pays. |
Ссылка на платежи пользователя |
| user.delete |
Удаление пользователя (с нулевым балансом, без услуг) |
| user.list_for_api( 'admin', 1) |
Получить всех пользователей |
Услуги пользователя
| Метод |
Описание |
| us.id() |
Идентификатор пользовательской услуги (получить/установить) |
| us.name |
Имя пользовательской услуги |
| us.created |
Дата создания пользовательской услуги |
| us.expire |
Дата истечения пользовательской услуги |
| us.status |
Статус пользовательской услуги |
| us.settings |
Получить параметры пользовательской услуги |
| us.set_settings({ 'foo' => 1 }) |
Сохранить в settings услуги пользователя произвольные данные |
| us.set(FIELD, VALUE) |
Установка поля FIELD в значение VALUE. Пример: us.set('next', 123) |
| us.child_by_category(CATEGORY). |
Ссылка на дочернюю услугу определенной категории |
| us.finish( 'money_back', 1) |
Завершение услуги с возвратом средств (биллинг продлит или заблокирует услугу в зависимости от наличия средств) |
| us.block |
Принудительная блокировка услуги пользователя |
| us.activate |
Активация услуги пользователя после блокировки |
| us.delete |
Удаление заблокированной услуги пользователя |
| us.gen_store_pass |
Специальная функция для генерации и сохранения пароля в settings |
| us.parent. |
Ссылка на родительскую услугу пользователя |
| us.top_parent. |
Ссылка на самую верхнюю услугу пользователя |
| us.service. |
Ссылка на каталог услуг |
| us.withdraw. |
Ссылка на списание услуги |
| us.list_for_api() |
Получение списка услуг пользователя |
Каталог услуг
| Метод |
Описание |
| service.id() |
Идентификатор пользовательской услуги (получить/установить) |
| service.name |
Название услуги |
| service.cost |
Базовая стоимость услуги |
| service.period |
Период услуги |
| service.category |
Категория услуги |
| service.server |
Ссылка на сервер услуги |
| service.id( N ).name |
Получение имени услуги c идентификатором N |
| service.id( N ). |
Получение произвольного поля услуги c идентификатором N |
| service.api_price_list() |
Возвращает массив услуг из каталога |
| service.settings |
Получить settings услуги |
| service.set_settings({ 'foo' => 1 }) |
Сохранить в settings услуги произвольные данные |
| service.withdraw. |
Ссылка на объект списания |
| service.create_for_api( 'service_id', N, 'check_allow_to_order',1 ) |
Регистрирует услугу клиенту с идентификатором N |
| service.list_for_api() |
Получение списка услуг из каталога |
Платежи
| Метод |
Описание |
| pay.id() |
Получить/установить id платежа |
| pay.date |
Дата и время платежа |
| pay.money |
Cумма платежа |
| pay.pay_system_id |
Имя платежной системы |
| pay.comment |
Данные платежа |
| pay.last |
Получить ссылку на последний платеж |
| pay.forecast |
Возвращает JSON прогноза оплат услуг |
| pay.paysystems |
Получить список платежных систем |
| pay.list_for_api() |
Получение списка платежей |
Бонусы
| Метод |
Описание |
| bonus.list_for_api() |
Получение списка бонусов |
Списания
| Метод |
Описание |
| wd.id() |
Получить/установить id списания |
| wd.create_date |
Дата создания списания |
| wd.withdraw_date |
Дата списания списания |
| wd.cost |
Сумма |
| wd.discount |
Скидка |
| wd.bonus |
Кол-во бонусов |
| wd.months |
Период услуги |
| wd.total |
Итоговая стоимость |
| wd.service_id |
идентификатор каталога услуг |
| wd.user_service_id |
идентификатор услуги пользователя |
| wd.qnt |
Кол-во единиц товара |
| wd.list_for_api() |
Получение списка списаний |
Сервера
| Метод |
Описание |
| server.id() |
Получить/установить id сервера |
| server.name |
Имя сервера |
| server.host |
Host сервера |
| server.transport |
Транспорт сервера |
| server.settings |
Получение settings текущего сервера |
| server.set_settings({ 'foo' => 1 }) |
Сохранить в settings сервера произвольные данные |
| server.group. |
Ссылка на группу сервера |
| server.servers_by_group_id( N ) |
Получение списка серверов из группы N |
| server.list_for_api() |
Получение списка серверов |
Группы серверов
| Метод |
Описание |
| sg.id() |
Получить/установить id группы серверов |
| sg.name |
Имя группы серверов |
| sg.type |
Способ выбора серверов (random,by-one,evenly) |
| sg.transport |
Транспорт группы (local,ssh,http…) |
| sg.settings |
settings группы серверов |
| sg.set_settings({ 'foo' => 1 }) |
Сохранить в settings группы серверов произвольные данные |
| sg.list_for_api() |
Получение списка групп серверов |
Шаблоны
| Метод |
Описание |
| tpl.id |
Получить/установить id шаблона |
| tpl.id( NAME ).parse( 'usi', 123 ) |
Выполнить шаблон с именем NAME для пользовательской услуги с идентификаторм 123 |
| tpl.data |
Данные шаблона |
| tpl.settings |
Получить settings шаблона |
Хранилище
| Метод |
Описание |
| storage.save( NAME, DATA ) |
Сохранить данные DATA в хранилище с ключом NAME |
| storage.load( NAME ) |
Получить данные из хранилища с ключом NAME |
| storage.del( NAME ) |
Удалить данные из хранилища с ключом NAME |
| storage.list_for_api() |
Получение списка данных |
Конфигурация
| Метод |
Описание |
| config.NAME |
Получить данные NAME из конфигурации |
Telegram
| Метод |
Описание |
| telegram.bot(TEMPLATE, CMD, [ARGS]) |
Выполнить CMD с аргументами ARGS из шаблона TEMPLATE |
Задачи
| Метод |
Описание |
| task |
Работа с задачами |
Вспомогательные ф-ии
| Метод |
Описание |
| params |
Аргументы вызова шаблона (http query string) |
| event_name |
Переменная содержит название текущего события |
| toJson() |
Функция преобразования объекта в JSON |
| toQueryString() |
Функция преобразования объектов в Query string |
| ref() |
Функция для преобразования данных в массив |
| list_for_api() |
Функция для получения списков данных из объекта |
Примеры
1 - Использование методов
Ряд методов, описанных в разделе Шаблоны не будут работать в ряде случаев.
Работа с идентификаторами
Практически все методы поддерживают работу с идентификаторами (id).
Например, user.id вернет идентификатор текущего пользователя, а us.id вернет идентификатор текущей пользовательской услуги.
Если метод не возвращает свой id, то значит он небыл инициализирован, и следует “добираться” до метода либо через услугу пользователя, либо
через явное указание идентификатора: id( N ). Например, в ряде случаев, server.id не вернет свой идентификатор, однако: us.service.server.id - вернет.
Помимо получения идентификатора, его можно и установить, пример:
user.id(123) - вернет объект для пользователя с идентификатором 123.
user.login - вернет login текущего пользователя
user.id(123).login - вернет login пользователя 123
us.name - вернет название текущей услуги пользователя (если определена)
us.id(99).name - вернет название услуги пользователя с идентификатором 99
Контекст применения шаблонов
| Метод |
Контекст |
| us.* |
События |
| us.id( N ).* |
Везде |
| us.withdraw |
Для платных услуг |
| us.service.server |
Для услуг, у которых определен сервер (server_id в settings услуги пользователя) |
| server.* |
События, Задачи, INIT сервера |
| server.id( N ) |
Везде |
| task |
События, Задачи |
2 - Платежные системы
Описание
SHM имеет встроенный модуль paysystems, позволяющий получать список доступных платежных систем.
Получить список платежных систем можно:
- Через Web:
/shm/v1/user/pay/paysystems
- Из шаблонов:
pay.paysystems( АРГУМЕНТЫ )
Аргументы
| Параметр |
Описание |
| user_id |
Идентификатор пользователя |
| amount |
Сумма платежа. По-умолчанию в неё записывается значение total из “Прогноз оплаты” |
| pp |
Proposed Payment (Предлагаемый платеж). Установите этот параметр в 1, если хотите, чтобы сумма платежа (amount) была установлена в ссылку shm_url |
| paysystem |
Укажите платежную систему, если хотите получить ссылку только для одной конкретной платежной системы |
Описание полей
Пример ответа:
{
"TZ": "Europe/Moscow",
"data": [
{
"amount": 123,
"forecast": 0,
"name": "yookassa",
"paysystem": "yookassa",
"shm_url": "/shm/pay_systems/yookassa.cgi?action=create&user_id=1&ts=1706539331&amount=",
"user_id": 1,
"weight": 10
},
{
"amount": 123,
"forecast": 0,
"name": "ЮMoney",
"paysystem": "yoomoney",
"shm_url": "/shm/pay_systems/yoomoney.cgi?action=create&user_id=1&ts=1706539331&amount=",
"user_id": 1,
"weight": 0
}
],
"date": "Mon Jan 29 17:42:11 2024",
"items": 0,
"limit": 25,
"offset": 0,
"version": "0.10.0"
}
Где:
paysystem - Платежная система
name - Произвольное название платежной системы (для отображения)
amount - Сумма платежа. По-умолчанию заполняется из “Прогноз оплаты”, если он положительный, или из переданного аргумента amount. В остальных случаях - пустой.
forecast - “Прогноз оплаты”
weight - “вес”. Используется для сортировки платежных систем
shm_url - Ссылка для выставления счета в платежной системе. Если флаг pp не установлен, то amount в ссылке остается пустой. Это сделано для удобства использования ссылки.
3 - Функции
toJson()
Преобразует объект в JSON.
Данную ф-ию удобно использовать для отладки запросов, когда не очевидно, что вернет тот или иной метод, для просмотра полей и т.п.
Пример 1:
Смотрим, что вернет метод user.list_for_api:
{{ toJson( user.list_for_api ) }}
Результат:
{
"balance": 123.45,
"block": 0,
"bonus": 0,
"can_overdraft": 0,
"created": "2024-01-08 15:18:16",
"credit": 0,
"discount": 0,
"full_name": "Admin",
"last_login": "2024-01-22 20:52:53",
"login": "admin",
"user_id": 1
}
Пример 2:
Строим JSON объект. Удобно для использования в Telegram bot-е, в HTTP запросах и т.п.:
{{
toJson(
a = user.id
b = 2
c = [3,4,5]
)
}}
Результат:
{"a":1,"b":2,"c":[3,4,5]}
toQueryString()
Преобразование объекта в Query String:
Пример:
{{
toQueryString(
a = user.id
b = 2
c = "hello world"
)
}}
Результат:
a=1&b=2&c=hello%20world
list_for_api()
Метод для получения списка данных объекта.
Без аргументов выдаст первые 25 строк данных.
Аргументы:
| Параметр |
Описание |
| admin |
Установка этого параметра в 1 позволяет получить данные всех клиентов |
| limit |
Кол-во отдаваемых данных. По-умолчанию: 25. (0 - без лимитов) |
| offset |
Индекс начала смещения списка. По-умолчанию: 0 |
| filter |
Используется для поиска данных по определенным полям |
| sort_field |
Поле для сортировки (по-умолчанию ключевое поле) |
| sort_direction |
Порядок сортировки: asc, desc (по-умолчанию desc) |
Пример 1:
Выведем всех пользователей:
{{ arr = ref(user.list_for_api('admin', 1)) }}
{{ FOR item IN arr }}
User id: {{ item.user_id }}, Login: {{ item.login }}, Balance: {{ item.balance }}
{{ END }}
Результат:
User id: 1, Login: admin, Balance: 0
User id: 22, Login: danuk, Balance: 224.44
User id: 34, Login: Dima, Balance: 0
User id: 117, Login: xims, Balance: 200
Пример 2:
Выведем список всех услуг с категорией начинающиеся на web, и период которых равен 1 месяцу:
{{ arr = ref(service.list_for_api('filter', { 'category' => 'web%', period => 1 } )) }}
{{ FOR item IN arr }}
Service id: {{ item.service_id }}, Name: {{ item.name }}, Cost: {{ item.cost }}
{{ END }}
Результат:
Service id: 111, Name: Web хостинг, Cost: 0
Service id: 110, Name: Тариф X-MAX, Cost: 300
Service id: 5, Name: Web хостинг LITE, Cost: 0
Сортировка
Существует два типа сортировки:
- Сортировка на уровне запросов
- Сортировка на уровне шаблона
При использовании пагинации важно сортировать результаты на уровне запросов.
Сортировка на уровне запросов
Сортировка на уровне запросов осуществляется непосредственно в БД.
Пример выдачи результатов отсортированных по возрастанию:
{{ arr = ref(service.list_for_api('sort_direction','asc')) }}
Пример выдачи результатов отсортированных по возрастанию по полю name:
{{ arr = ref(service.list_for_api('sort_direction','asc', 'sort_field','name')) }}
Сортировка в шаблонах
Сортировка в шаблонах используется для сортировки полученных данных.
Для сортировки используете функции: sort (для алфавитной сортировки), nsort (для числовой сортировки) и reverse (обратный порядок данных).
Пример сортировки по полю category:
{{ arr = ref(service.list_for_api().sort('cateogry')) }}
Пример сортировки по полю cost, в убывающем порядке:
{{ arr = ref(service.list_for_api().nsort('cost').reverse) }}
4 - Автоматизации
4.1 - Подсчет доходов за месяц
Ниже приведен пример шаблона для подсчета поступления средств за Январь 2024 года:
{{ sum = user.pays.filter( date = '2024-01-%' ).sum( all_users = 1 ).money }
Итого за Январь: {{ sum }} руб.
4.2 - Рассылки
SHM умеет делать рассылки по всем пользователям.
Для того, чтобы сделать рассылку, необходимо:
- В кабинете Администратора выбрать пункт меню: “Задачи -> Текущие задачи”, далее нажать кнопку “ADD”.
- Выберите для кого сделать рассылку: для одного пользователя или для всех (при тестировании используйте одного конкретного пользователя)
- Выберите группу серверов, которая будет использоваться для рассылки
- Выберите необходимый шаблон
- Создайте задачу
- Контролируйте исполнение задчи в “Текущие задачи”
В случае, если после рендера шаблон получается пустой, то такое сообщение отправлено не будет.
Этот свойство используется для выборочной отправки сообщений.
Примеры шаблонов
Шаблон для всех клиентов
Уважаемый {{ user.full_name }}!
Это тестовое сообщение.
Ваш личный кабинет находится по адресу: {{ config.cli.url }}
Шаблон для пользователей Telegram
Если рассылку делать с помощью транспорта Телеграм, то данная проверка в
шаблоне смысла не имеет, так как транспорт Телеграм сам проверяет это поле.
{{ IF user.settings.telegram.login }}
Вы получили это сообщение потому, что у Вас есть Telegram.
Ваш Telegram логин: {{ user.settings.telegram.login }}
{{ END }}
Шаблон для услуг в определенной категории
Данный шаблон будет отправлен только клиентам, у которых есть услуги в категории test.
Категорию услуг можно указать и через маску, например так: te%.
{{ IF user.services.list_for_api('category','test') }}
Уважаемый {{ user.full_name }}!
Вы получили это сообщение потому, что у Вас есть услуга в категории test.
{{ END }}
Информация об услугах в определенной категории
Показываем сообщение для каждой услуги в категории test.
{{ user_services = ref(user.services.list_for_api('category','test')) }}
{{ IF user_services }}
Услуги в категории test найдены в количестве: {{ user_services.size }} штук.
{{ FOR item IN user_services }}
Услуга: {{ item.name }}
Категория: {{ item.category }}
Статус: {{ item.status }}
Действует до: {{ item.expire }}
Цена: {{ item.withdraws.cost }}
Кол-во: {{ item.withdraws.qnt }}
Cкидка: {{ item.withdraws.discount }}%
Итого: {{ item.cost }}
{{ END }}
{{ END }}
Активная услуга в определенной категории
Перебираем (ищем) все услуги пользователя с категорией test, и проверяем, что статус активный.
Как только активная услуга будет найдена, то пишем сообщение и прекращаем перебор (LAST).
Таким образом, будет выведено только одно сообщение, даже если услуг несколько.
Если нужно выводить сообщения для каждой услуги, необходимо убрать LAST.
{{ FOR item IN ref(user.services.list_for_api('category','test')) }}
{{ IF item.status == 'ACTIVE' }}
Вы видите это сообщение, потому что у вас есть активная услуга в категории test
{{ LAST }}
{{ END }}
{{ END }}
Уведомление клиентам без услуг в определенной категории
{{ IF ref(user.services.list_for_api('category','test')).empty }}
Вы видите это сообщение, потому что у вас нет ниодной услуги в категории test
{{ END }}
Подробнее о создании и настройке шаблонов можно прочитать здесь
4.3 - Удаление услуг при блокировке
Для удаления услуг при блокировке создайте шаблон вида:
{{ IF us.status == 'BLOCK' }}
{{ us.delete }}
{{ END }}
и добавьте его к событию CHANGED для нужной категории услуг.
Каждый раз, когда услуга будет переходить в статус BLOCK, SHM будет удалять её.
4.4 - Массовое начисление бонусов
Бывают случаи, когда необходимо начислить бонусы всем клиентам. Здесь приведены примеры, как это сделать.
Массовое начисление бонусов клиентам с указанной активной услугой:
Следующий код начислит всем клиентам с активной услугой 5 по 100 бонусов:
{{ FOR u IN user.items }}
{{ us_list = u.us.filter( service_id = 5, status = 'ACTIVE' ).items }}
{{ IF us_list.size }}
{{ u.add_bonus( 100, 'Акция' ) }}
{{ END }}
{{ END }}
4.5 - Массовое обновление тарифов
Бывают случаи, когда нужно обновить тарифы всем клиентам. Здесь приведены примеры, как это сделать.
Обновление стоимости текущей услуги (тарифа)
Просто изменить стоимость услуги в Каталоге не достаточно.
Необходимо для таких услуг пользователя установить “следующую” услугу в “текущую”:
{{ FOR u IN user.items }}
{{ FOR us IN u.us.items }}
{{ us.set(next = us.service_id) }}
{{ END }}
{{ END }}
Массовая смена услуг (тарифов)
Например, мы хотим сменить (со следующего учетного периода) услугу 5 на 6, делается это так:
{{ FOR u IN user.items }}
{{ FOR us IN u.us.filter( service_id = 5 ).items }}
{{ us.set(next = 6) }}
{{ END }}
{{ END }}
5 - Уведомления клиентам
Для отправки уведомлений клиентам создайте соответствующее событие и привяжите к нему шаблон.
Уведомления будут отправлены с помощью выбранного транспорта. Например, Вы можете отправить уведомление EMAIL, и/или Telegram (настраивается в событии).
5.1 - Прогноз оплаты
Описание
SHM имеет встроенный модуль forecast, позволяющий получать информацию о прогнозе оплаты услуг.
forecast находит все услуги (кроме уже заблокированных), дата истечения которых менее чем 3 дня (days), и ещё неоплаченные услуги, и вычисляет стоимость их продления.
Получить прогноз оплаты можно следующими способами:
- Через Web для текущего авторизованного пользователя:
/shm/v1/user/pay/forecast
- Через Web для пользователя с ID 123:
/shm/v1/user/pay/forecast?user_id=123 (нужно быть авторизованным под администратором)
- Из шаблонов:
user.pays.forecast
Настройки
| Параметр |
Описание |
| days |
Кол-во дней для прогноза (3 дня по-умолчанию) |
| blocked |
Учитывать заблокированные услуги (0 - по-умолчанию НЕТ) |
Пример команды в шаблонах:
{{ forecast = user.pays.forecast(days = 10, blocked = 1) }}
Пример шаблона
Метод user.pays.forecast возвращает JSON вида:
{
"items": [
{
"name": "Регистрация домена в зоне .RU",
"service_id": 11,
"user_service_id": 2949,
"usi": 2949,
"cost": 590,
"discount": 0,
"months": 12,
"qnt": 1,
"total": 590,
"expire": "2017-07-29 12:39:46",
"status": "ACTIVE",
"next": {
"name": "Продление домена в зоне .RU",
"service_id": 12,
"cost": 890,
"discount": 0,
"months": 12,
"qnt": 1,
"total": 890
}
}
],
"balance": -21.56,
"bonuses": 100,
"dept": 21.56,
"total": 768.44
}
Мы можем построить шаблон письма о прогнозе опаты услуг следующим образом:
Уважаемый {{ user.full_name }}
{{ forecast = user.pays.forecast }}
{{ ap = user.make_autopayment( forecast.total ) }}
{{ IF ap == 1 }}
Выполнен автоплатеж в размере: {{ forecast.total }}.
Ваши услуги будут продлены автоматически.
{{ ELSE }}
Уведомляем Вас о сроках действия услуг:
{{ FOR item IN ref(forecast.items) }}
- Услуга: {{ item.name }}
{{ IF item.expire }}
Истекает: {{ item.expire }}
{{ IF item.service_id != item.next.service_id }}
Следующая услуга: {{ item.next.name }}
Стоимость: {{ item.next.total }}
{{ ELSE }}
Стоимость продления: {{ item.next.total }}
{{ END }}
{{ ELSE }}
Стоимость: {{ item.total }}
{{ END }}
{{ END }}
{{ IF forecast.dept }}
Погашение задолженности: {{ forecast.dept }}
{{ END }}
Итого к оплате: {{ forecast.total }} руб.
{{ END }}
Подробнее о создании и настройке шаблонов можно прочитать здесь
5.2 - Уведомление о зачислении платежа
Описание
Создайте шаблон со следующим содержимым и привяжите его к событию PAYMENT:
{{ IF pay.money == 0 }}
Ошибка, платеж не прошел
{{ ELSE }}
Зачислен платеж на сумму: {{ pay.money }} руб.
Ваш баланс: {{ user.balance }} руб.
{{ END }}
6 - HTTP (API)
SHM позволяет использовать шаблоны для внешнего использования
Поддерживаемые методы:
HTTP адрес
Доступ к шаблону с именем my_template можно получить следующим способами:
Для пользователей
Доступ с авторизацией:
/shm/v1/template/my_template?format=html&foo=1&bar=hello
Пример для curl
curl -s -u 'admin:admin' http://127.0.0.1:8081/shm/v1/template/my_template
Более детально о вариантах аутентификации можно почитать здесь
Для публичного использования
/shm/v1/public/my_template?format=html&foo=1&bar=hello
Для того, чтобы шаблон работал без авторизации необходимо прописать в его settings параметр:
allow_public: true
В публичных шаблонах переменная user не устанавливается автоматически, но её можно установить самостоятельно:
-
Указать идентификатор вручную (статически):
в шаблоне: {{ user = user.switch( 123 ) }}
-
Указать идентификатор через HTTP запрос:
/shm/v1/public/my_template?uid=123
в шаблоне: {{ user = user.switch( request.params.uid ) }}
Пример для curl
curl -s http://127.0.0.1:8081/shm/v1/public/my_template?uid=123
Пример шаблона для проверки существования пользователя:
{{ IF user.switch( request.params.uid ).id }}
...
{{ END }}
Аргументы
В строку запроса можно добавить любые аргументы. Внутри самого шаблона к ним можно обратиться через переменную request.params
{{ foo = request.params.foo }}
Ниже приведен список специальных аргументов:
plain (text/plain)
html (text/html)
json (application/json)
other (application/octet-stream)
qrcode
user_id - зарезервирован
В случае работы с шаблоном из под прав администратора можно явно указать идентификатор пользователя
HTTP заголовки
В шаблонах можно читать заголовки. Их удобно использовать для различных проверок
{{ headers = request.headers }}
Пример шаблона для проверки заголовка x-webhook-secret:
{{ IF request.headers.x-webhook-secret == 'something-very-very-secret' }}
...
{{ END }}
Примеры
6.1 - Вывод данных в формате HTML
Пример шаблона (my_template) для формирования данных в HTML:
<table border=1>
{{ FOR u IN ref( user.list_for_api('admin',1,'limit',0)) }}
<tr>
<td>{{ u.user_id }}</td>
<td>{{ u.login }}</td>
<td>{{ u.balance }}</td>
</tr>
{{ END }}
</table>
Пример вызова шаблона для curl:
curl -s http://127.0.0.1:8081/shm/v1/public/my_template?format=html
Необходимо прописать в settings шаблона параметр: allow_public: true
Результат работы HTML шаблона лучше всего смотреть в браузере:
http://127.0.0.1:8081/shm/v1/public/my_template?format=html
6.2 - Вывод данных в формате JSON
Для формирования JSON объекта удобно использовать следующий синтаксис:
Пример шаблона (my_template) для формирования данных в JSON:
{{ u = user.id( request.params.uid ) }}
{{
toJson({
user_id = u.id
login = u.login
balance = u.balance
last_payment = u.pays.last
forecast = u.pays.forecast.total
})
}}
Пример вызова шаблона для curl:
curl -s http://127.0.0.1:8081/shm/v1/public/my_template?format=json&uid=123
Необходимо прописать в settings шаблона параметр: allow_public: true
Пример результата:
{
"user_id": "123",
"login": "danuk",
"balance": -21.56,
"last_payment": {
"comment": null,
"date": "2016-01-04 20:33:35",
"id": 2,
"money": 455,
"pay_system_id": "manual",
"user_id": 123
},
"forecast": 1013.45
}
7 - Выполнение скриптов
Шаблоны позволяют генерировать как однострочные команды, так и целые блоки текста.
Эти механизмы являются основой построения взаимодействий SHM.
8 - Telegram bot
Шаблон для Telegram Bot-а
Это двух-уровневый шаблон. Сначала используются теги <% ... %> для нахождения
нужной секции шаблона, соответствующей команды. После нахождения нужной секции
шаблонизатор будет использовать теги вида: {{ ... }}.
Для сопоставления команды пользователя/бота используется внутренняя переменная cmd.
Так, при наборе команды /balance будет найдена секция: <% CASE '/balance' %>.
Команда USER_NOT_FOUND является встроенной в SHM, и вызывается автоматичеки, когда SHM не может найти у себя этого пользователя.
В каждой секции мы можем писать реальные команды Telegram. Например, команда sendMessage отправляет сообщение в Telegram.
Вы можете использовать эту команду в соответсвии с документацией Telegram.
Для отправки команд в API Telegram используйте метод tg_api.
Для того, чтобы лучше понять, как строятся всевозможные кнопочки, читайте документацию Telegram. В этом шаблоне всего-лишь описаны вызовы этих методов.
Пример шаблона:
<% SWITCH cmd %>
<% CASE 'USER_NOT_FOUND' %>
{{ tg_api( shmRegister = { callback_data = "/menu" } ) }}
<% CASE ['/start', '/menu'] %>
{{ tg_api( sendMessage = {
text = "Я Ваш тестовый Telegram Bot"
reply_markup = {
inline_keyboard = [
[
{
text = "Баланс"
callback_data = "/balance"
}
]
]
}
}
)
}}
<% CASE '/balance' %>
{{ tg_api( deleteMessage = { message_id = message.message_id } ) }}
{{ tg_api( sendMessage = {
text = "Баланс: " _ user.balance
reply_markup = {
inline_keyboard = [
[
{
text = "Назад"
callback_data = "/menu"
}
]
]
}
}
)
}}
<% CASE %>
{{ tg_api( sendMessage = { text = 'Я не знаю команды: ' _ cmd } ) }}
<% END %>
Стандартные методы Telegram
В SHM можно использовать любые методы Telegram.
Полный перечень доступных методов и синтаксис их использования
можно посмотреть на официальном сайте документации Telegram https://core.telegram.org/bots/api#available-methods
chat_id - заполняется автоматически, но при необходимости его можно указать
Встроенные переменные SHM
cmd - специальная переменная SHM в которую записывается значение, полученное из Telegram, в зависимости от типа:
message.text для команд введеных пользователем, и callback_query.data для callback_data. Если команда пользователя начинается
с символа /, то такая команда будет усечена до первого слова.
args - массив аргументов команды, разделитель - пробел.
start_args - именованный массив аргументов для команды start
message - полное сообщение от Telegram (json объект)
Примеры парсинга cmd и args:
| Источник |
Команда |
cmd |
args |
| Пользователь |
/test 1 2 3 |
/test |
[1,2,3] |
| Пользователь |
test 1 2 3 |
test 1 2 3 |
[1,2,3] |
| callback_data |
/test 1 2 3 |
/test |
[1,2,3] |
| callback_data |
test 1 2 3 |
test |
[1,2,3] |
args - это массив. Для получения значений из него используйте синтаксис: args.N, где N - индекс элемента.
Например, получить первый элемент массива можно так: args.0
Передача дополнительных параметров при старте бота
При старте бота может понадобится передача каких-либо данных, например для отслеживания рекламных акций (utm метрики),
или для создания партнерской ссылки.
ВНИМАНИЕ: суммарная длина параметров не может превышать 64 символа
Генерация партнерской ссылки
Для генерации партнерской ссылки можно использовать следующий шаблон:
https://t.me/myshm_bot?start={{ toBase64Url(toQueryString( pid = user.id )) }}
где myshm_bot - имя бота (замените на свой)
Генерация ссылки с произвольными параметрами
https://t.me/myshm_bot?start={{ toBase64Url(toQueryString(
utm_source = 'google'
utm_medium = 'telegram'
foo = 'bar'
))
}}
где myshm_bot - имя бота (замените на свой)
Переменные utm_ автоматически сохраняются в settings пользователя
Чтение переданных параметров
Вы можете прочитать переданный при старте бота параметр с помощью специальной переменной: start_args, пример:
Источник: {{ start_args.utm_source }}
Встроенные методы SHM
shmRegister
Метод позволяет зарегистрировать нового клиента
"shmRegister": {
"callback_data": "/menu",
"error": "ОШИБКА"
}
shmServiceOrder
Метод для регистрации новых услуг. Пример использования:
"shmServiceOrder": {
"service_id": "{{ args.0 }}",
"expire": "2014-09-25 10:11:12",
"parent": 123,
"check_exists": 1,
"check_exists_unpaid": 1,
"check_category": "test-%",
"callback_data": "/menu",
"cb_not_enough_money": "/pay",
"error": "ОШИБКА"
}
где: service_id - ID услуги,
expire - установка произвольной даты истечения услуги (опционально),
parent - ID родительской услуги (опционально),
check_exists - проверка существования услуги (опционально),
check_exists_unpaid - проверка существования неоплаченной услуги (опционально),
check_category - проверка существования услуги по категории (опционально),
callback_data - команда для случая успешного заказа услуги,
cb_not_enough_money - команда для случая нехватки средств для активации услуги.
Если используется один из флагов: check_exists, check_exists_unpaid, check_category и услуга найдена,
то регистрация новой услуги не осуществляется, а метод вернет первую найденную услугу (callback_data или cb_not_enough_money).
shmServiceDelete
Метод для удаления услуг пользователя. Пример использования:
"shmServiceDelete": {
"usi": "{{ args.0 }}",
"callback_data": "/menu",
"error": "ОШИБКА"
}
где: usi - ID услуги пользователя
uploadDocumentFromStorage
Метод загружает данные из Storage и отправляет их в виде файла
"uploadDocumentFromStorage": {
"name": "{{ args.0 }}",
"filename": "{{ args.0 }}.conf"
}
uploadPhotoFromStorage
Метод загружает данные из Storage и отправляет их в виде картинки (QR code)
"uploadPhotoFromStorage": {
"name": "{{ args.0 }}",
"format": "qr_code_png"
}
shmRedirectCallback
Метод вызывает указанную команду (cmd)
"shmRedirectCallback": {
"callback_data": "/help"
}
Приём платежей
Для приёма платежей в Telegram удобно использовать дополнительный шаблон (web_app).
Шаблон используется для возможности ввода произвольной суммы и выбора настроенных платежных систем SHM.
- Настройте одну или несколько платежных систем
- Скачайте шаблон и сохраните в SHM под названием
tg_payments_webapp
- Сделайте шаблон публичным: пропишите в его
settings параметр: allow_public: true
- В Шаблоне своего бота используйте конструкцию вида:
<% CASE '/payment' %>
{{ tg_payment_webapp="$config.api.url/shm/v1/public/tg_payments_webapp?format=html&user_id=$user.id&profile=$tpl.id" }}
{{ tg_api(
sendMessage = {
text = "Оплата покупки",
reply_markup = {
inline_keyboard = [
[{
text = "Оплатить..."
web_app = { url = tg_payment_webapp }
}]
]
}
}
)
}}
Дополнительно можно передавать:
email, например: &email={{ user.settings.email }}
ack_email, например: &ack_email=1 - появится поле ввода email
8.1 - Пагинация
Пример шаблона для постраничного вывода списка услуг
{{
limit = 5
data = []
}}
<% SWITCH cmd %>
<% CASE '/list' %>
{{
offset = args.0 || 0
items = ref( user.services.list_for_api('limit',limit, 'offset',offset) )
}}
{{ FOR item IN items }}
{{ data.push(
[{
"text" = 'Услуга: ' _ item.name _ ' ID: ' _ item.user_service_id
"callback_data" = '/service ' _ item.user_service_id
}]
)
}}
{{ END }}
{{ data.push(
[{
"text" = 'Еще...'
"callback_data" = '/list ' _ (limit + offset)
}]
) IF items.size == limit
}}
{
"sendMessage": {
"text": "Список услуг",
"reply_markup" : {
"inline_keyboard": {{ toJson( data ) }}
}
}
}
<% END %>