В форму перед открытием тикета можно добавить поле для файлов: участник прикладывает скриншоты или записи экрана прямо в окне, и они приходят в первое сообщение тикета вместе с ответами
включается в панели, в настройках кнопки тикета: «Файлы в форме» — до 1, 3, 5 или 10 файлов
поле занимает одно из пяти мест формы
если у кнопки нет вопросов, форма появится только с полем для файлов
В панели сервера на главной странице появился выбор языка бота: русский, английский, немецкий, испанский или украинский
На выбранном языке бот отвечает на команды и ведёт панели, тикеты, кадры, смены, музыку, экономику, модерацию и журналы
Мафия, Бункер и Каракули идут на языке сервера: роли, карточки, события, сообщения ведущего
язык партии задаётся при её создании и не меняется до конца игры
Описания slash-команд и названия параметров Discord показывает на языке приложения каждого участника
Новый сервер сразу получает язык своего сервера Discord, у уже подключённых остаётся русский
Заготовки по умолчанию — приветствие, работы и товары экономики, кнопки тикетов, голосования — создаются на языке сервера; тексты, которые вы написали сами, не меняются
Музыка
На серверах со своим ботом панель музыки больше не дублируется: её ведёт только ваш бот, Echo в этот чат не пишет
Тикеты открываются даже после удаления ролей поддержки
БотАнглийской версии пока нет
Английской версии пока нет
Кнопка тикета отвечала «Не удалось создать тикет. Проверь права бота» — при исправных правах. Панель тикетов хранит роли поддержки, а на сервере их со временем удаляют и заводят заново. Если хотя бы одна роль из настроек панели больше не существовала, бот не мог собрать права для нового канала и тикет не создавался вовсе — ни у кого на сервере. Сообщение при этом кивало на права бота, и найти причину было невозможно.
Теперь удалённые роли просто пропускаются: тикет создаётся, доступ получают автор и живые роли поддержки.
Чтобы вернуть команду в тикеты, проверьте роли поддержки в настройках панели на сайте и укажите актуальные.
Премиум-модерация: выключатель формата ника заработал
БотАнглийской версии пока нет
Английской версии пока нет
Галочка «Требовать формат ника» ничего не выключала. Стоило задать хоть один формат и включить «Роли по нику», как бот откатывал роли и слал уведомления «ник участника не соответствует формату сервера» — даже когда владелец снимал главную галочку. Теперь она действительно главная: без неё ни «Роли по нику», ни «Охрана смены ника» не срабатывают, а под галочкой появилась подсказка об этом.
Один замок вместо двух. У раздела была своя галочка «Разрешить администраторам пользоваться этими инструментами» — отдельно от общего замка «Доступ администраторов» на обзоре. Они спорили друг с другом: на обзоре раздел открыт, а у администратора он не открывается, потому что кто-то снял внутреннюю галочку (её мог снять и сам администратор, закрыв раздел от себя). Внутренняя галочка убрана; кому из администраторов доступна премиум-модерация, решает только замок на обзоре.
Мониторинг: ссылку на сервер бот делает сам
Карточка без ссылки больше не висит впустую. Владелец включал «Показывать в каталоге», а поле «Ссылка-приглашение» оставлял пустым — карточка попадала в каталог, но без кнопки «Войти», и людям было некуда нажимать. Одиннадцать серверов стояли так неделями. Теперь поле можно не заполнять: Echo стоит на сервере и сам создаёт вечное приглашение — в канал правил или системный канал, а если их нет, в первый текстовый, где ему разрешено звать людей. Сразу после сохранения карточки, а не по расписанию. Если у сервера есть собственный адрес discord.gg/имя — берётся он.
Если права нет — владелец узнает. Когда боту не хватает права «Создавать приглашения», он шлёт владельцу одно уведомление с просьбой выдать право или вписать ссылку руками, а не молчит.
Панели действий: удалённая панель больше не висит в канале
В чём была проблема. Панель удаляли или переносили в другой канал, а сообщение с кнопками оставалось на месте. Кнопки выглядели живыми, но записи о панели уже не было — участники жали «Получить роль» и получали «Панель не найдена», админ был уверен, что панель давно снёс.
Что стало. При удалении панели сообщение в Discord снимается вместе с ней, как у форм, тикетов и ролевых панелей. При переносе в другой канал старое сообщение убирается, а в новом бот выкладывает свежее.
Если такое сообщение уже висит на сервере — удалите его руками, новых не появится.
Обновление
Безопасность сайта: обновления и защита входа
Движок сайта обновлён. Next.js поднят до 16.3.5. В версиях до неё разработчики нашли дыру в обработке картинок: особым файлом в формате AVIF можно было заставить сервер выполнить чужой код, без всякого входа. Мы этот формат раздаём, так что заплатка касалась нас напрямую. Заодно обновлена почтовая библиотека — в ней чинили обход проверки адреса получателя.
Вход считает попытки по аккаунту. Раньше неудачные попытки пароля считались по адресу посетителя, а его сайту сообщает заголовок запроса — и на домены игры, которые открыты напрямую, этот заголовок можно было прислать поддельный и менять на каждой попытке. Починено с двух сторон. Во-первых, сайт больше не верит заголовку: настоящий адрес ему передаёт сам сервер, тем же путём, каким пришло соединение, — подставить туда чужой нельзя. Во-вторых, счётчик теперь стоит и на самом нике: пятнадцать промахов подряд — и вход в этот аккаунт замирает на десять минут, откуда бы ни стучались. Побочно починились и журналы: раньше все посетители были записаны одним адресом, и разбирать по ним было нечего.
Больше половины суток бот отказывался включать что-либо с ютуба: в ответ на любой трек — «формат недоступен». В логе за десять часов набралось одиннадцать тысяч таких отказов.
Причина в том, каким клиентом бот представляется ютубу. Клиенты ломаются по очереди и без предупреждения: прошлый раз мы уходили с одного, потому что тот стал отвечать отказом в доступе, — теперь перестал отдавать звуковые дорожки его сменщик.
Чинили дважды. Сначала вернули звук, отдав выбор клиента самой качалке. Потом убрали саму возможность повториться: теперь при отказе, похожем на сломанного клиента, бот сам переходит к следующему в очереди и повторяет попытку. Раньше это означало сутки тишины и правку руками.
Кнопка отклонения в кадровых заявках
Нажатие на «отклонить» иногда молчало: у нажатия есть три секунды на ответ, и запрос к базе перед показом окна успевал их съесть. Теперь окно с причиной открывается сразу, а проверки — при отправке.
Обновление
Ивенты: анонсы и победители
Новый раздел в панели управления — «Ивенты». Он для команд, которые регулярно проводят мероприятия и каждый раз собирают один и тот же пост руками: баннер, призовой фонд, тег роли.
Теперь мероприятия живут в справочнике: у каждого своё название, картинка и призовой фонд. Ивент-команда жмёт кнопку на панели, выбирает мероприятие из списка — и анонс уходит в канал готовым. Публикация победителя устроена так же: выбрал мероприятие, вписал имя, статик и фотоотчёт.
Справочник правится и с сайта, и прямо из Discord — кнопкой на самой панели, чтобы за добавлением нового конкурса не приходилось идти в браузер. Тексты обеих публикаций свои: в них подставляются название мероприятия, призовой фонд, имя победителя и статик.
Панели действий: пятое поле формы и длинные цепочки действий
БотАнглийской версии пока нет
Английской версии пока нет
В чём была проблема. Оба случая выглядели как поломка, а были молчаливым обрезанием при сохранении: редактор принимал сколько угодно, кнопка «Сохранить» отрабатывала без ошибки, а лишнее не доезжало до базы.
Поля формы заявок. Пятое поле пропадало: сохранялось только четыре, хотя Discord разрешает пять строк в окне и весь остальной бот работает именно с пятью. Теперь пятое поле сохраняется и показывается.
Цепочка действий. Сохранялись только первые пять действий — поэтому шестое и дальше «не срабатывали» и казалось, что после пятого ломается проверка условий. На деле их просто не было. Предел поднят до двадцати пяти: этого хватает на длинные цепочки с условиями, а выполняет их бот по очереди, как и раньше.
Заодно длинный ответ такой цепочки больше не роняет нажатие: раньше при выходе за предел Discord кнопка отвечала «не удалось выполнить действие», хотя действия уже выполнились.
Спасибо @Metallist (баг #29) и @VanGex (баг #28) — оба репорта попали точно в причину.
В чём была проблема. Свой бот подключается отдельно от Echo, и на сервере, с которого Echo убрали, он продолжал работать как ни в чём не бывало: настройки хранятся ещё неделю на случай возвращения, а всё это время бот держал сессию и отвечал на команды. Со стороны это выглядело так, будто выгнать Echo нельзя — он остаётся под другим именем.
Что стало. Нет Echo — нет и своего бота: он не поднимается вовсе, а не отключается после подъёма. В панели у такого бота теперь стоит «отключён» с прямой причиной, а не «подключён» у бота, которого нет. Вернёте Echo — свой бот поднимется сам следующим проходом, ничего перенастраивать не нужно.
В чём была проблема. На сервере не оказалось ffmpeg — программы, через которую бот пропускает звук. Каждая попытка включить музыку упиралась в его отсутствие, и вместо отказа одного трека падал весь процесс: на минуту отваливались все серверы разом. Нажатые в этот момент кнопки и команды отвечали «приложение не ответило вовремя» — со стороны это выглядело как случайные сбои на ровном месте, хотя причина была одна.
Что стало. ffmpeg установлен, музыка играет. А чтобы это не повторилось, отказ запуска обрабатывается там же, где и отказ источника: не заигравший трек теперь остаётся не заигравшим треком и уводит плеер к следующему, вместо того чтобы гасить бота.
Причина отказа пишется в лог с названием и ссылкой на трек — раньше в логе оставалась голая системная ошибка без единого намёка, на чём именно всё сломалось.
Одобренная бессрочная заявка считалась активной вечно. Если у кнопки включено «один активный запрос на человека», а срок не задан, то после первого же одобрения подать заявку снова было нельзя — никогда. Панель вступления во фракцию превращалась в одноразовую на всю жизнь, а бот советовал «дождитесь окончания» того, что не кончится.
Теперь активной считается только та заявка, которая действительно активна: ещё не рассмотренная либо одобренная на срок, пока срок идёт. Одобренная бессрочно не мешает подать новую.
Сообщение стало точнее: «ещё на рассмотрении — дождитесь решения» и «уже действует одобренная заявка — дождитесь окончания срока» вместо одной фразы на оба случая.
Цепочки действий: условия заработали, а формы стали отправляться
Условие на заявке, тикете и форме не проверял никто. В цепочке действий у каждого шага можно указать «выполнять, только если есть роль». Для выдачи ролей, монет и сообщений это работало. Но заявка, тикет и форма без рассмотрения исполняются иначе — они забирают нажатие себе и открывают окно, — и выбирались просто как «первое действие такого типа», не глядя на условие.
Из-за этого ветвление не работало вовсе. Цепочка вида «заявка в канал A, если роль A → заявка в канал B, если роль B» всегда отправляла заявку в канал A: условие первого шага никто не смотрел, а до второго дело уже не доходило. Сколько бы шагов вы ни настроили, срабатывал первый.
Кнопка «Написать в канал» с полями формы не отправлялась. Отправка формы приходит отдельным событием, и бот заново искал нужное действие в цепочке — по тому же правилу «первое подходящее». Если перед формой стоял любой другой шаг, находился он, вид действия не совпадал, и вместо отправленной формы человек получал ошибку. Заявки в цепочке из нескольких штук по той же причине уходили не в тот канал, даже когда окно открывалось от правильной.
Форма, которую не нужно одобрять, и тихий час по своему поясу
БотАнглийской версии пока нет
Английской версии пока нет
Кнопка панели может открывать форму, ответы из которой сразу уходят карточкой в канал. Раньше форма была только у заявки на одобрение, и отчёт о проделанном — «сдал смену», «запись с рейда», «вынес предупреждение» — приходилось оформлять как заявку с кнопкой «одобрить», которую жали не глядя. Теперь у действия «Написать в канал» есть свои поля и пинг ролей: заполнил — ушло по адресу.
Тихий час в отклике на теги считается в своём часовом поясе. По умолчанию московский, но у команды из другого города «не дёргать с 23 до 8» означало нашу ночь, а не их. В настройке появился выбор пояса — от Калининграда до Камчатки.
Напоминания по заявкам можно ставить лестницей: через сколько минут звать дежурных, кого звать вторым шагом и нужно ли повторять дальше.
Авто-сообщение с удалённым каналом больше не бьётся в стену. Если канал удалили, публикация останавливается, а владельцу приходит уведомление — раньше бот пытался отправить его каждые полчаса бесконечно, и об этом никто не знал.
Розыгрыши, защита и формы: чиним то, что молчало
БотАнглийской версии пока нет
Английской версии пока нет
Розыгрыши: «Реролл» и «Удалить» срабатывают сразу. Кнопки на сайте ставили задачу в очередь, а бот забирал её раз в полминуты — со стороны выглядело, что они не работают, и люди жали снова и снова. Теперь сайт будит бота сигналом, строка сразу подписывается «реролл запрошен» или «удаляется», а список обновляется сам.
Отказ перестал быть тихим. Раньше ответ сервера не проверялся: нет прав — выглядело ровно как успех. Теперь появляется красная строка с причиной.
Пустой реролл больше не молчит: если участников не было, бот так и пишет в канал, а не оставляет тишину.
Защита ловит добавление бота надёжнее. Правило «Добавление ботов» опиралось на событие аудита, а Discord доставляет его через раз: на живом сервере бота добавили, событие не пришло, и через пять минут он выкинул восемь человек. Теперь бот проверяет каждого пришедшего бота сам и находит в аудите, кто его привёл. Одно и то же добавление дважды не накажет.
Взбесившегося бота теперь кикает, а не «снимает роли». Права бота живут на роли интеграции — снять её нельзя, и наказание отрабатывало вхолостую.
Формы перестали пропадать. Если настройку панели меняли, пока человек заполнял форму, отправка падала с ошибкой в консоль, а заявка исчезала без следа. Теперь бот читает то, что реально прислали, а при нехватке обязательного поля честно просит открыть форму заново.
Кнопки с формой открываются вовремя. У Discord три секунды на ответ; поход в базу за лимитом нажатий их съедал, и вместо формы появлялось «взаимодействие не сработало». Проверки по памяти остались перед формой, лимит проверяется при отправке.
Заявки: напоминания по шагам, досье в форуме, дашборд, статистика и выплаты
БотАнглийской версии пока нет
Английской версии пока нет
Заявки дозрели до полноценного конвейера. Раньше это была подача → карточка на рассмотрение → одобрил/отклонил. Теперь вокруг неё выросло всё, чего не хватало для настоящей работы отдела.
Лестница напоминаний вместо одного порога. Шаги задаются списком: через час — дежурным, ещё через три — им же, ещё через два — руководству, дальше повторять каждые шесть часов. У каждого шага свои роли и свой канал; последний шаг помечается как эскалация.
Досье в форуме. Карточка заявки дублируется в ветку форума и обновляется вместе со статусом. Ветка ищется по имени и заводится сама — так в одном месте копится вся история по организации, отделу или объекту, и её видят те, кто не имеет доступа к каналу рассмотрения.
Дашборд открытых заявок — одно живое сообщение: сколько сейчас висит, сколько каждая ждёт, кто взял, ссылка на карточку. Обновляется при каждой подаче и решении.
Статистика проверяющих — кто сколько взял, одобрил, отклонил и за сколько в среднем. Неделя считается с понедельника по Москве.
Выплаты за одобренные заявки. Раз в неделю бот собирает всё одобренное и ещё не оплаченное, считает по цене за заявку, группирует по полю формы (обычно ник) и присылает отчёт с кнопками «Выплачено / Отменить / Пересчитать». Заявка помечается номером отчёта — дважды её не оплатят; «Отменить» возвращает заявки в следующий расчёт, «Пересчитать» применяет новую цену.
Бот: команды с целью, карточки напоминаний и причины пропуска голосований
БотАнглийской версии пока нет
Английской версии пока нет
Свои команды теперь действуют на того, кого в них назвали. Кнопка под ответом выдавала роль тому, кто её нажал, — собрать «!verify <id> → карточка с кнопками → роль уходит этому пользователю» было нельзя. В каждом действии появился выбор «Кому»: тому, кто нажал, или участнику из аргумента команды.
Появились поля профиля этого пользователя: {target}, {target.name}, {target.tag}, {target.id}, {target.avatar}, {target.created}, {target.joined}, {target.roles}, {target.toprole}, {target.onserver}. Те же поля есть у любого аргумента по его имени — например, {member.joined}. Каждое имя работает и по-русски: {цель.ник}, {цель.зашёл} — то же самое. Дата регистрации считается из самого id, поэтому известна даже про того, кого на сервере уже нет.
Кнопки помнят, о ком была команда. Нажатие может случиться через час, когда аргументов уже нет, — поэтому участник запоминается в самой кнопке. Если он успел выйти с сервера, бот скажет об этом, а не отрапортует «готово».
Что теперь собирается без единой строчки кода: команда с id пользователя отвечает карточкой с его профилем и тремя кнопками — «Верифицировать» (выдать роль), «Выдать недопуск» (другая роль и запись в канал), «Отказать» (снять роль и написать причину). У каждой кнопки свои роли, кому она доступна, и свой лог.
Напоминания об оставленном теге стали карточками. Была строка «@роль Без ответа уже 2 минуты» и ссылка отдельным абзацем: в канале, куда падает десяток таких, взгляду не за что зацепиться. Теперь сразу видно, кто звал, в каком канале, когда — временем Discord, у каждого в своём поясе, — и сколько висит без ответа. Тег роли остаётся строкой над карточкой: упоминание внутри вложения никого не зовёт.
Музыка снова играет, кнопки выговоров не отваливаются
БотАнглийской версии пока нет
Английской версии пока нет
Музыка. YouTube перестал отдавать треки — качалка устарела на полтора месяца и получала «403 Forbidden». Обновили: треки, падавшие с ошибкой, снова играют, и бот больше не уходит на SoundCloud там, где YouTube работает.
Выговоры. Нажатие «снять выговор» иногда отвечало ошибкой, хотя выговор снимался. Бот успевал сходить в базу, загрузить участника, поправить роль и написать в журнал — а на ответ Discord даёт три секунды. Теперь он отвечает сразу, а работу доделывает после.
Обрывы соединения с базой. Простаивающее подключение молча рвали по пути, и следующий запрос падал уже посреди нажатия кнопки. Включили keep-alive — соединение не засыпает.
Комнаты игр перестали копить утечку
Потоки событий больше не сжимаются. Комнаты Мафии, Бункера, Гартика и страницы сделок держат открытый поток обновлений. Каждая запись в сжатый поток вешала свой обработчик, и сервер ругался на утечку слушателей — по сотне предупреждений в сутки. Сжимать поток из коротких строк всё равно нечего, теперь он идёт как есть.
Сервер больше не пропадает из каталога бота
БотАнглийской версии пока нет
Английской версии пока нет
«Бота нет на сервере», когда он есть. При запуске бот сверял свой список серверов с базой: обновлял живые и удалял «лишние» строки. Список берётся из того, что успел прислать Discord, — и если поток отставал или часть серверов была помечена недоступной из-за сбоя, сверка выкидывала из каталога живые серверы. После этого сайт честно отвечал, что бота на сервере нет: не открывались игры, в панели висело предложение добавить бота.
Теперь удаление только при полной картине. Пустой список серверов, недоступные серверы или список, заметно короче того, что уже в базе, — сверка обновляет данные, но ничего не удаляет и пишет причину в лог. Лишняя строка доживёт до следующего запуска; потерянный сервер ломает всё сразу.
Панель перестала верить каталогу на слово. Прежде чем сказать «бота нет на сервере», она переспрашивает Discord — и если бот на месте, пишет об этом прямо, а не отправляет добавлять бота, который и так стоит.
Свой бот теперь говорит за весь Echo, а не только за команды
БотАнглийской версии пока нет
Английской версии пока нет
На что жаловались
Премиум-сервер подключает собственного бота, чтобы всё происходило под его именем и аватаром. Но под его именем шли только ответы на команды и реакции на события. Всё, что затевает сам Echo — голосования по расписанию, отложенные посты, панели, поздравления, ночной режим, счётчики в названиях каналов, — и всё, что отправляет сайт из панели управления, уходило от Echo Assistant. Получалось, что на сервере говорят два бота, хотя человек подключал одного.
Что изменилось
Теперь адресат определяет исполнителя: если у сервера есть свой подключённый бот, и сообщение, и действие идут от него — откуда бы их ни затеяли, из планировщика бота или со страницы панели.
Под именем своего бота идёт всё: публикация и обновление панелей, форм и тикетов, голосования по расписанию и их итоги, состав и смены, отложенные посты, поздравления с днём рождения, личные роли и награды за уровни, кадровые панели, ночной режим, каналы-счётчики, снятие временных наказаний и выговоров, временные голосовые комнаты, экономика, игровые комнаты и панель музыки.
Если своего бота нет или он отключился
Ничего не меняется: работает главный Echo. Если своему боту не выдали прав в конкретном канале, сообщение всё равно будет доставлено главным — потому что доставленное сообщение важнее имени под ним.
Что осталось за Echo намеренно
Личные сообщения людям, каталог серверов, еженедельная сводка владельцу и всё, что происходит на официальном сервере проекта: это общие для проекта вещи, к отдельному серверу они не относятся.
Панель показывает настройки, указывающие в пустоту
БотАнглийской версии пока нет
Английской версии пока нет
Зачем это
Канал удалили, роль переименовали и пересоздали, старую стёрли — а в настройках остался её номер. Модуль после этого молчит: приветствие не приходит, журнал не пишется, ранги кадровой системы не выдаются. Со стороны выглядит как «бот сломался», и понять причину невозможно — в настройке лежит номер, которого больше нет.
Что стало
На главной странице сервера появилась заметка со списком таких настроек и ссылками прямо в нужные разделы. Выбрали замену — и модуль снова работает. Проверяются приветствия и прощания, роль новичкам, журналы событий, модерации, автомодерации и защиты, роль оповещения и канал-ловушка, формы и роли одобрения, кадровая система целиком — форум, ранги, отделы и их каналы, панели состава, — активность, экономика с её ролями-товарами и наградами, личные роли, уровни, браки, ночной режим, отложенные посты, голосования и каналы-счётчики.
Насколько это частое
На момент выкладки — шесть десятков таких настроек на пятнадцати серверах. Половина владельцев об этом не знала.
Удалённый канал перестал притворяться чужим
Если настроенный канал удаляли, поле настройки превращалось в строку для ввода номера с подписью «бот не видит этот канал — проверьте, что он есть на том сервере». Совет бесполезный: канал был на этом сервере, его просто стёрли. Теперь на месте настройки обычный список каналов и понятная строка: канал удалён, выберите новый, иначе модуль молчит. Ввод номера остался там, где он нужен, — у руководства проекта, которое указывает канал другого сервера.
Пропавшие роли больше не прячутся
Выбранные роли, которых больше нет на сервере, просто исчезали из поля: выбрали пять, видно три, и кажется, что так и настраивали. При этом в базе продолжали лежать номера удалённых ролей. Теперь под полем видно, сколько ролей пропало, и есть кнопка убрать их из настройки.
Бот больше не молчит, когда что-то не сработало
БотАнглийской версии пока нет
Английской версии пока нет
Еженедельные голосования приходят на все серверы
Голосование по расписанию открывалось, только если минута совпала с минутой из настроек — с запасом в две минуты, не больше. На двух десятках серверов бот рассылает по очереди, и Discord на каждой отправке просит подождать по три-четыре секунды: хвост списка до окна не доживал, и эти серверы молча оставались без голосования до следующей недели. Теперь бот запоминает, какое плановое открытие он уже отработал, и сравнивает с расписанием, а не с текущей минутой. Опоздал тик, затянулась рассылка, перезапустился бот — пропущенное открывается на следующем же проходе, в пределах шести часов от планового времени. Позже этого срока голосование не приходит: посреди дня оно уже никому не нужно.
Голосования больше не зависают
Опубликованное вручную из панели голосование, живущее по недельному расписанию, оставалось без срока закрытия — и выпадало сразу из обоих кругов: закрывать нечего, а открывать нельзя, потому что оно уже открыто. Такое висело в канале неделями. Теперь при публикации проставляется ближайшее плановое закрытие, а уже зависшие бот подхватывает сам.
Проверка роли перестала врать
Если голосование настроено «отправлять, только когда на роли есть люди», бот раньше смотрел в свою память об участниках. Сразу после перезапуска она пустая, роль выглядела пустой, и голосование не уходило. Теперь при пустом ответе состав роли перезапрашивается, а если проверить не удалось — голосование всё равно отправляется.
Бот сам отчитывается, все ли голосования открылись
Через двадцать минут после планового открытия в канал логов приходит короткий отчёт: сколько голосований открылось из скольких и что помешало остальным — выключенный модуль, удалённый канал, пустая роль. Когда открылись все, так и написано: тишина в этом канале больше не означает «всё хорошо, наверное». Отметка об отчёте хранится в базе, поэтому перезапуски не превращают сверку в поток одинаковых сообщений.
Раньше команда сервера была подписью и готовым текстом: !правила — и всё. Теперь у неё есть аргументы, права, условия, действия и кнопки.
Аргументы. Команда спрашивает участника, роль, канал, число, файл или текст — Discord подсказывает их прямо при наборе. В ответе они подставляются по имени: «Выдал {роль} игроку {кого} на {срок} дней». Можно задать готовый список значений или свои подсказки, а из двух слов в названии получается подкоманда: /заявка подать, /заявка статус.
Права. Команду можно закрыть правами Discord — тогда её просто не видно тем, кому нельзя. Сверху свои условия: нужные роли, запрещённые роли, разрешённые каналы, кулдаун на человека и на весь сервер, лимит запусков, «один раз на человека», расписание «с 18:00 до 23:00».
Действия. Команда теперь не только отвечает: выдаёт и снимает роли (в том числе на срок), начисляет и списывает монеты, ставит тайм-аут, меняет ник, пишет в канал, открывает тикет или заявку на одобрение. Движок общий с «Панелями действий» — что умеет кнопка, то умеет и команда.
Кнопки и меню под ответом. У каждой кнопки своё действие и свои условия. Меню ролей, участников и каналов Discord собирает сам, а выбранное подставляется в действие: меню ролей + «выдать роль» — и получилась выдача любой роли из списка.
Форма перед выполнением. До пяти полей: причина, срок, ссылка на доказательства. Ответы уходят и в текст, и в действия.
Сообщения об ошибках помогают улучшать продукт. Спасибо за обратную связь.
После смены токена своего бота панель не пропадает и не появляется заново на каждом треке
Исправления
Отклонение заявки в панели действий больше не зависает на «думает…»
Шаблон ника по умолчанию в кадрах снова принимает ники: при включённом требовании к нику кадровые действия раньше блокировались у всех, кроме лидеров
В казино «орёл» больше не засчитывается как «решка»
Числа склоняются правильно: «1 монета», «5 треков», «1 балл»
Тумблер «Показывать в каталоге» срабатывает сразу. Раньше он был обычным полем формы: щёлкнул — «включено», а в каталог сервер попадал только после кнопки «Сохранить» внизу страницы; к тому же до первого сохранения тумблер рисовался включённым, и владелец уходил уверенным, что сервер в каталоге, — а его там не было. Теперь щелчок сам создаёт карточку и включает её (или снимает), без «Сохранить», а пока карточки нет, тумблер честно показывает «выкл».
Видно, есть ли сервер в каталоге — и почему нет. Над настройками стоит плашка с ответом: «Карточка в каталоге — N-е место в топе» со ссылкой на карточку, либо «Карточки в каталоге нет» с причиной — не сохранено, бота нет на сервере, выключен тумблер, скрыта модерацией. Если карточка есть, но без кнопки «Войти» (нет приглашения, ссылка мертва, вход заблокирован), плашка говорит и это, и что делать.
Файл с ключами закрыт от посторонних. Настройки сайта с паролями к базам лежали с правом чтения для всех пользователей машины. Оставлено чтение только владельцу.
Доступ раздаётся ролями: отдельно те, кто пользуется панелью, отдельно те, кому можно править справочник.
Подпись под анонсом
Под постом стоял юзернейм Discord — вида adm.roxy, а не то имя, под которым человека знают на сервере. Теперь по умолчанию ник на сервере, и это выбирается в настройках: ник, имя пользователя или вовсе без подписи.
Теперь при отправке формы берётся ровно то действие, которое её открыло — с учётом условий. Если не подошёл ни один шаг, бот так и говорит, вместо молчаливого «Готово».
Отклик на теги перестал дёргать Discord впустую. Каждая реакция на сервере — смайлик под новостью, что угодно — заставляла бота подтягивать сообщение целиком. Теперь сначала память и база, и только потом сеть: очередь ограничений разгрузилась.
Защита: взбесившегося бота теперь кикает
Взбесившегося бота защита теперь кикает, а не «снимает роли». Права бота живут на роли интеграции, а её нельзя снять ни боту, ни человеку — Discord запрещает. Наказание «снять все роли» отрабатывало вхолостую: в журнале стояло «снял все роли», а бот продолжал сносить сервер.
Теперь для ботов подставляется кик — и на «снять все роли», и на «мьют» (тайм-аут бота тоже ничего не останавливает: он работает через API, а не через право писать). В журнале защиты так и написано: «Кикнул бота — роль интеграции снять нельзя».
Когда ответили, карточка становится зелёной: «Решено — ответил такой-то за 6 минут», тег снимается. Если между вызовом и ответом был тихий час, рядом стоит и календарное время: «прошло 8 часов — тихий час в счёт не идёт». Сводка после тихого часа собрана так же: сколько накопилось, по каждому вызову ссылка, время ожидания и кто звал.
Тег неупоминаемой роли теперь считается. Если роль закрыта от упоминаний, Discord не помечает её как упомянутую, и вызов проходил мимо бота — со стороны это выглядело как «отслеживание не работает». Настройка вступает в силу сразу: раньше бот держал её в памяти до минуты, и тег, отправленный сразу после сохранения, терялся.
Голосования по расписанию: видно, почему не открылись. Причина хранилась в памяти бота — после перезапуска отчёт писал «причина неизвестна», а на сайте её не было вовсе. Теперь причина и пропущенный момент лежат в самой записи и показываются в списке голосований: «Не открылось по расписанию 24 августа 00:00: опоздали больше чем на догон». Причины называются словами: бота нет на сервере, нет канала, выключен бот или модуль, на роли-триггере никого, не отправилось. Отметка снимается сама, когда голосование открылось.
Кнопка может спросить перед действием. У каждой кнопки под ответом команды появилась своя форма — до пяти полей: оценка, причина, комментарий. Спросить их при вызове команды невозможно: их пишет тот, кто нажимает, и по конкретному решению. Ответы подставляются в тексты действий по имени поля.
Новое действие «Написать в личные сообщения». Решение можно отправить самому участнику, а не только в канал. Если личные закрыты, бот скажет об этом — решение всё равно остаётся в силе.
Новое действие «Снять все роли, кроме». Перечислять сотню ролей руками в настройке невозможно, поэтому список собирается на месте: остаётся то, что указали, остальное снимается. Роли выше роли бота бот тронуть не может — их он назовёт отдельно, а не отрапортует «готово».
Отчёт о восстановлении снова называет вещи по именам
После восстановления сервера из резервной копии панель показывала список того, что бот сделал, — только вместо названий в нём стояли пустые кавычки: «Роль «» — создана», «Канал «» — создан». Понять по такому списку, что именно вернулось, было невозможно. Теперь в каждой строке стоит имя роли или канала, а у участника — упоминание и число возвращённых ролей.
Заодно проверили само восстановление
На тестовом сервере прогнали полный круг: удалили роль с настроенным цветом и правами, канал с темой и настройками доступа, сняли роль с участника — и восстановили из копии. Вернулось всё: цвет, права, тема, настройки доступа (причём привязанные к заново созданной роли, а не к её исчезнувшему номеру) и роль у участника.
Отложенные посты больше не пропадают молча
Если пост не удавалось опубликовать — канал удалили, у бота отобрали права, Discord попросил подождать, — бот всё равно записывал «опубликовано». В панели стояла отметка о свежей публикации, в канале не было ничего, а разовый пост при этом выключался навсегда и терялся вместе с текстом. Теперь отметка ставится только по факту. Повторяющийся пост держит свой ритм и в следующий раз пробует снова; разовый не выключается из-за временной помехи — бот вернётся к нему через десять минут и будет пробовать сутки. Если канала уже нет, пост отключается сразу, а не делает вид, что всё прошло. Каждая неудача пишется в журнал с номером поста и причиной; розыгрыши, которые не смогли подвести итоги, тоже больше не молчат — раньше они пытались каждые полминуты, не оставляя следа.
Еженедельная сводка приходит один раз
Сводка владельцу сервера отправляется по понедельникам, а отметка «этому серверу уже отправили» жила только в памяти бота и стиралась при каждом перезапуске. Несколько выкладок за день — несколько одинаковых сводок в личке. Теперь отметка хранится в базе и ставится до отправки, одним неделимым запросом: даже перезапуск ровно в момент рассылки не приводит ко второму письму. Закрытая личка больше не вызывает попыток каждые полчаса до конца дня, а в журнале видно, сколько сводок ушло и сколько не дошло.
Музыка снова играет
YouTube отвечал отказом на любую попытку получить звук — не через раз, а на каждый ролик: бот честно пробовал пять раз подряд, потом искал ту же песню на SoundCloud, и всё это время в голосовом канале стояла тишина. Дело в том, каким приложением YouTube представляется программа, которая забирает звук: её обычный выбор перестал работать, а другое приложение из того же списка отдаёт те же ролики без единой осечки. Приложение вынесено в настройку — когда сломается и оно, достаточно вписать другое и перезапустить бота, не дожидаясь обновления.
Правый клик. Появился новый вид команд — пункт в меню по правому клику на участнике или на сообщении: «Досье», «Пожаловаться», «В цитаты».
Оформление ответа. Эмбед с полями, автором и временем, отправка в другой канал или в личные сообщения, автоудаление через N секунд, ветка под ответом, реакции, случайный ответ из списка и режим «молча» — когда команда только выполняет действия.
Журнал и перенос. Видно, кто, когда и с какими аргументами звал команду; есть выгрузка и загрузка файлом — перенести набор на второй сервер или сделать копию. И заготовки: правила, IP сервера, роль по кнопке, жалоба, предупреждение, досье.
Слэш-команды и пункты правого клика по-прежнему на Premium, префиксные — всем.