LoginSignup
3
6

More than 1 year has passed since last update.

Discord.jsでWebhookを利用したグローバルチャットの作り方

Last updated at Posted at 2020-10-16

はじめに

この記事では、webhookを利用したグローバルチャットのサンプルコードを書きます。
投稿するのは、初めてなので何か間違っていたら、教えてください。

追記

この記事のコードは最新のdiscord.jsには対応していません。
暇があればdiscord.js v13向けのものを書きます(その頃には既にほかの人が書いてるかも)

必要なもの

  • fs
  • discord.js v12.3.0
  • Botアカウント

(Botアカウントの設定や、Discord.js、fsのインストールなどはすでに済ませている前提で書きます。)

コード

const Discord = require("discord.js")
const client = new Discord.Client()
const fs = require("fs")
const prefix = "?"

client.on("ready", () => {
  console.log(client.user.tag + "でログイン中")
});
client.on("message", message => {
  if (message.author.bot) {
    return;
  }
  if (message.channel.type == "dm") {
    return;
  }
  if (message.content == prefix+"globalchatjoin") {
    if (!message.channel.permissionsFor(message.guild.me).has("MANAGE_WEBHOOKS")) {
      message.channel.send("Webhookを作成する権限がありません。")
      return;
    }
    message.channel.createWebhook('グローバルチャット用webhook').then(webhook => {
      var webhookinfo = {
        "id": webhook.id,
        "token": webhook.token,
        "channel": message.channel.id
      }
      var savedata = JSON.stringify(webhookinfo);
      try {
        fs.mkdirSync(`globalchatfiles/${message.guild.id}/`, { recursive: true });
        fs.writeFileSync(`globalchatfiles/${message.guild.id}/webhook.json`, savedata);
        //成功すれば、Webhookが保存されます。
      }
      catch (error) {
        message.channel.send("参加できませんでした。")
        return;
      }
      var sentchannelid = webhook.channel
      const webhooks = new Discord.WebhookClient(webhook.id, webhook.token)
      webhooks.send("グローバルチャットに参加しました。")
      //ほかのサーバーに参加通知を送る
      //サーバーごとにファイルを読み込んで、webhookで送信する。
      client.guilds.cache.forEach(guild => {
        try {
          var webhookjoined = JSON.parse(fs.readFileSync(`globalchatfiles/${guild.id}/webhook.json`))
        } catch (err) {
          return;
          //参加していなければ、そのサーバーはパスする。
        }
        var channelid = webhookjoined.channel
        try {
          client.channels.cache.get(channelid).id
        }
        catch (error) {
          return;
          //チャンネルが削除されていたら、動作をキャンセルするコード。
        }
        var webhookid = webhookjoined.id
        var webhooktoken = webhookjoined.token
        if (message.channel.id == sentchannelid) return;
        if (message.guild.id == guild.id) return;
        try {
          new Discord.WebhookClient(webhookid, webhooktoken).send(message.guild.name + "が、グローバルチャットに参加しました。", { username: "グローバルチャットマネージャー", disableMentions: "all"})
        } catch (error) {

        }
      })
      //webhookは、チャンネルごとに10個までしか作れないので、作成できなかった場合には、参加成功メッセージが来ない仕組み。
    }).catch(console.error);
  } 
});
client.on("message", message => {
  if (message.author.bot) {
    return;
  }
  if (message.channel.type == "dm") {
    return;
  }
  try {
    const guild_webhook = JSON.parse(fs.readFileSync(`globalchatfiles/${message.guild.id}/webhook.json`))
    var sentchannelid = guild_webhook.channel
  } catch (error) {
    return;
    //読み取れなかった場合、ほとんどの場合は参加していないのでリターンする。
  }
  if (message.channel.id == sentchannelid) {
    //サーバーごとにファイルを読み込んで、webhookで送信する。
    client.guilds.cache.forEach(guild => {
      try {
        var webhook = JSON.parse(fs.readFileSync(`globalchatfiles/${guild.id}/webhook.json`))
      } catch (err) {
        return;
        //参加していなければ、そのサーバーはパスする。
      }
      var channelid = webhook.channel
      try {
        client.channels.cache.get(channelid).id
      }
      catch (error) {
        return;
        //チャンネルが削除されていたら、動作をキャンセルするコード。
      }
      var webhookid = webhook.id
      var webhooktoken = webhook.token
      const serverwebhook = new Discord.WebhookClient(webhookid, webhooktoken)
      if (message.channel.id == channelid) return;
      if (message.guild.id == guild.id) return;
      try {
        serverwebhook.send(message.content, { username: message.author.tag, avatarURL: `https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png`, disableMentions: "all"})
      } catch (error) {
      }
    })
  }
});

client.login("トークンをここに記述")

これ単体でも、Botは動くと思うので、お試しください。

説明

権限不足時

if (!message.channel.permissionsFor(message.guild.me).has("MANAGE_WEBHOOKS")) {
  message.channel.send("Webhookを作成する権限がありません。")
  return;
}

このコードは、webhookを作る権限がBotに与えられていないときにキャンセルするためのコード

disableMentions

webhookで送信するときのコードに書かれている disableMentions: "all" は、@everyoneや、ユーザーに対するメンションを無効化するためのコード
(ユーザーに対するメンションを許可するには、everyoneに設定する。)

参考サイト

公式ドキュメント

3
6
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
3
6