Руководство по триггерам

Инструкция по автоматизации процессов в amoCRM с помощью виджета «Триггеры»

Виджет «Триггеры» помогает автоматизировать рутинные действия в amoCRM, настраивать бизнес-процессы и связывать любые сервисы с amoCRM с использованием веб-хуков.

В данной инструкции вы научитесь:

  • Создавать сценарии автоматизации на различные события в CRM;
  • Работать с шаблонизатором переменных;
  • Связывать несколько виджетов в единую систему через Триггеры;
  • Интегрировать через Триггеры внешние сервисы и сайты с amoCRM;

Описание виджета и цены

Плейлист с примерами настроек на Youtube

Список переменных для шаблонизатора

ОБЩИЕ ПОНЯТИЯ

  • Как запускается сценарий?
  • Пример настройки сценария
  • Все сценарии по типу запуска
  • Список всех условий
  • Список всех сравнений
  • Работа с отложенные триггерами
  • Работа с глобальными переменными
  • Триггерные ссылки
  • Входящие веб хуки
  • Отладка сценариев
  • Ответы на вопросы и коды ошибок
  • Технические ограничения
  • Примеры готовых решений

БАЗОВЫЕ ТРИГГЕРЫ

  1. Создать сделку
  2. Создать контакт
  3. Создать компанию
  4. Копировать сделку
  5. Сменить значение поля
  6. Поставить задачу
  7. Добавить примечание
  8. Сменить теги
  9. Сменить статус сделки
  10. Запустить другой сценарий
  11. Запустить SalesBot (чаты с клиентами)
  12. Отправить веб-хук
  13. Подписать на сделку (на чат)
  14. Изменить задачу
  15. Изменить глобальную переменную
  16. Удалить отложенный триггер
  17. Нормализовать телефон и e-mail
  18. Добавить товары
  19. Удалить товары

ТРИГГЕРЫ С ДРУГИМИ ВИДЖЕТАМИ

  1. Отправить письмо («Почтовик»)
  2. Отправить сообщение в («Телеграм»)
  3. Отправить уведомление, запросить данные («Пушер»)
  4. Создать документ («Документы»)
  5. Отправить СМС («SMS-шлюз»)
  6. Подтянуть реквизиты («Dadata»)
  7. Добавить чек-лист («Чек-листы»)
  8. Создать платеж («Касса»)

Сценарии автоматизации

Сценарий — это основная сущность автоматизации, которая содержит в себе логику запуска триггеров. Сценарий может быть запущен по обширному списку действий, в том числе вручную.

На что можно запустить сценарий?

  • Сделки

    • Создание сделки
    • Изменение сделки
    • Смена ответственного у сделки
    • Изменение статуса сделки
  • Контакты

    • Создание контакта
    • Изменение контакта
    • Смена ответственного у контакта
  • Компании

    • Создание компании
    • Изменение компании
    • Смена ответственного у компании
  • Задачи

    • Создание задачи
    • Изменение задачи
    • Смена ответственного у задачи
  • Примечания

    • Создание примечания на контакт
    • Создание примечания на компанию
    • Создание примечания на сделку

    Звонки, СМС, письма тоже являются примечаниями. На эти действия тоже можно выполнять триггеры.

  • При входящем сообщении

    Можно выполнять действия при входящем сообщении из чата, например, если клиент пишет в WhatsApp, можно запустить триггер автоматического ответа.

  • Цифровая воронка

    Можно применять все фильтры и правила цифровой воронки в совокупности с правилами в триггерах

    Запуск из SalesBot
    Можно запустить сценарий из SalesBot.

  • Ручной запуск

    • Запуск из всплывающего уведомления с запросом.
    • Запуск из карточки сделки
    • Запуск из карточки контакта
    • Запуск из карточки компании
    • Запуск из списков сделок, контактов, компаний.
  • Запуск из другого сценария

    Триггеры могут запускать другие сценарии, таким образом можно конструировать цепочки действий по вашим условиям.

Интерфейс — список сценариев

  1. Сценарий можно включить и выключить. Выключенный сценарий не будет выполняться, но если есть отложенные триггеры, они будут выполнены согласно расписанию.
  2. Можно менять порядок строк перетаскиванием.
  3. При клике на Событие отобразятся последние 1000 событий, которые запускали данный сценарий.
  4. Колонка «Сработал» показывает дату и время последнего запуска. При клике на дату можно увидеть последнее действие, которое выполнил сценарий.

Как создать и настроить сценарий?

Чтобы создать новый сценарий, выберите событие, на которое он должен запускаться, например «Сделка добавлена», введите название, например «Задача на обработку» и нажмите на кнопку «Создать сценарий».

Выйдет окно создания нового сценария.

Это окно содержит

  1. Название — краткое название сценария. Кроме того данный текст будет отображаться в карточках сделки, контакта, компании для ручного запуска сценария.
  2. Описание — более подробное описание, чтобы не забыть, что выполняет данный сценарий.
  3. Блок условий — блок, разделенный на 2 части. В левой части Условия, в правой Триггеры, которые будут выполнены в том случае, если условия из левого блока будут выполнены. Можно добавить несколько блоков, и каждый из них выполнится последовательно сверху вниз. Порядок блоков можно менять перетаскиванием. Так же можно задать таймер, который отсрочит выполнение данного блока условий. У блока может быть свое название.
  4. Поле для выбора сценария, который выполнится, если не сработает ни один блок условий.
  5. Выбор тайминга выполнения — как часто можно запускать данный сценарий. Например сделка меняется каждые 10 секунд, нужно ли пересчитывать бюджет каждый раз или достаточно делать это раз в минуту. Кроме того можно задать условие, при котором сценарий для данной конкретной сущности выполнится всего 1 раз, для этого поставьте галочку «только 1 раз». Минимальный тайминг сценария для конкретной сущности 5 секунд.

Работа с блоками условий

  1. Триггеры, в блоке условий, выполняются только тогда, когда все условия в данном блоке соблюдены, иначе блок игнорируется и не выполняется.
  2. Блоки условий выполняются последовательно сверху вниз. Проверка условий в самом блоке так же происходит сверху вниз. Блоку условий можно задать небольшой тайминг выполнения, до 20 секунд, например, чтобы дождаться заполнения полей, после предыдущих действий.
  3. В блоке условий можно добавить несколько условий, по умолчанию условия проверяются по принципу «И», то есть все условия должны выполниться.
  4. Внутри условия можно выбрать разные типы данных для сравнения (дата, время, кол-во сделок, значение поля, текущий день недели и т.д.), в зависимости от выбранного типа, могут быть доступны различные типы сравнений.
  5. Блоки условий и сами условия можно перетаскивать на свое усмотрение. Выполнения и проверки идут сверху вниз.

Пример настройки
Например, нам нужно назначить ответственного за новую заявку одному из двух сотрудников. Оптовые заявки одному менеджеру, розничные другому. В названии заявки указано, это опт или розница, на нее и будем ориентироваться при задании условий. Таким образом условия задачи выглядят так:

  • Если сделка называется «Заявка с формы ОПТ», назначить ответственного за сделку Елену, поставить Елене задачу.
  • Если сделка называется «Заявка с формы РОЗНИЦА», назначить ответственного Анну, поставить Анне задачу.

Добавляем условия:

  1. Кликните на строку условия «Не настроено», или добавьте новое условие, если такой строки нет.
  2. Здесь мы видим три поля. Сверху и снизу — это поля для сравнения их между собой, среднее — это оператор сравнения. Сравнивать можно что угодно с чем угодно, в том числе значения из связанных сущностей (например моле сделки сравнить с полем связанной компании), даты, системные поля и т.д., весь список значений и операторов приведен ниже.
  3. В данном случае мы сравниваем название сделки с текстовым значением заданным в ручную — «Заявка с формы ОПТ», если название удовлтеворяет этому значению, то выполнятся триггеры в этом блоке. Таким образом наше условие выглядит так: Название>Сделки > «Равно» > Текстовое значение> «Заявка с формы ОПТ». Смотрите скрин.
  4. Сохраните условие.

5. В результате блок условий выглядит следующий образом

При необходимости можно добавить еще условия, например если сейчас не выходной, если у сделки бюджет не меньше 1000 рублей и т.д. Условия можно комбинировать между собой по типу «И» (все условия должны быть выполнены) и «ИЛИ» (хотя бы одно условие должно быть выполнено).

Добавим еще несколько условий и зададим название этому блоку «Если ОПТ». Название поможет в будущем нам отслеживать, какие блоки запускаются, какие нет, это нужно при отладке.

Условия заданы, теперь можно добавлять Триггеры, которые, собственно, будут выполнять нужные нам действия.

Использование нескольких условий И и ИЛИ в одном блоке. Из за особенностей работы алгоритмов PHP (ввиду отсутствия скобок), блок содержащий хотя бы одно условие ИЛИ, выполнится независимо от других условий, если в этом блоке сработает хотя бы одно условие ИЛИ.

Добавляем Триггеры
По условиям задачи нам нужно назначить Елену ответственной за сделку. Для этого выберем триггер «Сменить ответственного» и настроим его.

  • Название — можно оставить пустым.
  • Применить — выберите «В сделке» или оставьте по умолчанию, так как данный сценарий запускается из сделки, сущность по умолчанию будет сделкой.
  • Таймер — можно отсрочить запуск данного действия, но в данном случае этого не требуется, оставим «Без таймера».
  • Параметры > Новый ответственный — здесь нужно выбрать сотрудника, на которого будет переведена сделка.
  • Сменить в связанных сущностях — можно сменить ответственного в том числе в Компании, в Контактах и в задачах.

Сохраним параметры триггеров.

Настроим аналогичные условия и триггеры для розничных заявок, для этого добавим новый блок условий.

  • Добавим условие на другой текст названия заявки, остальные условия такие же.
  • Ответственного назначим Анну

Итоговый сценарий с двумя блоками условий выглядит так.

Как видим, создалась сделка контакт и компания. Затем Триггеры сменили ответственного за сделку на Елену, так же сменился ответственный за Контакт и Компанию

Результат работы триггеров можно увидеть подробно, если нажать на Детали в списке сработавших сценариев

Результат сравнения условий так же можно увидеть в списке событий.

Как видим, нижняя сделка не подпадает под условия и по нему сценарий не выполнился. В верхней же сделке все три условия выполнились и триггеры были запущены.

Таким образом вы можете создавать бесконечное множество сценариев автоматизации в зависимости от задач в ваших бизнес-процессах.

Список всех условий и как они работают

Условия используются для фильтрации запуска триггеров в блоке. Например, создание определенной задачи должно происходить только, если сделка перешла в конкретный статус.

Список условий может меняться в зависимости от сравниваемых сущностей и типа сценария. Если, при выборе какой то сущности, условие пропадает, значит его нельзя применить, так как тип данных в этом случае может на совпадать.

Список всех сравниваемых значений

Можно сравнивать практически все данные из CRM в том числе из связанных сущностей. В настройках сравнения и в нижем и в верхнем поле одинаковые данные, от их перестановки результат не меняется.
Например, вы можете сравнить «Название сделки» с «Текстовым значением»

ТРИГГЕРЫ

Триггер — это конечный результат работы сценария, который собственно производит изменения в системе: создает сделку, ставит задачу, меняет поле и т.д.

  • Список триггеров может меняться, в зависимости от сценария, в котором он выполняется. Если какого то триггера вы не видите, значит его нельзя запустить в этом сценарии. Например, нельзя создать сделку при создании сделки.
  • У каждого триггера, в зависимости от типа, есть свои условия.
  • По умолчанию триггер запускается сразу (а точнее, встает в очередь на выполенение), но выполнение можно отложить по таймеру или выполнить его в конкретную дату и время которое записано в поле.

1. Создать сделку

Триггер автоматически создает сделку в amoCRM.
Параметры:

  • Название сделки — задает заголовок сделки. Текст, числа или переменные.
  • Теги — задает теги сделке, можно подставить переменные
  • Ответственный — можно назначить ответственного вручную, или автоматически.
  • Воронка — задает воронку, в которой будет создана сделка
  • Статус — этап сделки на котором создастся сделка.
  • Так же, при создании новой сделки в компании, можно прикрепить к ней существующие контакты компании.

Пример: при завершении сделки, сразу создать еще одну.

2. Создать контакт

Триггер автоматически создает Контакт в amoCRM.
Параметры:

  • Применить — можно выбрать к какой сущности прикрепить контакт, к сделке или к компании. Нельзя прикрепить контакт к контакту.
  • Название контакта — Имя нового контакта. Текст, числа или переменные.
  • Теги — задает теги сделке, можно подставить переменные
  • Ответственный — можно назначить ответственного вручную, или автоматически.
  • Таймер запуска — позволяет отложить действие. Подробнее про отложенные триггеры.

3. Создать компанию

Триггер автоматически создает Компанию в amoCRM.
Параметры:

  • Применить — можно выбрать к какой сущности прикрепить компанию, к сделке или к контакту. Нельзя прикрепить компанию к компании.
  • Название — название создаваемой компании. Текст, числа или переменные.
  • Теги — задает теги сделке, можно подставить переменные
  • Ответственный — можно назначить ответственного вручную, или автоматически.

Пример: при создании сделки, сразу создать компанию.

4. Копировать сделку

Копирует существующую сделку в новую со всеми заполненными полями.
Параметры:

  • Название сделки — по умолчанию будет «Название старой сделки (копия)». Текст, числа или переменные.
  • Теги — Текст, числа или переменные.
  • Ответственный
  • Воронка, Статус
  • Применить — Данный можно можно применить только к Сделке

5. Сменить значение поля

Меняет значения полей Сделки, Контакта и Компании. Для каждой сущности свой триггер смены значения. Параметры:

  • Таймер запуска
  • Поле — выбор поля, которому нужно сменить значение. Выберите нужное поле, в текстовом поле напишите значение этого поля. В значении можно использовать любой текст, переменные, калькуляции, значения из других полей.
  • Применить — для каждой сущности свой триггер, поэтому в данном случае выбрать сущность нельзя.

Так же данный триггер позволяет в том числе переносить значения полей из одних сущностей в другие. Например поля сделки бюджет перенести в поле компании.
Так же при использовании данного триггера можно использовать модификаторы полей: производить математические операции, числа писать текстом и много другое. Подробнее на странице переменные для виджетов.

В одном триггере можно сменить значения сразу нескольких полей.

  • Чтобы записать значение из другой сущности, используйте переменные, например {{contact.cf(123456)}} — значение поля контакта с ID 123456
  • Чтобы задать значения списков и мультисписков, введите через запятую точные значения из этих списков.
  • Чтобы очистить все значения списков напишите {reset}.
  • Чтобы включить или выключить флажки и переключатели, введите 0 или 1
  • Чтобы сделать калькуляцию полей используйте переменные, например: {{ (поле1+поле2):calc }}
  • Список системных переменных (текущая дата, время, длительность входящего звонка, текст примечания, текст входящего письма, количество сделок компании и тд.) смотрите тут.

Примеры: при успешном завершении сделки, бюджет сделки добавить к полю компании; при входящем звонке, сохранить длительность разговора в секундах в поле Контакта.
Так же задавать значения полям можно в ручном режиме, например выделить 500 сделок и всем задать бюджет. Для этого предварительно нужно создать сценарий с типом «Свой сценарий», задать в нем условия (при необходимости) и триггер, который меняет значение нужного поля. Затем выделить сделки и применить к ним данный сценарий.

6. Поставить задачу

