Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What is going on with this article?
@sbhr

Node.jsでユーザ動作に反応するDiscordのBotを作ってみた

More than 3 years have passed since last update.

Discord Advent Carendar 2017 3日目

こういった文を書くのがはじめてなのでお手柔らかにお願いします:bow:

はじめに

DiscordのBotを作るためにいろいろ記事をあさってみた所、
コメントに反応する例や、コマンドを実装する例は見つかったのですが、
ユーザの動作に反応する例が見つからなかったのでその簡単な実装例を記そうと思います。

環境

  • Node.js: 8.9.1
  • eris: 0.8.1

Node.jsの8系がLTSになったので使ってみました。
また、DiscordのAPIのNode.js wrapperとしてerisを使っています。

Botの準備

https://discordapp.com/developers/applications/me
↑のリンクのNew AppからBotを作成します。
スクリーンショット 2017-12-02 15.46.52.png

次にCreate a Bot Userをクリック
スクリーンショット 2017-12-02 15.48.08.png

次に↓のリンクのCLIENT_IDの部分を作成したBotのIDに置き換えて押してください。
https://discordapp.com/oauth2/authorize?&client_id=CLIENT_ID&scope=bot&permissions=0
その後Botを追加するサーバを選択してください。

そして、BotTokenを取得してください。このTokenが必要となります。
スクリーンショット 2017-12-02 15.55.54.png

Botを作る

目的

  • ユーザのゲーム開始/終了のイベントを取得する
  • 通話が開始/終了したイベントを取得する

今回は↑のイベントをトリガーにして、メッセージを投稿するというBotを作ろうと思います。

コード

bot.js
const Eris = require('eris');
// BOT_TOKENには先程取得したTokenを入れてください。
const bot = new Eris("BOT_TOKEN");

// Botの準備が整ったらコンソールに通知
bot.on('ready', () => {
  console.log('Ready!');
});

// presenceUpdate というイベントは
// ユーザまたはrelationship(そのままですみません…)のステータスが変更された時、
// またはゲームが変更された時に発火します。
bot.on('presenceUpdate', (other, oldPresence) => {

  // Botが投稿するためのTextChannelを取得
  // TextChannelが1つの場合を想定しています。
  // 複数ある場合はchannel.id等で判別できます。
  const textChannel = other.guild.channels.find((channel) => channel.type === 0);
  const userName = other.user.username;

  if (other.game) { // ゲームが始まった時
    const gameName = other.game.name;
    bot.createMessage(textChannel.id, `${userName}${gameName} をはじめました`);
  } else if (oldPresence.game) { // ゲームを終了した時
    const gameName = oldPresence.game.name;
    bot.createMessage(textChannel.id, `${userName}${gameName} を終了しました`);
  }

});

// voiceChannelJoin というイベントは
// ユーザが音声チャンネルに参加した時に発火します。
bot.on('voiceChannelJoin', (member, newChannel) => {
  const textChannel = newChannel.guild.channels.find((channel) => channel.type === 0);
  const msg = `${member.username} が通話をはじめました`;
  bot.createMessage(textChannel.id, msg);
});

// voiceChannelLeave というイベントは
// ユーザが音声チャンネルから退出した時に発火します。
bot.on("voiceChannelLeave", (member, oldChannel) => {
  const textChannel = oldChannel.guild.channels.find((channel) => channel.type === 0);
  const msg = `${member.username} が通話をやめました`;
  bot.createMessage(textChannel.id, msg);
});

// BotをDiscordに接続します
bot.connect();

2017/12/06 修正 voiceChannelLeave の変数名を修正しました。

まとめ

ユーザがゲームを始めたり、通話を開始したらメッセージを投稿するBotを作ってみました。
今回はイベント発火時にユーザ名やゲーム名を取得していますが、他にもゲームの開始時間を取得してプレイ時間を出したり、ユーザのIDを取得してメンションを飛ばしたりすることができるので試してみてください。

初めての記事なので読みにくいとは思いますが手助けになれば幸いです。
間違っている点や改善点等あればコメントにて教えていただける助かります。

補足

erisはドキュメントがしっかりしているので、見ればだいたい分かると思います。
Botが取得できるイベントはこちらにあります。

はじめにでも書きましたが、ユーザのコメントに反応する例や、任意のプレフィックスをつけてコマンドを作成する例はerisのexampleに例がありますのでそちらをご覧ください。

11
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
sbhr

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
11
Help us understand the problem. What is going on with this article?