Реакции
Боты могут работать с реакциями на сообщения. Существует два типа реакций: реакции на эмодзи и пользовательские реакции на эмодзи.
Реакция на сообщения
Боты могут добавить к сообщению одну реакцию в виде эмодзи.
В тех же случаях боты могут реагировать и пользовательскими эмодзи (хотя боты не могут иметь Telegram Премиум). Когда премиум пользователь добавляет к сообщению пользовательскую реакцию с помощью эмодзи, боты впоследствии могут добавить такую же реакцию к этому сообщению. Кроме того, если администратор чата явно разрешает использовать пользовательские эмодзи, их могут использовать и боты в этом чате.
Вот как можно реагировать на сообщения.
// Используйте `ctx.react` для реакции на текущее сообщение.
bot.command("start", (ctx) => ctx.react("😍"));
bot.on("message", (ctx) => ctx.react("👍"));
// Используйте `ctx.api.setMessageReaction` для реакций в другом месте.
bot.on("message", async (ctx) => {
await ctx.api.setMessageReaction(chat_id, message_id, "🎉");
});
// Используйте `bot.api.setMessageReaction` вне обработчиков.
await bot.api.setMessageReaction(chat_id, message_id, "💯");
2
3
4
5
6
7
8
9
10
11
Как обычно, TypeScript предоставит автодополнение для эмодзи, которые вы можете использовать. Список доступных эмодзи-реакций можно найти здесь.
Плагин Emoji
Программировать с помощью эмодзи может быть некрасиво. Не все системы могут правильно отображать исходный код. Кроме того, надоедает постоянно копировать их из разных мест.
Пусть плагин emoji поможет вам!
Теперь, когда вы знаете, как ваш бот может реагировать на сообщения, давайте посмотрим, как мы можем обрабатывать реакцию ваших пользователей.
Получение обновлений о реакциях
Существует несколько различных способов обработки обновлений о реакциях. В личных чатах и групповых чатах ваш бот будет получать обновление message
, если пользователь изменил свою реакцию на сообщение. В каналах (или автоматически пересылаемых сообщениях каналов в группах) ваш бот будет получать обновление message
, которое показывает только общее количество реакций, но не раскрывает, кто отреагировал.
Оба типа реакций поступают только тогда, когда бот является администратором в чате. Кроме того, они должны быть включены с помощью allowed
. Например, при polling вы можете включить их следующим образом:
bot.start({
allowed_updates: ["message", "message_reaction", "message_reaction_count"],
});
2
3
Включение всех типов обновлений
Возможно, вы захотите импортировать API
из grammY и затем указать
allowed_updates: API_CONSTANTS.ALL_UPDATE_TYPES;
чтобы получать все обновления. Обязательно ознакомьтесь с API документацией.
grammY runner и set
имеют схожие способы указания allowed
.
Теперь, когда ваш бот может получать обновления реакции, давайте посмотрим, как он может их обрабатывать!
Обработка новых реакций
Очень просто обрабатывать вновь добавленные реакции. В grammY для этого есть специальная поддержка через bot
.
bot.reaction("🎉", (ctx) => ctx.reply("блюп блюп"));
bot.reaction(["👍", "👎"], (ctx) => ctx.reply("Красивый палец"));
2
Эти обработчики будут срабатывать каждый раз, когда пользователь добавляет в сообщение новую реакцию.
Естественно, если ваш бот обрабатывает пользовательские реакции от премиум-пользователей - вы можете прослушать и их.
bot.reaction(
{ type: "custom_emoji", custom_emoji_id: "identifier-string" },
async (ctx) => {/* ... */},
);
2
3
4
Для этого необходимо заранее знать идентификатор пользовательского эмодзи.
Наконец, когда пользователь ставит реакцию звезды, вы можете обработать это обновление следующим образом.
bot.reaction({ type: "paid" }, (ctx) => ctx.reply("Спасибо!"));
Обработка произвольных изменений в реакциях
Хотя это не видно в пользовательском интерфейсе официального клиента Telegram, на самом деле пользователи могут изменять несколько реакций одновременно. Именно поэтому при обновлении реакций вы получаете два списка - старых и новых реакций. Это позволяет вашему боту обрабатывать произвольные изменения в списке реакций.
bot.on("message_reaction", async (ctx) => {
const reaction = ctx.messageReaction;
// Мы получаем только идентификатор сообщения, но не его содержимое.
const message = reaction.message_id;
// Разница между этими двумя списками описывает изменения.
const old = reaction.old_reaction; // предыдущие
const now = reaction.new_reaction; // текущие
});
2
3
4
5
6
7
8
grammY позволяет еще больше отфильтровать обновления с помощью специальных фильтрующих запросов для типа реакции.
// Обновления, в которых текущая реакция содержит хотя бы один эмодзи.
bot.on("message_reaction:new_reaction:emoji", (ctx) => {/* ... */});
// Обновления, в которых предыдущая реакция содержала хотя бы один пользовательский эмодзи.
bot.on("message_reaction:old_reaction:custom_emoji", (ctx) => {/* ... */});
// Обновление, когда текущая реакция содержит реакцию звезды.
bot.on("message_reaction:new_reaction:paid", (ctx) => {/* ... */});
2
3
4
5
6
Хотя эти два массива объектов Reaction
технически дают вам всю информацию, необходимую для работы с обновлениями реакций, они все же могут быть немного громоздкими для работы. Поэтому grammY может вычислять из обновлений более полезные вещи.
Проверка того, как изменилась реакция
Существует краткая запись под названием ctx
, которая позволяет увидеть, как именно изменилась реакция.
Вот как можно использовать ctx
, чтобы определить, удаляет ли пользователь свой палец вверх (но простить его, если он сохраняет свою реакцию окей).
bot.on("message_reaction", async (ctx) => {
const { emoji, emojiAdded, emojiRemoved } = ctx.reactions();
if (emojiRemoved.includes("👍")) {
// Палец вверх был удален! Неприемлемо.
if (emoji.includes("👌")) {
// Все в порядке, не наказывайте.
await ctx.reply("Я прощаю тебя");
} else {
// Как они смеют.
await ctx.banAuthor();
}
}
});
2
3
4
5
6
7
8
9
10
11
12
13
Есть четыре массива, возвращаемые ctx
: добавленные эмодзи, удаленные эмодзи, сохраненные эмодзи и список, который говорит вам о результате изменения. Кроме того, есть еще четыре массива для пользовательских эмодзи с аналогичной информацией. Наконец, есть два булевых флага для платных реакций.
const {
/** Эмодзи, присутствующие в данный момент в реакции этого пользователя */
emoji,
/** Эмодзи, недавно добавленные в реакцию этого пользователя */
emojiAdded,
/** Эмодзи, не измененные обновлением реакции этого пользователя */
emojiKept,
/** Эмодзи, удаленные из реакции этого пользователя */
emojiRemoved,
/** Пользовательские эмодзи, присутствующие в данный момент в реакции этого пользователя */
customEmoji,
/** Пользовательский эмодзи, недавно добавленный в реакцию этого пользователя */
customEmojiAdded,
/** Пользовательские эмодзи, не измененные обновлением реакции этого пользователя */
customEmojiKept,
/** Пользовательские эмодзи удалены из реакции этого пользователя */
customEmojiRemoved,
/** Указывает, присутствует ли платная реакция в реакциях этого пользователя. */
paid,
/** Указывает, была ли платная реакция недавно добавлена к реакции этого пользователя */
paidAdded,
} = ctx.reactions();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Многое было сказано о работе с обновлениями в личных чатах и групповых чатах. Давайте рассмотрим каналы.
Обработка обновлений счетчика реакций
В личных чатах, группах и супергруппах известно, кто и как реагирует на то или иное сообщение. Однако для сообщений в канале у нас есть только список анонимных реакций. Невозможно получить список пользователей, которые отреагировали на определенное сообщение. То же самое справедливо и для сообщений канала, которые автоматически пересылаются в связанный с каналом чат.
В обоих случаях ваш бот получит обновление message
.
Вы можете поступить с ним следующим образом.
bot.on("message_reaction_count", async (ctx) => {
const counts = ctx.messageReactionCount;
// И снова мы видим только идентификатор сообщения.
const message = counts.message_id;
// Вот список реакций с подсчетом.
const { reactions } = counts;
});
2
3
4
5
6
7
Обязательно следите за спецификацией для обновления количества реакций на сообщения.