Конструктор команд

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

Флоу может запускаться:

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

Важно: конструктор не создаёт slash-команды. Команды запускаются как обычные сообщения с префиксом, например r!hello.

Как создать флоу

Откройте страницу «Конструктор».

Управлять флоу могут:

  • владелец сервера;
  • участники с разрешением Discord Администратор;
  • участники с разрешением Управлять сервером.

Чтобы создать флоу:

  1. Нажмите Новый флоу — откроется экран С чего начнём?.
  2. Выберите готовый сценарий или нажмите на способ запуска в разделе «Начать с нуля».
  3. Готовый сценарий сразу расставит блоки и откроет первый шаг, который нужно дополнить своими данными — обычно это ID роли или канала.
  4. «Начать с нуля» задаёт только запуск: если это команда, введите её имя — префикс сервера подставится сам.
  5. Добавьте остальные блоки, соедините их и заполните обязательные поля.
  6. Проверьте граф кнопкой Прогнать.
  7. Включите флоу кнопкой Включить.

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

Если флоу пока не должен запускаться:

  1. вернитесь в список флоу;
  2. выключите его кнопкой питания;
  3. после настройки снова откройте и опубликуйте.

Статусы и сохранение

Общего переключателя для всего конструктора нет. Каждый флоу включается и выключается отдельно.

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

Изменения активного флоу после сохранения сразу становятся рабочими.

Выключенный флоу остаётся черновиком до публикации.

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

Изменение имени триггера

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

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

Основные настройки

ПараметрГде изменяетсяЗначение по умолчаниюОписание
Имя триггераПри создании и в верхней части редактораcmd_ без имени командыОпределяет команду или событие, которое запускает граф.
СтатусВ карточке флоу или кнопкой ОпубликоватьНовый флоу активенОпределяет, может ли бот запускать флоу.
Префикс команд«Сервер»r!Используется для всех команд, созданных в конструкторе.
Стартовый блокНа холстеВ новом флоу — СообщениеПервый блок, с которого начинается выполнение.
Обработка ошибкиКрасный выход блокаНе подключенаПозволяет продолжить граф по отдельной ветке при ошибке.

В графе должен быть только один стартовый блок — блок без входящего соединения.

Несколько несвязанных стартовых блоков сохранить нельзя.

Команда в чате

При создании команды указывается только её имя.

Например, если имя команды — hello, а префикс сервера — r!, участники вызывают её так:

r!hello

Имя команды может содержать:

  • строчные латинские буквы;
  • цифры;
  • символ _.

Допустимая длина — от 1 до 32 символов.

Внутри системы такая команда называется cmd_hello. Это название может отображаться:

  • в сообщениях об ошибках;
  • в экспортированном графе;
  • в переменной {trigger_name}.

Участникам вводить cmd_ не нужно.

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

Команду из конструктора может вызвать любой участник, который:

  • не является ботом;
  • может отправлять сообщения в канале.

Обычные настройки прав команд и дополнительные права staff-системы к таким командам не применяются.

Чтобы ограничить команду определённой ролью:

  1. добавьте в начало графа блок Права / роль;
  2. подключите защищённые действия к выходу да;
  3. подключите к выходу нет сообщение об отказе или другой завершающий блок.

Условие должно иметь обе ветки: да и нет.

События сервера

Действия других ботов не запускают флоу.

ТриггерКогда срабатываетДополнительные переменные
Вход участникаЧеловек входит на серверmember_count
Выход участникаЧеловек выходит, исключается или блокируетсяmember_count
Любое сообщениеОтправляется сообщение без префикса командыmessage_text, message_length
Вход в голосовойУчастник подключается к голосовому каналуchannel_id, channel_name
Выход из голосовогоУчастник полностью выходит из голосового каналаvoice_seconds
Реакция на сообщениеУчастник ставит реакциюmessage_id, emoji, emoji_id, channel_id
Буст сервераУчастник бустит серверboost_count, boost_level

Для события Выход участника нельзя определить, вышел ли пользователь самостоятельно, был исключён или заблокирован. Discord передаёт для этих случаев одно событие.

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

