【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の仕様変更により、一部の機能が動作しなくなる可能性があります。

Just downloaded forestmouse and wow, it's an absolute banger! The Sprunki music slaps so hard I've been vibing to it all day. Can't wait to see what other secrets are hidden in these woods!