Добавляет новую задачу для сотрудника.
К задаче можно добавить результат выполнения. В этом случае задачу нельзя закрыть без выбора результата, а после закрытия задачи с результатом автоматически запустится следующий сценарий.
Параметры:

  • Применить — можно выбрать сущность к которой добавится задача. Например сценарий запускается на создание Сделки, а задачу можно добавить к Компании этой сделки.
  • Таймер — выбрать таймер для запуска.
  • Ответственный — выбрать ответственного за задачу. По умолчанию ответственным является ответственный за сущность.
  • Тип задачи — можно выбрать из типов, которые есть в amoCRM
  • Срок выполнения — выбрать время, за которое нужно закрыть задачу, например 1 час.
  • Текст задачи — текст задачи. Можно использовать любой текст, числа или переменные.
  • Результат по задаче — можно добавить выбор результата при закрытии, в зависимости от выбранного пункта можно запускать следующий сценарий. Если добавлен хотя бы один результат, то задачу нельзя будет закрыть без выбора результата. Сценарии, запускаемые из задачи, должны быть созданы заранее.

Видео https://www.youtube.com/watch?v=e0hjW0rQaOg

7. Добавить примечание

Добавляет новое примечание в ленту.
Параметры:

  • Текст примечания -текст, который будет добавлен в ленту. Можно использовать переменные. Например: Сделка на {{lead.sale}} успешно завершена!
    Поздравляем тебя, {{client.responsible.name}}!
  • Применить — Данный триггер можно применить к Сделке, Контакту, Компании.

Так же можно добавить системное примечание. Системное примечание отображается мелким шрифтом без рамочки.

8. Сменить теги

Позволяет добавить или убрать тег у Сделки, Контакта, Компании.
Параметры:

  • Применить — можно выбрать сущность у которого необходимо сменить тег. Данный можно применить к Сделке, Контакту, Компании.
  • Таймер — выбрать таймер для запуска.
  • Добавить теги / Удалить теги — можно добавлять тег или несколько через запятую. Чтобы убрать тег нужно знать его название, так же можно указать несколько через запятую. Чтобы удалить все теги оставьте поле «Значения тегов» пустым.

9. Сменить статус сделки

Меняет этап сделки в воронке, в том числе можно сменить саму воронку.
Параметры:

  • Воронка — выбрать воронку
  • Статус — выбрать статус в который нужно перенести Сделку.

Данный триггер можно применить только к Сделке.

10. Выполнить другой сценарий

Один сценарий можно запускать из другого, а из второго запускать третий, таким образом можно настраивать недлинные цепочки действий.

Данным триггером можно запускать только ручные сценарии (тип сценария при создании — «Свой сценарий»)

Пример: при закрытии сделки, через неделю нужно создать еще одну сделку, но, при условии, что на тот момент не будет активных сделок по клиенту.
Данную автоматизацию можно реализовать, через запуск ручного сценария. При закрытии сделки, ставится отложенный на неделю запуск ручного сценария, который, через 7 дней, посмотрит нет ли других активных сделок и создаст новую при их отсутствии.

Параметры триггера:

  • Применить — можно выбрать применительно к чему запустить сценарий. Например задать теги можно для сделки, контакта, компании, а сменить статус, только у сделки. Учитывайте это при настройке ручных сценариев.
  • Таймер — можно отложить запуск сценарий.
  • Сценарий — собственно сам сценарий, который предварительно должен быть создан.

11. Запустить Sales бота

Автоматически запускает настроенного Salesbot в amoCRM.
Параметры:

  • БОТ — можно выбрать из списка созданных ботов.
  • Таймер — настроить отложенное действие.

Например вам нужно оповестить клиента через тот же канал, из которого он обращался (например WhatsApp). Для этого предварительно создайте сейлз-бота, в котором происходит отправка сообщения. Затем запускаете его на любом этапе сделки или по какому то действию в системе, например когда наступила дата рождения клиента и т.д.

12. Отправить веб-хук (web hook)

Отправляет HTTP запрос (вебхук) на внешний адрес в интернете, при необходимости может слушать ответ и принять данные.
Параметры:

  • URL — адрес, куда нужно отправить запрос.
  • Заголовоки — можно добавлять свои заголовки (headers) в запрос.
  • Тело запроса — добавьте нужные переменные и их значения.

Запрос всегда содержит: id сущности amoCRM, тип сущности, id сценария, id группы сработавших условий. В полях можно использовать переменные и шаблонизатор.

Запустить сценарий при получении ответа
Триггер может слушать ответ и, при его получении, запустить сценарий, передав в него все переменные, которые пришли в ответе. Ответ слушается максимум 5 секунд.
Переменные приходят в формате {var}, или {parrent_child1_child2…}, до 10 вложений. Все тело ответа содержится в переменной {webhook_data}, например его можно вывести в примечание, чтобы увидеть все данные. Переменные можно использовать, чтобы заполнить поля или в условиях блоков условий, система работы такая же как с входящими хуками.

13. Отправить письмо через виджет «Почтовик»

Отправляет e-mail с отслеживанием открытия письма и кликов по ссылкам. Шаблон должен быть создан в виджете «Почтовик» и сам виджет должен быть установлен.
Параметры:

  • Отправитель — от чьего имени отправляется письмо
  • Получатель (по сделке) — если письмо отправляется из Сделки, можно выбрать получателя в ручную, например только основной контакт. Иначе получатель ставится автоматически из компании и контакта.
  • Шаблон письма — заранее созданный шаблон письма с текстом, картинками, переменными, которое отправится клиенту.

В шаблоне письма могу быть свои триггеры автоматизации, например при открытии письма или при кликах по ссылкам, они так же сработают.

14. Отправить сообщение в Телеграм

Отправляет сообщение в мессенджер Telegarm в общую группу или в личку (не клиенту!). Данный функционал работает через виджет «Уведомления в Телеграм». Виджет должен быть установлен и настроен. Параметры:

  • Чат — чат или личка, куда нужно отправить сообщение.
  • Текст, числа, эмоджи или переменные. Так же можно формировать ссылки через HTML теги и форматировать текст определенным образом.

Примеры:
<b>жирный</b>
<i>курсив</i>
<u>подчеркнутый</u>
<s>зачеркнутый</s>
Ссылка <a href=»http://www.example.com/»>Подробнее</a>

Пример ссылки на сделку в amoCRM:
<a href=»https://вашдомен.amocrm.ru/leads/detail/{{lead.id}}/»>Открыть сделку</a>

Пример ссылки, по клику которого, можно запустить следующий сценарий:
<a href=»{tlink:290}»>Закрыть эту сделку</a>
Предварительно ссылку нужно создать во вкладке Ссылки, затем добавить к ней ручной сценарий, который закрывает сделку. После этого уникальную переменную ссылки {tlink:290}, можно использовать в качестве ссылки, при переходе по которой будет запускаться настроенная в ней автоматизация.
Ссылки так-же можно отправлять клиентам, они будут по ним переходить, и будут срабатывать сценарии.

Добавление кнопок вместо ссылок
Чтобы при нажатии по триггерной ссылке не происходило перехода в браузер, преобразуйте их в кнопки через маску:
Вместо: <a href =»{tlink:123}»>Создать</a>
напишите: [button url=»{tlink:123}» text=»Создать»]
При нажатии на такую кнопку браузер не откроется, но сценарий в Триггерах сработает.

Обратная связь из Телеграм в Триггеры
В Триггерах можно ловить ID кликнувшего по ссылке пользователя и не только, и запускать разные сценарии. Например, настроить распределение на того, кто первый кликнул на кнопку в общем чате.
Для этого существую переменные:
{tg_user_id} — ID кликнувшего пользователя
{tg_user_name} — Имя кликнувшего пользователя
{tg_button} — Текст кнопки, по которой был клик
{tg_chat_id} — ID чата в котором был клик
{tg_chat_name} — Имя чата в котором был клик
Эти переменные можно использовать в блоках условий и в самих триггерах.

Пример такой настройки на распределение на пользователя, который первым кликнул по ссылке в общем чате:

  1. Создаем новый сценарий.
  2. Создаем блоки условий: если пользователь равно «Sergey», и статус сделки «Отправлено в распределение», то меняем ответственного на Сергея и меняем статус «Принято в работу», и так для всех пользователей. На статус нужно ориентироваться для того, чтобы повторные клики других пользователей не меняли ответственного повторно. Таким образом, кто первый нажал, тот забрал сделку и поменял Статус сделки, дальнейшие нажатия будут отфильтровываться.
  3. Создаем триггерную ссылку во вкладке «Ссылки», выбираем запускаемый сценарий, который добавили пунктом выше.
  4. Добавляем действие в цифровой воронке или сценарием через Триггеры: при переходе сделки на этап «Отправлено в распределение», отправляем в Телеграм сообщение с триггерной ссылкой и текстом. Пример — Новая сделка [button url=»{tlink:123}» text=»Принять»]. ID триггерной ссылки тот, который создали в третьем пункте.
  5. Добавьте сообщение, которое приходит в чат, после принятия сделки, чтобы пользователи понимали, что сделка принята и кем. Например: Сделку забрал {tg_user_name}.

Готово!

15. Отправить СМС сообщение

Отправляет SMS на нужный номер. Это может быть номер клиента или любой произвольный номер. Для отправки используется виджет «СМС шлюз». Виджет должен быть установлен и настроен один из 8 агрегаторов , через который будут отправляться сообщения.

Параметры:

  • Отправитель — от кого отправляется сообщение.
  • Получатель — получатель сообщения. Можно выбрать: все контакты, компания, произвольный номер, номер из поля (через переменную)
  • Сообщение — текст сообщения. Текст, числа, переменные.

16. Отправить уведомление в amoCRM с запросом дальнейших действий

Отправляет оповещение пользователю через виджет «Пушер», виджет должен быть установлен в системе. Доступны: push-уведомление в браузер, звуковое уведомление и всплывающее уведомление в amoCRM.

При отправке всплывающего уведомления, в запрос можно добавить кнопки, при нажатии на которые, будет запускаться следующий сценарий. Таким образом можно запрашивать от сотрудника следующее действие и запускать его сразу при нажатии. Кроме того уведомление и кнопку можно показывать не только ответственному, а любым пользователям.

Например: когда приходит новая заявка, всем пользователям показывается оповещение с кнопками, при нажатии на «Взять заявку», запускается следующий сценарий, который сменит ответственного на того, кто нажал на кнопку. При этом, у остальных сотрудников эта кнопка тут же становится недоступной. Таким образом, к примеру, можно настроить ручное распределение заявок среди менеджеров.

Параметры:

  • Тип уведомления: уведомление в amoCRM, браузерный push, звук.
  • Текст заголовка и текст сообщения — текст выводимый в уведомлении, недоступно для звуковых уведомлений. Можно использовать переменные.
  • Пользователи: кому показывать уведомление. Можно показывать ответственному за сущность, всем пользователям или выбранным.
  • Добавить кнопки действий: добавляет кнопки запуска следующих сценариев. Можно указать текст кнопки, сценарий, который будет запущен. При выборе флажка справа от сценария, он будет запущен только 1 раз при первом нажатии на кнопку, при этом кнопки у других пользователей этого же уведомления станут недоступны.
  • Применить: к какой сущности применить триггер.

Особенности при настройке пушей на входящее сообщение.
Входящее сообщение всегда крепится к контакту. Поэтому, для корректной работы Пушера, в поле «Применить» всегда нужно выбирать «К контакту», только в таком случае будут работать все переменные и текст сообщения корректно придет в ПУШ.

Пример сценария на распределение:
При нажатии на кнопку в Пушере, запускается сценарий, в который добавлен триггер на смену ответственного сделки. Туда передается ID пользователя нажавшего на кнопку. Данный ID в виде переменной {user_id} нужно вставить в триггер смены ответственного. В поле «Новый ответственный» выберите «Свое значение» и вставьте текст {user_id} (скрин). Теперь, тот, кто первым нажмет на кнопку, станет ответственным за нее.

На нажатие кнопки доступны следующие переменные:
ID пользователя, который нажал на кнопку {user_id}
Имя пользователя, который нажал на кнопку {user_name}
Текст нажатой кнопки {button}

17. Сгенерировать новый документ

Создает документ через виджет «Документы». В данном триггере можно выбрать единственный параметр «Шаблон документа». Если вам нужно создать несколько документов, добавьте несколько триггеров.
При срабатывании триггера документ будет сгенерирован и появится в карточке сделки. Ссылка на документ появится в поле, которое добавлено в настройках шаблона в самом виджете Документы.

18. Подписать на сделку, отписать от сделки

Позволяет подписать на сделку (на чат), чтобы уведомления по чатам приходили не только ответственному по сделке, а, в том числе, другим определенным. Например с помощью виджета «Дополнительный ответственный в сделке», можно выбрать выбрать второго ответственного по сделке. После выбора, второго пользователя можно автоматически подписывать на уведомления по этой сделке.

Параметры:

  • Подписать/отписать — можно выполнить одно из данных действий.
  • Событие — Чат, в данном случае нет других параметров.
  • Пользователи — можно выбрать пользователей из списка, так же id пользователя можно вставить в специальное поле через переменную. Например id пользователя хранится в поле сделки и ставится туда виджетом «Дополнительный ответственный».

18. Изменить задачу

Триггер может изменять задачи по сущности: менять текст, открыть, закрыть, сменить ответственного и тип задачи.

Работает со ВСЕМИ или с ПОСЛЕДНЕЙ задачей определенного ТИПА. Например, при смене статуса сделки можно закрыть все задачи с определенным типом. При попытке закрыть задачу без добавления результата, можно открыть ее снова, а к тексту задачи добавить «Добавьте результат по задаче!».

Параметры:

  • Найти задачи по типу — находит все задачи по типу и выполняет нужное действие
  • Применить для — можно применить действие для всех задач с таким типом или для последней.
  • Ответственный — можно сменить ответственного.
  • Тип задачи — можно поменять тип задачи.
  • Статус задачи — можно поменять статус, например закрыть.
  • Текст задачи — можно поменять текст.

19. Отменить отложенный триггер

Триггер позволяет отменить другой триггер, который был запланирован на определенное время. Например, можно отменить отложенное уведомление клиенту, если клиент полностью отказался от услуги.
Триггер удаляет все отложенные триггеры для этой сущности в выбранном сценарии, в выбранном блоке условий и в конкретном триггере.

Более подробно по работе с отложенными триггерами.

20. Изменить значение глобальной переменной

Триггер задает значение глобальной переменной. Можно задать значение, дополнить новым значением, стереть значение (например отправив пустое значение).
Более подробно по работе с глобальными переменными.

21. Подтянуть реквизиты через виджет Dadata

Данный триггер запрашивает данные из сервиса Dadata.ru и записывает в поля используя виджет «Интеграция amoCRM и Dadata». Виджет должен быть установлен в amoCRM и настроен.

Например, при вводе ИНН, можно запустить сценарий, который автоматически, подтянет все остальные реквизиты и запишет их в поля: полное наименование компании, адрес, реквизиты, ФИО директора, уставной капитал и т.д.

Все настройки по сопоставлению полей делаются в виджете dadata, подробная инструкция. Триггеры лишь запускают инициализацию настроенного сопоставления из списка. Можно запускать сразу несколько сопоставлений в одном триггере.

Так же вы можете создать нужный сценарий и запустить его на список компаний, сделок или контактов (до 500 шт. за раз), чтобы обогатить свою базу новыми данными.

Пример 1. Автоматическое подтягивание реквизитов при создании сделки с компанией с известным ИНН.

Пример 2. Групповое обновление данных компаний, на основании одного ИНН при перемещении их сделок на определенный этап.

22. Нормализовать телефон и e-mail

Данный триггер приводит к единому виду телефоны и e-mail контакта и компании. Телефон приводит к единому виду, выбранному в настройках.
Например может нормализовать при создании сущности, при изменении или вручную при групповой операции.

Видео https://www.youtube.com/watch?v=p_yEvhS5Als