Канал для сообщений

У некоторых событий нет исходного текстового канала:

  • вход участника;
  • выход участника;
  • буст сервера;
  • голосовые события;
  • реакция на сообщение.

Если такой флоу содержит блок Сообщение, укажите в нём ID канала. Иначе бот не будет знать, куда отправить текст, и граф завершится ошибкой.

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

Задержка применения изменений

Часто срабатывающие триггеры могут обновляться с задержкой до 30 секунд:

  • Любое сообщение;
  • голосовые события;
  • Реакция на сообщение.

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

Переменные и плейсхолдеры

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

Привет, {user_name}!

Перед выполнением бот заменит плейсхолдер значением переменной.

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

Массивы и объекты вставляются в формате JSON, логические значения — как true или false.

Системные переменные

Эти переменные бот создаёт автоматически при каждом запуске.

ПеременнаяВ командахВ событияхЗначение
trigger_nameДаДаПолное имя триггера, например cmd_hello.
guild_idДаДаID сервера.
user_idДаДаID участника, вызвавшего флоу.
user_nameДаДаОтображаемое имя участника.
user_mentionДаДаУпоминание участника.
channel_idДаНе у всех событийID исходного канала.
argsДаНетАргументы команды в виде массива.
args_textДаНетАргументы команды одной строкой.

Остальные переменные зависят от выбранного события и указаны в таблице триггеров.

Защищённые имена переменных

Нельзя перезаписать:

  • guild_id;
  • user_id;
  • channel_id;
  • message_id;
  • trigger_name;
  • переменные с точкой, например loop.index, server.name и error.message.

Блоки работы с переменными отклонят такое имя, а флоу с ним не сохранится.

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

Такое поле поддерживают, в частности:

  • выдача и снятие роли;
  • кик;
  • начисление и списание очков;
  • paywall;
  • блоки уровней.

Локальные и глобальные переменные

ТипСрок храненияКак используется
localТолько во время одного запускаСоздаётся блоками и результатами действий.
globalМежду запусками и перезапусками ботаЗаписывается в базу данных и доступна всем флоу сервера.

Имена переменных:

  • могут содержать латинские буквы, цифры и _;
  • не могут начинаться с цифры;
  • не могут быть длиннее 64 символов.

Локальная переменная

Блок Локальная переменная поддерживает операции:

  • set — записать значение;
  • make_array — создать массив;
  • increment — увеличить числовое значение;
  • append — добавить элемент в массив.

set

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

  • число;
  • true или false;
  • массив;
  • объект.

Остальной текст сохраняется как строка.

make_array

Создаёт массив из:

  • JSON-массива;
  • значений, разделённых запятыми.

increment

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

Если переменная ещё не существует, её начальное значение считается равным нулю.

По умолчанию прибавляется 1.

append

Добавляет значение в конец массива.

Если переменная ещё не существует, сначала создаётся пустой массив.

Операции make_array и append поддерживают не больше 200 элементов.

Тип переменной

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

При операции set реальный тип всё равно определяется содержимым значения.

Для надёжного изменения типа существующей переменной используйте блок Преобразовать тип.

Глобальная переменная

Глобальные переменные поддерживают операции:

  • set;
  • increment.

Операция set сохраняет значение в базе данных, но не создаёт доступный плейсхолдер автоматически.

Чтобы использовать сохранённое значение дальше в графе, добавьте блок Прочитать из БД.

Операция increment:

  • изменяет значение в базе данных;
  • сразу создаёт локальную переменную с тем же именем и новым значением.

Удалить глобальную переменную через панель пока нельзя.

Блоки действий

БлокЗначения по умолчаниюЧто делает
СообщениеТекст пустой, ID канала пустойОтправляет сообщение длиной до 2000 символов.
Выдать рольID роли пустойВыдаёт роль участнику.
Снять рольID роли пустойСнимает роль с участника.
КикнутьПричина пустаяИсключает участника с сервера.
Задержка3 секундыПриостанавливает граф на срок от 1 до 300 секунд.
Случайное числоОт 1 до 10Создаёт случайное целое число в {random_result}.
Начислить очкиСумма пустаяНачисляет положительное количество очков и создаёт {new_balance}.
Статистика сервераБез настроекСоздаёт переменные со статистикой сервера.

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

