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

Bot in Discord with discord.js (10)

时间:2022-11-21 13:24:18浏览次数:47  
标签:10 const description discord await Bot US 下拉菜单 Math

Bot in Discord with discord.js (10)

Chapter 11 - 交互四大组件之:下拉菜单 Select Menu

建议你先学习上一章的按钮,再来学习这章的下拉菜单,因为上一章已经比较详细地介绍了 MessageComponentCollector,这里不会重复介绍。

建立一个下拉菜单

下拉菜单(Select Menu)是交互组件(Component)的一种。

在新建一个下拉菜单之前,你需要先导入这里用到的 ActionRowBuilder 和 SelectMenuBuilder。

const { ActionRowBuilder, SelectMenuBuilder } = require('discord.js');

const row = new ActionRowBuilder()
    .addComponents(
        new SelectMenuBuilder()
            .setCustomId('select_1')
            .setPlaceholder('Nothing selected')
            .addOptions(
                {
                    label: 'Las Vegas, NV',
                    description: 'This is a description',
                    value: 'Las_Vegas_NV_US',
                },
                {
                    label: 'Denver, CO',
                    description: 'This is also a description',
                    value: 'Denver_CO_US',
                },
            ),
    );

这个下拉菜单长这样:
image

需要指出的是,customId 是一个由程序员指定的长度不超过 100 字符的字符串。尽量不要让它们的 customId 与其他交互组件的 customId 重复,从而让 filter 更轻松地工作。

每条消息最多可以有五个 ActionRow,一个 ActionRow 中可以有一个选择菜单。

你可以为一条下拉菜单消息指定 ephemeral: trueembeds: [] 来丰富样式。

修改 events/interactionCreate.js

在文件的最后那块儿附近,找到最后一个 else,在这个 else 上面插入一种新情况,用于下拉菜单:

else if (interaction.isSelectMenu()) {
	console.log("a select menu!");
}

如何回复下拉菜单事件:交互事件收集器

建立收集器前,先建立 filter。具体看上一章。不够你也可以直接看下面例子的代码,应该也能看懂。

上一章按钮里讲过,你可以在频道 channel 上建立一个 MessageComponentCollector, 也可以选择在 message 上建立 MessageComponentCollector,二者都能完成对某一条交互事件的收集,但是二者的收集范围各有不同。

(如果代码上文里有 async 的话,才需要用 await)

通过 const collector = await interaction.channel.createMessageComponentCollector() 来在 channel 上建立一个消息事件收集器。

通过 const message = await interaction.fetchReply(); const collector = await mesage.createMessageComponentCollector() 在 bot 最后回复的 message 上建立一个交互组件事件的收集器。

具体看代码:commmands/menus/selectMenu.js

const { ActionRowBuilder, EmbedBuilder, SelectMenuBuilder, SlashCommandBuilder } = require('discord.js');
const wait = require('node:timers/promises').setTimeout;

module.exports = {
    data: new SlashCommandBuilder()
        .setName('selectmenu')
        .setDescription('Replies with a select menu!'),
    async execute(interaction) {

        const row = new ActionRowBuilder()
            .addComponents(
                new SelectMenuBuilder()
                    .setCustomId('select_1')
                    .setPlaceholder('Nothing selected')
                    .addOptions(
                        {
                            label: 'Las Vegas, NV',
                            description: 'This is a description',
                            value: 'Las_Vegas_NV_US',
                        },
                        {
                            label: 'Denver, CO',
                            description: 'This is also a description',
                            value: 'Denver_CO_US',
                        },
                    ),
            );

        const embed1 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Live Weather Report')
            .setURL('https://weather.com/weather/today/l/Las+Vegas+NV?canonicalCityId=8699c391df74aabce6a01ab22e01fd094d01ff77fcc7ef7e314ea4067fbc1066')
            .setDescription(`Las Vegas, NV\nAs of ${Math.floor(Math.random() * 11) + 1}:${10 + Math.floor(Math.random() * 49)} am PST\n38°F\nClear\nDay ${Math.floor(Math.random() * 10) + 55}°F • Night ${35 - Math.floor(Math.random() * 10)}°F`);
        const embed2 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Live Weather Report')
            .setURL('https://weather.com/weather/today/l/3f345b93f02bdea125a122a4798a6b17174a3153bb0f45b4d5238343613d7368')
            .setDescription(`Denver, CO\nAs of ${Math.floor(Math.random() * 11) + 1}:${10 + Math.floor(Math.random() * 49)} am PST\n25°F\nClear\nDay ${Math.floor(Math.random() * 10) + 47}°F • Night ${25 - Math.floor(Math.random() * 10)}°F`);

        await interaction.reply({ content: "Choose a city to see its weather report:", components: [row], embeds: [] });

        const filter = i => {
            return interaction.customId === 'select_1' && i.user.id === interaction.user.id;
        }

        const message = await interaction.fetchReply();
        const collector = message.createMessageComponentCollector(
            filter,
        );

        collector.on('collect', async i=> {
            await i.update({ content: 'Selected! Syncing the weather data...', components: [], embeds:[] });
            await wait(3750); // wait 3.75 secs to emulate the delay of the network
            const city = Array.from(i.values)[0];
            if (city === 'Las_Vegas_NV_US') {
                await i.editReply({content: "Here's your weather report!", embeds: [embed1], components: [row]});
            } else if (city === 'Denver_CO_US') {
                await i.editReply({content: "Here's your weather report!", embeds: [embed2], components: [row]});
            }
        });
    },
};

