Skip to content

Commit

Permalink
Discordボットにシャッフルコマンドを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
tissueMO committed Jun 10, 2024
1 parent bfbf653 commit 508b508
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 119 deletions.
2 changes: 1 addition & 1 deletion extensions/discord/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:16
FROM node:18

WORKDIR /app

Expand Down
97 changes: 92 additions & 5 deletions extensions/discord/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,84 @@
const { Client, Intents, VoiceState } = require('discord.js');
const {
Client,
GatewayIntentBits,
VoiceState,
VoiceChannel,
} = require('discord.js');
const axios = require('axios').default;
const client = new Client({ intents: Object.keys(Intents.FLAGS) });
const client = new Client({ intents: [GatewayIntentBits.GuildVoiceStates] });
const config = require('./config');

/**
* @type VoiceChannel[]
*/
const shuffleChannels = [];

/**
* ログイン完了後に一度だけ実行されます。
*/
client.on('ready', () => {
console.info(`Botは ${client.user.tag} でログインしています。`)
client.once('ready', async () => {
const guildId = client.guilds.cache.firstKey();

console.info(`Botは ${client.user.tag}@${guildId} でログインしています。`);

// スラッシュコマンドを追加
const commands = config.commands.filter((c) => c.guildId === guildId);
await client.application.commands.set(commands, guildId);
});

/**
* スラッシュコマンドをハンドリングします。
*/
client.on('interactionCreate', async (interaction) => {
const guildName = interaction.guild.name;

if (interaction.isCommand()) {
switch (interaction.commandName) {
case 'shuffle':
console.info(`[${guildName}] コマンド: シャッフル`);

const members = shuffleChannels
.map(c => [...c.members.values()])
.flat()
.sort(() => Math.random() - 0.5);

const groups = chunkArray(members, Math.ceil(members.length / shuffleChannels.length));
groups.forEach((g, i) => console.log(`シャッフル結果(${i + 1}): ${g.map(m => m.user.username).join(', ')}`));

await Promise.allSettled(
groups
.map((g, i) => g.map(m => m.voice.setChannel(shuffleChannels[i])))
.flat()
);

interaction.reply('OK');
break;

case 'shuffle-list':
console.info(`[${guildName}] コマンド: シャッフル一覧`);
interaction.reply(`シャッフル対象のチャンネル: ${shuffleChannels.join(', ')}`);
break;

case 'shuffle-set':
console.info(`[${guildName}] コマンド: シャッフル設定`);

shuffleChannels.splice(0);

const channels = [
interaction.options.getChannel('channel1'),
interaction.options.getChannel('channel2'),
interaction.options.getChannel('channel3'),
interaction.options.getChannel('channel4'),
interaction.options.getChannel('channel5'),
]
channels
.filter(c => c !== null)
.forEach(c => shuffleChannels.push(c));

interaction.reply('OK');
break;
}
}
});

/**
Expand Down Expand Up @@ -47,7 +118,7 @@ const getChangedState = (oldState, newState) => {
if (isEntry) {
if (afterUsedDevices) {
return 'on';
} else {
} else {
return null;
}
}
Expand All @@ -69,6 +140,22 @@ const getChangedState = (oldState, newState) => {
return null;
};

/**
* 配列を指定した要素数ごとに区切って分割します。
* @param {any[]} array
* @param {number} size
* @returns {any[]}
*/
const chunkArray = (array, size) => {
const result = [];

for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size));
}

return result;
};

// プロセス終了時にログアウト
process
.on('SIGINT', () => {
Expand Down
2 changes: 1 addition & 1 deletion extensions/discord/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"dependencies": {
"axios": "^0.27.2",
"discord.js": "^13.7.0"
"discord.js": "^14"
},
"scripts": {
"dev": "yarn && node index.js",
Expand Down
Loading

0 comments on commit 508b508

Please sign in to comment.