Сообщение

Сообщение обрезается до 2000 символов.

Если ID канала не указан:

  • в команде сообщение отправится в канал вызова;
  • в событии без исходного канала граф завершится ошибкой.

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

Выдать или снять роль

Боту необходимо разрешение Управлять ролями.

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

Кикнуть

Боту необходимо разрешение Исключать участников.

Роль бота должна находиться выше роли участника.

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

Случайное число

Минимальное и максимальное значения включаются в диапазон.

Например, диапазон от 1 до 10 может вернуть как 1, так и 10.

Начислить очки

Сумма должна быть положительным целым числом. Вместо числа можно подставить переменную, заданную выше по цепочке, — например {random_result} из блока «Случайное число».

После выполнения новый баланс доступен в переменной:

{new_balance}

Статистика сервера

Блок создаёт переменные:

  • server.name;
  • server.member_count;
  • server.boost_level;
  • server.boost_count;
  • server.role_count;
  • server.channel_count;
  • server.owner_id;
  • server.age_days.

Условия и ветвление

Каждый блок условия должен иметь обе связи:

  • да;
  • нет.
БлокЗначения по умолчаниюЧто проверяет
СравнениеОператор >Сравнивает переменную с указанным значением.
Права / рольID роли пустойПроверяет наличие роли у участника.
Вероятность3%С заданной вероятностью переходит в ветку да.
Списать очкиСумма пустаяПытается атомарно списать очки.
SwitchВарианты yes,noВыбирает ветку по строковому значению переменной.

Сравнение

Если обе стороны можно преобразовать в числа, сравниваются числа.

Для операторов == и !=, если числовое преобразование невозможно, сравниваются строки.

Вероятность

Допустимое значение — от 0 до 100%.

  • 0 — ветка да никогда не выбирается;
  • 100 — ветка да выбирается всегда.

Списать очки

Списание выполняется как одна операция.

  • Выход да — очки успешно списаны.
  • Выход нет — у участника недостаточно очков, баланс не изменён.

Switch

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

Если совпадения нет, используется выход default.

Циклы

Обычные циклические соединения блоков на холсте запрещены.

Для повторения используйте:

  • Foreach;
  • While.

Блок цикла на холсте — контейнер. Шаги, лежащие внутри его рамки, и есть тело цикла: перетащите их туда из библиотеки блоков или прямо с холста, а порядок задайте перетаскиванием внутри контейнера. Отдельного порта «тело цикла» больше нет — наружу из контейнера ведёт единственный выход дальше, он же выход после цикла.

Чтобы вынести шаг обратно, перетащите его из контейнера на холст: он встанет в цепочку сразу после цикла.

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

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

Вложенность — часть формата самого флоу, а не только картинки в редакторе: тело цикла хранится списком шагов (children). Флоу, сохранённые раньше, конвертируются при первом открытии автоматически — ничего делать не нужно. Версия формата записана в поле schema_version.

Цикл Foreach

Блок Цикл Foreach перебирает элементы массива.

В поле Переменная-массив укажите имя переменной.

Поддерживаются:

  • настоящий массив;
  • строка с JSON-массивом;
  • строка со значениями через запятую.

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

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

  • {loop.item} — текущий элемент;
  • {loop.index} — индекс, начиная с нуля;
  • {loop.count} — общее количество элементов.

В конструкторе они подписаны по-русски — {текущий}, {номер} и {всего}, — но в текст шага и в сохранённый флоу подставляются под своими именами loop.*.

Один блок Foreach выполняет не больше 100 итераций.

Цикл While

Блок Цикл While проверяет условие перед каждой итерацией.

Поддерживаемые условия:

  • truthy;
  • falsy;
  • ==;
  • !=;
  • >;
  • <.