效果图:
image

image

image

image

多项选择下拉菜单:

前面的下拉菜单是单选的,如果我们需要多选或者对用户的选择数量进行限制比如1到3项呢?

我们可以在建立 SelectMenu 的时候,设置 .setMinValues().setMaxValues() 来指导用户的最少选择量和最大选择量。

比如 commands/menus/multiSelect.js

const { ActionRowBuilder, EmbedBuilder, SelectMenuBuilder, SlashCommandBuilder } = require('discord.js');
const wait = require('node:timers/promises').setTimeout;

module.exports = {
    data: new SlashCommandBuilder()
        .setName('multiselect')
        .setDescription('Replies with a multi-select menu!'),
    async execute(interaction) {

        const row = new ActionRowBuilder()
            .addComponents(
                new SelectMenuBuilder()
                    .setCustomId('select_1')
                    .setPlaceholder('Nothing selected')
                    // here we demand our friendly user to choose more than 2 options while less than 4 options
                    .setMinValues(2)
                    .setMaxValues(4)
                    .addOptions(
                        {
                            label: 'Las Vegas, NV',
                            description: 'This is a description',
                            value: 'Las_Vegas_NV_US',
                        },
                        {
                            label: 'Denver, CO',
                            description: 'This is also a description',
                            value: 'Denver_CO_US',
                        },
                        {
                            label: 'Houston, TX',
                            description: 'This is also a description',
                            value: 'Houston_TX_US',
                        },
                        {
                            label: 'Seattle, WA',
                            description: 'This is also a description',
                            value: 'Seattle_WA_US',
                        },
                        {
                            label: 'Salt Lake City, UT',
                            description: 'This is also a description',
                            value: 'Salt_Lake_City_UT_US',
                        },
                    ),
            );

        const embed1 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Las Vegas\nCity in Nevada')
            .setDescription(`Las Vegas, often known simply as Vegas, is the 25th-most populous city in the United States, the most populous city in the state of Nevada, and the county seat of Clark County. The city anchors the Las Vegas Valley metropolitan area and is the largest city within the greater Mojave Desert.\n` +
                `Sales tax: 8.38%\n` +
                `Time zone: Pacific Standard Time, GMT-8`);
        const embed2 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Denver\nCity in Colorado')
            .setDescription(`Denver, the capital of Colorado, is an American metropolis dating to the Old West era. Larimer Square, the city’s oldest block, features landmark 19th-century buildings. Museums include the Denver Art Museum, an ultramodern complex known for its collection of indigenous works, and the mansion of famed Titanic survivor Molly Brown. Denver is also a jumping-off point for ski resorts in the nearby Rocky Mountains.\n` +
                `Sales tax: 8.81%\n` +
                `Time Zone: Mountain Standard Time, GMT-7`);
        const embed3 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Houston\nCity in Texas')
            .setDescription(`Houston is a large metropolis in Texas, extending to Galveston Bay. It’s closely linked with the Space Center Houston, the coastal visitor center at NASA’s astronaut training and flight control complex. The city’s relatively compact Downtown includes the Theater District, home to the renowned Houston Grand Opera, and the Historic District, with 19th-century architecture and upscale restaurants.\n` +
                `Sales tax: 8.25%\n` +
                `Time zone: Central Standard Time, GMT-6`);
        const embed4 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Seattle\nCity in Washington State')
            .setDescription(`Seattle, a city on Puget Sound in the Pacific Northwest, is surrounded by water, mountains and evergreen forests, and contains thousands of acres of parkland. Washington State’s largest city, it’s home to a large tech industry, with Microsoft and Amazon headquartered in its metropolitan area. The futuristic Space Needle, a 1962 World’s Fair legacy, is its most iconic landmark.\n` +
                `Sales tax: 10.25%\n` +
                `Time zone: Pacific Standard Time, GMT-8`);
        const embed5 = new EmbedBuilder()
            .setColor(0x0099FF)
            .setTitle('Salt Lake City\nCity in Utah')
            .setDescription(`Salt Lake City is the capital and most populous city of Utah, as well as the seat of Salt Lake County, the most populous county in Utah. With a population of 200,133 in 2020, the city is the core of the Salt Lake City metropolitan area, which had a population of 1,257,936 at the 2020 census.\n` +
                `Sales tax: 7.75%\n`+
                `Time zone: Mountain Standard Time, GMT-7`);

        await interaction.reply({ content: "Choose 2-4 cities to make your very own vacation destination list:", components: [row], embeds: [] });

        const filter = i => {
            return interaction.customId === 'select_1' && i.user.id === interaction.user.id;
        }

        const collector = interaction.channel.createMessageComponentCollector(
            filter,
        );

        collector.on('collect', async i=> {
            await i.update({ content: 'Selected! Fetching the detailed data relating to your choices...', components: [], embeds:[] });
            await wait(3150); // wait 3.15 secs to emulate the delay of the network
            await i.editReply({content: "Here's your detailed descriptions related to your choices!", embeds: [], components: []});

            const cityArr = Array.from(i.values);
            if (cityArr.includes('Las_Vegas_NV_US')) {
                await i.followUp({content: "", embeds: [embed1], components: []});
            }
            if (cityArr.includes('Denver_CO_US')) {
                await i.followUp({content: "", embeds: [embed2], components: []});
            }
            if (cityArr.includes('Houston_TX_US')) {
                await i.followUp({content: "", embeds: [embed3], components: []});
            }
            if (cityArr.includes('Salt_Lake_City_UT_US')) {
                await i.followUp({content: "", embeds: [embed4], components: []});
            }
            if (cityArr.includes('Seattle_WA_US')) {
                await i.followUp({content: "", embeds: [embed5], components: []});
            }
        });
    },
};