Нормализация электронной почты

  • Удаляет лишние пробелы и символы.
  • Приводит все символы к нижнему регистру

Нормализация телефона

  • Работает только с мобильными номерами из РФ.
  • Если в двух полях содержится 2 одинаковых телефона, то триггер удалит один из них.
  • Может быть запущен по полям компании или контакта (по всем телефонам или только по основному).
  • Если не удалось нормализовать (поле невозможно привести к нормальному телефону), то значение можно удалить, при этом можно исключить удаление тех номеров, в которых определенное кол-во символов, например для местных коротких номеров.

Пример настройки:

  1. Создайте сценарий на создание контакта.
  2. Добавьте триггер Нормализатор.
  3. Выберите — что нормализовать: Телефон, E-mail или оба поля.
  4. Выберите нужные настройки нормализации и сохраните.
  5. Теперь при создании нового контакта с некорректным телефоном он будет приведен к единому формату.

Как нормализовать всю базу?
Создайте Свой сценарий и запустите его вручную на выделенные сущности. Или создайте сценарий на изменение, база постепенно приведется в нормальный вид, при условии, что производятся изменения в базе.

23. Создать чек-лист

Создает чек-лист к нужной сущности используя виджет «Чек-листы».
Виджет Чек-листы работает и без триггеров, но только из цифровой воронки и только со сделками. Используя Триггеры можно создавать чек-листы по более сложным сценариям и для сущности Контакт, Компания.

Настройка

  1. Добавьте новый сценарий или откройте существующий.
  2. Добавьте триггеры в разделе Виджеты — Чек-листы: создать.
  3. Выберите нужный чек-лист, который должен быть создан заранее.
  4. При необходимости выберите сущность, к которому нужно применить триггер, в этом случае чек-лист прикрепится к этой сущности.
  5. Сохраните настройки. Готово.

При нажатии на флажок на пункт чек-листа, процент выполнения можно записывать в поле сущности, задается в настройках конкретного чек-листа. Таким образом, например, можно запускать какой либо сценарий автоматически, когда чек-лист выполнен на сколько то %, опираясь на это значение в поле.

24. Добавить товары

Добавляет выбранные в триггере товары к сделке.

  1. Выберите нужный список товаров;
  2. В поле Поиск найдите и выберите нужный товар или несколько;
  3. Укажите для каждого товара количество;
  4. Укажите для каждого товара тип цены, если у вас несколько цен;
  5. Сохраните настройки. Готово.

При запуске данного триггера, виджет добавит выбранные товары в карточку сделки во вкладку Товары (название выбранного списка)

Например, если создается сделка с определенным значением поля, вы можете автоматически добавлять нужный товар и на нужном этапе выписать счет и отправить клиенту автоматически.

25. Удалить товары

Удаляет все добавленные товары в конкретном списке.
Для удаления выберите нужный список.
При срабатывании триггеры все добавленные товары из конкретного списка будут удалены. Товары в других списках останутся нетронутыми.

26. Создать новый счет в «Кассе»

Создает новый счет в виджете «КАССА»
Перед созданием счета в виджете необходимо добавить шаблон счета. Все настройки по счету задаются в шаблоне виджета Касса, а именно:

  • Эквайринг: в Юкассе, в Тинькофф, Тинькофф-бизнес, или без;
  • Товары: брать из списка товаров в сделке, добавить определенные при создании счета, взять из поля сделки;
  • Цены: тип цены;
  • Количество;
  • Скидка;
  • Комментарий к счету;
  • Тип НДС.

В триггерах выбирается только сам шаблон и сущность, к которой нужно прикрепить счет (основной контакт или компания). Сделка будет по умолчанию прикреплена всегда.

При срабатывании данного триггера, создастся новый счет к сделке, ссылка на счет добавится в поле (если это настроено в Кассе).

Сценарий с данным триггером необходимо запускать только применительно к сделке, так как счет всегда выписывается к сделке. Например: если выписать счет на изменение контакта, это вызовет ошибку.

Работа с отложенными триггерами

Отложенные триггеры позволяют запланировать выполнение триггера на определенное время. Именно через отложенные триггеры выполняются задачи вроде: поздравлений с днем рождения, проверка условий через определенное время, постановка задач на будущее и т.д.

У каждого триггера есть параметр «Таймер запуска». Если его указать, то действие выполнится не сразу, а запланируется на определенную дату и время. Время таймера может быть любым — от 1 секунды до 99 лет. Кроме того дату выполнения можно брать из поля Сделки, Контакта или Компании.
Условия таймера следующие:

  • Без таймера — триггер будет выполнен как обычно без задержек.
  • Секунды, минуты, часы, дни — выполнение триггера можно отложить на количество указанных единиц, например на 30 секунд или на 7 дней. Начало отсчета таймера это момент выполнения триггера.
  • Дата из поля Сделки, Контакта, Компании — триггер будет выполнен в указанную дату. Например СМС уведомление клиента в этот день о записи на услугу. Время срабатывания можно указать в ручную. Можно смещать данную дату по дням + / -. Например через столько то дней или за столько то дней. Поле должно быть с типом Дата.
  • День года из поля Сделки, Контакта, Компании — триггер будет выполняться каждый год в указанный день. При этом в поле должна стоять обычная дата, например 05.05.1990. Триггер будет выполняться каждый год 5 мая. Например таким образом, можно поздравлять клиентов с праздниками или с днем рождения. Можно смещать данную дату по дням + / -. Например через столько то дней или за столько то дней.

Очень важная галочка!
Перезаписывать отложенные действия по сущности
По умолчанию отложенное действие по триггеру будет ставиться (читай добавляться новое) каждый раз, при выполнении сценария. Например сценарий такой: при изменении Контакта, если поле «день рождения» непустое, запустить отложенный триггер на поздравление. Данный сценарий будет выполняться каждый раз при изменении любого поля контакта.

Например, вы по ошибке ввели не ту дату рождения клиента и сохранили контакт, затем изменили дату на правильную и снова сохранили. После этого создастся 2 отложенных действия по поздравлению клиента, одно с правильной датой, второе с неправильной и оба будут выполнены. Чтобы этого избежать поставьте в триггере галочку «Перезаписывать отложенные действия по сущности», тогда каждый раз при выполнении триггера, предыдущие действия, которые еще не выполнены, будут удалены и заменены новым.

Отложенный триггер ставится 1 раз при выполнении сценария, и выполнится 1 раз при наступлении этой даты. Чтобы поставить следующий триггер, нужно снова запустить сценарий. К примеру, вы настроили отложенную отправку SMS на день года из поля Контакта, сценарий настроили на изменение контакта. Соответственно, если после первого поздравления, с контактом не производилось никаких действий, то следующие триггеры на поздравление не будут создаваться. Триггер сам по себе не запланирует поздравления на годы вперед. Нужно снова изменить Контакт, если сценарий был на изменение контакта, так же это можно сделать другим триггером.

Удаление отложенного триггера

Отложенный триггер можно удалить. Например, если клиент отказался от записи, нужно отменить ему напоминание об этой встрече. Для это существует специальный триггер «Отменить отложенные задания». Например, если сделка перешла в статус «Услуга отменена», можно запустить триггер, в котором выбрать нужный сценарий, блок ссылок и конкретный триггер, который ставил отложенные задания.

Триггер «Отменить отложенные задания» удаляет ВСЕ отложенные триггеры в этом сценарии в выбранном блоке условий и в выбранном конкретном триггере по этой сущности.

Примеры настроек отложенных триггеров

Поставить задачу через 7 дней

Отправить клиенту СМС в шесть вечера за день до назначенной встречи

В день рождения клиента в 9 утра отправить клиенту e-mail с поздравлением и скидкой внутри

Работа с глобальными переменными

Глобальные переменные используются в рамках всей системы. В них можно сохранять любые данные, в том числе значения полей из amoCRM. Переменные можно перезаписывать, очищать, добавлять значение к имеющемуся. Одну и ту же переменную можно использовать во всех сценариях, в том числе в качестве условий. Переменные не привязаны к какой либо сущности amoCRM. Тип данных в переменной всегда текстовый, однако вы можете хранить в них: числа, текст, даты (в виде UNIX-time), флаги 1/0). Виджет автоматически поймет формат и корректно отработает, например, калькуляцию значений из переменной.

Вы можете добавить неограниченное количество переменных, в одной переменной можно хранить до 30 тысяч символов.

Примеры использования:

  • Перенос значений полей из одной сделки в другую

    Например, вам требуется перенести значение поля из одной сделки в другую сделку. При заполнении поля, можно сохранить его значение в переменную, при создании новой сделки, значение переменной вставить в поле новой сделки.

  • Счетчик значений

    Например, нам надо считать, сколько всего пропущенных звонков было по компании. Можно добавить сценарий на пропущенный звонок, и, каждый раз при его срабатывании, значение переменной увеличивать на 1. Если значение переменной превысит 10, то можно отправить уведомление РОПу.

  • Сделать мини отчет

    Пример: нужно понять, сколько раз вовремя не обработали заявку. Для этого необходимо добавить сценарий, который контролирует время нахождения сделки на определенном этапе, каждый раз при просроченном действии, в переменную добавляем новую строку текста, в котором будет ссылка на сделку и ответственный. В конце недели в переменной накопится много строк с данными, его можно отправить в Телеграм и очистить для следующей недели.

  • Использовать в условиях

    Значения переменных можно использовать в блоках условий. Например: если в переменной значение 1, то сценарии будут работать определенным образом, например, распределять на одних людей, если 0, то на других. Таким образом вы можете поменять переменную в одном месте и все сценарии начинают работать по другому алгоритму.

Добавление новой глобальной переменной

Чтобы с переменной можно было работать, ее предварительно нужно добавить. Перейдите во вкладку «Переменные», введите название новой переменной, например «report» (только латинские символы) и нажмите «Добавить переменную». Вы можете сразу задать значение этой переменной или оставить поле пустым. Нажмите сохранить.

Переменная добавлена. Так же в любой момент вы можете открыть нужную переменную и посмотреть ее текущее значение прямо в этом окне.

Изменение значения глобальной переменной

Значение переменной можно изменить через специальный триггер «Изменить значение переменной».

  • Добавьте новый триггер в блок условий вашего сценария
  • Выберите из списка «Изменить значение переменной»
  • В открывшемся окне выберите переменную, которую нужно изменить
  • В поле «Новое значение» введите значение, которое нужно присвоить переменной, например «{{date.now}} — произошло событие«. Можно использовать любые системные переменные, значения полей, модификаторы, калькуляции, произвольный текст и т.д.
  • Сохраните триггер, сохраните сценарий, запустите данный сценарий.

В данном случае значение переменной полностью перезапишется новым значением, стирая предыдущие данные.
Откройте снова переменную, чтобы убедиться, что в нее записался нужный текст.

Добавление текстового значения к имеющемуся значению переменной

Чтобы текстовое значение не стиралось, а добавлялось к предыдущему, перед новым значением добавьте саму переменную в фигурных скобках. Пример:
{report}
{{date.now}} — произошло событие

В этом случае, каждый раз при срабатывании триггера, к переменной будет прибавляться новый текст.

Математический подсчет в глобальной переменной (счетчик)

Чтобы сделать калькуляцию, используйте название переменной, точно так же как поле сделки.
Пример: прибавление единицы к переменной, каждый раз при срабатывании — {{ ({report}+1):calc }}

Более подробно про калькуляцию переменных тут.
При этом следите, чтобы в переменной не было текстовых данных, иначе результат математических функций может быть некорректным.

Значение переменной после калькуляции, к примеру, можно вывести в примечание.

Как записать значение глобальной переменной в поле amoCRM

Добавьте триггер на изменение поля, например: «Изменить значение сделки». В параметрах выберите нужное поле, в значение вставьте название переменной в фигурных скобках, например: {report}.

Как отправить значение глобальной переменной в Телеграм

  • Добавьте новый триггер «Отправить уведомление в Телеграм».
  • Выберите чат, куда отправить сообщение.
  • Введите сообщение и впишите название переменной.

Таким же образом текст переменной можно отправить, например по СМС через виджет СМС-шлюз, по почте через Почтовик, в мессенджер клиенту через SalesBot.

Как использовать глобальную переменную в условиях

  • В блоке условий добавьте новое условие «Значение переменной», справа от поля выберите нужную переменную.
  • Выберите нужное сравнение и второе значение. В данном случае метод работы ничем не отличается от полей.
  • Можно делать сравнение со значением из поля, с произвольным значением или с другой переменной.

ЗАПУСК СЦЕНАРИЕВ

Сценарии запускаются автоматически при действиях в amoCRM или в ручную. В зависимости от типа события, на которые запускается сценарий, доступны разные параметры и переменные.

  • При создании сделки, контакта, компании

    Сценарий запускается автоматически как только создается одна из этих сущностей. При этом можно запускать триггеры, которые применимы к данному типу сущности. Например: нельзя поменять поле у связанной к сделке компании, если при создании сделки компания еще не создана. Или, нельзя создать сделку, на создание сделки, так как это вызовет бесконечную рекурсию.

    В условиях сценария ко всему прочему доступны:

    • Все поля данной сущности и связанных сущностей
    • Теги, бюджет, ответственный, воронка, статус и т.д.
    • Задачи: дата ближайшей задачи, кол-во задач (открытых, просроченных, всего)
    • Количество прикрепленных сделок, контактов, в зависомости от конкретной сущности
  • При изменении сделки, контакта, компании

    Сценарий запускается автоматически при любом изменении сущностей. При этом можно работать со всеми связанными сущностями. Например, при изменении сделки, мы можем менять поля у компании этой сделки.

    Также изменения происходят при смене ответственного, добавлении примечания, в том числе системного, смене тегов, то есть почти при любых действиях с сущностью. То есть при всех этих действиях запустится ваш сценарий, который настроен на изменение. Так же стоит отметить, что изменения сущности могут быть вызваны самим сценарием, тем самым вызывая бесконечное выполнение сценария и триггеров.
    Например: на изменение сделки, мы добавляем примечание, а добавление примечания вызывает изменение сделки, на что снова запускается сценарий и снова добавляется примечание. В функционале виджета заложена базовая защита от таких рекурсий — это прежде всего таймаут сценария. Минимальное время повторного выполнения любого сценария для конкретной сущности составляет 5 секунд. Тем не менее могут быть цикличные сценарии, которые запускают друг друга, поэтому внимательно отнеситесь к выстраиванию логики.

    В условиях сценария ко всему прочему доступны:

    • Все поля данной сущности и связанных сущностей
    • Теги, бюджет, ответственный, воронка, статус и т.д.
    • Задачи: дата ближайшей задачи, кол-во задач (открытых, просроченных, всего)
    • Количество прикрепленных сделок, контактов, в зависомости от конкретной сущности
  • При входящем сообщении

    Сценарий автоматически запускается если клиент пишет в чат который подключен как источник лидов в amoCRM. Например в Telegram, Instagram, Viber, WhatsApp, Skype или в онлайн-чат amoCRM на сайте.

    В условиях, ко всему прочему, доступен текст сообщения. Например: если текст сообщения содержит «сколько стоит», триггером можно автоматически отправить ответ с ценой.

  • При смене ответственного

    Сценарий автоматически запускается при смене ответственного.
    В условиях сценария доступны все условия на изменение сущности.

  • При добавлении/изменении задачи

    Сценарий запускается при создании задачи к любой сущности.
    В условиях ко всему прочему доступны:

    • Тип связанной сущности, к которой добавилась задача
    • Тип задачи
    • Задача завершена? Да/Нет
    • Дата и время начала, и дата и время завершения задачи
    • Длительность задачи
  • При добавлении примечания

    Сценарий автоматически запускается при добавлении примечания в сделке, в контакте, в компании. В amoCRM добавление примечания происходит при:

    • Добавлении обычного текстового примечания
    • Добавлении системного примечания
    • Входящее/исходящее СМС сообщение
    • Входящий/исходящий e-mail
    • Входящий/исходящий телефонный звонок

    Пример настройки, видео «Как узнать время первого звонка клиенту и записать в поле»

    Таким образом для настройки логики становятся доступны следующие условия:

    • Тип примечания (звонок, письмо, смс, системное, текст)
    • По e-mail: тип письма (входящее/исходящее), заголовок письма
    • По СМС: тип сообщения (входящее, исходящее), текст сообщения
    • По звонкам: тип звонка (входящий/исходящий), длительность звонка в секундах, статус звонка (разговор состоялся, не дозвонился, занято и т.д.)
  • Ручной запуск

    Сценарий запускается в ручную при клике по кнопке в карточке сделки, контакта или компании. При этом внутри сценария корректно сработают только те триггеры, к сущностями которых они применимы.
    Кнопки запуска покажутся только для сценариев такого же типа сущности. Например, кнопка сценария связанного со сделкой будет показана только в карточке сделки.

    Кроме того ручной запуск невозможен для следующих типов сценариев:

    • Смена статуса сделки
    • Смена ответственного
    • Задача добавлена/изменена
    • Добавление примечания в любой сущности
    • Входящее сообщение

    Для этих сценариев кнопка в карточке не покажется

  • Запуск из цифровой воронки amoCRM

    Сценарий запускается из цифровой воронки. В виду специфики функционала при это доступны сценарии только следующих типов:

    • Сценарий на создание сделки
    • Сценарий на изменение сделки
    • Ручной сценарий (свой сценарий)

    Все остальные сценарии не будут отображены при добавлении действия в цифровой воронке

  • Запуск из SalesBot

    Сценарий можно запустить и бота. Будут доступны только сценарии связанные со сделками ручные сценарии.

  • Запуск другим триггером

    Запускается триггером из другого сценария. Доступны переменные и данные из привязанных сущностей, переданные из родительского сценария.

  • Запуск при переходе по ссылке

    Сценарий можно запустить при переходе по ссылке. Например, клиенту отправляется письмо или СМС со ссылкой, он по ней переходит и в amoCRM срабатывает автоматизация. Ссылки можно автоматически отправить через мессенджер или почтой. Кроме того ссылку можно отправить в Телеграм в общий чат или себе в личку, например для выполнения автоматизации. Подробнее.

  • Запуск при нажатии кнопки в виджете Пушер

    Виджет Пушер, может отсылать сотруднику запрос с текстом и кнопками, при нажатии на которые запускается следующий сценарий. Запрос можно отправить сразу нескольким пользователям и выполнять сценарий только для того кто нажмет кнопку первым, для остальных кнопка будет отключена.

