import discord from discord.ext import commands from discord import app_commands import aiohttp import re class Lyrics(commands.Cog): def __init__(self, bot): self.bot = bot @app_commands.command(name="lyrics", description="Get lyrics for a song") @app_commands.describe( artist="Name of the artist", song="Title of the song", language="Target language code (optional)" ) @app_commands.choices(language=[ app_commands.Choice(name="Bulgarian", value="bg"), app_commands.Choice(name="Czech", value="cs"), app_commands.Choice(name="Danish", value="da"), app_commands.Choice(name="German", value="de"), app_commands.Choice(name="Greek", value="el"), app_commands.Choice(name="English", value="en"), app_commands.Choice(name="Spanish", value="es"), app_commands.Choice(name="Estonian", value="et"), app_commands.Choice(name="Finnish", value="fi"), app_commands.Choice(name="French", value="fr"), app_commands.Choice(name="Irish", value="ga"), app_commands.Choice(name="Croatian", value="hr"), app_commands.Choice(name="Hungarian", value="hu"), app_commands.Choice(name="Italian", value="it"), app_commands.Choice(name="Lithuanian", value="lt"), app_commands.Choice(name="Latvian", value="lv"), app_commands.Choice(name="Maltese", value="mt"), app_commands.Choice(name="Dutch", value="nl"), app_commands.Choice(name="Polish", value="pl"), app_commands.Choice(name="Portuguese", value="pt"), app_commands.Choice(name="Romanian", value="ro"), app_commands.Choice(name="Slovak", value="sk"), app_commands.Choice(name="Slovene", value="sl"), app_commands.Choice(name="Swedish", value="sv"), ]) async def lyrics(self, interaction: discord.Interaction, artist: str = None, song: str = None, language: app_commands.Choice[str] = None): await interaction.response.defer() if not artist or not song: member = interaction.guild.get_member(interaction.user.id) if not member: member = await interaction.guild.fetch_member(interaction.user.id) act_artist, act_song = await self.get_artist_song_from_presence(member) if act_artist and act_song: artist = artist or act_artist song = song or act_song else: await interaction.followup.send("No artist or song provided and couldn't find it from your current activity.") return lyrics = await self.fetch_lyrics(artist, song) if not lyrics: await interaction.followup.send(f"Could not find lyrics for **{artist} - {song}**") return if language: translated = await self.translate_text(lyrics, language.value) if translated: lyrics = translated if len(lyrics) > 1900: lyrics = lyrics[:1900] + "\n\n[...lyrics truncated...]" embed = discord.Embed( title=f"{artist} - {song}", description=lyrics, color=discord.Color.blue() ) embed.set_footer(text=f"Requested by {interaction.user}", icon_url=interaction.user.display_avatar.url) await interaction.followup.send(embed=embed) async def get_artist_song_from_presence(self, member: discord.Member): for activity in member.activities: if isinstance(activity, discord.Spotify): return activity.artist, activity.title return None, None async def fetch_lyrics(self, artist, song): artist_q = artist.replace(' ', '+').lower() song_q = song.replace(' ', '+').lower() url = f"https://lrclib.net/api/get?artist_name={artist_q}&track_name={song_q}" print(url) async with aiohttp.ClientSession() as session: try: async with session.get(url) as resp: if resp.status != 200: return None data = await resp.json() return data.get('plainLyrics') except Exception: return None async def translate_text(self, text: str, target_lang: str) -> str | None: translate_url = "https://translate.googleapis.com/translate_a/single" params = { "client": "gtx", "sl": "auto", "tl": target_lang, "dt": "t", "q": text } async with aiohttp.ClientSession() as session: try: async with session.get(translate_url, params=params) as resp: if resp.status != 200: return None result = await resp.json() translated_chunks = [item[0] for item in result[0] if item[0]] return ''.join(translated_chunks) except Exception: return None async def setup(bot): await bot.add_cog(Lyrics(bot))