首页 > 其他分享 >Bot in Discord with discord.js (8)

Bot in Discord with discord.js (8)

时间:2022-11-21 12:12:01浏览次数:70  
标签:category interaction const discord Bot js autocomplete choice

Chapter 9 - 事件处理 Event handling

这一章只是根据新的 discord.js v14.6.0,对已有文件进行小修小补。

如果你是跟着本教程前几章来的,不要跳过本章!

根据官方的说法,Node.js 使用事件驱动的架构,使得在特定事件发生时执行特定代码成为可能。discord.js 库就充分利用了这一点。

修改后的 events/interactionCreate.js

const { Events } = require('discord.js');

module.exports = {
	name: Events.InteractionCreate,
	execute(interaction) {
		console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an interaction.`);
	},
};

修改后的 events/ready.js

const { Events } = require('discord.js');

module.exports = {  
   name: Events.ClientReady,  
   once: true,  
   execute(client) {  
      console.log(`Ready! Logged in as ${client.user.tag}`);  
   },  
};

修改后的 index.js

这个文件改动的地方不算多,但是把完整源码粘贴过来又显得冗杂,因此,我把这次的 git commit 地址放在这里,大家可以自己点开去看。

https://github.com/wtflmao/discord_bot_example/commit/f6eeddd2d975cb43803075e884bbc4d7174f6dfe

Chapter 10 自动完成 Autocomplete

自动完成允许根据用户的输入动态地向用户提供一系列值,而不是依赖于静态选项。你需要学习 Chapter 6 的 Option 才能继续学习本章。换句话说,Autocomplete 只是服务于 Option 的。

用户被自动完成提供了一些 choices,但是用户可以键入执行除了给定的 choices 以外的其他任意合法值。想像一个新闻搜索机器人,query 项用于接收关键词。用户可以键入任何字符串,但是为了方便用户使用,机器人维护了一个“24小时热搜前一百”的列表,用户只需输入某个字或词,就能把列表里所有相关的新闻标题作为选项展示给用户,以减少用户输入量。当然用户也可以输入自己任何想搜的,不受热搜的限制。

在使用自动完成之前,一定要根据 Chapter 9 的内容,修改你的机器人代码,因为 Chapter 9 对 index.js 和 events/interactionCreate.js 做了大改。本章开始的代码直接跑在前八章里是会报错的。

自动完成举例:commands/autocomplete.js

const { SlashCommandBuilder } = require('discord.js');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('autocomplete')
		.setDescription('Autocomplete test.')
		.addStringOption(option =>
			option.setName("category")
				.setDescription("The category you'd like to dive in")
				.setAutocomplete(true)),
	async autocomplete(interaction) {
		
		const focusedValue = interaction.options.getFocused();
		const choices = ['beer', 'coffee', 'milk', 'apple', 'banana', 'tea', 'zebra'];
		const filtered = choices.filter(choice => choice.includes(focusedValue));
		await interaction.respond(
			filtered.map(choice =>({ name: choice, value: 'v_' + choice })),
		).then(() => console.log('Successfully responded to the autocomplete interaction'))
 		.catch(console.error);
	},
	async execute(interaction) {
		const category = interaction.options.getString("category");
		await interaction.reply(`You acquired some ${category}.`);
	},
};

解析:通过 .setAutoComplete(true) 来开启一个 Option 的自动完成。

autocomplete() 函数里:

通过 interaction.options.getFocused() 获取用户在该域内实时键入的值。

我们用 choices 数组维护了一些用户可能会输入的字符串,通过 choices.filter(choice => choice.includes(focusedValue) (实时键入的字符串是否是 choices 数组某个元素的字串与否)来判断是否要将该元素加入到针对目前实时键入的值的自动完成响应里去。比如,用户输入 "ee",能匹配 "beer" 和 "coffee"。

interaction.respond() 用于向用户响应自动完成列表。

程序执行到现在,用户应还未回车执行命令。

execute() 函数里:

这里是我们最常见的斜杠命令的函数主题了,执行到这里意味着用户已经敲击了回车,执行了斜杠命令。

这里是实时输入"ee"时,根据我们 filter 设定的规则,自动完成匹配到的:
image

当我们执行 /autocomplete category: news时:
image

用户的最终输入可以与自动完成的无关,就像没有自动完成的普通 Option 那样对待:
执行 /autocomplete category: news
image

我们没有对 category 域设置必填,等价于 .setRequired(false)。因此不理会这个域执行命令也是可以的:
执行 /autocomplete
image

多个 Option 的 Autocomplete

上代码:commands/autocomplete2.js

const { SlashCommandBuilder } = require('discord.js');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('autocomplete2')
		.setDescription('Multi-Autocomplete test.')
		.addStringOption(option =>
			option.setName("category")
				.setDescription("The category you'd like to dive in")
				.setAutocomplete(true)
				.setRequired(true))
		.addNumberOption(option =>
			option.setName("amount")
				.setDescription("How many you want")
				.setAutocomplete(true)
				.setRequired(true)),
	async autocomplete(interaction) {
		
		const focusedOption = interaction.options.getFocused(true);

		if(focusedOption.name === "category") {

			const choices = ['beer', 'coffee', 'milk', 'apple', 'banana', 'tea', 'zebra'];
			const filtered = choices.filter(choice => choice.includes(focusedOption.value));
			await interaction.respond(
				filtered.map(choice =>({ name: choice, value: choice })),
			).then(() => console.log('Successfully responded to the autocomplete interaction'))
	 		.catch(console.error);

		}

		if(focusedOption.name === "amount") {

			const choices = [12, 24, 48, 81, 9];
			const filtered = choices.filter(choice => `${choice}`.includes(`${focusedOption.value}`));
			await interaction.respond(
				filtered.map(choice =>({ name: `${choice}`, value: choice })),
			).then(() => console.log('Successfully responded to the autocomplete interaction'))
	 		.catch(console.error);
 		
		}
	},
	async execute(interaction) {
		const category = interaction.options.getString("category");
		const amount = interaction.options.getNumber("amount");
		// P.S. .getUser(), .getMember(), .getRole(), .getChannel(), .getMentionable() and .getAttachment() methods are not available to autocomplete interactions.
		// but .getBoolean(), .getInteger() are available
		await interaction.reply(`You acquired ${amount} of ${category}.`);
	},
};

我们设置了两个 Option,一个叫 category,类型是字符串型;另一个叫 amount,类型是 Number 型。

针对字符串和 Number 的值处理是不同的,这也使得我们用 if(focusedOption.name === "category") if(focusedOption.name === "amount") 来分别处理他们。

注意,对 autocomplete() 的调用是实时关于用户键入的。这意味着,用户(以一个不太快的速度)每敲一个字符,Discord 客户端都会向机器人后台请求一遍新的 Autocomplete 结果列表。

执行 /autocomplete2 category: tea amount: 24
image

执行 /autocomplete2 category: zombie amount: 7
image

允许设置 Autocomplete 的只有 string、integer、boolean 和 number 四类 Option。

const string = interaction.options.getString('input');
const integer = interaction.options.getInteger('int');
const boolean = interaction.options.getBoolean('choice');
const number = interaction.options.getNumber('num');

像 .getUser(), .getMember(), .getRole(), .getChannel(), .getMentionable() and .getAttachment(),都不能设置自动完成。

其他注意的地方

  • 与其他应用程序命令交互一样,自动完成交互必须在 3 秒内收到响应。
  • 您不能推迟对自动完成交互的响应。 如果您正在处理异步建议,例如等待来自 API 的数据,请考虑保留本地缓存。
  • 用户选择一个值并发送命令后,将作为常规接收 ChatInputCommandInteraction 与 Option 的值。
  • 您一次最多只能回复 25 项,但如果超过这个数,则可能意味着您应该修改过滤器以进一步缩小选择范围。

标签:category,interaction,const,discord,Bot,js,autocomplete,choice
From: https://www.cnblogs.com/hhzm/p/16900138.html

相关文章

  • JS中this在【全局、事件绑定、对象定义、构造函数】下的理解
    学前端也好久啦,看了很多文档,结合自己的一点经验来讲,对于this,最通俗易懂的理解就是:函数在哪里调用的,this就指向哪里。首先看个例子:这里的函数getFullName,在哪里调用呢,是不......
  • js 数组对象根据多个key值进行分类
    constlist=[{id:1,name:"手机1",orderNo:"6901443393268",sku:"51095BKR"},{id:2,name:"手机2",orderNo:"6901443393262",sku:"51095BBQ"},{id......
  • 陪你去看 Lodash.js 起步
    lodash起步(数组)Lodash是一个较为流行的JavaScript的实用工具库。在开发过程中如果能熟练使用一些工具库提供的方法,有利于提高​​开发效率​​。笔者从API上入手,不分......
  • js-001
    JavaScript独立的语言,浏览器具有js解释器JavaScript代码存在形式:-Head中<script>//javascript代码alert(123);......
  • 48、OAK通过共享内存传递变长结构体(Rapidjson)进行数据和图片交互
    基本思想:主要学习一下在共享内存中传递变长的数据,这样在c#调用c++dll也可以雷同操作,以oak的检测和共享内存为代码整合,集成了rapidjson的使用,代码自己摘要和参考吧cmakelist......
  • js中的base64转化
    创建一个base64.js文件,将以下代码粘贴进去varBase64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){......
  • c#/JS RSA 非对称加密
    可以用到前端加密,后端解密,或者后端加解密首先要知道这这个rsa是需要一个公钥一个私钥进行加解密的,公钥加密,私钥解密。可以去百度在线生成。脚本或者页面中先引用jsencry......
  • 一个jsqlparse+git做的小工具帮我节省时间摸鱼
    背景前些时间做了个小工具解决了团队内数据库脚本检验&多测试环境自动执行的问题,感觉挺有意思,在这跟大家分享一下。工具诞生之前的流程是这样:1.开发人员先在开发环境编......
  • nodejs版本管理工具nvm
    linux版本安装curl-o-https://gitee.com/Annlix/nvm-sh_nvm/raw/master/install.sh|bash查看nodejs版本nvmls-remote安装指定版本nvminstallv16.18.1......
  • jsencypt (RSA加密工具)
    配置npminstalljsencrypt--dev建立jsencrypt.js文件importJSEncryptfrom'jsencrypt/bin/jsencrypt.min'//密钥对生成http://web.chacuo.net/netrsakeypair;......