ТРИГГЕРНЫЕ ССЫЛКИ

Вы можете отправлять клиентам ссылки на страницы в интернете, например КП, каталог, прайс и при переходите по этим ссылкам запускать сценарии. Ссылку можно отправить через месенеджер (через SalesBot), почтой, или СМС клиенту.

Создание автоматической триггерной ссылки
Перейдите во вкладку Ссылки, выберите тип ссылки Автоматическая, введите название Название и нажмите кнопку Добавить ссылку.

В открывшемся окне введите:

  • Название ссылки
  • URL — страница на которую будет переход при клике по ссылке, например ваше КП в GoogleDoc или ваш сайт с каталогом товаром.
  • Сценарий — заранее настроенный сценарий, который выполнится при переходе по данной ссылке.

После сохранения сформируется переменная вида {tglink:58}, которую можно вставить в любое поле через триггер «Изменение полей». Далее ссылку можно отправить клиенту через почту, СМС, в мессенджер через SaleBot использую подстановку того самого поля, в которой хранится ссылка.

При переходе по данной ссылке сработает сценарий, и выполнятся триггеры, которые в нем заложены. Например поставится задача или сделка переместится в нужный этап.

Лайфхак: Так же ссылку можно отправить в Telegram (не клиенту), в общий чат, себе в личку или руководителю, и сделать автоматизацию по клику.

Например:Приходит сообщение директору о просроченной задаче «По сделке Проект на 2 млн., просрочена задача на отправку счета», и в ней две ссылки: Оштрафовать | Передать другому. При нажатии на «Оштрафовать» создастся задача «Выписать штраф», для руководителя этого сотрудника. При нажатии «Передать другому», сделка тут же переводится другому сотруднику или уходит в общее распределение.

Ручная триггерная ссылка
В такой ссылке используются ID сущностей подставленные через переменные. Сначала сгенерируйте ссылку, затем подставьте нужную переменную с ID цифру сущности после ID.

  • цифру 1 — для контакта
  • цифру 2 — для сделки
  • цифру 3 — для компании

Например:


https://tglk.ru/{{contact.id}}/1/ - ссылка для контакта
https://tglk.ru/{{lead.id}}/2/ - ссылка для сделки
https://tglk.ru/{{company.id}}/3/ - ссылка для компании

Входящие веб хуки (web hooks)

Виджет может принимать входящие веб-хуки с различных сервисов и обрабатывать их используя свой мощный функционал. Например:

  • При заполнении формы на сайте в Tilda, заявку можно пробросить в amoCRM, при этом можно запускать разные сценарии в зависимости от наличия дублей контакта в amoCRM. Если у вас сайт на WordPress, то можно установить бесплатный модуль WebHooks.
  • При обновлении или отписывании контакта в рассылках MailChimp, можно прокинуть обновленную информацию в amoCRM.
  • При оплате счета в 1С, программа может прислать веб-хук, по которому можно найти, к примеру, компанию по ИНН и поставить ей сумму оплаты. Или найти сделку по ID и передвинуть статус.

Если сервис поддерживает WEB-hooks, будьте уверены, его легко можно будет интегрировать с amoCRM через данный виджет, без программиста.

Общий принцип работы с хуками выглядит так:


  1. Создать веб-хук в виджете и скопировать URL.
  2. Вставить URL в сервис, который имеет возможность их отправлять. Например в Тильде это — Настройки сайта > Формы > Другое > Webhook.
  3. Отправить хук с сайта, например, отправить текстовую заявку.
  4. Дождаться приема запроса в настройках данного хука в Триггерах и убедиться, что данные пришли.
  5. Используя пришедшие переменные настроить сценарии в Триггерах. Например, сделать поиск контакта по телефону, если нет, создать новый, если есть, обновить и поставить задачу.

Пример настройки — видео https://www.youtube.com/watch?v=uC6dPc5-JlY

Ниже рассмотрим эту последовательность более подробно.

1. Создание входящего веб-хука в Триггерах

  • Зайдите в настройки виджета, вкладка ХУКИ.
  • В правом верхнем углу введите название хука, например «Заявки с сайта», нажмите Создать.
  • Создастся новый приемщик хуков сгенерируется URL вида https://tglk.ru/in/QB4PoBsADoF9e6lA.
  • На данный момент никакие другие настройки можно не делать, настройки начинаются после приема первых данных по этому хуку.

2. Вставить URL в сервис отправки хуков

Сервисов, которые могут отправлять хуки огромное количество. Например: конструкторы сайтов, сервисы рассылки, некоторые платежные шлюзы, система 1С со специальным модулем, мессенджеры, например Телеграм, так же сама amoCRM (например, если вам нужно отправлять данные из одного аккаунта amoCRM в другую)

Скопируйте URL вида https://tglk.ru/in/QB4PoBsADoF9e6lA и вставьте в соответствующий сервис в настройках.

3. Отправьте тестовую заявку

Отправьте тестовую заявку с сервиса (например заполните форму), вернитесь в окно настройки хука и убедитесь, что данные пришли (окно обновляется в реальном времени).

Пример настройки веб-хука

4. Дождитесь принятия хука и изучите перемменные

Посмотрите все данные, которые пришли в запросе. Это могут быть контактные данные клиента, список товаров, куки и различные ID отслеживания, названия форм и т.д.

Все данные, автоматически преобразовываются в переменные, которые можно использовать в сценариях, в условиях и триггерах а так же при проверке сущностей на наличие.

Например, можно проверить наличие контакта по номеру телефона и запустить разные сценарии в зависимости от наличия контакта (смотрите скрин выше). Если есть дубль, то обновить данные и поставить задачу о том, что клиент оставил повторную заявку и обновить поля через триггер изменения полей. Если контакта нет, то создать новый контакт, сделку, задачу.

Поиск сущности может осуществляться по нескольким полям, при этом если сущность будет найдена хотя бы по одному полю, остальные проверяться не будут, то есть поиск всегда осуществляется по принципе ИЛИ.

5. Настройте нужные сценарии

Используя пришедшие переменные необходимо настроить сценарии в Триггерах.

Например, сделать поиск контакта по телефону, если контакт не найден, запустить сценарий создания контакта (данный сценарий предварительно должен быть создан), в котором можно использовать переменные из хука для задания полей новому контакту.

Если контакт найден, то например, можно обновить найденный контакт новыми полями через триггер изменения полей, добавить сделку и задачу.

Небольшая подборка сервисов имеющих хуки

Конструкторы сайтов и CMS

  • Tilda
  • LP платформы,
  • WordPress (через бесплатный плагин)
  • WIX
  • Taplink
  • 1C Битрикс Управление сайтом

E-mail рассылки

  • MailChimp
  • SendPulse (есть хуки на открытие письма)
  • GetResponse
  • Unisender (есть хуки на открытие письма и переход по ссылке)

Телефония

  • OnlinePBX
  • UIS
  • Sipuni
  • Asterisk

Сервисы колтрекинга

  • RingoStat
  • ROIstat
  • Comagic
  • Calltouch
  • Callibri

Онлайн чаты

  • JivoChat
  • Chatra
  • Marquiz — квизы
  • Callibri

Система 1С Предприятие
По умолчанию в 1С нет функционала хуков, но его можно добавить небольшим модулем. В зависимости от версии и конфигурации могут быть свои особенности, посоветуйтесь со своим разработчиком по 1С.

ОТЛАДКА И РЕШЕНИЕ ПРОБЛЕМ

Почему не сработал сценарий?
Почему не выполнился триггер внутри сценария?
Почему сценарий сработал, хотя не должен был?
Почему не сработало условие?

На все эти вопросы отвечает отладчик, который заложен в системе.

СИСТЕМА ОТЛАДКИ

