musicbot
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
musicbot [2025/09/18 23:32] – created miko | musicbot [2025/09/23 09:25] (current) – [🔐 Insert Your Bot Token] miko | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== 🎵 Ambient Lo-Fi Discord Music Bot – Installation & Usage ====== | + | ====== 🎵 Discord Music Bot – Installation & Usage ====== |
This bot plays ambient lo-fi music automatically in your Discord voice channel. It starts with shuffle, continues playing without stopping, and can be controlled via simple commands. | This bot plays ambient lo-fi music automatically in your Discord voice channel. It starts with shuffle, continues playing without stopping, and can be controlled via simple commands. | ||
Line 17: | Line 17: | ||
===== 🔐 Insert Your Bot Token ===== | ===== 🔐 Insert Your Bot Token ===== | ||
- | Open `bot.py` and replace: | + | Open `.env` and replace: |
- | `bot.run(" | + | < |
with your actual Discord bot token. | with your actual Discord bot token. | ||
- | ===== 🚀 Starting the Bot ===== | + | ===== 🤖 Creating a Discord |
- | To start manually: | + | * Go to https://discord.com/developers/ |
- | `python3 | + | * Click **New Application**, |
+ | * Go to **Bot** tab → click **Add Bot** | ||
+ | * Under **Privileged Gateway Intents**, enable: | ||
+ | - Message Content Intent | ||
+ | - Server Members Intent | ||
+ | * Copy the token and paste it into `bot.py` | ||
- | Or set up a systemd service: | + | ===== 🔗 Invite the Bot to Your Server ===== |
+ | Go to the **OAuth2 → URL Generator** tab: | ||
+ | * Scopes: `bot` | ||
+ | * Bot Permissions: | ||
+ | - Connect | ||
+ | - Speak | ||
+ | - Send Messages | ||
+ | - Read Message History | ||
- | < | + | Copy the generated URL and open it in your browser to invite the bot. |
- | sudo adduser musikbot | + | |
- | sudo chown -R musikbot: | + | |
- | </ | + | |
- | Autostart on server start | + | |
- | < | + | |
- | sudo nano / | + | |
- | </ | + | |
- | < | + | ===== 🚀 Bot ===== |
- | [Unit] | + | Now available on github! |
- | Description=Discord Music Bot | + | |
- | After=network.target | + | |
- | [Service] | + | [[https://github.com/JoranJix/discord-musicbot|discord-musicbot]] |
- | ExecStart=/ | + | |
- | WorkingDirectory=/ | + | |
- | Restart=always | + | |
- | User=musikbot | + | |
- | + | ||
- | [Install] | + | |
- | WantedBy=multi-user.target | + | |
- | </ | + | |
- | + | ||
- | Enable and start the service: | + | |
- | `sudo systemctl daemon-reload` | + | |
- | `sudo systemctl enable musicbot` | + | |
- | `sudo systemctl start musicbot` | + | |
- | + | ||
- | ===== 🎧 Discord Commands ===== | + | |
- | * `!join` – Bot joins your voice channel and starts shuffle playback | + | |
- | * `!leave` – Bot leaves the voice channel | + | |
- | * `!list` – Lists all available MP3 files | + | |
- | * `!play [filename]` – Plays a specific file or a random one if none is given | + | |
- | * `!next` – Skips to the next track | + | |
- | * `!shuffle` – Shuffles the playlist and starts playback | + | |
- | * `!pause` – Pauses playback | + | |
- | * `!resume` – Resumes playback | + | |
- | * `!stop` – Stops playback | + | |
- | * `!help` – Displays all available commands | + | |
- | + | ||
- | ===== 🧠 Notes ===== | + | |
- | * The bot plays continuously without stopping after each track | + | |
- | * Volume is set to 100% | + | |
- | * Make sure the bot has “Speak” permissions in the voice channel | + | |
- | * Works best in standard voice channels (not Stage Channels) | + | |
- | + | ||
- | ===== 📂 Folder Structure ===== | + | |
- | < | + | |
- | /var/www/mbot/ | + | |
- | ├── bot.py | + | |
- | ├── music/ | + | |
- | │ | + | |
- | │ | + | |
- | </code> | + | |
- | <file bot.py> | + | |
- | import | + | |
- | from discord.ext import commands | + | |
- | import os | + | |
- | import random | + | |
- | + | ||
- | intents = discord.Intents.default() | + | |
- | intents.message_content = True | + | |
- | intents.members = True | + | |
- | intents.guilds = True | + | |
- | + | ||
- | bot = commands.Bot(command_prefix=" | + | |
- | + | ||
- | MUSIC_DIR = " | + | |
- | playlist = [] | + | |
- | current_index = -1 | + | |
- | + | ||
- | @bot.event | + | |
- | async def on_ready(): | + | |
- | print(f" | + | |
- | + | ||
- | def play_next_track(ctx): | + | |
- | global playlist, current_index | + | |
- | vc = ctx.voice_client | + | |
- | if not vc or not playlist: | + | |
- | return | + | |
- | + | ||
- | current_index = (current_index + 1) % len(playlist) | + | |
- | filepath = os.path.join(MUSIC_DIR, | + | |
- | source = discord.FFmpegPCMAudio(filepath, | + | |
- | + | ||
- | def after_playing(error): | + | |
- | if error: | + | |
- | print(f" | + | |
- | else: | + | |
- | play_next_track(ctx) | + | |
- | + | ||
- | vc.play(source, | + | |
- | + | ||
- | async def start_shuffle(ctx): | + | |
- | global playlist, current_index | + | |
- | vc = ctx.voice_client | + | |
- | + | ||
- | playlist = [f for f in os.listdir(MUSIC_DIR) if f.endswith(" | + | |
- | if not playlist: | + | |
- | await ctx.send(" | + | |
- | return | + | |
- | + | ||
- | random.shuffle(playlist) | + | |
- | current_index = 0 | + | |
- | filepath = os.path.join(MUSIC_DIR, | + | |
- | source = discord.FFmpegPCMAudio(filepath, | + | |
- | + | ||
- | def after_playing(error): | + | |
- | if error: | + | |
- | print(f" | + | |
- | else: | + | |
- | play_next_track(ctx) | + | |
- | + | ||
- | vc.stop() | + | |
- | vc.play(source, | + | |
- | await ctx.send(f" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def join(ctx): | + | |
- | member = ctx.guild.get_member(ctx.author.id) | + | |
- | if member and member.voice and member.voice.channel: | + | |
- | channel = member.voice.channel | + | |
- | await channel.connect() | + | |
- | await ctx.send(f" | + | |
- | await start_shuffle(ctx) | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def leave(ctx): | + | |
- | if ctx.voice_client: | + | |
- | await ctx.voice_client.disconnect() | + | |
- | await ctx.send(" | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def list(ctx): | + | |
- | files = [f for f in os.listdir(MUSIC_DIR) if f.endswith(" | + | |
- | if not files: | + | |
- | await ctx.send(" | + | |
- | else: | + | |
- | msg = " | + | |
- | await ctx.send(f" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def play(ctx, filename=None): | + | |
- | vc = ctx.voice_client | + | |
- | global playlist, current_index | + | |
- | + | ||
- | if not vc: | + | |
- | await ctx.send(" | + | |
- | return | + | |
- | + | ||
- | if filename: | + | |
- | filepath = os.path.join(MUSIC_DIR, | + | |
- | if not os.path.isfile(filepath): | + | |
- | await ctx.send(" | + | |
- | return | + | |
- | playlist = [filename] | + | |
- | current_index = 0 | + | |
- | else: | + | |
- | playlist = [f for f in os.listdir(MUSIC_DIR) if f.endswith(" | + | |
- | if not playlist: | + | |
- | await ctx.send(" | + | |
- | return | + | |
- | current_index = random.randint(0, | + | |
- | + | ||
- | filepath = os.path.join(MUSIC_DIR, | + | |
- | source = discord.FFmpegPCMAudio(filepath, | + | |
- | + | ||
- | def after_playing(error): | + | |
- | if error: | + | |
- | print(f" | + | |
- | else: | + | |
- | play_next_track(ctx) | + | |
- | + | ||
- | vc.stop() | + | |
- | vc.play(source, | + | |
- | await ctx.send(f" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def next(ctx): | + | |
- | if ctx.voice_client: | + | |
- | play_next_track(ctx) | + | |
- | await ctx.send(" | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def shuffle(ctx): | + | |
- | if ctx.voice_client: | + | |
- | await start_shuffle(ctx) | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def pause(ctx): | + | |
- | if ctx.voice_client and ctx.voice_client.is_playing(): | + | |
- | ctx.voice_client.pause() | + | |
- | await ctx.send(" | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def resume(ctx): | + | |
- | if ctx.voice_client and ctx.voice_client.is_paused(): | + | |
- | ctx.voice_client.resume() | + | |
- | await ctx.send(" | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def stop(ctx): | + | |
- | if ctx.voice_client and ctx.voice_client.is_playing(): | + | |
- | ctx.voice_client.stop() | + | |
- | await ctx.send(" | + | |
- | else: | + | |
- | await ctx.send(" | + | |
- | + | ||
- | @bot.command() | + | |
- | async def help(ctx): | + | |
- | help_text = ( | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | ) | + | |
- | await ctx.send(help_text) | + | |
- | + | ||
- | bot.run(" | + | |
- | </ | + | |
- | ===== 🛟 Support & Extensions ===== | + | |
- | You can expand the bot anytime – with volume control, queue management, or even a web interface. For questions or ideas, feel free to reach out! | + |
musicbot.1758238363.txt.gz · Last modified: by miko