【2025年最新版】Discord音楽Botの作り方初心者向け完全ガイド - Node.jsで超高機能な音楽再生Botを作ろう!
はじめに
「Discordで友達と通話しながら、みんなで音楽を聴きたい!」そんな願いを叶える音楽Botを、Node.jsで一から作ってみませんか?
この記事では、プログラミング初心者の方でも理解できるように、YouTube音楽を再生できる高機能Discord Botの作り方を徹底解説します。完成するBotには、以下のような豪華な機能が搭載されています。
完成するBotの機能一覧
- ✅ YouTube音楽の再生(URLまたは検索ワードで指定可能)
- ✅ プレイリスト対応(最大50曲を一括追加)
- ✅ キュー管理(複数の曲を順番に再生)
- ✅ シャッフル・ループ再生
- ✅ 音量調整・一時停止・スキップ
- ✅ 進行状況バー表示
- ✅ 5分間未使用時の自動退出
それでは、一緒に作っていきましょう!
1. 準備:必要なものをインストールしよう
1-1. Node.jsのインストール
まず、Node.jsをインストールします。Node.jsは、JavaScriptをパソコン上で動かすための環境です。
インストール手順:
- Node.js公式サイトにアクセス
- 「LTS版(推奨版)」をダウンロード
- ダウンロードしたファイルを実行してインストール
インストールできたか確認するため、ターミナル(WindowsならコマンドプロンプトやPowerShell)を開いて以下を実行してください。
bash
node --version
v18.0.0
のようなバージョン番号が表示されればOKです!
1-2. FFmpegのインストール
FFmpegは、音声ファイルを処理するための必須ツールです。
macOSの場合:
bash
brew install ffmpeg
Windowsの場合:
- FFmpeg公式サイトからダウンロード
- 解凍してパスを通す(詳しくは「FFmpeg Windows インストール」で検索)
Linuxの場合:
bash
sudo apt update
sudo apt install ffmpeg
2. Discord Botの作成と招待
2-1. Discord Developer Portalでアプリを作成
- Discord Developer Portalにアクセス
- 「New Application」ボタンをクリック
- 好きな名前を入力(例:「My Music Bot」)
- 左メニューから「Bot」を選択
- 「Add Bot」をクリックしてBotユーザーを作成
2-2. 重要な設定を有効化
Bot設定画面で、以下の設定を必ず有効にしてください:
- ✅ MESSAGE CONTENT INTENT - これがないとメッセージを読み取れません
- ✅ SERVER MEMBERS INTENT(推奨)
- ✅ PRESENCE INTENT(推奨)
2-3. トークンを取得
「TOKEN」セクションで「Reset Token」をクリックし、表示されたトークンをコピーします。
⚠️ 重要: トークンは他人に見せないでください!悪用される可能性があります。
2-4. Botをサーバーに招待
- 左メニューから「OAuth2」→「URL Generator」を選択
- 「SCOPES」で「bot」にチェック
- 「BOT PERMISSIONS」で以下にチェック:
- Send Messages(メッセージ送信)
- Connect(接続)
- Speak(発言)
- Read Message History(メッセージ履歴を読む)
- 画面下部に生成されたURLをコピーしてブラウザで開く
- Botを追加したいサーバーを選択して「認証」
これでBotがサーバーに参加しました!(まだオフライン状態ですが、これから起動させます)
3. プロジェクトのセットアップ
3-1. プロジェクトフォルダの作成
好きな場所に新しいフォルダを作り、そこで作業します。
bash
mkdir discord-music-bot
cd discord-music-bot
3-2. package.jsonの作成
プロジェクトの初期化を行います。
bash
npm init -y
これでpackage.json
というファイルが作成されます。このファイルを開いて、以下のように編集します。
json
{
"name": "discord-music-bot",
"version": "1.0.0",
"description": "Discord音楽再生Bot",
"main": "main.js",
"type": "module",
"scripts": {
"start": "node main.js",
"dev": "node --watch main.js"
},
"dependencies": {
"@discordjs/opus": "^0.9.0",
"@discordjs/voice": "^0.16.1",
"@distube/ytdl-core": "^4.16.12",
"discord.js": "^14.14.1",
"dotenv": "^16.4.1",
"ffmpeg-static": "^5.2.0",
"play-dl": "^1.9.7",
"sodium-native": "^5.0.9",
"youtube-dl-exec": "^3.0.25"
}
}
各パッケージの役割:
discord.js
: Discord APIを簡単に使えるようにするライブラリ@discordjs/voice
: 音声機能を提供play-dl
: YouTube動画の情報取得と再生ytdl-core
: YouTubeストリーミング(予備手段)youtube-dl-exec
: yt-dlpを使った確実な動画取得dotenv
: 環境変数の管理sodium-native
: 音声の暗号化
3-3. 依存関係のインストール
以下のコマンドで、必要なパッケージを一括インストールします。
bash
npm install
これには数分かかる場合があります。コーヒーでも飲んで待ちましょう☕
3-4. 環境変数ファイルの作成
プロジェクトフォルダに.env
というファイルを作成し、以下を記述します。
env
DISCORD_TOKEN=先ほどコピーしたBotのトークン
PREFIX=!
YOUTUBE_COOKIE=cookies.txt
DISCORD_TOKEN
の部分には、Developer Portalでコピーしたトークンを貼り付けてください。
3-5. cookieの設定
Chrome/Edgeの場合
1. 拡張機能「Get cookies.txt LOCALLY」をインストール
- https://chrome.google.com/webstore/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc
2. YouTubeにログイン(https://www.youtube.com)
3. 拡張機能アイコンをクリック
4. 「 ALL Export」をクリック
5. ダウンロードした `cookies.txt` をこのプロジェクトのルートフォルダに配置
Firefoxの場合
1. アドオン「cookies.txt」をインストール
- https://addons.mozilla.org/firefox/addon/cookies-txt/
2. YouTubeにログイン(https://www.youtube.com)
3. アドオンアイコンをクリック
4. 「Current Site」を選択
5. `cookies.txt` として保存し、このプロジェクトのルートフォルダに配置
4. メインコードの実装
いよいよコーディングです!main.js
という名前でファイルを作成し、以下のコードを記述していきます。
4-1. 基本的な構造とインポート
javascript
import { Client, GatewayIntentBits, EmbedBuilder } from 'discord.js';
import {
joinVoiceChannel,
createAudioPlayer,
createAudioResource,
AudioPlayerStatus,
VoiceConnectionStatus,
entersState,
StreamType
} from '@discordjs/voice';
import play from 'play-dl';
import ytdl from '@distube/ytdl-core';
import youtubedl from 'youtube-dl-exec';
import dotenv from 'dotenv';
import { PassThrough } from 'stream';
dotenv.config();
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildVoiceStates,
],
});
const PREFIX = process.env.PREFIX || '!';
const queues = new Map();
解説:
- 必要なモジュールをインポート
dotenv.config()
で.env
ファイルを読み込みintents
でBotが受け取るイベントの種類を指定queues
でサーバーごとの再生キューを管理
4-2. キュー管理クラスの作成
音楽の再生を管理するクラスを作ります。これがBotの心臓部です。
javascript
class MusicQueue {
constructor(guildId, textChannel) {
this.guildId = guildId;
this.textChannel = textChannel;
this.songs = [];
this.connection = null;
this.player = createAudioPlayer();
this.isPlaying = false;
this.currentSong = null;
this.volume = 50;
this.loop = false;
this.loopQueue = false;
this.startTime = null;
// 曲が終わったら次の曲を再生
this.player.on(AudioPlayerStatus.Idle, () => {
if (this.loop && this.currentSong) {
this.songs.unshift(this.currentSong);
} else if (this.loopQueue && this.currentSong) {
this.songs.push(this.currentSong);
}
this.playNext();
});
this.player.on('error', error => {
console.error('プレイヤーエラー:', error.message);
this.playNext();
});
}
addSong(song) {
this.songs.push(song);
}
// ... 他のメソッドは後述
}
クラスのポイント:
songs
: 再生待ちの曲を保存する配列player
: 実際に音楽を再生するプレイヤーloop
: 1曲リピート機能loopQueue
: キュー全体のリピート機能
4-3. 再生機能の実装
javascript
async playNext() {
if (this.songs.length === 0) {
this.isPlaying = false;
this.currentSong = null;
if (this.textChannel) {
this.textChannel.send('✅ キューの再生が完了しました。');
}
return;
}
this.currentSong = this.songs.shift();
this.isPlaying = true;
try {
// yt-dlpを最優先使用(最も信頼性が高い)
const ytdlpStream = youtubedl.exec(this.currentSong.url, {
format: 'bestaudio[ext=webm]/bestaudio',
output: '-',
});
const passThrough = new PassThrough();
ytdlpStream.stdout.pipe(passThrough);
const resource = createAudioResource(passThrough, {
inputType: StreamType.Arbitrary,
inlineVolume: true,
});
this.player.play(resource);
// 再生開始メッセージ
if (this.textChannel) {
const embed = new EmbedBuilder()
.setColor(0x00FF00)
.setTitle('🎵 再生中')
.setDescription(`[${this.currentSong.title}](${this.currentSong.url})`)
.setThumbnail(this.currentSong.thumbnail || '')
.addFields(
{ name: '再生時間', value: formatDuration(this.currentSong.duration), inline: true },
{ name: 'リクエスト', value: this.currentSong.requestedBy, inline: true }
);
this.textChannel.send({ embeds: });
}
} catch (error) {
console.error('再生エラー:', error.message);
this.playNext(); // エラーが出ても次の曲を再生
}
}
3段階フォールバック戦略:
- yt-dlp: 最も確実な方法(第一選択)
- ytdl-core: yt-dlpが失敗した場合の予備
- play-dl: 最後の手段
この3つを組み合わせることで、ほとんどの動画を再生できるようになります。
4-4. playコマンドの実装
ユーザーからのコマンドを処理する部分です。
javascript
client.on('messageCreate', async (message) => {
if (message.author.bot || !message.content.startsWith(PREFIX)) return;
const args = message.content.slice(PREFIX.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
let queue = queues.get(message.guild.id);
if (command === 'play' || command === 'p') {
const voiceChannel = message.member?.voice?.channel;
if (!voiceChannel) {
return message.reply('先にボイスチャンネルに参加してください!');
}
if (!args.length) {
return message.reply('YouTubeのURLまたは検索ワードを入力してください!');
}
const query = args.join(' ');
try {
await message.channel.sendTyping();
let song;
const validateResult = play.yt_validate(query);
if (validateResult === 'video') {
// 直接URLが指定された場合
const songInfo = await play.video_info(query);
song = {
title: songInfo.video_details.title,
url: songInfo.video_details.url,
duration: songInfo.video_details.durationInSec,
thumbnail: songInfo.video_details.thumbnails[0]?.url || '',
requestedBy: message.author.tag,
};
} else {
// 検索ワードの場合
const searchResults = await play.search(query, {
limit: 1,
source: { youtube: 'video' }
});
if (!searchResults || searchResults.length === 0) {
return message.reply('❌ 曲が見つかりませんでした。');
}
const video = searchResults[0];
song = {
title: video.title,
url: video.url,
duration: video.durationInSec,
thumbnail: video.thumbnails[0]?.url || '',
requestedBy: message.author.tag,
};
}
if (!queue) {
queue = new MusicQueue(message.guild.id, message.channel);
queues.set(message.guild.id, queue);
}
queue.addSong(song);
const embed = new EmbedBuilder()
.setColor(0x00FF00)
.setTitle('🎵 キューに追加しました')
.setDescription(`[${song.title}](${song.url})`)
.setThumbnail(song.thumbnail);
await message.reply({ embeds: });
if (!queue.isPlaying) {
await queue.play(voiceChannel);
}
} catch (error) {
console.error('playコマンドエラー:', error);
message.reply('❌ エラーが発生しました。');
}
}
});
このコードのポイント:
play.yt_validate()
でURLか検索ワードかを判定- URLなら直接情報取得、検索ワードなら検索してから取得
- Embedメッセージで見た目を美しく
- エラーハンドリングでBotが落ちないようにする
4-5. その他の便利なコマンド
javascript
// スキップコマンド
else if (command === 'skip' || command === 's') {
if (!queue || !queue.isPlaying) {
return message.reply('再生中の曲がありません。');
}
queue.skip();
message.reply('⏭️ スキップしました。');
}
// キュー表示コマンド
else if (command === 'queue' || command === 'q') {
if (!queue || (!queue.currentSong && queue.songs.length === 0)) {
return message.reply('キューは空です。');
}
let queueList = '';
if (queue.currentSong) {
queueList += `**▶️ 再生中:**\n${queue.currentSong.title}\n\n`;
}
if (queue.songs.length > 0) {
queueList += '**次の曲:**\n';
queue.songs.slice(0, 10).forEach((song, index) => {
queueList += `${index + 1}. ${song.title}\n`;
});
}
const embed = new EmbedBuilder()
.setColor(0xFF00FF)
.setTitle('📜 再生キュー')
.setDescription(queueList);
message.reply({ embeds: });
}
// ループコマンド
else if (command === 'loop' || command === 'l') {
if (!queue) {
return message.reply('再生中の曲がありません。');
}
queue.loop = !queue.loop;
message.reply(queue.loop ? '🔂 1曲ループを有効にしました。' : '▶️ 1曲ループを無効にしました。');
}
4-6. Bot起動処理
javascript
client.once('clientReady', () => {
console.log(`${client.user.tag} としてログインしました!`);
client.user.setActivity('音楽 | !help', { type: 'LISTENING' });
});
client.login(process.env.DISCORD_TOKEN);
5. Botを起動しよう
すべてのコードが揃ったら、いよいよ起動です!
bash
npm start
ターミナルに「としてログインしました!」というメッセージが表示されれば成功です🎉
Discordを開いて、Botがオンラインになっているか確認しましょう。
6. 使ってみよう
基本的な使い方
- ボイスチャンネルに参加
- テキストチャンネルで
!play https://www.youtube.com/watch?v=...
または!play 曲名
- Botが自動的にVCに参加して音楽を再生開始!
便利なコマンド例
bash
# 曲を検索して再生
!play YOASOBI 夜に駆ける
# キューを確認
!queue
# 現在再生中の曲を表示
!nowplaying
# シャッフル
!shuffle
# ループ再生
!loop
# 音量調整(次の曲から反映)
!volume 70
7. よくある問題と解決法
問題1: 「MESSAGE CONTENT INTENT」エラー
解決法: Discord Developer PortalでINTENTを有効にする
問題2: 音が出ない
原因と解決法:
- FFmpegがインストールされていない → インストールし直す
- Botに権限がない → サーバー設定で権限を付与
- トークンが間違っている →
.env
ファイルを確認
問題3: YouTube 403エラー
2024年後半から、YouTubeの保護が強化されています。
解決法:
- Cookieを設定する(推奨・最も効果的)
- 別の動画を試す
- APIを設定する
問題4: 再生が途中で止まる
原因と解決法:
- ネット回線が不安定 → 安定した回線に切り替える
- サーバー負荷が高い → 他のプログラムを終了する
- 動画が削除/非公開 → 別の動画を試す
8. さらに機能を追加するアイデア
このBotはすでに高機能ですが、さらに以下のような機能を追加できます:
追加機能のアイデア
- お気に入り機能: ユーザーごとにプレイリストを保存
- 歌詞表示: Genius APIと連携
- イコライザー: 音質調整機能
- 投票スキップ: 複数人の投票でスキップ
- 24時間配信: 自動で音楽を流し続ける
- Spotify連携: Spotifyのプレイリストにも対応
データベース連携
より高度な機能を実装するなら、MongoDBやSQLiteを使ってデータを永続化しましょう。
bash
npm install mongoose # MongoDBの場合
まとめ
お疲れ様でした!これで、あなただけの高機能Discord音楽Botが完成しました🎉
この記事で学んだこと:
- ✅ Discord Botの作成と招待
- ✅ Node.jsでの非同期プログラミング
- ✅ 音声ストリーミングの処理
- ✅ エラーハンドリングとフォールバック戦略
- ✅ Embedメッセージでの美しいUI作成
このBotをベースに、自分だけのオリジナル機能を追加してみてください。プログラミングは楽しむことが一番大切です!
質問や改善案があれば、ぜひコミュニティで共有してください。それでは、素敵な音楽ライフを!🎵
参考リンク:
この記事は2025年10月時点の最新情報に基づいています。APIの仕様変更により、一部の機能が動作しなくなる可能性があります。