效果图:

image

image

image

image

其他操作

  • reply()
  • editReply()
  • deferReply()
  • fetchReply()
  • deleteReply()
  • followUp()

获取下拉菜单被选中的值

不论你的下拉菜单是单选、多选还是混合的,下拉菜单返回值是个数组。

  • 比如单选菜单,i 是收集器里收集到的 interaction 变量:

    const value = Array.from(i.values)[0];
    
  • 如果不是单选:

    const valueArr = Array.from(i.values);
    

    此时,你可以用简单的 for 遍历数组里的所有值:

    for (let j=0; j<valueArr.length; j++) {
    	console.log(valueArr[j]);
    }
    

如果你想判断该数组是否包含某项:

if (valueArr.includes('Choice_6')) {
    await i.editReply({content: "You choosed the sixth option", embeds: [], components: []});
}

标签:10,const,description,discord,await,Bot,US,下拉菜单,Math
From: https://www.cnblogs.com/hhzm/p/16911102.html

相关文章

  • Bot in Discord with discord.js (8)
    Chapter9-事件处理Eventhandling这一章只是根据新的discord.jsv14.6.0,对已有文件进行小修小补。如果你是跟着本教程前几章来的,不要跳过本章!根据官方的说法,Node......
  • 10个优秀的AI艺术生成器
    作者|AlexMcFarland编译|岳扬目录​​1.NightCafe[1]​​​​2.DALL-E2[2]​​​​3.DeepDreamGenerator[3]​​​​4.Artbreeder[4]​​​​5.BigSleep​​......
  • 110:特殊方法和运算符重载
    ###特殊方法和运算符重载Python的运算符实际上是通过调用对象的特殊方法实现的。比如:a=20b=30c=a+bd=a.__add__(b)print("c=",c)print("d=",d)输出结果:c......
  • 109:多态
        多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。在现实生活中,我们有很多例子。比如:同样是调用人的休息方法,张三的休息是睡觉,李四的休息......
  • 107:mro()
    Python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左向右”按顺序搜索。MRO(MethodResolutionOrder):方法解析顺序。我们可以通过mro()方......
  • 108:super()获得父类的定义
    在子类中,如果想要获得父类的方法时,我们可以通过super()来做。super()代表父类的定义,不是父类对象。#super()classA:defsay(self):print("A:",self)......
  • 104:object根类_dir()
    ###object根类object类是所有类的父类,因此所有的类都有object类的属性和方法。我们显然有必要深入研究一下object类的结构。对于我们继续深入学习Python很有好处......
  • 105:重写__str__()方法
    ###重写__str__()方法object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮助我们查看对象的信息。__str__()可以重写......
  • Win10系统hosts文件
    Win10系统hosts文件在哪:在Windows系统中,包括XP、Win7、Win8以及最新的Win10系统中,hosts文件都是位于系统盘的Windows文件夹夹下,文件位置路径如下。C:\WINDOWS\system32\driv......
  • CF1034D Intervals of Intervals
    题意:给定\(N\)条线段,定义一个区间的价值为区间线段并的长度,求前\(K\)大区间价值和。题解:首先考虑一个简化版本,求区间线段并。扫描线,维护每个左端点的答案。对于每个......