LoginSignup
0
0

More than 1 year has passed since last update.

【Discord.js V14】スラッシュコマンドのオプションで、既に選択済みの選択肢を2つ目の引数のリストから消す。

Last updated at Posted at 2023-01-31

皆さん初めまして。Morichanと申します。
下記の※の記述を理解したうえで、記事を読んでください。

※DiscordBot開発初心者の書いた記事です。
(また、プログラミング自体、2年ほどのブランクあり)

2つのBOTを別々のVCに参加させるまでの流れに関しては、別の記事にまとめてあります。

関連記事:

目次

  1. 開発環境
  2. スラッシュコマンドのオプションで、既に選択済みの選択肢を2つ目の引数のリストから消す。
  3. 関連記事

開発環境

OS (Windows11)
discord.js (14.7.1)
node.js (18.13.0)
npm (8.19.3)
@discordjs/voice (^0.14.0)

スラッシュコマンドのオプションで、既に選択済みの選択肢を2つ目の引数のリストから消す。

  • Autocompleteを使って、スラッシュコマンドのオプションに渡される選択肢を変更する。
    公式ガイドに沿って記述していきます。

  • index.jsにautocompleteを呼び出す記述を追加する。

// コマンドが送られてきた際の処理
client1.on(Events.InteractionCreate, async interaction => {
    // コマンドでなかった場合は処理せずさよなら。
    // autocompleteが実行されないと困るので、autocompleteでなかった場合も追加。
	if (!interaction.isChatInputCommand() && !interaction.isAutocomplete()) return;

	const command = interaction.client.commands.get(interaction.commandName);
		else {
			await command.execute(interaction);
		}
        // autocompleteの場合に呼び出す。記述を追記。
		if (interaction.isAutocomplete()) {
			await command.autocomplete(interaction);
		}
	} catch (error) {
		console.error(error);
		await interaction.reply({ content: 'コマンドを実行中にエラーが発生しました。', ephemeral: true });
	}
  • join.jsにautocompleteの記述を追記する。
    ※addStringOptionでないとsetAutocompleteが正常に機能しないため、VCの形で取得してきたい場合は、今回の方法は使えない。
    VCの形で取得してくる方法を見つけた方は、ぜひ教えてください。
        .addChannelOption((option) =>
			option
				.setName('channel1')
				.setDescription('The channel that Listener-bot join')
				.setRequired(true)
				.addChannelTypes(ChannelType.GuildVoice),
		)
        // addStringOptionでないとsetAutocompleteが正常に機能しない。
		.addStringOption((option) =>
			option
				.setName('channel2')
				.setDescription('The channel that Speaker-bot join')
                // ここでAutocompleteを使うよと宣言する
				.setAutocomplete(true)
				.setRequired(true),
		),
    // Autocomplete時に呼ばれる処理
	async autocomplete(interaction) {
        // ユーザーが途中まで入力すると表示される選択肢が絞られる機能
		const focusedValue = interaction.options.getFocused();
        // options.getChannelではまだ取得できないため、options.get()で取得。(チャンネルIDが格納されたオブジェクトが返る)
		const vc = interaction.options.get('channel1');
        // すべてのChatを取得(VC以外のテキスト系チャンネルも)
		const chats = interaction.guild.channels.cache;
        // type:2(おそらくVoiceChat形式)を取得することで、全てのVCを取得。
		const voiceChannels = chats.filter(file => file.type === 2);
		let unSelectedVoiceChannels = [];

        // 'channel1'で選択されたVC以外のすべてのVCを変数に格納
		for (const voiceChannel of voiceChannels) {
			if (voiceChannel[0] !== vc.value) {
				unSelectedVoiceChannels.push(voiceChannel);
			}
		}
		
        // フォーカスされているVCを一番最初に持ってくる
		const filtered = unSelectedVoiceChannels.filter(unSelectedVoiceChannel => unSelectedVoiceChannel[1].name.startsWith(focusedValue));

        // 選択肢を渡す処理
		await interaction.respond(
			//Discordの制約で、選択肢は25個以下である必要があるため、.slice()を使って制限をかける。
			filtered.map(unSelectedVoiceChannel => ({ name: unSelectedVoiceChannel[1].name, value: unSelectedVoiceChannel[1].id })).slice(0, 25)
		);
	},
		const voiceChannel1 = interaction.options.getChannel('channel1');
        // addStringOptionに変えたため、取得方法も修正。
		const voiceChannel2 = interaction.options.getString('channel2');
        // Speaker-botがVCに参加する処理
			const connection2 = joinVoiceChannel({
				group: 'speaker',
				guildId: interaction.guildId,
                // channelIdがそのまま渡ってくるので、記述を修正
				channelId: voiceChannel2,
				adapterCreator: client2.guilds.cache.get(interaction.guildId).voiceAdapterCreator,
				selfMute: false,
				selfDeaf: true,
			});
			await interaction.reply('VCに参加しました!');
			return [connection1, connection2];
		}
        // Autocomplete前にここも一度処理されるため、エラーが出ないように削除。(そもそも両方.setRequired(true)のため不要)
		// else {
			// await interaction.reply('BOTを参加させるVCを指定してください!');
		// }
	},

関連記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0