Функции API для Discord
Функции вызываются в блоке в поле переменных или прямо в тексте ответа через #{...}:
#{discord_add_role(message_from, '1465674567090704592')}
Идентификаторы серверов, каналов, ролей и сообщений в Discord — это длинные числа. Копировать их удобнее всего так: Настройки → Расширенные → Режим разработчика, после чего в контекстном меню любого объекта появится пункт «Копировать ID».
Подключение бота описано в статье «Как создать чат-бота в Discord».
Где взять id сообщения
Id сообщения, на которое сработал блок, лежит в переменной discord_message_id — отдельно доставать его не нужно:
#{discord_delete_message(discord_message_id)}
Если нужны данные, которых нет в готовых переменных, полный вебхук доступен в переменной discord_webhook — она заполняется, когда переменной save_webhook присвоено любое значение:
data = discord_webhook["data"]
msg_id = data["id"]
result = discord_reply_to_message(msg_id, "Это ответ на сообщение")
Переменные, которые появляются сами
Заполняются при каждом событии, настраивать их не нужно.
| Переменная | Что внутри | Пример |
|---|---|---|
guild_id |
id сервера | 1465674567090704591 |
discord_event |
тип события одним словом | message |
discord_message_id |
id сообщения, с префиксом mid
|
mid1465674569095319625 |
message_from |
id автора события, с префиксом uid
|
uid413984787162726410 |
from_username |
логин автора в Discord | 00rei |
from_name |
как автор подписан в чате | Рус |
username |
логин, для личных сообщений боту | 00rei |
is_bot |
1, если автор события — другой бот |
0 |
nickname |
ник на сервере, пусто если не задан | Модератор |
roles |
список id ролей автора | ["1465674567090704592"] |
is_admin |
1 — администратор или владелец сервера |
1 |
reply_from |
id автора сообщения, на которое ответили | uid493121376652230668 |
reply_from_username |
его логин | _deikin |
reply_from_name |
его отображаемое имя | Рус |
reply_to_bot |
1, если ответили боту |
0 |
reply_message_id |
id сообщения, на которое ответили | mid1534837349219958804 |
reply_text |
текст сообщения, на которое ответили | кто дежурит сегодня? |
Префиксы uid, cid и mid — часть значения. Передавать переменные в функции нужно как есть, ничего отрезать не надо.
from_name против from_username. В from_name лежит то имя, которым к человеку обращаются в чате: ник на сервере, если он задан, иначе отображаемое имя аккаунта, иначе логин. Именно его стоит подставлять в приветствия — from_username часто выглядит как _deikin или 00rei.
Группа reply_* заполняется, только когда сообщение является ответом на другое. На обычном сообщении все они очищаются, поэтому проверка:
#{reply_from != ''}
надёжно отличает ответ от обычного сообщения.
nickname, roles и is_admin относятся к автору текущего события. На реакциях Discord этих данных не присылает, поэтому проверять администратора надо на сообщении или слэш-команде.
Текст входящего сообщения лежит в стандартной переменной question, как и в остальных каналах.
События
Кроме обычных сообщений в воронку приходят служебные события. Их текст попадает в question, так что ловить их можно обычным текстовым условием.
discord_event |
Текст в question
|
Когда |
|---|---|---|
message |
текст сообщения | участник написал |
message_edit |
новый текст сообщения | сообщение отредактировали |
interaction |
/warn @user спам |
вызвали слэш-команду или нажали кнопку |
reaction_add |
new_like ❤️ uid413984787162726410 |
поставили реакцию |
reaction_remove |
reaction_remove ❤️ uid413984787162726410 |
сняли реакцию |
message_delete |
message_delete mid1465674569095319625 |
удалили сообщение |
messages_delete_bulk |
messages_delete_bulk 12 |
удалили несколько сообщений |
member_join |
member_join uid413984787162726410 |
участник зашёл на сервер |
member_leave |
member_leave uid413984787162726410 |
вышел |
member_update |
member_update uid413984787162726410 |
сменил ник или роли |
member_ban |
member_ban uid413984787162726410 |
забанен |
member_unban |
member_unban uid413984787162726410 |
разбанен |
У кастомной реакции вместо эмодзи будет её id:
new_like beer:1479419477396291696 uid413984787162726410
Подробнее — в разделе про реакции.
Если блок должен срабатывать только на живые сообщения участников, добавьте в условие:
discord_event == 'message'
Это отсечёт все служебные события разом. Проверять по тексту ненадёжно: участник может написать member_join руками.
member_update приходит на любое изменение участника, в том числе на роль, которую выдал сам бот. Блок, который реагирует на member_update и выдаёт роль, зациклится — такие условия всегда стоит ограничивать.
Сообщения
| Функция | Что делает |
|---|---|
discord_send_message(channel_id, text) |
написать в произвольный канал |
discord_send_dm(user_id, text) |
написать участнику в личные сообщения |
discord_reply_to_message(message_id, text) |
ответить на сообщение |
discord_edit_message(message_id, text) |
изменить своё сообщение |
discord_delete_message(message_id) |
удалить сообщение |
discord_bulk_delete_messages(channel_id, message_ids) |
удалить несколько сообщений сразу |
discord_get_message(channel_id, message_id) |
прочитать сообщение |
discord_pin_message(message_id) |
закрепить |
discord_unpin_message(message_id) |
открепить |
Ограничения Discord: ограничения по времени на правку и удаление своих сообщений нет; массовое удаление работает только для сообщений не старше 14 дней, за раз от 2 до 100 штук.
Реакции
| Функция | Что делает |
|---|---|
discord_send_reaction(message_id, reaction) |
поставить реакцию |
discord_delete_reaction(message_id, reaction, user_id) |
снять реакцию; без user_id снимается реакция бота |
В параметр reaction передаётся либо один эмодзи, например ❤️, либо id кастомного эмодзи сервера.
Где взять id кастомной реакции
Поставьте нужную кастомную реакцию на любое сообщение в канале — в чат придёт коллбек вида:
new_like beer:1479419477396291696 uid413984787162726410
Здесь beer:1479419477396291696 и есть id реакции. Его можно скопировать и подставлять в функции работы с реакциями:
#{discord_send_reaction(discord_message_id, 'beer:1479419477396291696')}
Обычные эмодзи приходят в коллбеке как есть:
new_like ❤️ uid413984787162726410
где uid413984787162726410 — id участника, поставившего реакцию.
Модерация
| Функция | Что делает |
|---|---|
discord_timeout_member(user_id, seconds) |
мьют на указанное количество секунд, максимум 28 суток |
discord_remove_timeout(user_id) |
снять мьют досрочно |
discord_kick_member(user_id) |
исключить с сервера, вернуться можно по приглашению |
discord_ban_member(user_id, delete_message_seconds) |
забанить; вторым аргументом — за сколько секунд удалить его сообщения, максимум 7 суток |
discord_unban_member(user_id) |
разбанить |
Модерировать участника, чья роль стоит выше роли бота, Discord не позволит. Владельца сервера — тоже.
Роли и участники
| Функция | Что делает |
|---|---|
discord_add_role(user_id, role_id) |
выдать роль |
discord_remove_role(user_id, role_id) |
снять роль |
discord_get_roles() |
список ролей сервера с их id |
discord_get_member(user_id) |
данные участника: ник, роли, дата входа |
discord_set_nickname(user_id, nickname) |
сменить ник на сервере |
Роль бота должна стоять выше выдаваемой. Роль @everyone и роли, которыми управляют интеграции, в том числе роли других ботов, выдать нельзя.
Каналы и тикеты
| Функция | Что делает |
|---|---|
discord_create_channel(name, type, parent_id, permission_overwrites) |
создать канал |
discord_delete_channel(channel_id) |
удалить канал |
discord_set_channel_permission(channel_id, target_id, allow, deny, type) |
выдать или запретить права на канал |
discord_create_invite(channel_id, max_age, max_uses) |
ссылка-приглашение |
discord_get_invites() |
список приглашений сервера |
У discord_create_channel тип по умолчанию 0 — текстовый канал; 2 — голосовой, 4 — категория. В parent_id можно передать id категории, чтобы канал появился внутри неё.
У discord_set_channel_permission последний аргумент — кому выдаются права: 1 — участнику, 0 — роли. В allow и deny передаются числа:
| Число | Право |
|---|---|
1024 |
видеть канал |
2048 |
писать в канал |
3072 |
видеть и писать |
65536 |
читать историю |
У discord_create_invite время жизни ссылки задаётся в секундах (86400 — сутки), max_uses со значением 0 означает «без ограничения».
Слэш-команды
| Функция | Что делает |
|---|---|
discord_get_commands() |
список команд, зарегистрированных на сервере |
discord_set_commands(commands) |
заменить набор команд целиком |
discord_set_commands принимает список команд:
#{discord_set_commands('[
{"name": "rules", "description": "Показать правила сервера"},
{
"name": "warn",
"description": "Выдать предупреждение",
"options": [
{"type": 6, "name": "user", "description": "Кому", "required": true},
{"type": 3, "name": "reason", "description": "Причина", "required": false}
]
}
]')}
Требования Discord: name — строчными буквами, без пробелов, от 1 до 32 символов; description обязательно, от 1 до 100 символов.
Типы опций:
-
3— строка; -
4— целое число; -
5— да/нет; -
6— участник; -
7— канал; -
8— роль.
Обязательные опции должны идти раньше необязательных. Пустой список удаляет все команды бота на сервере.
Вызов команды приходит в воронку строкой вида:
/warn @user спам
То есть имя команды и значения опций через пробел. Ловится обычным текстовым условием.
Отдельная функция для кнопок не нужна: кнопки настраиваются у обычного блока ответа, а нажатие приходит так же, как слэш-команда, — в тексте будет значение кнопки.
Очки и рейтинг
Встроенная система благодарностей: очки начисляются тому, чьё сообщение процитировали. На ней собираются уровни, звания и лидерборды.
| Функция | Что делает |
|---|---|
discord_add_thanks_score(value) |
начислить очки автору цитируемого сообщения |
discord_add_thanks_score_for_answer(value) |
начислить тому, кто ответил |
discord_minus_thanks_score(value) |
снять очки |
discord_get_score(user_id) |
очки участника числом; без аргумента — автор события |
discord_get_level(user_id, points_per_level) |
уровень участника; порог по умолчанию 100 очков |
discord_get_user_info(user_id) |
очки, место в рейтинге и имя одним объектом |
discord_get_top(count, shift, humanize, delimiter) |
лидерборд |
У discord_get_top аргумент count — сколько строк вывести, shift — со скольких пропустить для листания, humanize со значением true вернёт готовый текст, delimiter — чем разделять имя и очки.
В условии блока очки надо сравнивать через discord_get_score — эта функция возвращает число, с которым сравнение работает как ожидается.
Примеры
Приветствие новичка в личные сообщения
Условие блока — member_join, в поле переменных:
discord_send_dm(message_from, 'Привет, #{from_name}! Загляни в правила в закрепе.')
Удалить сообщение со стоп-словом и выдать мьют на сутки
Условие — список стоп-слов, дополнительное условие is_admin != 1:
discord_delete_message(discord_message_id)
discord_timeout_member(message_from, 86400)
Роль за реакцию под конкретным сообщением
Условие — new_like 🍕, дополнительное условие:
contains(discord_message_id, '1534927170965602324')
Код:
discord_add_role(message_from, '1465674567090704592')
Личный канал-тикет по кнопке
ticket = discord_create_channel('ticket-' + from_username)
ticket_channel = get(get(ticket, 'data'), 'id')
discord_set_channel_permission(ticket_channel, guild_id, None, 1024, 0)
discord_set_channel_permission(ticket_channel, message_from, 3072, None, 1)
discord_send_message(ticket_channel, 'Опишите проблему одним сообщением.')
Первая строка с правами закрывает канал от всех (guild_id здесь — это роль @everyone), вторая открывает его автору обращения.
Очки за благодарность и роль за уровень
Условие блока — слова спасибо;спс;благодарю, дополнительное условие:
reply_from != '' and reply_from != message_from and reply_to_bot != 1
Код:
discord_add_thanks_score(1)
if (discord_get_level(reply_from) >= 1) {
discord_add_role(reply_from, '1465674567090704592')
}
Проверка reply_from != message_from не даёт начислять очки самому себе, reply_to_bot != 1 — боту.
Показать свои очки по команде
Условие — /xp:
points = discord_get_score()
lvl = discord_get_level()
В тексте ответа:
#{from_name}, у тебя #{points} XP · уровень #{lvl}
Лидерборд по команде
Условие — /top, текст ответа:
🏆 Топ по XP:
#{discord_get_top(10, 0, true, ' — ')}