Внутри While доступна переменная:

{loop.index}

Она начинается с нуля.

Переменные {loop.item} и {loop.count} доступны только внутри Foreach.

Лимит итераций

Допустимый диапазон — от 1 до 100 итераций.

  • значение меньше 1 заменяется на 1;
  • значение больше 100 заменяется на 100.

Если цикл выполнил максимальное количество итераций и не был остановлен блоком Break или Return, он завершается ошибкой.

После последней разрешённой итерации условие повторно не проверяется.

Вложенные While

После завершения вложенного While текущая версия удаляет внешний {loop.index}.

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

Break и Return

Break

Блок Break завершает ближайший цикл и продолжает выполнение с выхода дальше.

Рекомендуется класть его непосредственно внутрь контейнера цикла.

Break вне цикла вызывает ошибку.

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

Return

Блок Return полностью останавливает выполнение флоу.

Указанное в нём значение сейчас не отправляется пользователю и не используется Discord-исполнителем.

Отложить продолжение

Блок Отложить продолжение останавливает текущий запуск и продолжает граф позднее.

Допустимая отсрочка:

  • от 1 секунды;
  • до 30 суток.

Состояние сохраняется на сервере и переживает перезапуск бота.

Это позволяет создавать сценарии вроде:

  • выдать роль через неделю после входа;
  • отправить напоминание через сутки;
  • продолжить цепочку через несколько дней.

Количество времени можно брать из переменной, например:

{cooldown}

Отличие от задержки

Задержка:

  • ждёт внутри текущего запуска;
  • ограничена 300 секундами;
  • расходует общий лимит времени выполнения.

Отложить продолжение:

  • сохраняет состояние отдельно;
  • может ждать до 30 суток;
  • переживает перезапуск бота.

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

Блок нельзя размещать:

  • внутри цикла;
  • внутри саб-флоу.

Состояние итератора или саб-флоу восстановить невозможно, поэтому такой граф будет отклонён.

К выходу блока должен быть подключён следующий блок.

Если продолжать нечего, отсрочка не имеет смысла.

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

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

Отложенное продолжение не выполнится, если флоу:

  • удалён;
  • выключен.

На одном сервере может одновременно храниться не больше 1000 ожидающих продолжений.

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

Тестирование отсрочки

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

Запись в очередь отложенных продолжений при этом не создаётся.

Саб-флоу

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

Чтобы создать саб-флоу:

  1. выделите связанные блоки;
  2. нажмите Саб-флоу;
  3. укажите имя;
  4. задайте входные параметры;
  5. укажите выходные переменные.

Выбранные блоки сохранятся внутри текущего графа и будут заменены одним блоком вызова.

Переменные саб-флоу

Саб-флоу видит локальные переменные вызывающего графа.

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

После завершения:

  • прежние значения восстанавливаются;
  • наружу передаются только объявленные выходные переменные.

Указанные типы входов и выходов во время выполнения не проверяются.

Общая глубина вложенных циклов и саб-флоу — не больше трёх.

Макросы

Кнопка Макрос сохраняет выделенный набор блоков как шаблон.

Макрос хранится только в локальном хранилище текущего браузера.

Он:

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

Саб-флоу, в отличие от макроса, сохраняется вместе с графом.

Custom Code

Блок Custom Code позволяет выполнять ограниченные вычисления над локальными и системными переменными.

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

score

а не:

{score}

Блок получает только JSON-совместимые значения.

Изменённые значения возвращаются в локальные переменные.

Доступные переменные

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

Переменные с точками недоступны, например:

  • server.name;
  • loop.item;
  • error.message.

Доступ к свойствам и элементам массивов запрещён.

Разрешённые возможности

Разрешены:

  • присваивания;
  • числа и строки;
  • массивы и объекты;
  • арифметика;
  • логические выражения;
  • сравнения;
  • условия if.

Запрещены:

  • импорты;
  • вызовы функций;
  • доступ к свойствам;
  • индексация, например items[0];
  • циклы;
  • определения функций.