В списке сценария, кликните на название события справа (зеленая ссылка — например «Сделка добавлена»).

      Будут показаны последние 100 действий, которые могли вызывать данный сценарий. Например, если это сценарий на создание сделки, то последние 100 созданных сделок с их ID.

      • Если в списке нет ни одной строчки, значит после создания сценария еще ни одна сделка не была создана.
      • Если внутри сценария несколько блоков с условиями, то будет показан каждый блок в виде отдельной строчки и статуса срабатывания конкретного блока.
      • Найдите свою сделку, по которой предполагался запуск сценария и выполнение триггеров (ищите по ID), и посмотрите как выполнились или не выполнились конкретные блоки условий.

          Если сделки, по которой вы тестируете, еще нет в этом списке, значит web-hook на нее еще не пришел. Посмотрите во вкладке Статистика число «Очередь обработки событий», если оно отлично от нуля, то возможно этот хук еще находится в очереди, такое бывает, если приходит очень много хуков из amoCRM. Это штатная работа системы и ускорить ее нельзя, чтобы не заблокировать API amoCRM.

          Блок условий может иметь три статуса:

          • Выполнен — блок выполнился и запустил триггеры, которые были в нем заложены. Значит все хорошо. Можно кликнуть на слово выполнен и увидеть какие триггеры внутри были сработаны. Так же вы можете узнать почему данный блок условий сработал, кликнув на его название.
          • Не соответствует условиям — данный блок не выполнился, так как не подходит по условиям. Нужно кликнуть по названию блока условий и увидеть все условия и значения, которые не дали запуститься этому блоку. Блок условий выполнится только если все строки будут зелеными. Красные строки говорят о том, что какое то условие не выполнилось. При наведении на строку условия покажется более подробная техническая информация: какие данные пришли, как они сравнивались, и к чему это привело, в том числе, время за которое сработала проверка. Скрин ниже.
              • Превышена частота выполнения — данная надпись появляется, если сценарий инициировался чаще чем заложено в настройках сценария — «Выполнять для конкретной сущности: не чаще чем 1 раз в XX сек.». Например в данном поле стоит 60 сек., а сделка будет меняться раз в 10 секунд, в таком случае, сценарий будет запущен только после того изменения, которое произошло спустя 60 секунд после предыдущего изменения, все остальные изменения в этом промежутке будут проигнорированы.

                  Старайтесь не понижать этот тайминг без особой необходимости. Это напрямую влияет на количество срабатываний триггеров, соответственно будут быстрее расходоваться лимиты на операции, которые ограничены на каждый аккаунт.
                  Вообще старайтесь сценарии «на изменение», использовать по минимуму, так как изменения происходят довольно часто. Любое обновление сущности, добавление примечания, звонки, чаты и т.д. вызывают изменение сущности. Поэтому в зависимости от бизнес-процесса, старайтесь использовать менее «частые» сценарии, например: смена статуса, создание сущности, добавление примечания и т.д.

                  Коды ошибок при выполнении триггеров

                  Ограничения на скорость выполнения

                  В следствие особенностей работы API amoCRM, у виджета существуют некоторые ограничения по скорости выполнения операций. В частности, все процессы ставятся в очередь заданий и выполняются с определенным интервалом, чтобы не допустить блокировки API вашего аккаунта. Каждое следующее задание ставится в конец очереди, в следствие этого могут быть задержки в выполнении операций.

                  Например, вы запустили сценарий для 1000 сделок, в зависимости от сложности и количества триггеров в нем, весь процесс будет выполняться 5-10 минут. Все это время остальные запускающиеся процессы будут вставать в очередь и будут выполнены, когда до них дойдет очередь. При этом специальный алгоритм следит за тем, чтобы сценарии, в которых накопились большие очереди, не мешали другим сценариям.
                  Это штатная работа системы и ускорить ее нельзя.

                  Ограничения на количество операций

                  Для защиты от чрезмерной, в виджете предусмотрен учет количества операций. Сценарии необходимо настраивать таким образом, чтобы не было зацикливаний процессов, дублирования операций, лишних триггеров и т.д.

                  Существует лимит операций для аккаунта. На каждого купленного пользователя дается 50 000 операций в месяц, например за 5 пользователей это 250 000 операций. За операцию считается каждое действие триггера и каждый пришедший web-hook из amoCRM. Количество операций можно посмотреть во вкладке Статистика.

                  Данное количество операций в среднем три раза превышает необходимые потребности обычного аккаунта. Однако некоторые аккаунты могут его превышать в следствие неправильной настройки или сложности процессов. Если вы много и часто превышаете лимиты, мы поможем вам оптимизировать сценарии, а если это невозможно, нужно будет докупать нужное количество операций. Рассчет производится по той же схеме — 50 тыс. на одного пользователя. То есть, если вы превысили на 100 тыс. в месяц, нужно будет доплатить за 2 пользователей.

                  Данное ограничение контролируется полностью в ручную, ваш аккаунт не отключится автоматически в следствии превышения. Мы обратим на это внимание, только если это происходит системно, в этом случае мы свяжемся с вами, чтобы обсудить дальнейшую работу.

                  Ограничения на количество сценариев

                  В одном аккаунте не может быть больше 100 сценариев. Данная цифра полностью покрывает потребности, а бОльшее количество ведет к невозможности нормальной работы с интерфейсом программы. Если у вас больше 100 сценариев, обратитесь к нам, посмотрим, почему так получилось и найдем решение.
                  Максимальное количество активных сценариев по изменению сущностей (сделки, контакта, компании, задачи) не должно превышать более 3-х штук на каждое из событий.

                  Ограничения на хранение очереди отложенных триггеров
                  При наступлении отложенного события, сценарий, инициировавший данное событие, может не активным (выключен). В данном случае отложенное событие не выполнится, и будет ждать, пока сценарий включится. Если выключенный сценарий не включается в течение 3 месяцев с того момента как должен выполниться отложенный триггер, то данный триггер удаляется.
                  Если же сценарий включится, то все отложенные триггеры у которых уже наступил срок выполнения, выполнятся моментально.

                  Работа триггеров в разных временных зонах
                  Виджет работает по серверному времени UTC+3 (Europe/Moscow). Все интерфейсные элементы, история срабатываний, настройки запуска, привязаны к московскому времени. При настройке автоматизации для разных часовых поясов, вы можете самостоятельно настраивать сценарии и триггеры с учетом сдвига временных зон. Например отсрочить или ускорить запуск триггера на несколько часов.

                  Готовые решения

                  Примеры готовых настроек по сценариям со скриншотами

                  Как поздравить клиента с днем рождения?

                  Пример готовых настроек виджета для поздравления клиента.

                  Как уведомить клиента о записи за 2 часа?

                  Уведомляем клиента о записи с помощью виджета Триггеры и бесплатного виджета СМС-шлюз

                  Как работать с базой и напоминать о себе клиентам, которые купили, но давно не выходили на связь?

                  Готовый бизнес процесс для напоминания клиентам по следующей покупке. (переписать)

                  Не получается настроить? Сложные процессы в компании?

                  Закажите профессиональную настройку виджета «Командой F5». Полная автоматизация ваших бизнес-процессов под ключ, с учетом специфики компании.

                  Telegram канал «Команды F5»

                  Лучшие кейсы автоматизаций, новости о выходе новых виджетов и обновлениях действующих.

                  В мире стартапов с открытыми исходными кодами и разработкой полного стека (типа Django, Rails, Javascript, PHP, MySQL, Postgres…) очень популярны ORM, а средства типа триггеров SQL не так востребованы.

                  Но все же триггеры SQL сохраняют свое значение. Когда я работал над нестандартной ERP-системой, триггеры оказались неоценимым инструментом. При построении сильно ориентированного на данные ПО, особенно с данными в финансовой сфере, где точность является главным требованием, вы с большей вероятностью увидите, что данные обрабатываются непосредственно на более низком уровне.

                  В этой статье я поделюсь информацией о том, как эффективно использовать триггеры SQL.

                  Содержание

                  1. Что такое триггер?
                  2. Как создать триггер SQL — синтаксис PostgreSQL
                  3. Пример триггера в PostgreSQL #1: создание таймера
                  4. Пример триггера в PostgreSQL #2: создание таблицы аудита
                  5. Дополнительные соображения о триггерах

                  Что такое триггер?

                  Триггеры SQL, также называемые триггерами баз данных, позволяют вам сказать движку SQL (например PostgreSQL) выполнить часть кода при наступлении некоторого события, или даже перед наступлением события.

                  В PostgreSQL вы описываете исполняемый код посредством создания функции, которая возвращает значение типа trigger. В некоторых других движках, например, MySQL блок кода является частью триггера, и находится внутри него.

                  Прежде чем рассматривать различные типы событий и конкретный синтаксис создания триггера, обсудим, зачем бы вам понадобилось использовать триггеры баз данных.

                  Преимущества использования триггеров SQL

                  Поддержание целостности данных

                  Триггеры баз данных могут найти множество применений и являются прекрасным инструментом для обеспечения строгой целостности данных. Альтернативные решения типа хуков модели Django могут сбоить, если вы имеете другие серверы приложений или пользователей с доступом к базе данных, которые не знают конкретной бизнес-логики, закодированной в вашем приложении.

                  Разделение бизнес-логики

                  Размещение критичной бизнес-логики в коде приложения также представляет проблему, когда бизнес-логика обновляется. Если вашим бизнес-требованием являлось умножение входящих номеров на 10, а теперь вы захотели умножать это число на 20, изменение логики в SQL гарантировало бы, что каждые данные, начиная точно с момента развертывания, будут обрабатываться новой логикой.

                  Сервер SQL действует как единственная точка истины. Если логика внедрена на множестве серверов приложений, вы не сможете ожидать определенного изменения в поведении, выполненного чисто.

                  Атомарные транзакции

                  Естественная атомарность является еще одной желательной особенностью, присущей триггерам. Поскольку событие и триггерная функция являются частью одной атомарной транзакции, вы знаете с абсолютной определенностью, что триггер сработает, если возникнет событие. Они как единое целое в идеальном браке SQL.

                  Как создать триггер SQL: синтаксис PostgreSQL

                  Вот составляющие создания триггера для вашей базы данных:

                  1. Тип события триггера
                  2. До или после события
                  3. Воздействие триггера

                  Типы событий триггера

                  Триггеры баз данных будут мониторить конкретные события для таблицы. Вот некоторые примеры различных событий, которые могут активировать триггер:

                  Триггер базы данных допускает также перечисление более одного из этих событий.

                  Если одним из перечисленных событий является UPDATE, вы можете передать список столбцов, которые должны активировать триггер. Если вы не включаете этот список, обновление любого столбца будет его активировать.

                  Триггер BEFORE (до) или AFTER (после)

                  Триггер может выполняться либо до, либо после события.

                  Если вы хотите заблокировать событие типа INSERT, вы захотите выполнять действие до (BEFORE). Если вы хотите быть уверенным, что событие действительно произойдет, идеальный вариант — после (AFTER).

                  Воздействие триггера

                  Триггер может выполняться либо на строку, либо на оператор. Скажем, вы выполняете один оператор UPDATE, который изменяет 5 строк в таблице.

                  Если вы укажете в триггере FOR EACH ROW, тогда триггер выполнится 5 раз. Если вы укажете FOR EACH STATEMENT, тогда он выполнится только раз.

                  И, конечно, мы не можем забыть о фактическом коде, который выполняется при срабатывании триггера. В PostgreSQL он помещается в функцию и отделен от триггера. Разделение триггера и кода, который он выполняет, создает более чистый код и позволяет нескольким триггерам выполнять один и тот же код.

                  Пример триггера #1: создание таймера

                  Фиксация времени прихода и ухода с работы сотрудников, и вычисление общего отработанного времени. Давайте создадим пример таймера и посмотрим, каким образом мы можем использовать триггеры для предотвращения ввода сотрудниками неверных данных.

                  Настройка схемы базы данных

                  Структура схемы предполагает каждый вход и выход отдельными событиями. Каждое событие — это строка в таблице time_punch. Как альтернативу вы можете также сделать каждую «рабочую смену» сотрудника событием и хранить время как входа, так и выхода в одной строке.

                  В следующей статье я глубже погружусь в разработку схемы базы данных.

                  Для нашего примера я уже разработал схему таблиц. Нижеприведенный код создает таблицы employee и time_punch и вставляет некоторые данные по времени прохода для нового сотрудника Bear.

                  create table employee ( id serial primary key, username varchar );
                  create table time_punch (
                  id serial primary key,
                  employee_id int not null references employee(id),
                  is_out_punch boolean not null default false,
                  punch_time timestamp not null default now()
                  );
                  insert into employee (username) values ('Bear');
                  insert into time_punch (employee_id, is_out_punch, punch_time)
                  values
                  (1, false, '2020-01-01 10:00:00'),
                  (1, true, '2020-01-01 11:30:00');

                  Bear зашел в 10:00 и вышел в 11:30 (длинный рабочий день). Давайте напишем запрос SQL для вычисления рабочего времени Bear.

                  Остановитесь и подумайте, как бы вы решили эту задачу при данной схеме и с помощью одного SQL.

                  Использование SQL для вычисления рабочего времени

                  Решение, которое я предлагаю, ищет на каждый «выход» соответствующий ему «вход».

                  select tp1.punch_time - tp2.punch_time as time_worked
                  from time_punch tp1
                  join time_punch tp2
                  on tp2.id = (
                  select tps.id
                  from time_punch tps
                  where tps.id < tp1.id
                  and tps.employee_id = tp1.employee_id
                  and not tps.is_out_punch
                  order by tps.id desc limit 1
                  )
                  where tp1.employee_id = 1 and tp1.is_out_punch;

                  time_worked
                  2
                  -------------
                  3
                  01:30:00 (1 row)

                  В этом запросе я выбираю все выходы, затем я соединяю их с наиболее близким «входом». Беру разность временных меток и получаю количество часов, которое отработал Bear в каждой смене!

                  Одна из проблем в этой схеме состоит в том, что возможно вставить несколько «входов» или «выходов» подряд. С созданным запросом это приведет к неоднозначности, которая может привести к неточным расчетам и зарплате сотрудников — тбольше или меньше, чем они должны были бы получить.

                  Пример триггера INSERT BEFORE: сохранение целостности данных

                  Нам требуется то, что не позволит нарушить шаблон вход/выход. К сожалению, ограничения check только отслеживают вставляемую или обновляемую строку и не могут учитывать данные из других строк.

                  Это идеальная ситуация для использования триггера баз данных!

                  Давайте создадим триггер для предотвращения события INSERT, которое нарушает наш шаблон. Сначала мы создадим «триггерную функцию». Эта функция есть то, что будет выполнять триггер при наступлении события.

                  Триггерная функция создается как обычная функция PostgreSQL за тем исключением, что возвращает триггер.

                  create or replace function fn_check_time_punch() returns trigger as $psql$
                  begin
                  if new.is_out_punch = (
                  select tps.is_out_punch
                  from time_punch tps
                  where tps.employee_id = new.employee_id
                  order by tps.id desc limit 1
                  ) then
                  return null;
                  end if;
                  return new;
                  end;
                  $psql$ language plpgsql;

                  Ключевое слово new представляет значения вставляемой строки. Это также объект, который вы можете вернуть, чтобы позволить продолжиться вставке. Напротив, возвращение null остановит вставку.

                  Этот запрос сначала находит в time_punch предыдущее значение и гарантирует, что это значение входа/выхода не совпадает с вставляемым значением. Если значения совпадают, то триггер возвращает null, и time_punch не записывается. В противном случае, триггер возвращает new и оператор insert продолжается.

                  Теперь мы привяжем функцию в качестве триггера к таблице time_punch. BEFORE здесь ключевой момент. Если мы выполним этот триггер как триггер AFTER, он будет выполнен слишком поздно, чтобы остановить вставку.

                  create trigger check_time_punch before insert on time_punch
                  for each row execute procedure fn_check_time_punch();

                  Давайте попробуем вставить еще один «выход»:

                  insert into time_punch (employee_id, is_out_punch, punch_time)
                  values
                  (1, true, '2020-01-01 13:00:00');

                  Output: INSERT 0 0

                  Как можно видеть по выводу, триггер предотвратил вставку двух последовательных выходов для одного и того же сотрудника.

                  Можно также вызвать исключение из триггера с тем, чтобы ваше приложение (или лицо, выполняющее запрос SQL) получило уведомление об отказе вместо 0 как числа вставленных строк.

                  Пример триггера в PostgreSQL #2: создание таблицы аудита

                  Аккуратное сохранение данных о нахождении сотрудников критично для бизнеса. Данные подобного типа часто непосредственно отражаются на зарплате и, с другой стороны, на заработках компании.

                  Ввиду важности этих данных, пусть компания хочет воссоздавать в хронологии состояние таблицы на случай обнаружения нарушений.

                  Таблица аудита выполняет эту роль, отслеживая каждое изменение основной таблицы. Когда в главной таблице обновляется строка, в таблицу аудита вставляется строка в ее предыдущем состоянии.

                  Я буду использовать нашу таблицу time_punch для демонстрации создания и автоматического обновления таблицы аудита с помощью триггеров.

                  Создание таблицы аудита

                  create table time_punch_audit (
                  id serial primary key,
                  change_time timestamp not null default now(),
                  change_employee_id int not null references employee(id),
                  time_punch_id int not null references time_punch(id),
                  punch_time timestamp not null
                  );

                  В эту таблицу записывается:

                  • Время обновления прохождения.
                  • Сотрудник, который выполнил обновление.
                  • ID прохода, который был изменен.
                  • Время прохода до того, как было сделано обновление.

                  Прежде чем создавать триггер, сначала нам нужно добавить столбец change_employee_id в таблицу time_punch. Тогда триггер будет знать, какой сотрудник сделал каждое изменение в таблице time_punch.

                  alter table time_punch 
                  add column change_employee_id int null references employee(id);

                  (Как альтернативное решение без добавления каких-либо столбцов в time_punch, можно аннулировать права update на эту таблицу и заставить пользователей базы данных использовать пользовательскую функцию типа update_time_punch(id, change_user_id, …))

                  После того, как произойдет обновление таблицы time_punch, выполнится этот триггер и запишет OLD (старое) значение времени прохода в нашу таблицу аудита.

                  create or replace function fn_change_time_punch_audit() returns trigger as $psql$
                  begin
                  insert into time_punch_audit (change_time, change_employee_id, time_punch_id, punch_time)
                  values
                  (now(), new.change_employee_id, new.id, old.punch_time);
                  return new;
                  end;
                  $psql$ language plpgsql;

                  create trigger change_time_punch_audit after update on time_punch
                  for each row execute procedure fn_change_time_punch_audit();

                  Функция NOW() возвращает текущую дату и время с точки зрения сервера SQL. Если бы это было привязано к настоящему приложению, вы, вероятно, захотели бы передавать точное время, когда пользователь фактически сделал запрос, чтобы избежать расхождения из-за задержки.

                  Для триггера на обновление объект NEW представляет те значения, которые будут содержаться
                  в строке при успешном обновлении. Вы можете использовать триггер для «перехвата» вставки или обновления простым присвоением своих собственных значений в объект NEW. Объект OLD содержит значения строки до обновления.

                  Проверим, работает ли это! Я добавил второго пользователя с именем Daniel, который будет редактором времени прохода Bear.

                  select punch_time
                  from time_punch
                  where id=2;

                  punch_time
                  ---------------------
                  2020-01-01 11:30:00
                  (1 row)

                  Я собираюсь выполнить дважды нижеприведенный запрос для имитации 2 редакций, которые увеличивают время на 5 минут.

                  update time_punch 
                  set punch_time = punch_time + interval '5 minute', change_employee_id = 2
                  where id = 2;

                  А вот таблица аудита, отражающая прошлые времена прохода:

                  Дополнительные сообщажения относительно триггеров

                  Вот несколько вещей, связанные с триггерами, которые следует иметь в виду:

                  1. Обслуживание триггеров с течением времени.
                  2. Связанная логика триггера.
                  3. Опыт разработчиков.

                  Обслуживание триггеров с течением времени

                  Бизнес-логика в коде приложения документируется естественным образом, т.к. она меняется со временем, с помощью git или другой системы управления исходниками. Разработчику легко увидеть логику в базовом коде и сделать быструю журнализацию git, а также посмотреть список изменений.

                  Обслуживание изменений со временем с помощью триггеров SQL и функций более сложно, менее стандартизовано и требует большего осмысливания и планирования.

                  Связанная логика триггера

                  Триггеры также могут запускать другие триггеры, быстро усложняя результаты казалось бы невинных INSERT или UPDATE. Этот риск также может привести к побочным эффектам кода приложения.

                  Опыт разработчиков

                  Знания триггеров так же довольно низки в среде некоторых разработчиков, поэтому введение их увеличивает вложения в обучение, которое потребуется новым разработчикам для успешной работы над проектом.

                  Изначально SQL может показаться неуклюжим и неудобным языком для изучения, поскольку многие из шаблонов, которые вы изучаете для построения запроса, «вывернуты наизнанку» по сравнению с тем, как вы извлекаете данные на процедурном языке.

                  Я надеюсь, что у вас появится возможность изучить и реализовать одну из самых увлекательных и интригующих функций SQL!

                  Мне было 12 лет, когда я впервые услышал о триггерах SQL. Мой брат, Джонатан, только начал свою карьеру программиста в стартапе. Однажды Джонатан пришел домой, разочарованный базой данных, полной запутанных триггеров SQL.

                  Поскольку мой единственный опыт программирования заключался в воссоздании моей любимой видеоигры на VB6, у меня было мало утешения.

                  Перенесемся на 16 лет вперед, и теперь я могу видеть с точки зрения моего брата. В мире разработки полного стека в стиле стартапов с открытым исходным кодом (например, Django, Rails, Javascript, PHP, MySQL, Postgres…) ORM очень популярны, а такие функции, как триггеры SQL, гораздо менее традиционны.

                  Но все еще есть ценность с триггерами SQL. Когда я работал над заказным программным обеспечением, подобным ERP, триггеры SQL были бесценным инструментом. При создании программного обеспечения, ориентированного на данные, особенно когда данные имеют финансовый характер и требуется высокая точность, вы, скорее всего, увидите, что данные манипулируются на более низком уровне более прямым способом.

                  Эта статья содержит всю информацию, которой я хотел бы поделиться со своим братом о том, как эффективно использовать триггеры SQL.

                  Оглавление

                  • Что такое SQL-триггер?
                  • Как создать триггер SQL — синтаксис
                  • Пример 1 триггера Postgres: создание часов
                  • Пример 2 триггера Postgres: создание таблицы аудита
                  • Дополнительные соображения по триггерам

                  Что такое триггер SQL?

                  Триггеры SQL, также называемые триггерами базы данных, позволяют указать механизму SQL (в данном случае Postgres) выполнять фрагмент кода, когда происходит событие или даже до него.

                  В Postgres вы определяете код для запуска, создавая функцию с типом возвращаемого значения trigger. В некоторых других движках, таких как MySQL, блок кода является частью триггера и находится внутри него.

                  Прежде чем я расскажу о различных типах событий и конкретном синтаксисе для создания триггера, почему вы хотите использовать триггер базы данных?

                  Преимущества использования триггеров SQL

                  Поддержание целостности данных. Триггеры базы данных имеют множество применений и являются отличным инструментом для обеспечения строгой целостности данных. Альтернативные решения, такие как перехватчики моделей Django, могут потерпеть неудачу, если у вас есть другие серверы приложений или пользователи, обращающиеся к базе данных, которые не знают о конкретной бизнес-логике, закодированной в вашем приложении.

                  Разделение бизнес-логики. Кодирование критической бизнес-логики в коде приложения также создает проблемы при обновлении бизнес-логики. Если бы у вас было бизнес-требование умножить входящее число на 10, и вы хотели бы пересмотреть эту логику, чтобы умножить число на 20, изменение логики в SQL гарантировало бы, что каждый фрагмент данных с этого точного времени развертывания будет затронут новая логика.

                  Сервер SQL действует как единственная точка истины. Если логика реализована на нескольких серверах приложений, вы больше не можете ожидать четкого, окончательного изменения в поведении.

                  Атомарные транзакции. Естественная атомарность — еще одна желательная функция, связанная с триггерами. Поскольку событие и триггерная функция являются частью одной атомарной транзакции, вы с абсолютной уверенностью знаете, что триггер сработает, если сработает событие. Они как одно целое, в идеальном SQL-супружестве.

                  Как создать триггер SQL — синтаксис Postgres

                  Вот компоненты для создания триггера для вашей базы данных:

                  1. Тип триггерного события
                  2. До или после события
                  3. Эффект триггера

                  Типы триггерных событий

                  Триггеры базы данных будут отслеживать таблицы на наличие определенных событий. Вот несколько примеров различных событий, которые могут активировать триггер:

                  • Изменение данных: INSERT, UPDATE, DELETE

                  Триггер базы данных также может отображать более одного из этих событий.

                  Если UPDATE было одним из перечисленных событий, вы можете передать список столбцов, которые должны активировать триггер. Если вы не включите этот список, обновление любого столбца активирует его.

                  Триггер BEFORE или AFTER

                  Триггер может запустить BEFORE или AFTER событие.

                  Если вы хотите заблокировать такое событие, как INSERT, вам нужно запустить BEFORE. Если вам нужно быть уверенным, что событие действительно произойдет, AFTER идеально подходит.

                  Эффект триггера

                  Триггер может запускаться либо для каждой строки, либо для каждого оператора. Допустим, вы запускаете один оператор UPDATE, который изменяет 5 строк в таблице.

                  Если в триггере указать FOR EACH ROW, то триггер сработает 5 раз. Если вы укажете FOR EACH STATEMENT, то он запустится только один раз.

                  И, конечно же, мы не можем забыть код, который запускается при активации триггера. В Postgres помещается в функцию и отделяется от триггера. Отделение триггера от кода, который он запускает, создает более чистый код и позволяет нескольким триггерам выполнять один и тот же код.

                  Пример триггера Postgres № 1: создание часов

                  Табель учета рабочего времени фиксирует приход и уход сотрудника с работы и подсчитывает общее количество отработанных им часов. Давайте создадим пример часов и посмотрим, как мы можем использовать триггеры, чтобы предотвратить ввод сотрудниками неверных данных.

                  Настройка схемы БД

                  Дизайн этой схемы рассматривает каждое включение и выключение как отдельные события. Каждое событие представляет собой строку в таблице time_punch. Кроме того, вы также можете сделать «смену» каждого сотрудника событием и сохранить время начала и окончания работы в одной строке.

                  В этом примере я пошел дальше и определил схему для наших таблиц. Приведенный ниже код создает таблицу employee и time_punch и вставляет некоторые данные об отметке времени для нового сотрудника Bear.

                  create table employee (
                    id serial primary key,
                    username varchar
                  );
                  
                  create table time_punch (
                    id serial primary key,
                    employee_id int not null references employee(id),
                    is_out_punch boolean not null default false,
                    punch_time timestamp not null default now()
                  );
                  
                  insert into employee (username) values ('Bear');
                  insert into time_punch (employee_id, is_out_punch, punch_time)
                  values
                  (1, false, '2020-01-01 10:00:00'),
                  (1, true, '2020-01-01 11:30:00');

                  Медведь пришел в 10:00 и ушел в 11:30 (долгий рабочий день). Давайте напишем SQL-запрос, чтобы вычислить, как долго Медведь работал.

                  Сделайте здесь паузу и подумайте, как бы вы решили это, учитывая нашу схему и используя только SQL.

                  Использование SQL для расчета отработанного времени

                  Решение, которое я выбрал, рассматривает каждый удар «наружу» и сопоставляет его с предыдущим ударом «внутрь».

                  select tp1.punch_time - tp2.punch_time as time_worked
                  from time_punch tp1
                  join time_punch tp2
                  on tp2.id = (
                  	select tps.id
                  	from time_punch tps
                  	where tps.id < tp1.id
                  	and tps.employee_id = tp1.employee_id
                  	and not tps.is_out_punch
                  	order by tps.id desc limit 1
                  )
                  where tp1.employee_id = 1
                  and tp1.is_out_punch
                  time_worked
                  -------------
                   01:30:00
                  (1 row)

                  В этом запросе я выбираю все исходящие удары, затем присоединяю их к ближайшему предшествующему «внутреннему» удару. Вычтите метки времени, и мы получим, сколько часов Медведь отработал за каждую смену!

                  Одна из проблем с этой схемой заключается в том, что вы можете вставить несколько ударов «в» или «вне» подряд. С созданным нами запросом это может привести к неточностям, которые могут привести к неточным расчетам и зарплате сотрудников больше или меньше, чем они должны.

                  Пример триггера SQL INSERT BEFORE — сохранение целостности данных

                  Нам нужно что-то, чтобы предотвратить прерывание схемы входа/выхода. К сожалению, контрольные ограничения учитывают только вставляемую или обновляемую строку и не могут учитывать данные из других строк.

                  Это идеальная ситуация для использования триггера базы данных!

                  Давайте создадим триггер для предотвращения события INSERT, которое нарушит наш шаблон. Сначала мы создадим «триггерную функцию». Эта функция — то, что триггер будет выполнять при обнаружении типа события.

                  Триггерная функция создается как обычная функция Postgres, за исключением того, что она возвращает trigger.

                  create or replace function fn_check_time_punch() returns trigger as $psql$
                    begin
                      if new.is_out_punch = (
                        select tps.is_out_punch
                        from time_punch tps
                        where tps.employee_id = new.employee_id
                        order by tps.id desc limit 1
                      ) then
                        return null;
                      end if;
                      return new;
                    end;
                  $psql$ language plpgsql;

                  Ключевое слово new представляет значения вставляемой строки. Это также объект, который вы можете вернуть, чтобы продолжить вставку. В качестве альтернативы, когда возвращается null, вставка останавливается.

                  Этот запрос находит time_punch раньше и гарантирует, что его входное/исходное значение не совпадает с тем, что вставляется. Если значения совпадают, триггер возвращает null и time_punch не записывается. В противном случае триггер возвращает new, и оператор insert может продолжить работу.

                  Теперь мы свяжем функцию как триггер с таблицей time_punch. BEFORE имеет решающее значение здесь. Если бы мы запустили этот триггер как триггер AFTER, он запустился бы слишком поздно, чтобы остановить вставку.

                  create trigger check_time_punch before insert on time_punch for each row execute procedure fn_check_time_punch();

                  Попробуем вставить еще один удар «вне»:

                  insert into time_punch (employee_id, is_out_punch, punch_time)
                  values
                  (1, true, '2020-01-01 13:00:00');
                  Output:
                  INSERT 0 0

                  Из вывода видно, что триггер предотвратил вставку двух последовательных выходов для одного и того же сотрудника.

                  Также можно вызвать исключение из триггера, чтобы ваше приложение (или человек, выполняющий SQL-запрос) получало уведомление об ошибке, а не количество вставок, просто равное 0.

                  Пример триггера Postgres № 2: создание таблицы аудита

                  Точное хранение данных о сотрудниках имеет решающее значение для бизнеса. Этот тип данных часто в конечном итоге напрямую преобразуется в зарплату сотрудника, а с другой стороны, в стоимость заработной платы компании.

                  Из-за важности этих данных, допустим, компания хочет иметь возможность воссоздать все исторические состояния таблицы в случае обнаружения несоответствия.

                  Таблица аудита выполняет это, отслеживая каждое изменение в таблице. Когда строка обновляется в основной таблице, строка будет вставлена ​​в таблицу аудита, в которой будет записано ее прошлое состояние.

                  Я буду использовать нашу таблицу time_punch, чтобы продемонстрировать, как создать автоматически обновляемую таблицу аудита с помощью триггеров.

                  Создайте таблицу аудита

                  Существует несколько способов ведения таблицы аудита или истории. Создадим отдельную таблицу, в которой будут храниться прошлые состояния time_punch.

                  create table time_punch_audit (
                    id serial primary key,
                    change_time timestamp not null default now(),
                    change_employee_id int not null references employee(id),
                    time_punch_id int not null references time_punch(id),
                    punch_time timestamp not null
                  );

                  В этой таблице хранятся:

                  • Время обновления пунша
                  • Сотрудник, обновивший его
                  • ID пуансона, который был изменен
                  • Время перфорации до обновления перфорации

                  Прежде чем мы создадим наш триггер, нам сначала нужно добавить столбец change_employee_id в нашу таблицу time_punch. Таким образом, триггер будет знать, какой сотрудник внес каждое изменение в таблицу time_punch.

                  alter table time_punch add column change_employee_id int null references employee(id);

                  (Альтернативное решение без добавления каких-либо столбцов в time_punch может состоять в том, чтобы отозвать разрешение на обновление этой таблицы и заставить пользователей этой базы данных использовать пользовательскую функцию, например update_time_punch(id, change_user_id, ...))

                  Пример триггера SQL UPDATE AFTER — вставка данных

                  После обновления нашего time_punch table этот триггер запускается и сохраняет значение времени пунша OLD в нашей таблице аудита.

                  create or replace function fn_change_time_punch_audit() returns trigger as $psql$
                    begin
                      insert into time_punch_audit (change_time, change_employee_id, time_punch_id, punch_time)
                      values
                      	(now(), new.change_employee_id, new.id, old.punch_time);
                      return new;
                    end;
                  $psql$ language plpgsql;
                  create trigger change_time_punch_audit after update on time_punch
                  for each row execute procedure fn_change_time_punch_audit();

                  Функция NOW() возвращает текущую дату и время с точки зрения сервера SQL. Если бы это было связано с реальным приложением, вы бы хотели рассмотреть возможность передачи точного времени, когда пользователь фактически сделал запрос, чтобы избежать расхождений из-за задержки.

                  Во время триггера обновления объект NEW представляет, какие значения будет содержать строка в случае успешного обновления. Вы можете использовать триггер для «перехвата» вставки или обновления, просто назначив свои собственные значения объекту NEW. Объект OLD содержит значения строки перед обновлением.

                  Посмотрим, работает ли это! Я добавил второго пользователя по имени Даниэль, который будет редактором тайм-панчей Медведя.

                  select punch_time
                  from time_punch
                  where id=2;
                  punch_time      
                  ---------------------
                   2020-01-01 11:30:00
                  (1 row)

                  Я собираюсь запустить запрос ниже дважды, чтобы смоделировать 2 редактирования, которые увеличат время на 5 минут.

                  update time_punch set punch_time = punch_time + interval '5 minute', change_employee_id = 2 where id = 2;

                  А вот таблица аудита, отражающая прошлые времена ударов:

                  change_time         | username |     punch_time      
                  ----------------------------+----------+---------------------
                   2021-01-06 20:10:56.44116  | Daniel   | 2020-01-01 11:35:00
                   2021-01-06 20:10:55.133855 | Daniel   | 2020-01-01 11:30:00

                  Дополнительные сведения о триггерах

                  Есть несколько вещей, которых следует опасаться при работе с триггерами базы данных:

                  1. Поддержание триггеров с течением времени
                  2. Логика подключенного триггера
                  3. Опыт разработчиков

                  Поддержание триггеров с течением времени. Бизнес-логика в коде приложения, естественно, документируется, поскольку она изменяется с течением времени посредством git или другой системы контроля версий. Разработчику легко увидеть некоторую логику в кодовой базе, сделать быстрый git log и увидеть список изменений.

                  Управление изменениями с течением времени с помощью триггеров и функций SQL является более сложным, менее стандартизированным и требует большего внимания и планирования.

                  Подключенная логика триггера. Триггеры также могут запускать другие триггеры, быстро усложняя результаты того, что может показаться невинным INSERT или UPDATE. Этот риск также присущ коду приложения с побочными эффектами.

                  Опыт разработчиков. Осведомленность о триггерах также намного ниже среди некоторых кругов разработчиков, поэтому их внедрение увеличивает инвестиции в обучение, которое потребуется новым разработчикам для успешной работы над вашим проектом.

                  SQL изначально может быть неуклюжим и разочаровывающим языком для изучения, поскольку многие шаблоны, которые вы изучаете для построения запроса, «наизнанку» отличаются от того, как вы извлекаете данные на процедурном языке.

                  Использование триггеров для повышения уровня вашей игры в SQL

                  Я надеюсь, что эти примеры помогли вам лучше понять триггеры базы данных. Я добился больших успехов, используя триггеры для проблем с данными, где прослеживаемость, согласованность и точность имеют первостепенное значение.

                  Решение о внедрении триггеров в ваше приложение должно приниматься после тщательного обдумывания, и я, например, надеюсь, что вы получите возможность реализовать и изучить одну из самых забавных и интригующих функций SQL!

                  Если вы заинтересованы в дальнейшем улучшении своих навыков SQL, рассмотрите возможность проверить Arctype. Arctype — это современный редактор SQL, предназначенный для упрощения процесса работы с базами данных и SQL. Присоединяйтесь к нашему растущему сообществу и загрузите Arctype сегодня.

                  Триггеры — это объекты базы данных в SQL Server. Технически они представляют собой особый класс вызовов функций, которые реагируют на определенные операции с базой данных.

                  Это важное руководство предоставит вам подробную информацию о триггерах SQL, которая может оказаться весьма полезной в вашей профессии. Давайте начнем!

                  Слово «триггер» описывает утверждение, что сервер автоматически выполняет запрос каждый раз, когда содержимое базы данных изменяется.

                  Триггер — это группа SQL-запросов со специальными именами, которые хранятся в памяти. Это особый тип вызова функции, который немедленно вызывается всякий раз, когда происходит какое-либо событие базы данных. Каждому триггеру назначена таблица.

                  Например, триггер может активироваться всякий раз, когда в определенную таблицу добавляется новый столбец или если изменяются определенные записи.

                  Согласно Microsoft Developer Network, триггеры представляют собой особый класс хранимых процедур. В операторе триггера мы сначала определяем, когда должен запускаться триггер, а затем указываем действие, которое должно быть выполнено после активации триггера.

                  Синтаксис:

                  CREATE TRIGGER trigger_name
                  BEFORE/AFTER
                  INSERT/UPDATE/DELETE
                  ON tableName
                  FOR EACH ROW SET operation [trigger_body];

                  Объяснение каждого параметра

                  • CREATE TRIGGER trigger_name — используется для создания триггера или для изменения имени существующего триггера.
                  • ДО/ПОСЛЕ — этот запрос используется для определения времени выполнения триггера (до или после определенного события).
                  • INSERT/UPDATE/DELETE — описывает действие, которое мы хотим выполнить над таблицами.
                  • ON tableName — здесь мы определяем имя таблицы для настройки триггера.
                  • ДЛЯ КАЖДОЙ СТРОКИ — этот оператор относится к триггеру строки, что означает, что триггеры будут выполняться всякий раз, когда строка изменяется.
                  • trigger_body — указывает действие, которое должно быть выполнено при срабатывании триггера.

                  Триггеры — это сохраненные функции с отличительными идентификаторами, которые позволяют нам повторно использовать запросы, которые уже были выполнены и надежно сохранены в памяти. Теперь попробуем понять, зачем они нужны SQL.

                  Триггеры в основном используются для регулирования развертывания кода всякий раз, когда происходит событие. Иными словами, использование триггеров является идеальным выбором, если вам требуется, чтобы определенный фрагмент кода постоянно запускался в ответ на определенное событие.

                  Ниже приведены некоторые преимущества использования триггеров в операциях базы данных SQL.

                • Выполняет дополнительные проверки при вставке, обновлении или удалении данных из затронутой таблицы.
                • Сокращает время отклика, что способствует увеличению вычислительных затрат.
                • Позволяет кодировать сложные параметры по умолчанию, которые недоступны из-за начальных ограничений.
                • Ссылочная целостность является ключевым свойством систем реляционных баз данных. Это означает, что данные, хранящиеся в системе баз данных, всегда должны быть точными для каждой транзакции и каждой операции.

                  Если две таблицы расположены в разных базах данных или системах, невозможно обеспечить проверку данных в них с помощью значений ограничений. В такой ситуации триггеры — единственный вариант исполнения.

                  Комбинация триггерных аргументов

                  Для каждой таблицы мы можем указать шесть различных типов триггеров. Это комбинация аргументов триггера, включенных в триггеры уровня строки SQL.

                  BEFORE INSERT: Эти триггеры выполняют действие над строками перед выполнением любых операций INSERT в указанной таблице или в базе данных.

                  ПОСЛЕ ВСТАВКИ: он выполняет действие над строками сразу после любого действия INSERT базы данных.

                  ПЕРЕД ОБНОВЛЕНИЕМ: с помощью этих триггеров функция в строках выполняется до выполнения действия ОБНОВЛЕНИЕ в базе данных.

                  ПОСЛЕ ОБНОВЛЕНИЯ: он выполняет действие над строками сразу после любого действия ОБНОВЛЕНИЯ базы данных или конкретной таблицы.

                  ПЕРЕД УДАЛЕНИЕМ: он выполняет определенную операцию над строками еще до того, как база данных или таблица будут подвергнуты действию DELETE.

                  ПОСЛЕ УДАЛЕНИЯ: Эти триггеры выполняют действие над строками после каждой транзакции УДАЛЕНИЯ.

                  Типы триггеров SQL

                  Триггеры SQL — это сохраненные функции, которые запускаются немедленно при возникновении определенных событий. Это напоминает планирование, управляемое событиями. Последующие ситуации могут запускать выполнение триггеров.

                  Триггеры DML — DML расшифровывается как язык манипулирования данными. Выполнение кода в ответ на изменение данных стало возможным с помощью триггеров DML. Этот триггер активируется при выполнении команд DML, таких как INSERT, UPDATE и DELETE. Их также называют «триггерами уровня таблицы».

                  Триггеры DDL — DDL означает язык определения данных. Триггеры DDL позволяют нам запускать код в ответ на изменения схемы базы данных, такие как добавление или удаление таблиц, или события сервера, такие как регистрация пользователя. Они называются «триггерами уровня базы данных».

                  Эти триггеры можно активировать, когда определенные операторы DDL, такие как CREATE, ALTER или DROP, выполняются в активной базе данных. Их также можно использовать для наблюдения и управления выполняемыми действиями.

                  Триггеры входа в систему — всякий раз, когда происходит какое-либо событие входа в систему (запуск, вход в систему, выход из системы, завершение работы), немедленно активируются триггеры входа в систему. Они выполняются только после процесса аутентификации пользователя, даже до того, как транзакция пользователя будет инициирована. Триггеры LOGON не сработают в случае сбоя авторизации.

                  Эти триггеры можно использовать для записи истории входа в систему или установки ограничения событий для определенного входа в систему, а также других функций аудита и управления идентификацией для подключений к серверу.

                  Триггеры CLR — CLR расшифровывается как Common Language Runtime. Триггеры CLR действительно представляют собой уникальное подмножество триггеров, построенных в основном на CLR в рамках технологии .NET. Эти триггеры полезны, если триггеру необходимо выполнить множество вычислений или он должен быть связан с сущностью, отличной от SQL.

                  Триггеры DML и DDL действительно можно создать, включив кодирование поддерживаемых триггеров CLR в технологиях .NET, включая Visual Basic, C# и F-sharp.

                  Пример триггера SQL Server

                  Давайте разберемся с этими концепциями триггеров на примере.

                  Во-первых, давайте создадим базу данных с помощью операторов SQL.

                  CREATE DATABASE testdb;
                  use testdb;

                  Здесь я дал «testdb» в качестве имени базы данных. И следующим шагом будет создание таблицы.

                  CREATE TABLE student(
                    name varchar(25),
                    id int(2),
                    maths int(2),
                    physics int(2),
                    biology int(2),
                    social int(2),
                    total int(2)
                   );

                  Я создал таблицу для хранения данных о студентах. А вот и команда для описания структуры таблицы. Здесь «студент» — это имя таблицы, которое я дал.

                  DESC student;

                  Ниже представлена ​​структура таблицы, которую я создал.

                  +---------+-------------+------+-----+---------+-------+
                  | Field   | Type        | Null | Key | Default | Extra |
                  +---------+-------------+------+-----+---------+-------+
                  | name    | varchar(25) | YES  |     | NULL    |       |
                  | id      | int         | YES  |     | NULL    |       |
                  | maths   | int         | YES  |     | NULL    |       |
                  | physics | int         | YES  |     | NULL    |       |
                  | biology | int         | YES  |     | NULL    |       |
                  | social  | int         | YES  |     | NULL    |       |
                  | total   | int         | YES  |     | NULL    |       |
                  +---------+-------------+------+-----+---------+-------+
                  7 rows in set (0.00 sec)

                  После создания таблицы следующим шагом будет настройка триггера. Давайте попробуем использовать аргумент BEFORE INSERT.

                  Название созданного мной триггера — «метки». Как только в таблицу вносятся оценки учащегося, нижеприведенный триггер пытается автоматически определить общую оценку учащегося.

                  CREATE TRIGGER marks
                  BEFORE INSERT
                  ON
                  student
                  FOR EACH ROW
                  set new.total=new.maths+new.physics+new.biology+new.social;

                  Поскольку нам требуется заменить данные строк, а не работать со старыми, мы определили «итого» с помощью нового имени класса, а все последующие выражения имеют префикс с новыми ключевыми словами после итога с помощью оператора точки. Теперь мы добавим значения в каждую строку и посмотрим на результаты. Изначально общая оценка равна 0 для каждого ученика.

                  INSERT INTO student VALUES("George",02,99,87,92,91,0);
                  INSERT INTO student VALUES("James",03,91,81,94,90,0);
                  INSERT INTO student VALUES("Harry",04,86,70,73,88,0);
                  INSERT INTO student VALUES("John",05,73,89,78,92,0);
                  INSERT INTO student VALUES("Lisa",01,94,75,69,79,0);
                  

                  В этом случае оператор триггера будет автоматически запускаться при вставке данных в таблицу учеников. Триггер подсчитывает общие оценки каждого учащегося. Теперь давайте посмотрим, вызывается ли триггер с помощью инструкции SELECT.

                  SELECT * FROM table_name;

                  И вот окончательный вывод.

                  mysql> select * from student;
                  +--------+------+-------+---------+---------+--------+-------+
                  | name   | id   | maths | physics | biology | social | total |
                  +--------+------+-------+---------+---------+--------+-------+
                  | George |    2 |    91 |      81 |      94 |     90 |   356 |
                  | James  |    3 |    86 |      70 |      73 |     88 |   317 |
                  | Harry  |    4 |    73 |      89 |      78 |     92 |   332 |
                  | John   |    5 |    94 |      75 |      69 |     79 |   317 |
                  | Lisa   |    1 |    99 |      87 |      92 |     91 |   369 |
                  +--------+------+-------+---------+---------+--------+-------+
                  5 rows in set (0.00 sec)

                  В приведенном выше результате вы можете видеть, что все предметные оценки автоматически добавляются для каждого учащегося. Итак, мы можем сделать вывод, что триггер был успешно вызван.

                  Дополнительные триггерные операции

                  Мы можем выполнять множество операций с помощью триггеров. Некоторые из них могут быть простыми, а некоторые могут быть немного сложными, но как только мы пройдемся по запросам, их будет легко понять. Используя операторы Transact-SQL, вы можете включать, отключать или удалять триггеры с помощью следующих команд.

                  Запрос, чтобы проверить, существует ли конкретный триггер или нет

                  Эта команда проверяет указанный триггер во всей базе данных.

                  SELECT * FROM [sys].[triggers] WHERE [name] = 'Trigger_name'

                  Запрос для отображения триггеров

                  Все триггеры, доступные в активной базе данных, будут показаны следующим оператором.

                  SHOW TRIGGERS;

                  Запрос на отключение триггера

                  Приведенная ниже команда деактивирует триггер в рабочей базе данных.

                  DISABLE TRIGGER trigger_name ON DATABASE;

                  Вы также можете указать определенное имя таблицы, чтобы отключить триггер.

                  DISABLE TRIGGER trigger_name ON table_name;

                  Запрос для включения триггера

                  Следующая команда сначала деактивирует определенный триггер, который был определен для указанной таблицы в активной базе данных, а затем повторно включает его.

                  ALTER TABLE table_name DISABLE TRIGGER trigger_name
                  
                  ALTER TABLE table_name ENABLE TRIGGER trigger_name

                  Триггер должен быть отключен, прежде чем пытаться его включить,

                  Запрос для включения или отключения всех триггеров в таблице

                  Используя приведенный выше оператор SQL, мы можем деактивировать или активировать все триггеры таблицы одновременно, подставив «ALL» вместо определенного имени триггера.

                  ALTER TABLE table_name DISABLE TRIGGER ALL 
                  
                  ALTER TABLE table_name ENABLE TRIGGER ALL

                  Запрос на удаление или удаление триггера

                  Триггер можно устранить, удалив его или всю таблицу. Каждый связанный триггер также удаляется при удалении таблицы.

                  DROP TRIGGER [trigger_name];

                  Всякий раз, когда триггер удаляется, связанные с ним данные удаляются из таблицы данных sys.objects.

                  Преимущества триггеров

                  • Создать триггеры просто, и сам триггер может вызывать сохраненные функции и методы.
                  • Пользователи могут реализовать простой аудит с помощью триггеров.
                  • К сожалению, вы не можете создавать ограничения для сущностей в системах баз данных с помощью SQL Server, хотя вы можете эмулировать действие ограничений, используя триггеры.
                  • Ограничения целостности могут быть реализованы в базах данных с помощью триггеров.
                  • Когда требуется групповая проверка, а не построчная проверка вновь введенных или измененных данных, могут быть полезны триггеры.

                  Недостатки триггеров

                  Триггеры SQL могут быть не лучшим выбором в некоторых ситуациях из-за их ограничений.

                  • Триггеры должны быть точно задокументированы.
                  • Из-за одновременного выполнения базы данных, которая может быть недоступна для компонентов приложения, отладка триггеров может быть сложной.
                  • Операторы DML усложняются при использовании триггеров.
                  • Даже незначительная проблема с триггером может привести к логическим ошибкам в заявлении.

                  Вывод

                  Триггеры — очень полезные компоненты Transact-SQL и SQL, и их можно использовать и в Oracle. Использование триггеров имеет решающее значение при вызове хранимых методов. Эти триггеры SQL позволяют нам анализировать временные рамки активности и определять, как реагировать на них, если это необходимо. Мы также можем проверить наличие определенной таблицы, которая подключена к триггеру для получения данных.

                  Рекурсия может быть включена с помощью триггеров. Всякий раз, когда триггер в таблице выполняет команду в родительской таблице, срабатывает вторая итерация триггера, и это называется рекурсивным триггером. Это помогает при попытке решить корреляцию идентичности.

                  Кроме того, триггеры регулируют шаблон обновления, который разрешено принимать базе данных. Крайне выгодно сохранять ограничения целостности данных в системе баз данных, если ключи ограничения SQL не существуют, в основном первичный ключ и внешний ключ.

                  Я надеюсь, что вы нашли эту статью полезной для изучения триггеров SQL.

                  Если вы хотите подробно изучить базы данных, вот несколько отличных ресурсов для изучения SQL и NoSQL.

                  # Триггеры

                  Триггеры предоставляют самый мощный функционал в боте. Вы можете настроить любую реакцию на любое сообщение пользователей.

                  Желать доброго утра админам (или любым конкретным пользователям), по утрам, если они зайдут в беседу? – Не вопрос.

                  При отправке пользователями gif’ок вежливо попросить её удалить в течение минуты, и если он это не сделает – удалить гифку и выдать предупреждение, а если сделает – написать «спасибо за понимание»? – Пожалуйста.

                  Отправлять в чат «Хозяин, вас звали!» с ссылкой на ваш профиль, когда вас упоминают в группе? – Да, и такое возможно.

                  Основная функция триггера – определенное УСЛОВИЕ, и при его выполнении, происходит определенное ДЕЙСТВИЕ, которое вы задаете сами.

                  # Тарифы на триггеры

                  Данная таблица рассказывает о различиях тарифов на триггеры. Лимита на группы условий/группы действий нет – вы можете создать 6 групп действий, в каждой из которой будет по одному действию, или 1 группу действий с шестью действиями для тарифа «Starter».

                  Если вы выйдете за лимиты триггера или истечет срок тарифа – (появится красная надпись, уведомляющая о том, что превышено количество триггеров или действий в них) триггеры будут работать, с ограничениями. Например, если вы создали 4 действия без тарифа, работать будут три. Также и количество триггеров – если будет больше, чем возможно, остальные просто не будут работать.

                  # Навигация по триггерам

                  Заходим в раздел «Триггеры чата», нажимаем на «+ Добавить новый»

                  Далее, выйдет окно с условиями создания триггера:

                  Задаем название триггеру.

                  Подсказка

                  Старайтесь назвать триггер так, чтобы его было легко найти и редактировать среди других.

                  # Тип выполнения триггера

                  «Выполнить все действие» — это значит, что за определенное условие, будет выполнены все указанные и заданные вами далее действия. (В том случае, если вы укажете несколько действий)

                  «Выполнить случайную группу действий» — в этом случае, за определенное условие, будет выбрана группа из нескольких выбранных вами действий в случайном порядке.

                  «Условия» — это определенные сообщения, слова, смайлы, после совершения которых применяются определенные действия.

                  «Действия» — это определенные реакции на заданные условия, действием может быть ограничение каких-либо действий участника чата, предупреждение, исключение из чата или удаление данного сообщения.

                  # Отработка триггеров

                  Отработка триггеров происходит поочередности.
                  На картинке ниже выделен красным номер, по которым идет очередь срабатывания триггеров

                  Чтобы триггеры работали подряд по порядку необходимо включить тумблер «Продолжить выполнение цепи триггера по окончании текущего триггера» в расширенных настройках, доступных с тарифа «Advanced»

                  Если тумблер выключен, то сработает только один триггер, тот, который с меньшим номерком.

                  # Условия триггеров

                  Создаем условия с помощью «+», открывается отдельное окно «Группа условий» и снизу отдельная кнопка «+». Нажимая на отдельную кнопку, создается еще одна группа условий с отдельными функциями.

                  Подсказка

                  В инструменте «Действия» функционал такой же.

                  # Типы условия:

                  Всего 18 условий, 4 инициатора, 8 типов сообщений и 6 фильтров для условий на текст сообщения.

                  # Полное совпадение

                  Триггер сработает при полном совпадении сообщения с указанным Вами значением в условии. То есть, если укажете в условии «Привет», условие выполнится только при сообщении «Привет». Если будет «Привет. Знаешь…», или «Привет.», или «Привет)» условие НЕ выполнится. *Исключение в том случае, если включить фильтр «Не учитавать символы» ниже, тогда последние два варианта бот пропустит.

                  # Сообщение начинается с

                  Триггер сработает, если сообщение пользователя будет начинаться со строк (слов/выражений), указанных вами в значениях условия. Пример: в значених «Ты». Условие сработает на сообщения: «Ты – самый вредный!», «Тыквы полезные!», «Ты123абв»

                  # Сообщение заканчивается на

                  Триггер сработает, если сообщение пользователя будет заканчиваться строками (словами/выражениями), указанными вами в значениях условия, иначе триггер не сработает. Аналогично: если в условии «ейка», оно сработает на «лейка», «абвгдейка».

                  # Сообщение содержит

                  Триггер сработает, если в сообщении будет присутствовать хоть одна из строк (слов/выражений), указанных в значениях условий. Укажете «лето» — сработает на «Какое лето жаркое!», «В кассе билетов нет!»

                  # Регулярное выражение

                  Самое мощное условие, самое сложное. Однако если вы овладеете регулярными выражениями – получите нескончаемый функционал для вашего бота. С помощью этого инструмента можно составлять любые условия на текст пользователя! При должной настройке оно может заменить шесть условий в триггерах и в какой-то мере большинство текстовых фильтров.

                  Выполняет поиск на основе регулярного выражения языка Java. Тестер и краткий справочник по регулярным выражениям доступен по нажатию кнопки «Помощь» в верхней панели. Также есть небольшая статья, посвященная регулярным выражениям в инструкции.

                  # Длина сообщения меньше или равна

                  Триггер сработает, если длина сообщения будет меньше или равна указанному вами количеству символов. Можно включить/отключить подсчёт пробелов.

                  # Длина сообщения больше или равна

                  Триггер сработает, если длина сообщения будет больше или равна указанному вами количеству символов. Можно включить/отключить подсчёт пробелов.

                  # Тип сообщения

                  Доступно 13 видов сообщений, выберите те, на которые сработает триггер. Например, если поставить фото, то каждый раз когда участники будут присылать фото, условие будет выполняться.

                  # Регулярное выражение на меньшинах в сообщениях

                  Регулярное выражение, срабатывающее на логин (@username), написанный в чат в сообщениях пользователей. Значения указывать так: (username), обязательно в нижнем регистре. О работе с регулярными выражениями можно ознакомиться в инструкции. Тестер и краткий справочник по регулярным выражениям доступен по нажатию кнопки «Помощь» в верхней панели.

                  # Регулярное выражение на текстовых меньшинах в сообщениях

                  В официальном клиенте Telegram’а при написании символа «@» в чат появляется список недавних участников:

                  Если юзернейм у пользователя есть, то кликнув по пользователю вы получите его @username. Если юзернейма нет, то по клику вы получите его кликабельный никнейм. Например, ник пользователя – Tania Pupkina. У вас после нажатия будет слово Tania с ссылкой на её профиль. Вот это условие срабатывает на такие слова. В значениях указывать это слово (например Tania), оформленное как регулярное выражение, например «(Tania)». О работе с регулярными выражениями можно ознакомиться в инструкции. Тестер и краткий справочник по регулярным выражениям доступен по нажатию кнопки «Помощь» в верхней панели.

                  # Регулярное выражение на номерах телефонов

                  Срабатывает на номер телефона (оформленный как регулярное выражение), на который был зарегистрирован аккаунт Telegram. Телефонный номер указывать в международном формате без плюса. Возможно использовать только когда пользователь отправил свои контакты боту.

                  # Язык клиента

                  Условие на основе выбранного языка клиента Telegram (установленный язык в приложении Telegram). Значения указывать по типу: ru, en, ua. Ввиду особенностей Telegram’а, если в приложении выставлен язык русский, срабатывает на значения en и ru, поэтому будьте аккуратны с этим. Со значениями, которые можно указывать в качестве языка клиента, Вы можете ознакомиться здесь.

                  # Регулярное выражение на логине пользователя

                  Возможность сделать срабатывание условия для конкретного пользователя по его юзернейму. Обычно работает в сочетаниях с другими условиями в одной группе действий. Значения указываются таким образом: ^(username1)$, ^(username2)$ ИЛИ ^(username1|username2)$, обязательно в нижнем регистре. О работе с регулярными выражениями можно ознакомиться в инструкции. Тестер и краткий справочник по регулярным выражениям доступен по нажатию кнопки «Помощь» в верхней панели.

                  # Минимальная длина логина

                  Можете указать минимальное количество символов которое будет содержаться в логине пользователя (@username пользователя). Если логин будет содержать меньше указанных вами символов, сработает действие. Минимально возможная длина логина в Telegram – 5, максимально возможная – 32.

                  # Максимальная длина логина

                  Можете указать максимальное количество символов которое будет содержаться в логине пользователя. Если логин будет содержать больше символов что вы указали, то сработает действие. Минимально возможная длина логина в Telegram – 5, максимально возможная – 32.

                  # Регулярное выражение на имени пользователя

                  Возможность сделать условие для конкретного пользователя по его никнейму. Обычно работает в сочетаниях с другими условиями в одной группе действий. Значения указываются таким образом: ^(ник этого пользователя)$ ИЛИ ^(имя1 фамилия1|имя2 фамилия2)$, обязательно в нижнем регистре. О работе с регулярными выражениями можно ознакомиться в инструкции. Тестер и краткий справочник по регулярным выражениям доступен по нажатию кнопки «Помощь» в верхней панели.

                  # Минимальная длина имени

                  Можете указать минимальное количество символов, которое будет содержаться в имени пользователя. Если имя пользователя будет содержать меньше символов, чем было указано, то триггер сработает.

                  # Максимальная длина имени

                  Можете указать максимальное количество символов, которое будет содержаться в имени пользователя. Если имя пользователя будет содержать больше символов что вы указали, то триггер сработает.

                  # Ранг пользователя соответствует

                  Укажите желаемое количество рангов и на участника с соответствующими рангами сработает триггер.

                  # Ранг пользователя ниже

                  Задайте минимальное количество рангов, на участника с показателем рангов меньше указанных, сработает триггер.

                  # Ранг пользователя выше

                  Задайте максимальное количество рангов, на участника с показателем рангов больше указанных, сработает триггер.

                  Ранг – это текущий статус участника в чате. Ранги даются за выполнение определенных действий, которые устанавливает администратор чата.

                  # Следующий инструмент «Фильтр условия»

                  Рассмотрим подробнее:

                  1. Не учитывать пробелы в начале и в конце строки — вне зависимости от того, будут или нет пробелы в начале или в конце строки в сообщении пользователя, триггер сработает.
                  2. Не учитывать пробелы и переносы строк — вне зависимости от того, как и где стоят пробелы и переносы в сообщении пользователя, триггер сработает. Например, с условием «Сообщение содержит», при включенном фильтре, если в значениях указать «громила», триггер сработает на: «Полный погроми ладно – потом уберу»
                  3. Не учитывать все пробелы — условие выполнится вне зависимости от того, как и где стоят пробелы в сообщении пользователя. Например, с условием «Сообщение содержит», при включенном фильтре, если в значениях указать «перламутр», сработает на «Спер лам утром», но не будет работать с переносами, как в пункте (2)
                  4. Не учитывать символы — условие сработает, даже если будут использованы символы, которые вы не указали в условии. Укажете в значениях «свет» — триггер сработает на «с()вет»
                  5. Не учитывать цифры — триггер сработает даже если будут использованы цифры, которые вы не указали в условии. В значениях «пора» — сработает на «по95ра»
                  6. Не учитывать регистр — триггер сработает вне зависимости от регистра (большие и маленькие буквы будут восприниматься одинаково). Пример: «Привет» в значениях сработает на «привет», «ПРИВЕТ», «пРиВеТ», и так далее.

                  # Инструмент «Инициатор триггера»

                  Инициатор триггера – участник группы, на которого будет срабатывать триггер.

                  • Кто угодно – условие сработает на всех участников группы
                  • Администраторы – условие сработает на всех администраторов, включая создателя
                  • Пользователи – условие сработает на всех пользователей, кроме администраторов
                  • Создатель – условие сработает только на создателя

                  Предупреждение

                  Под администраторами понимаются участники группы, которые способны изменять настройки бота, а не администраторы чата.

                  # Инструмент «Тип сообщения»

                  Любое – условие сработает при любом сообщении;

                  Все реплаи – условие сработает только на реплаи (ответы);

                  Реплаи к боту – условие сработает только на ответы ботов;

                  Реплаи к пользователю – условие сработает только на ответы пользователей, кроме администраторов;

                  Реплаи к админу – условие сработает только на ответы администраторов;

                  Предупреждение

                  Под администраторами понимаются участники группы, которые способны изменять настройки бота, а не администраторы чата.

                  Реплаи к @ChatKeeperBot – условие сработает на ответы к сообщениям от @ChatKeeperBot;

                  Не реплай – условие сработает на сообщения, которые были отправлены не реплаем (ответом);

                  Первое сообщение пользователя – условие сработает при первом сообщении нового участника.

                  # Инструмент «Инвертирование»

                  Инвертирование меняет все условия на обратные. Если условие должно было сработать на слово «Привет» — условие будет работать на все сообщения, в которых нет этого слова. Если стоит «Реплаи к @ChatKeeperBot» – условие будет срабатывать на все сообщения, которые не являются реплаями (ответами) к @ChatKeeperBot. Не меняются при инвертировании только фильтры условий, инициатор «Кто угодно» и тип сообщения «Любое».

                  # Действия триггеров

                  • Отправить сообщение
                    При выполнении условия, будет отправлено сообщение, текст которого вы ввели в поле ввода текста, после выбора действия;

                  • Отправить личным сообщением
                    Бот отправит текст в личные сообщения пользователю. Список получателей такого сообщения находится после выбора действия – туда можно указать @username (можно со знаком и без, в любом регистре) или ID пользователя. Чтобы сообщение отправилось, пользователю необходимо нажать на кнопку start в личных сообщениях с ботом. *Не забывайте, что бот первым писать не может;

                  • Удалить пользователя из чата с возможностью вернуться
                    Пользователь будет удален из чата, но он сможет вернуться при использовании команды /kick;

                  • Удалить пользователя из чата на время
                    Пользователь будет удален из чата на заданный вами период времени, по истечении этого времени, у пользователя есть возможность вернуться в чат;

                  • Пользователь не сможет писать
                    Пользователь не сможет писать в течении заданного вами периода времени, по истечении этого периода, пользователь сможет писать, использовав команду /mute;

                  • Разрешить пользователю вернуться в чат
                    Пользователь может вернуться в чат, если до этого он был исключен, для возврата в чат используйте команду /unban;

                  • Разрешить пользователю писать
                    Пользователь сможет писать сообщения, если до этого он был заблокирован, используйте команду /unmute;

                  • Удалить сообщение
                    Сообщение, на которое сработал триггер будет удалено;

                  • Увеличить или уменьшить репутацию пользователю
                    Действие дает возможность изменить репутацию участника в положительную или отрицательную сторону. После выбора действия будет форма «Количество», в которой вы зададите прибавление или отнятие репутации;

                  • Изменить количество очков пользователя
                    Действие дает возможность изменить количество очков участника. После выбора действия будет форма «Количество», в которой вы зададите прибавление или отнятие очков;

                  • Добавить или удалить предупреждение у пользователя
                    Возможность добавить пользователю определённое количество предупреждений, работает по принципу команды /warn;

                  • Добавить или удалить предупреждение в триггере
                    В данном триггере можно добавить или отнять количество предупреждений. *После заданного администратором количества предупреждений, пользователь попадает в блок;

                  • Отправить результат формы в чат
                    (действие доступно на тарифах Advance и Ultimate)
                    После того, как участник заполнил форму, результат формы отправится в чат и будет доступен для просмотра всем пользователям. После выбора действия, в поле ввода текста можно будет написать содержимое формы;

                  • Отправить результат формы личным сообщением — (действие доступно на тарифах Advance и Ultimate)
                    После того, как участник заполнил форму, результат формы отправится в личные сообщения указанным пользователям.
                    Список получателей результата указывается после выбора действия в форму «Список пользователей, которым придет результат формы».
                    Указывается юзернейм без знака @ в малом регистре, например «username» или ID пользователя.
                    Чтобы сообщение отправилось, пользователю необходимо нажать кнопку start в личных сообщениях с ботом.
                    Таким образом, результат формы будет доступен только определённым пользователям.
                    Форму можно задать в инструменте «Открыть расширенные настройки» под формой названия триггера.

                  Понравилась статья? Поделить с друзьями:

                  А вот и еще наши интересные статьи:

                • Апу химки официальный сайт руководство
                • Главное управление вооружения вооруженных сил российской федерации руководство
                • Прокуратура города белгорода руководство
                • Руководство для бариста
                • Junsun видеорегистратор зеркало инструкция на русском языке

                • 0 0 голоса
                  Рейтинг статьи
                  Подписаться
                  Уведомить о
                  guest

                  0 комментариев
                  Старые
                  Новые Популярные
                  Межтекстовые Отзывы
                  Посмотреть все комментарии