diff options
author | Parker <contact@pkrm.dev> | 2024-08-03 02:55:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-03 02:55:32 +0000 |
commit | 608fad20d4f8cf977c39a47a9e30865bda57adfe (patch) | |
tree | 47b1ad56786f89c36d1c4eb0c67713c6b6a87d62 /code | |
parent | 1bffa26776f6c80e2f2513d236f78ce9b7eea39f (diff) | |
parent | 3f23ef4edf5a33c3c184c8b92fc5143789cecbd1 (diff) |
Merge pull request #2 from PacketParker/dev
Update main
Diffstat (limited to 'code')
-rw-r--r-- | code/bot.py | 59 | ||||
-rw-r--r-- | code/cogs/help.py | 7 | ||||
-rw-r--r-- | code/cogs/lyrics.py | 78 | ||||
-rw-r--r-- | code/cogs/news.py | 5 | ||||
-rw-r--r-- | code/cogs/play.py | 8 | ||||
-rw-r--r-- | code/utils/config.py | 372 |
6 files changed, 330 insertions, 199 deletions
diff --git a/code/bot.py b/code/bot.py index 2864e85..3569e68 100644 --- a/code/bot.py +++ b/code/bot.py @@ -3,6 +3,7 @@ from discord.ext import commands, tasks import os import requests import openai +import lyricsgenius import utils.config as config from utils.command_tree import Tree @@ -19,24 +20,38 @@ class MyBot(commands.Bot): ) async def setup_hook(self): + # Get Spotify, Apple Music, Genius, and OpenAI access tokens/clients get_access_token.start() refresh_media_api_key.start() + login_genius.start() + if config.OPENAI_API_KEY: + bot.openai = openai.OpenAI(api_key=config.OPENAI_API_KEY) + config.LOG.info("Loading cogs...") for ext in os.listdir("./code/cogs"): if ext.endswith(".py"): + # Load the OPTIONAL feedback cog if ext[:-3] == "feedback" and config.FEEDBACK_CHANNEL_ID == None: config.LOG.info("Skipped loading feedback cog - channel ID not provided") continue + # Load the OPTIONAL bug cog if ext[:-3] == "bug" and config.BUG_CHANNEL_ID == None: config.LOG.info("Skipped loading bug cog - channel ID not provided") continue + # Load the OPTIONAL lyrics cog + if ext[:-3] == "lyrics" and config.GENIUS_CLIENT_ID == None: + config.LOG.info("Skipped loading lyrics cog - Genius API credentials not provided") + continue + # Load the OPTIONAL autoplay cog + if ext[:-3] == "autoplay" and config.OPENAI_API_KEY == None: + config.LOG.info("Skipped loading autoplay cog - OpenAI API credentials not provided") + continue + await self.load_extension(f"cogs.{ext[:-3]}") for ext in os.listdir("./code/cogs/owner"): if ext.endswith(".py"): await self.load_extension(f"cogs.owner.{ext[:-3]}") - bot.openai = openai.OpenAI(api_key=config.OPENAI_API_KEY) - async def on_ready(self): config.LOG.info(f"{bot.user} has connected to Discord.") config.LOG.info(f"Startup complete. Sync slash commands by DMing the bot {bot.command_prefix}tree sync (guild id)") @@ -50,15 +65,19 @@ bot.autoplay = [] # guild_id, guild_id, etc. @tasks.loop(minutes=45) async def get_access_token(): - auth_url = "https://accounts.spotify.com/api/token" - data = { - "grant_type": "client_credentials", - "client_id": config.SPOTIFY_CLIENT_ID, - "client_secret": config.SPOTIFY_CLIENT_SECRET, - } - response = requests.post(auth_url, data=data) - access_token = response.json()["access_token"] - bot.spotify_headers = {"Authorization": f"Bearer {access_token}"} + if config.SPOTIFY_CLIENT_ID and config.SPOTIFY_CLIENT_SECRET: + auth_url = "https://accounts.spotify.com/api/token" + data = { + "grant_type": "client_credentials", + "client_id": config.SPOTIFY_CLIENT_ID, + "client_secret": config.SPOTIFY_CLIENT_SECRET, + } + response = requests.post(auth_url, data=data) + if response.status_code == 200: + access_token = response.json()["access_token"] + bot.spotify_headers = {"Authorization": f"Bearer {access_token}"} + else: + bot.spotify_headers = None @tasks.loop(hours=24) @@ -73,6 +92,24 @@ async def refresh_media_api_key(): bot.apple_headers = None +@tasks.loop(hours=1) +async def login_genius(): + if config.GENIUS_CLIENT_ID and config.GENIUS_CLIENT_SECRET: + auth_url = "https://api.genius.com/oauth/token" + data = { + "client_id": config.GENIUS_CLIENT_ID, + "client_secret": config.GENIUS_CLIENT_SECRET, + "grant_type": "client_credentials", + } + response = requests.post(auth_url, data=data) + if response.status_code == 200: + access_token = response.json()["access_token"] + bot.genius = lyricsgenius.Genius(access_token) + bot.genius.verbose = False + else: + bot.genius = None + + if __name__ == "__main__": config.load_config() bot.run(config.TOKEN) diff --git a/code/cogs/help.py b/code/cogs/help.py index 3746482..97af668 100644 --- a/code/cogs/help.py +++ b/code/cogs/help.py @@ -70,6 +70,10 @@ commands_and_descriptions = { "description": "Resume the song that is currently paused", "usage": "/resume", }, + "lyrics": { + "description": "Get the lyrics of the song that is currently playing", + "usage": "/lyrics", + }, "news": { "description": "Get recent news and updates about the bot", "usage": "/news", @@ -88,7 +92,8 @@ commands_and_descriptions = { class HelpView(discord.ui.View): def __init__(self, timeout=180.0): super().__init__(timeout=timeout) - self.add_item(discord.ui.Button(label="Invite Me", url=BOT_INVITE_LINK, row=1)) + if BOT_INVITE_LINK: + self.add_item(discord.ui.Button(label="Invite Me", url=BOT_INVITE_LINK, row=1)) @discord.ui.button( label="View All Commands", style=discord.ButtonStyle.green, row=1 diff --git a/code/cogs/lyrics.py b/code/cogs/lyrics.py new file mode 100644 index 0000000..b3a918f --- /dev/null +++ b/code/cogs/lyrics.py @@ -0,0 +1,78 @@ +import discord +import datetime +from discord import app_commands +from discord.ext import commands +from cogs.music import Music + +from utils.config import BOT_COLOR + + +class Lyrics(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @app_commands.command() + @app_commands.check(Music.create_player) + async def lyrics(self, interaction: discord.Interaction): + "Get lyrics for the song that is currently playing" + player = self.bot.lavalink.player_manager.get(interaction.guild.id) + + # If the Genius API client is not setup, send an error message + if not self.bot.genius: + embed = discord.Embed( + title="Lyrics Feature Error", + description="The lyrics feature is currently disabled due to errors with the Genius API.", + color=BOT_COLOR, + ) + embed.set_footer( + text=datetime.datetime.now(datetime.timezone.utc).strftime( + "%Y-%m-%d %H:%M:%S" + ) + + " UTC" + ) + return await interaction.response.send_message(embed=embed, ephemeral=True) + + # Search for the songs lyrics with Genius + song = self.bot.genius.search_song(player.current.title, player.current.author) + + # If no lyrics are found, send an error message + if song is None: + embed = discord.Embed( + title="Lyrics Not Found", + description="Unfortunately, I wasn't able to find any lyrics for the song that is currently playing.", + color=BOT_COLOR, + ) + embed.set_thumbnail(url=player.current.artwork_url) + embed.set_footer( + text=datetime.datetime.now(datetime.timezone.utc).strftime( + "%Y-%m-%d %H:%M:%S" + ) + + " UTC" + ) + + return await interaction.response.send_message(embed=embed, ephemeral=True) + + # Remove unwanted text + lyrics = song.lyrics + lyrics = lyrics.split(" Lyrics", 1)[-1] + lyrics = lyrics.replace("You might also like", "\n") + lyrics = lyrics[:-7] + + embed = discord.Embed( + title=f"Lyrics for {player.current.title} by {player.current.author}", + description=lyrics, + color=BOT_COLOR, + ) + embed.set_thumbnail(url=player.current.artwork_url) + embed.set_footer( + text=datetime.datetime.now(datetime.timezone.utc).strftime( + "%Y-%m-%d %H:%M:%S" + ) + + " UTC" + ) + + await interaction.response.send_message(embed=embed, ephemeral=True) + + +async def setup(bot): + await bot.add_cog(Lyrics(bot)) diff --git a/code/cogs/news.py b/code/cogs/news.py index c115559..9013567 100644 --- a/code/cogs/news.py +++ b/code/cogs/news.py @@ -19,6 +19,11 @@ class News(commands.Cog): ) embed.add_field( + name="**Lyrics!**", + value="> You can now get lyrics for the song that is currently playing. Just use the `/lyrics` command! Some songs may not have lyrics available, but the bot will do its best to find them.", + ) + + embed.add_field( name="**Apple Music Support!**", value="> After some trial and error, you can now play music through Apple Music links. Just paste the link and the bot will do the rest!", ) diff --git a/code/cogs/play.py b/code/cogs/play.py index db21cf7..fdd0233 100644 --- a/code/cogs/play.py +++ b/code/cogs/play.py @@ -147,6 +147,14 @@ class Play(commands.Cog): ### elif "open.spotify.com" in query: + if not self.bot.spotify_headers: + embed = discord.Embed( + title="Spotify Error", + description="Spotify support seems to be broken at the moment. Please try again and fill out a bug report with </bug:1224840889906499626> if this continues to happen.", + color=BOT_COLOR, + ) + return await interaction.response.send_message(embed=embed, ephemeral=True) + embed = discord.Embed(color=BOT_COLOR) if "open.spotify.com/playlist" in query: diff --git a/code/utils/config.py b/code/utils/config.py index f319792..951676e 100644 --- a/code/utils/config.py +++ b/code/utils/config.py @@ -1,10 +1,13 @@ -import configparser +import jsonschema import re import os +import yaml import validators +import openai import sys import discord import logging +import requests from colorlog import ColoredFormatter log_level = logging.DEBUG @@ -30,230 +33,225 @@ FEEDBACK_CHANNEL_ID = None BUG_CHANNEL_ID = None SPOTIFY_CLIENT_ID = None SPOTIFY_CLIENT_SECRET = None +GENIUS_CLIENT_ID = None +GENIUS_CLIENT_SECRET = None OPENAI_API_KEY = None LAVALINK_HOST = None LAVALINK_PORT = None LAVALINK_PASSWORD = None -""" -Load the config.ini file and return the contents for validation or -create a new templated config.ini file if it doesn't exist. -""" - - +schema = { + "type": "object", + "properties": { + "bot_info": { + "type": "object", + "properties": { + "token": {"type": "string"}, + "bot_color": {"type": "string"}, + "bot_invite_link": {"type": "string"}, + "feedback_channel_id": {"type": "integer"}, + "bug_channel_id": {"type": "integer"}, + }, + "required": ["token"], + }, + "spotify": { + "type": "object", + "properties": { + "spotify_client_id": {"type": "string"}, + "spotify_client_secret": {"type": "string"}, + }, + "required": ["spotify_client_id", "spotify_client_secret"], + }, + "genius": { + "type": "object", + "properties": { + "genius_client_id": {"type": "string"}, + "genius_client_secret": {"type": "string"}, + }, + "required": ["genius_client_id", "genius_client_secret"], + }, + "openai": { + "type": "object", + "properties": { + "openai_api_key": {"type": "string"}, + }, + "required": ["openai_api_key"], + }, + "lavalink": { + "type": "object", + "properties": { + "host": {"type": "string"}, + "port": {"type": "integer"}, + "password": {"type": "string"}, + }, + "required": ["host", "port", "password"], + }, + }, + "required": ["bot_info", "lavalink"], +} + + +# Attempt to load the config file, otherwise create a new template def load_config(): - # Look for variables in the environment - if "TOKEN" in os.environ or "BOT_COLOR" in os.environ or "BOT_INVITE_LINK" in os.environ: - LOG.info("Detected environment variables. Checking for configuration options.") - return validate_env_vars() + if os.path.exists("/.dockerenv"): + file_path = "/config/config.yaml" else: - LOG.info("Detected local environment. Checking for config.ini file.") + file_path = "config.yaml" try: - with open("config.ini", "r") as f: + with open(file_path, "r") as f: file_contents = f.read() validate_config(file_contents) except FileNotFoundError: - config = configparser.ConfigParser() - config["BOT_INFO"] = { - "TOKEN": "", - "BOT_COLOR": "", - "BOT_INVITE_LINK": "", - "FEEDBACK_CHANNEL_ID": "", - "BUG_CHANNEL_ID": "", - } - - config["SPOTIFY"] = { - "SPOTIFY_CLIENT_ID": "", - "SPOTIFY_CLIENT_SECRET": "", - } - - config["OPENAI"] = { - "OPENAI_API_KEY": "", - } - - config["LAVALINK"] = { - "HOST": "", - "PORT": "", - "PASSWORD": "", - } - - with open("config.ini", "w") as configfile: - config.write(configfile) + # Create a new config.yaml file with the template + with open(file_path, "w") as f: + f.write( + """ +bot_info: + token: "" + bot_color: "" + bot_invite_link: "" + feedback_channel_id: "" + bug_channel_id: "" + +spotify: + spotify_client_id: "" + spotify_client_secret: "" + +genius: + genius_client_id: "" + genius_client_secret: "" + +openai: + openai_api_key: "" + +lavalink: + host: "" + port: "" + password: "" + """ + ) sys.exit( LOG.critical( - "Configuration file `config.ini` has been generated. Please fill out all of the necessary information. Refer to the docs for information on what a specific configuration option is." + "Configuration file `config.yaml` has been generated. Please fill out all of the necessary information. Refer to the docs for information on what a specific configuration option is." ) ) -""" -Validate all of the options in the config.ini file. -""" - - +# Thouroughly validate all of the options in the config.yaml file def validate_config(file_contents): - global TOKEN, BOT_COLOR, BOT_INVITE_LINK, FEEDBACK_CHANNEL_ID, BUG_CHANNEL_ID, SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, OPENAI_API_KEY, LAVALINK_HOST, LAVALINK_PORT, LAVALINK_PASSWORD - config = configparser.ConfigParser() - config.read_string(file_contents) + global TOKEN, BOT_COLOR, BOT_INVITE_LINK, FEEDBACK_CHANNEL_ID, BUG_CHANNEL_ID, SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, GENIUS_CLIENT_ID, GENIUS_CLIENT_SECRET, OPENAI_API_KEY, LAVALINK_HOST, LAVALINK_PORT, LAVALINK_PASSWORD + config = yaml.safe_load(file_contents) - hex_pattern_one = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" - hex_pattern_two = "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" + try: + jsonschema.validate(config, schema) + except jsonschema.ValidationError as e: + sys.exit(LOG.critical(f"Error in config.yaml file: {e.message}")) - errors = 0 + # + # Begin validation for optional BOT_INFO values + # - # Make sure all sections are present - if ["BOT_INFO", "SPOTIFY", "OPENAI", "LAVALINK"] != config.sections(): - sys.exit( + # If there is a "bot_invite_link" option, make sure it's a valid URL + if "bot_invite_link" in config["bot_info"]: + if not validators.url(config["bot_info"]["bot_invite_link"]): LOG.critical( - "Missing sections in config.ini file. Delete the file and re-run the bot to generate a blank config.ini file." + "Error in config.yaml file: bot_invite_link is not a valid URL" ) - ) - - if ["token","bot_color","bot_invite_link", "feedback_channel_id","bug_channel_id",] != config.options("BOT_INFO"): - sys.exit( - LOG.critical( - "Missing options in BOT_INFO section of config.ini file. Delete the file and re-run the bot to generate a blank config.ini file." - ) - ) + else: + BOT_INVITE_LINK = config["bot_info"]["bot_invite_link"] - if ["spotify_client_id", "spotify_client_secret"] != config.options("SPOTIFY"): - sys.exit( - LOG.critical( - "Missing options in SPOTIFY section of config.ini file. Delete the file and re-run the bot to generate a blank config.ini file." - ) - ) + # Make sure "bot_color" is a valid hex color + hex_pattern_one = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" + hex_pattern_two = "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" - if ["openai_api_key"] != config.options("OPENAI"): - sys.exit( + if "bot_color" in config["bot_info"]: + if not bool( + re.match(hex_pattern_one, config["bot_info"]["bot_color"]) + ) and not bool(re.match(hex_pattern_two, config["bot_info"]["bot_color"])): LOG.critical( - "Missing options in OPENAI section of config.ini file. Delete the file and re-run the bot to generate a blank config.ini file." + "Error in config.yaml file: bot_color is not a valid hex color" ) - ) - - if ["host", "port", "password"] != config.options("LAVALINK"): - sys.exit( - LOG.critical( - "Missing options in LAVALINK section of config.ini file. Delete the file and re-run the bot to generate a blank config.ini file." - ) - ) - - # Make sure BOT_COLOR is a valid hex color - if not bool(re.match(hex_pattern_one, config["BOT_INFO"]["BOT_COLOR"])) and not bool(re.match(hex_pattern_two, config["BOT_INFO"]["BOT_COLOR"])): - LOG.error("BOT_COLOR is not a valid hex color.") - errors += 1 - else: - BOT_COLOR = discord.Color(int((config["BOT_INFO"]["BOT_COLOR"]).replace("#", ""), 16)) - - # Make sure BOT_INVITE_LINK is a valid URL - if not validators.url(config["BOT_INFO"]["BOT_INVITE_LINK"]): - LOG.error("BOT_INVITE_LINK is not a valid URL.") - errors += 1 - else: - BOT_INVITE_LINK = config["BOT_INFO"]["BOT_INVITE_LINK"] - - # Make sure FEEDBACK_CHANNEL_ID is either exactly 0 or 19 characters long - if len(config["BOT_INFO"]["FEEDBACK_CHANNEL_ID"]) != 0: - if len(config["BOT_INFO"]["FEEDBACK_CHANNEL_ID"]) != 19: - LOG.error("FEEDBACK_CHANNEL_ID is not a valid Discord channel ID.") - errors += 1 else: - FEEDBACK_CHANNEL_ID = int(config["BOT_INFO"]["FEEDBACK_CHANNEL_ID"]) + BOT_COLOR = discord.Color( + int((config["bot_info"]["bot_color"]).replace("#", ""), 16) + ) - # Make sure BUG_CHANNEL_ID is either exactly 0 or 19 characters long - if len(config["BOT_INFO"]["BUG_CHANNEL_ID"]) != 0: - if len(config["BOT_INFO"]["BUG_CHANNEL_ID"]) != 19: - LOG.error("BUG_CHANNEL_ID is not a valid Discord channel ID.") - errors += 1 + # Make sure "feedback_channel_id" and "bug_channel_id" are exactly 19 characters long + if "feedback_channel_id" in config["bot_info"]: + if len(str(config["bot_info"]["feedback_channel_id"])) != 0: + if len(str(config["bot_info"]["feedback_channel_id"])) != 19: + LOG.critical( + "Error in config.yaml file: feedback_channel_id is not a valid Discord channel ID" + ) + else: + FEEDBACK_CHANNEL_ID = config["bot_info"]["feedback_channel_id"] + + if "bug_channel_id" in config["bot_info"]: + if len(str(config["bot_info"]["bug_channel_id"])) != 0: + if len(str(config["bot_info"]["bug_channel_id"])) != 19: + LOG.critical( + "Error in config.yaml file: bug_channel_id is not a valid Discord channel ID" + ) + else: + BUG_CHANNEL_ID = config["bot_info"]["bug_channel_id"] + + # + # If the SPOTIFY section is present, make sure the client ID and secret are valid + # + + if "spotify" in config: + auth_url = "https://accounts.spotify.com/api/token" + data = { + "grant_type": "client_credentials", + "client_id": config["spotify"]["spotify_client_id"], + "client_secret": config["spotify"]["spotify_client_secret"], + } + response = requests.post(auth_url, data=data) + if response.status_code == 200: + SPOTIFY_CLIENT_ID = config["spotify"]["spotify_client_id"] + SPOTIFY_CLIENT_SECRET = config["spotify"]["spotify_client_secret"] else: - BUG_CHANNEL_ID = int(config["BOT_INFO"]["BUG_CHANNEL_ID"]) - - # Assign the rest of the variables - TOKEN = config["BOT_INFO"]["TOKEN"] - SPOTIFY_CLIENT_ID = config["SPOTIFY"]["SPOTIFY_CLIENT_ID"] - SPOTIFY_CLIENT_SECRET = config["SPOTIFY"]["SPOTIFY_CLIENT_SECRET"] - OPENAI_API_KEY = config["OPENAI"]["OPENAI_API_KEY"] - LAVALINK_HOST = config["LAVALINK"]["HOST"] - LAVALINK_PORT = config["LAVALINK"]["PORT"] - LAVALINK_PASSWORD = config["LAVALINK"]["PASSWORD"] - - if errors > 0: - sys.exit( LOG.critical( - f"Found {errors} error(s) in the config.ini file. Please fix them and try again." + "Error in config.yaml file: Spotify client ID or secret is invalid" ) - ) - - -""" -Validate all of the environment variables. -""" - - -def validate_env_vars(): - global TOKEN, BOT_COLOR, BOT_INVITE_LINK, FEEDBACK_CHANNEL_ID, BUG_CHANNEL_ID, SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, OPENAI_API_KEY, LAVALINK_HOST, LAVALINK_PORT, LAVALINK_PASSWORD - hex_pattern_one = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" - hex_pattern_two = "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" - - errors = 0 - - # Make sure all required variables are present in the environment - required_vars = ["TOKEN", "BOT_COLOR", "BOT_INVITE_LINK", "SPOTIFY_CLIENT_ID", "SPOTIFY_CLIENT_SECRET", "OPENAI_API_KEY", "LAVALINK_HOST", "LAVALINK_PORT", "LAVALINK_PASSWORD"] - - for var in required_vars: - if var not in os.environ: - LOG.error(f"Missing environment variable: {var}") - errors += 1 - - # Make sure BOT_COLOR is a valid hex color - if not bool(re.match(hex_pattern_one, os.environ["BOT_COLOR"])) and not bool(re.match(hex_pattern_two, os.environ["BOT_COLOR"])): - LOG.error("BOT_COLOR is not a valid hex color.") - errors += 1 - else: - BOT_COLOR = discord.Color(int((os.environ["BOT_COLOR"]).replace("#", ""), 16)) - - # Make sure BOT_INVITE_LINK is a valid URL - if not validators.url(os.environ["BOT_INVITE_LINK"]): - LOG.error("BOT_INVITE_LINK is not a valid URL.") - errors += 1 - else: - BOT_INVITE_LINK = os.environ["BOT_INVITE_LINK"] + # + # If the GENIUS section is present, make sure the client ID and secret are valid + # - # Make sure FEEDBACK_CHANNEL_ID is either None or 19 characters long - try: - if len(os.environ["FEEDBACK_CHANNEL_ID"]) != 19: - LOG.error("FEEDBACK_CHANNEL_ID is not a valid Discord channel ID.") - errors += 1 - else: - FEEDBACK_CHANNEL_ID = int(os.environ["FEEDBACK_CHANNEL_ID"]) - except KeyError: - FEEDBACK_CHANNEL_ID = None - - # Make sure BUG_CHANNEL_ID is either None or 19 characters long - try: - if len(os.environ["BUG_CHANNEL_ID"]) != 19: - LOG.error("BUG_CHANNEL_ID is not a valid Discord channel ID.") - errors += 1 + if "genius" in config: + auth_url = "https://api.genius.com/oauth/token" + data = { + "grant_type": "client_credentials", + "client_id": config["genius"]["genius_client_id"], + "client_secret": config["genius"]["genius_client_secret"], + } + response = requests.post(auth_url, data=data) + if response.status_code == 200: + GENIUS_CLIENT_ID = config["genius"]["genius_client_id"] + GENIUS_CLIENT_SECRET = config["genius"]["genius_client_secret"] else: - BUG_CHANNEL_ID = int(os.environ["BUG_CHANNEL_ID"]) - except KeyError: - BUG_CHANNEL_ID = None - - if errors > 0: - sys.exit( LOG.critical( - f"Found {errors} error(s) with environment variables. Please fix them and try again." + "Error in config.yaml file: Genius client ID or secret is invalid" ) - ) - # Assign the rest of the variables - TOKEN = os.environ["TOKEN"] - SPOTIFY_CLIENT_ID = os.environ["SPOTIFY_CLIENT_ID"] - SPOTIFY_CLIENT_SECRET = os.environ["SPOTIFY_CLIENT_SECRET"] - OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] - LAVALINK_HOST = os.environ["LAVALINK_HOST"] - LAVALINK_PORT = os.environ["LAVALINK_PORT"] - LAVALINK_PASSWORD = os.environ["LAVALINK_PASSWORD"]
\ No newline at end of file + # + # If the OPENAI section is present, make sure the API key is valid + # + + if "openai" in config: + client = openai.OpenAI(api_key=config["openai"]["openai_api_key"]) + try: + client.models.list() + OPENAI_API_KEY = config["openai"]["openai_api_key"] + except openai.AuthenticationError: + LOG.critical("Error in config.yaml file: OpenAI API key is invalid") + + # Set appropriate values for all non-optional variables + TOKEN = config["bot_info"]["token"] + LAVALINK_HOST = config["lavalink"]["host"] + LAVALINK_PORT = config["lavalink"]["port"] + LAVALINK_PASSWORD = config["lavalink"]["password"] |