Код выполняется изолированно и не имеет доступа к файлам, сети, Discord или данным за пределами переданных переменных.

Лимиты одного блока:

  • 2 секунды выполнения;
  • 256 МБ памяти.

При превышении лимита блок завершается ошибкой.

Режим JavaScript

Режим JavaScript не использует полноценный JavaScript-движок.

Поддерживается только небольшой JS-подобный синтаксис:

  • let;
  • const;
  • var;
  • true;
  • false;
  • null;
  • точки с запятой.

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

Тестирование

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

Проверяются:

  • ветвления;
  • Switch;
  • циклы;
  • Break и Return;
  • саб-флоу;
  • обработка ошибок;
  • лимиты шагов.

Тест можно запускать с несохранёнными изменениями.

Что видно во время прогона

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

Правая панель показывает:

  • Что бы отправил бот — превью сообщения так, как его увидели бы в Discord;
  • Значения переменных — с пометкой, на каком шаге появятся ещё не вычисленные;
  • Журнал — что произошло на каждом шаге и сколько это заняло.

Кнопки Пауза, Шаг и Стоп управляют воспроизведением. Выйти из режима можно кнопкой Стоп или клавишей Esc — выделенный блок и открытый инспектор сохранятся.

За шестерёнкой в панели задаются вводные прогона: от чьего лица он идёт, из какого канала и с какими аргументами команды. Идентификатор участника при этом всегда ваш — подменить {user_id} нельзя.

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

Что не выполняется во время теста

Реальные действия не применяются:

  • сообщения не отправляются;
  • роли не выдаются и не снимаются;
  • баланс не изменяется;
  • реальные данные сервера не читаются.

Из-за этого тест не проверяет:

  • права бота;
  • существование каналов;
  • существование ролей;
  • существование участников;
  • реальные балансы.

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

Тестовые значения

Переменные во время теста синтетические, но предсказуемые.

Одинаковые входные данные приводят к одинаковому результату.

Блок Случайное число во время теста возвращает середину диапазона.

Условия по умолчанию обычно переходят в ветку да.

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

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

В реальном Discord такой блок выполнится, но во время теста не произведёт действие.

После тестирования в редакторе обязательно проверьте флоу на сервере Discord.

Обработка ошибок

У большинства блоков есть красный выход ошибки.

Если он подключён, при ошибке создаются переменные:

  • {error.message};
  • {error.type};
  • {error.node_id}.

После этого выполнение продолжается по красной ветке.

Если выход ошибки не подключён, обычная ошибка останавливает флоу.

Необработанная ошибка команды

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

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

Ошибка события

У событий без исходного канала ошибка остаётся:

  • в журналах бота;
  • в разделе Аналитика.

В аналитике учитываются:

  • запуски;
  • ошибки блоков;
  • остановки из-за лимитов.

Что не считается обычной ошибкой

Через красный выход не перенаправляются:

  • превышение общего времени выполнения;
  • Return;
  • Отложить продолжение;
  • корректный Break внутри цикла.

Это управляющие сигналы, а не ошибки.

Break вне цикла считается обычной ошибкой и может быть обработан красным выходом.

Ограничения

ОграничениеЗначение
Выполненных блоков за один запуск1000
Общая длительность запуска900 секунд
Итераций одного Foreach или While100
Вложенность циклов и саб-флоу3
Один блок Задержка300 секунд
Блок Отложить продолжениеДо 30 суток
Ожидающих продолжений на сервер1000
Сообщение Discord2000 символов
Имя команды после cmd_32 символа
Имя переменной64 символа
Массив через make_array или append200 элементов
Строковый ввод переменной4096 символов
Custom Code2 секунды и 256 МБ

Лимит 4096 символов применяется к:

  • set;
  • make_array;
  • append;
  • значению по умолчанию при чтении из базы данных.

Это не общий лимит для всех локальных строк. Другие блоки или Custom Code могут создать более длинное значение.

При записи глобальной переменной её JSON-представление также не должно превышать 4096 символов.

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

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