反应
Bot 可以处理消息反应 有两种类型的反应:emoji 反应和自定义 emoji 反应。
对消息做出反应
Bot 可以向消息添加单个 emoji 反应。
在相同的情况下,bot 也可以使用自定义 emoji 做出反应(即使 bot 无法拥有 Telegram Premium)。 当高级用户向消息添加自定义 emoji 反应时,bot 稍后可以向该消息添加相同的反应。 此外,如果聊天管理员明确允许使用自定义 emoji,则该聊天中的 bot 也可以使用它们。
以下是你可以如何对消息做出反应。
// 使用 `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 反应的列表可以在 此处 找到。
现在你已经知道 bot 如何对消息做出反应,让我们看看如何处理用户的反应。
接收有关反应的 Update
有几种不同的方法可以处理有关反应的 update。 在私聊和群聊中,如果用户更改了对消息的反应,你的 bot 将收到 message
update。 在频道(自动转发到群聊中的频道帖子)中,你的 bot 将收到 message
update,该 update 仅显示反应总数,但不会透露谁做出了反应。
仅当 bot 是聊天中的管理员时才会收到这两种类型的反应。 此外,它们需要通过 allowed
启用。 例如,通过内置轮询,你可以像这样启用它们:
bot.start({
allowed_updates: ["message", "message_reaction", "message_reaction_count"],
});
2
3
启用所有 update 类型
你需要从 grammY 导入 API
,然后设置
allowed_updates: API_CONSTANTS.ALL_UPDATE_TYPES;
来接收所有 update。 请务必查看 API 参考。
grammY runner 和 set
有着相同的方式来设置 allowed
。
现在你的 bot 可以接收反应 update,让我们看看它是如何处理它们的!
处理新的反应
处理新添加的反应非常简单。 grammY 通过 bot
对此提供了特殊支持。
bot.reaction("🎉", (ctx) => ctx.reply("呜呼~"));
bot.reaction(["👍", "👎"], (ctx) => ctx.reply("漂亮的大拇指"));
2
每当用户向消息添加新的 emoji 反应时,这些处理程序就会触发。
当然,如果你的 bot 可以处理高级用户的自定义 emoji 反应,你也可以监听它们。
bot.reaction(
{ type: "custom_emoji", custom_emoji_id: "identifier-string" },
async (ctx) => {/* ... */},
);
2
3
4
这就需要你提前知道自定义 emoji 的标识符。
最后,当用户为 star 反应付费并将其添加到消息中时,你可以按如下方式处理这些 update。
bot.reaction({ type: "paid" }, (ctx) => ctx.reply("谢谢惠顾!"));
处理任意变化的反应
尽管这在任何官方 Telegram 客户端的 UI 中都不可见,但用户实际上可以一次更改多个反应。 这就是为什么反应 update 会为你提供两个列表:旧反应和新反应。 这允许你的 bot 处理对反应列表的任意更改。
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 允许你使用针对反应类型的特殊的 filter 查询 进一步过滤 update。
// 当前的反应至少包含一个 emoji 的 update。
bot.on("message_reaction:new_reaction:emoji", (ctx) => {/* ... */});
// 之前的反应至少包含一个自定义 emoji 的 update。
bot.on("message_reaction:old_reaction:custom_emoji", (ctx) => {/* ... */});
// 当前反应中包含付费反应的 update。
bot.on("message_reaction:new_reaction:paid", (ctx) => {/* ... */});
2
3
4
5
6
虽然这两个 Reaction
对象 数组在技术上为你提供了处理反应 update 所需的所有信息,但它们用起来仍然有点麻烦。 这就是为什么 grammY 可以从 update 中计算出更多有用的东西。
查看反应如何变化
有一个名为 ctx
的 上下文快捷方式,可让你查看反应到底是如何变化的。
以下是如何使用 ctx
来检测用户是否取消了他们的点赞(但如果他们仍然保持ok手势反应,则原谅他们)。
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
返回四个数组:添加的 emoji、删除的 emoji、保留的emoji,以及一个告诉你更改结果的列表。 此外,还有四个具有类似信息的自定义 emoji 数组。 最后,还有两个布尔标志用于付费反应。
const {
/** 当前存在在该用户的反应中的 emoji */
emoji,
/** 新添加了到该用户的反应中的 emoji */
emojiAdded,
/** 未因该用户反应的 update 而改变的 emoji */
emojiKept,
/** 从该用户的反应中移除的 emoji */
emojiRemoved,
/** 当前存在在该用户的反应中的自定义 emoji */
customEmoji,
/** 新添加了到该用户的反应中的自定义 emoji */
customEmojiAdded,
/** 未因该用户反应的 update 而改变的自定义 emoji */
customEmojiKept,
/** 从该用户的反应中移除的自定义 emoji */
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
关于处理私聊和群聊中的 update 已经说了很多。 我们来看看频道。
处理反应计数 Update
在私聊、群组和超级群组中,我们知道谁对哪条消息做出反应。 但是,对于频道帖子,我们只有一个匿名的反应列表。 我们无法获取对某个帖子做出反应的用户列表。 自动转发到讨论组聊天的频道帖子也是如此。
在这两种情况下,你的 bot 都会收到一个 message
update。
你可以这样处理它。
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
请务必查看 规范 以获取消息反应计数 update。