🤖

Discord.jsで一括でユーザーにロールを振ってみる

2024/12/22に公開

この記事はUniMagic Advent Calendar 2024の8日目の記事です(14日遅れ)
一応ゆにまじに関係ある話題です

前提

UniMagicでは生徒向けのアナウンスや授業外でのコミュニケーションのためにDiscordを使用しており、毎期開始時に各生徒さんに所属するクラスのロールを振る必要があります
4期まではロールを付与する作業を人海戦術で行っていましたが、速度や正確性の観点から今期は試験的に自動化を行ってみました

環境

node v22.6
tsx v4.19
discord.js v14.16

解説

import { Client, GatewayIntentBits } from 'discord.js';

const DRY_RUN = false; // trueにすると実際の付与は行わずに結果だけを確認します
const TOKEN = 'aaaaaaaa'; // DiscordのBotトークン
const GUILD_ID = '000000'; // ロール振りを行いたいDiscordサーバーID

const GetRoleIdByDiscordId = (discordId: string): string|undefined => {
  // DiscordのユーザーIDをもとにロールIDを返す関数
  // 各自データソースに合わせて実装してください
  return "";
}


const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers] });

client.on('ready', async() => {
  console.log(`Logged in as ${client.user?.tag}!`);
  const guild = await client.guilds.fetch(GUILD_ID);
  console.log(`Guild: ${guild?.name}`);
  const members = await guild.members.fetch();
  for (const member of members.values()) {
    const roleId = GetRoleIdByDiscordId(member.user.username);
    if (roleId) {
      console.log(`Member: ${member.user.tag}, Role: ${roleId}`);
      if (!DRY_RUN) {
        await member.roles.add(roleId);
      }
    }
  }
  process.exit(0);
});

client.login(TOKEN);

解説

intents

DiscordのBotでは初期化の際に使用する権限を宣言する必要があります

GatewayIntentBits.Guilds

Guild(一般的にサーバーと呼ばれるものをAPI上ではGuildと呼びます)の情報を読み書きするための権限です

GatewayIntentBits.GuildMembers

Guildに所属するユーザーを取得するための権限です
100サーバー以上で使用されるBotの場合はDiscord運営からBotの認証を得る必要があります

client.guilds.fetch

Guildの情報を取得します

guild.members.fetch

Guildに所属する全メンバーを取得します
返り値.values()でメンバーの配列を取得できます

member.roles.add

メンバーに対してロールを追加できます
Botが所有しているロールより上位のロールは付与することができないので適時サーバーの設定からロールの順序を調整する必要があります

さいごに

今後機会があればサーバー参加時に自動的にロール振りを行うBotを作成したいなと考えています

宣伝

魔術学舎United、略してUniMagic(ユニマジック)とは、VRの世界に関係の深い技術を学ぶ学園空間型のイベントです。
15名~18名程度で構成されるクラスで、2週間の授業と1週間の修了制作を通して、技術についての知見を深めていきます。
https://twitter.com/UniMagicVRC

Discussion