-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbot.py
159 lines (133 loc) · 5.03 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import discord
from discord.ext import commands, tasks
from dotenv import load_dotenv
import os
import yt_dlp as youtube_dl
from discord import FFmpegPCMAudio
from discord.ext.commands import Bot
import asyncio
from shutil import which
# Load environment variables
load_dotenv()
def get_bot_token():
# Get the Bot Token
return os.getenv("DISCORD_TOKEN")
def create_bot():
# Create the bot
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot_instance = commands.Bot(command_prefix='.', intents=intents)
return bot_instance
def add_commands(bot_instance):
# Define the bot commands
@bot_instance.command()
async def greeting(ctx: commands.Context):
# Greet the user
user = ctx.author
await ctx.reply(f'Hi, {user.display_name}!')
@bot_instance.command()
async def join(ctx):
# Make the bot join the user's voice channel
if ctx.author.voice:
channel = ctx.author.voice.channel
try:
await channel.connect()
except Exception as e:
await ctx.reply(f"Could not join the voice channel. Error: {e}")
else:
await ctx.reply('Please join a voice channel first.')
@bot_instance.command()
async def leave(ctx):
# Make the bot leave the voice channel
if ctx.voice_client:
await ctx.voice_client.disconnect()
else:
await ctx.reply('The bot is not in a voice channel.')
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': True}
FFMPEG_OPTIONS = {
'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn'
}
@bot_instance.command()
async def play(ctx, url: str):
# Play a song from a URL
if not ctx.author.voice:
await ctx.reply("You need to join a voice channel first.")
return
if ctx.voice_client and ctx.voice_client.channel != ctx.author.voice.channel:
await ctx.reply("The bot is already in another voice channel.")
return
if not ctx.voice_client:
try:
channel = ctx.author.voice.channel
await channel.connect()
except discord.errors.ClientException as e:
await ctx.reply(f"Error to connect: {e}")
return
try:
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
if info and info.get('formats') and len(info['formats']) > 0:
audio_url = info['formats'][0]['url']
else:
await ctx.reply("Could not retrieve audio format from the provided URL.")
return
except youtube_dl.DownloadError as e:
await ctx.reply(f"Failed to retrieve the audio. The link might be invalid.\nError: {e}")
return
except Exception as e:
await ctx.reply(f"An unexpected error occurred: {e}")
return
voice_client = ctx.voice_client
if voice_client and voice_client.is_playing():
voice_client.stop()
FFMPEG_PATH = which("ffmpeg")
if not FFMPEG_PATH:
raise RuntimeError("FFmpeg not found. Please install it and add to PATH.")
voice_client.play(
FFmpegPCMAudio(source=audio_url, executable=FFMPEG_PATH, **FFMPEG_OPTIONS), # type: ignore
after=lambda e: print(f"Error playing audio: {e}" if e else "Playback finished.")
)
if not audio_url:
await ctx.reply("Could not retrieve a valid audio URL.")
return
await ctx.reply(f"Now playing: {url}")
@bot_instance.command()
async def pause(ctx):
# Pause the currently playing song
voice_client = ctx.voice_client
if voice_client and voice_client.is_playing():
voice_client.pause()
await ctx.reply('Song paused.')
else:
await ctx.reply('Nothing is playing.')
@bot_instance.command()
async def resume(ctx):
# Resume the currently paused song
voice_client = ctx.voice_client
if voice_client and voice_client.is_paused():
voice_client.resume()
await ctx.reply('Song resumed.')
else:
await ctx.reply('Nothing is paused.')
@bot_instance.command()
async def stop(ctx):
# Stop the currently playing song
voice_client = ctx.voice_client
if voice_client and voice_client.is_playing():
voice_client.stop()
await ctx.reply('Song stopped.')
else:
await ctx.reply('Nothing is playing.')
def setup_events(bot_instance):
@bot_instance.event
async def on_ready():
print(f'The bot "{bot_instance.user}" is ready and connected to {len(bot_instance.guilds)} servers!')
bot = create_bot()
add_commands(bot)
setup_events(bot)
TOKEN = get_bot_token()
if not TOKEN:
raise ValueError("DISCORD_TOKEN not found.")
bot.run(TOKEN)