feat(read description): Add translate utility cog and update categories

Introduces a new 'translate' command under a utilities category, with language autocomplete and Google Translate integration. Updates README and help command to reflect the new category and command. Renames 'rr.py' to 'rickroll.py'. Updates moderation cogs to use a new icon URL for embed authors.
This commit is contained in:
neoarz
2025-09-28 13:19:28 -04:00
parent 85526653f2
commit bcb8cf3326
10 changed files with 404 additions and 42 deletions

View File

@@ -13,7 +13,7 @@ class Help(commands.Cog, name="help"):
interaction: discord.Interaction,
current: str,
) -> list[app_commands.Choice[str]]:
categories = ["general", "fun", "moderation", "owner", "sidestore", "idevice", "miscellaneous"]
categories = ["general", "fun", "moderation", "owner", "sidestore", "idevice", "miscellaneous", "utilities"]
suggestions = []
for category in categories:
@@ -89,6 +89,9 @@ class Help(commands.Cog, name="help"):
"invite": "owner",
"logs": "owner",
# Utilities Commands
"translate": "utilities",
# Miscellaneous Commands
"keanu": "miscellaneous",
"labubu": "miscellaneous",
@@ -104,6 +107,7 @@ class Help(commands.Cog, name="help"):
"owner": "Owner commands",
"sidestore": "SideStore troubleshooting commands",
"idevice": "idevice troubleshooting commands",
"utilities": "Utility commands",
"miscellaneous": "Miscellaneous commands"
}

View File

@@ -41,7 +41,7 @@ class Ban(commands.Cog, name="ban"):
title="Ban",
description=f"**{user}** was banned by **{context.author}**!",
color=0x7289DA,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
embed.add_field(name="Reason:", value=reason)
await context.send(embed=embed)
return
@@ -50,7 +50,7 @@ class Ban(commands.Cog, name="ban"):
title="Error!",
description="I don't have permission to ban this user.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
except Exception:
@@ -58,7 +58,7 @@ class Ban(commands.Cog, name="ban"):
title="Error!",
description="An error occurred while trying to ban the user.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -67,7 +67,7 @@ class Ban(commands.Cog, name="ban"):
title="Missing Permissions!",
description="You don't have the `Ban Members` permission to use this command.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -76,7 +76,7 @@ class Ban(commands.Cog, name="ban"):
title="Cannot Ban User",
description="This user has a higher or equal role to me. Make sure my role is above theirs.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -86,7 +86,7 @@ class Ban(commands.Cog, name="ban"):
title="Cannot Ban User",
description="You cannot ban this user as they have a higher or equal role to you.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -111,7 +111,7 @@ class Ban(commands.Cog, name="ban"):
title="Ban",
description=f"You were banned by **{context.author}** from **{context.guild.name}**!\nReason: {reason}",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await member.send(embed=dm_embed)
except (discord.Forbidden, discord.HTTPException):
pass
@@ -128,7 +128,7 @@ class Ban(commands.Cog, name="ban"):
title="Ban",
description=f"**{user}** was banned by **{context.author}**!",
color=0x7289DA,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
embed.add_field(name="Reason:", value=reason)
if delete_messages != "none":
@@ -145,7 +145,7 @@ class Ban(commands.Cog, name="ban"):
title="Error!",
description="I don't have permission to ban this user. Make sure my role is above theirs.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
except discord.HTTPException as e:
if "Cannot ban the owner of a guild" in str(e):
@@ -153,20 +153,20 @@ class Ban(commands.Cog, name="ban"):
title="Cannot Ban User",
description="You cannot ban the server owner.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
else:
embed = discord.Embed(
title="Error!",
description=f"Discord API error: {str(e)}",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
except Exception as e:
embed = discord.Embed(
title="Debug Error!",
description=f"Error type: {type(e).__name__}\nError message: {str(e)}",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
except Exception as e:
@@ -174,7 +174,7 @@ class Ban(commands.Cog, name="ban"):
title="Error!",
description="An unexpected error occurred.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
async def delete_all_user_messages(self, guild: discord.Guild, user_id: int) -> None:

View File

@@ -37,7 +37,7 @@ class HackBan(commands.Cog, name="hackban"):
title="Ban",
description=f"**{user}** (ID: {user_id}) was banned by **{context.author}**!",
color=0x7289DA,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
embed.add_field(name="Reason:", value=reason)
await context.send(embed=embed)
except Exception:
@@ -45,7 +45,7 @@ class HackBan(commands.Cog, name="hackban"):
title="Error!",
description="An error occurred while trying to ban the user. Make sure ID is an existing ID that belongs to a user.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed)

View File

@@ -29,7 +29,7 @@ class Kick(commands.Cog, name="kick"):
title="Error!",
description="This user is not in the server.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -38,7 +38,7 @@ class Kick(commands.Cog, name="kick"):
title="Missing Permissions!",
description="You don't have the `Kick Members` permission to use this command.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -47,7 +47,7 @@ class Kick(commands.Cog, name="kick"):
title="Cannot Kick User",
description="This user has a higher or equal role to me. Make sure my role is above theirs.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -57,7 +57,7 @@ class Kick(commands.Cog, name="kick"):
title="Cannot Kick User",
description="You cannot kick this user as they have a higher or equal role to you.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
return
@@ -69,7 +69,7 @@ class Kick(commands.Cog, name="kick"):
title="Kick",
description=f"You were kicked by **{context.author}** from **{context.guild.name}**!\nReason: {reason}",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
)
except (discord.Forbidden, discord.HTTPException):
@@ -81,7 +81,7 @@ class Kick(commands.Cog, name="kick"):
title="Kick",
description=f"**{user}** was kicked by **{context.author}**!",
color=0x7289DA,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
embed.add_field(name="Reason:", value=reason)
await context.send(embed=embed)
@@ -91,7 +91,7 @@ class Kick(commands.Cog, name="kick"):
title="Error!",
description="I don't have permission to kick this user. Make sure my role is above theirs.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
except discord.HTTPException as e:
if "Cannot kick the owner of a guild" in str(e):
@@ -99,20 +99,20 @@ class Kick(commands.Cog, name="kick"):
title="Cannot Kick User",
description="You cannot kick the server owner.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
else:
embed = discord.Embed(
title="Error!",
description=f"Discord API error: {str(e)}",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
except Exception as e:
embed = discord.Embed(
title="Debug Error!",
description=f"Error type: {type(e).__name__}\nError message: {str(e)}",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)
except Exception as e:
@@ -120,7 +120,7 @@ class Kick(commands.Cog, name="kick"):
title="Error!",
description="An unexpected error occurred.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)

View File

@@ -31,7 +31,7 @@ class Nick(commands.Cog, name="nick"):
title="Missing Permissions!",
description="You are missing the permission(s) `manage_nicknames` to execute this command!",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
return await context.send(embed=embed, ephemeral=True)
if not context.guild.me.guild_permissions.manage_nicknames:
@@ -39,7 +39,7 @@ class Nick(commands.Cog, name="nick"):
title="Missing Permissions!",
description="I am missing the permission(s) `manage_nicknames` to execute this command!",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
return await context.send(embed=embed, ephemeral=True)
member = context.guild.get_member(user.id) or await context.guild.fetch_member(
@@ -51,14 +51,14 @@ class Nick(commands.Cog, name="nick"):
title="Nickname",
description=f"**{member}'s** new nickname is **{nickname}**!",
color=0x7289DA,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed)
except:
embed = discord.Embed(
title="Missing Permissions!",
description="An error occurred while trying to change the nickname of the user. Make sure my role is above the role of the user you want to change the nickname.",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.send(embed=embed, ephemeral=True)

View File

@@ -29,7 +29,7 @@ class Purge(commands.Cog, name="purge"):
description=f"**{context.author}** cleared **{len(purged_messages)-1}** messages!",
color=0x7289DA,
)
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await context.channel.send(embed=embed)

View File

@@ -33,7 +33,7 @@ class Warnings(commands.Cog, name="warnings"):
title="Missing Permissions!",
description="You are missing the permission(s) `manage_messages` to execute this command!",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
return await self.send_embed(context, embed, ephemeral=True)
if context.invoked_subcommand is None:
@@ -42,7 +42,7 @@ class Warnings(commands.Cog, name="warnings"):
description="Please specify a subcommand.\n\n**Subcommands:**\n`add` - Add a warning to a user.\n`remove` - Remove a warning from a user.\n`list` - List all warnings of a user.",
color=0x7289DA,
)
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await self.send_embed(context, embed)
@warning.command(
@@ -68,7 +68,7 @@ class Warnings(commands.Cog, name="warnings"):
title="Missing Permissions!",
description="You are missing the permission(s) `manage_messages` to execute this command!",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
return await self.send_embed(context, embed, ephemeral=True)
member = context.guild.get_member(user.id) or await context.guild.fetch_member(
user.id
@@ -81,7 +81,7 @@ class Warnings(commands.Cog, name="warnings"):
description=f"**{member}** was warned by **{context.author}**!\nTotal warns for this user: {total}",
color=0x7289DA,
)
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
embed.add_field(name="Reason:", value=reason)
await self.send_embed(context, embed)
try:
@@ -90,7 +90,7 @@ class Warnings(commands.Cog, name="warnings"):
description=f"You were warned by **{context.author}** in **{context.guild.name}**!\nReason: {reason}",
color=0xE02B2B,
)
dm_embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
dm_embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await member.send(embed=dm_embed)
except:
fallback = discord.Embed(
@@ -123,7 +123,7 @@ class Warnings(commands.Cog, name="warnings"):
title="Missing Permissions!",
description="You are missing the permission(s) `manage_messages` to execute this command!",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
return await self.send_embed(context, embed, ephemeral=True)
member = context.guild.get_member(user.id) or await context.guild.fetch_member(
user.id
@@ -134,7 +134,7 @@ class Warnings(commands.Cog, name="warnings"):
description=f"Removed the warning **#{warn_id}** from **{member}**!\nTotal warns for this user: {total}",
color=0x7289DA,
)
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
await self.send_embed(context, embed)
@warning.command(
@@ -154,11 +154,11 @@ class Warnings(commands.Cog, name="warnings"):
title="Missing Permissions!",
description="You are missing the permission(s) `manage_messages` to execute this command!",
color=0xE02B2B,
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
).set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
return await self.send_embed(context, embed, ephemeral=True)
warnings_list = await self.bot.database.get_warnings(user.id, context.guild.id)
embed = discord.Embed(title=f"Warnings of {user}", color=0x7289DA)
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.set_author(name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png")
description = ""
if len(warnings_list) == 0:
description = "This user has no warnings."

357
cogs/utilities/translate.py Normal file
View File

@@ -0,0 +1,357 @@
import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
import aiohttp
import asyncio
import re
import json
import urllib.parse
class Translate(commands.Cog, name="translate"):
def __init__(self, bot) -> None:
self.bot = bot
self.languages = {
"auto": "Auto-detect",
"en": "English",
"es": "Spanish",
"fr": "French",
"de": "German",
"it": "Italian",
"pt": "Portuguese",
"ru": "Russian",
"ja": "Japanese",
"ko": "Korean",
"zh-CN": "Chinese (Simplified)",
"zh-TW": "Chinese (Traditional)",
"ar": "Arabic",
"hi": "Hindi",
"th": "Thai",
"vi": "Vietnamese",
"nl": "Dutch",
"pl": "Polish",
"tr": "Turkish",
"sv": "Swedish",
"da": "Danish",
"no": "Norwegian",
"fi": "Finnish",
"cs": "Czech",
"sk": "Slovak",
"hu": "Hungarian",
"ro": "Romanian",
"bg": "Bulgarian",
"hr": "Croatian",
"sr": "Serbian",
"sl": "Slovenian",
"et": "Estonian",
"lv": "Latvian",
"lt": "Lithuanian",
"uk": "Ukrainian",
"be": "Belarusian",
"mk": "Macedonian",
"sq": "Albanian",
"mt": "Maltese",
"is": "Icelandic",
"ga": "Irish",
"cy": "Welsh",
"gd": "Scots Gaelic",
"eu": "Basque",
"ca": "Catalan",
"gl": "Galician",
"eo": "Esperanto",
"la": "Latin",
"af": "Afrikaans",
"sw": "Swahili",
"zu": "Zulu",
"xh": "Xhosa",
"yo": "Yoruba",
"ig": "Igbo",
"ha": "Hausa",
"am": "Amharic",
"om": "Oromo",
"ti": "Tigrinya",
"so": "Somali",
"rw": "Kinyarwanda",
"lg": "Ganda",
"ny": "Chichewa",
"sn": "Shona",
"st": "Sesotho",
"tn": "Tswana",
"ts": "Tsonga",
"ss": "Swati",
"nr": "Ndebele",
"nso": "Northern Sotho",
"ve": "Venda",
"bn": "Bengali",
"gu": "Gujarati",
"kn": "Kannada",
"ml": "Malayalam",
"mr": "Marathi",
"ne": "Nepali",
"or": "Odia",
"pa": "Punjabi",
"si": "Sinhala",
"ta": "Tamil",
"te": "Telugu",
"ur": "Urdu",
"as": "Assamese",
"bho": "Bhojpuri",
"doi": "Dogri",
"gom": "Konkani",
"mai": "Maithili",
"mni-Mtei": "Meiteilon",
"sa": "Sanskrit",
"id": "Indonesian",
"ms": "Malay",
"tl": "Filipino",
"jv": "Javanese",
"su": "Sundanese",
"ceb": "Cebuano",
"hil": "Hiligaynon",
"ilo": "Iloko",
"pam": "Kapampangan",
"war": "Waray",
"my": "Myanmar",
"km": "Khmer",
"lo": "Lao",
"ka": "Georgian",
"hy": "Armenian",
"az": "Azerbaijani",
"kk": "Kazakh",
"ky": "Kyrgyz",
"mn": "Mongolian",
"tk": "Turkmen",
"ug": "Uyghur",
"uz": "Uzbek",
"tg": "Tajik",
"fa": "Persian",
"ps": "Pashto",
"sd": "Sindhi",
"he": "Hebrew",
"yi": "Yiddish",
"iw": "Hebrew",
"el": "Greek",
"lt": "Lithuanian",
"lv": "Latvian",
}
async def send_embed(self, context: Context, embed: discord.Embed, *, ephemeral: bool = False, view: discord.ui.View = None) -> None:
interaction = getattr(context, "interaction", None)
if interaction is not None:
if interaction.response.is_done():
await interaction.followup.send(embed=embed, ephemeral=ephemeral, view=view)
else:
await interaction.response.send_message(embed=embed, ephemeral=ephemeral, view=view)
else:
await context.send(embed=embed, view=view)
async def _translate_with_google_web(self, text: str, from_lang: str = "auto", to_lang: str = "en") -> dict:
try:
base_url = "https://translate.googleapis.com/translate_a/single"
params = {
"client": "gtx",
"sl": from_lang,
"tl": to_lang,
"dt": ["t", "bd"],
"q": text
}
param_string = "&".join([f"{k}={'&'.join(v) if isinstance(v, list) else v}" for k, v in params.items()])
url = f"{base_url}?{param_string}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
if response.status == 200:
result_text = await response.text()
try:
result_text = result_text.strip()
if result_text.startswith('[['):
data = json.loads(result_text)
translated_text = ""
if data and len(data) > 0 and data[0]:
for item in data[0]:
if item and len(item) > 0:
translated_text += item[0] if item[0] else ""
detected_lang = from_lang
if len(data) > 2 and data[2]:
detected_lang = data[2]
return {
"translatedText": translated_text.strip(),
"detectedSourceLanguage": detected_lang
}
except:
pass
return None
except Exception:
return None
async def language_autocomplete(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
current = current.lower()
choices = []
for code, name in self.languages.items():
if current in code.lower() or current in name.lower():
display_name = f"{code} - {name}"
if len(display_name) > 100:
display_name = f"{code} - {name[:90]}..."
choices.append(app_commands.Choice(name=display_name, value=code))
if len(choices) >= 25:
break
if not choices:
popular = ["en", "es", "fr", "de", "it", "pt", "ru", "ja", "ko", "zh-CN"]
for code in popular:
name = self.languages.get(code, code)
choices.append(app_commands.Choice(name=f"{code} - {name}", value=code))
return choices
@commands.hybrid_command(
name="translate",
description="Translate text to another language",
)
@app_commands.describe(
text="The text to translate",
to_lang="Target language (e.g., 'en', 'es', 'fr')",
from_lang="Source language (leave empty for auto-detect)"
)
@app_commands.autocomplete(to_lang=language_autocomplete)
@app_commands.autocomplete(from_lang=language_autocomplete)
async def translate(self, context: Context, text: str, to_lang: str = "en", from_lang: str = None):
if not text.strip():
embed = discord.Embed(
title="Error",
description="Please provide text to translate.",
color=0xE02B2B,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
await self.send_embed(context, embed, ephemeral=True)
return
if to_lang not in self.languages:
embed = discord.Embed(
title="Error",
description=f"Invalid target language code: `{to_lang}`. Use the autocomplete feature to see available languages.",
color=0xE02B2B,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
await self.send_embed(context, embed, ephemeral=True)
return
if from_lang and from_lang not in self.languages:
embed = discord.Embed(
title="Error",
description=f"Invalid source language code: `{from_lang}`. Use the autocomplete feature to see available languages.",
color=0xE02B2B,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
await self.send_embed(context, embed, ephemeral=True)
return
result = await self._translate_with_google_web(text, from_lang or "auto", to_lang)
if result and result.get("translatedText"):
detected_lang = result.get("detectedSourceLanguage", from_lang or "auto")
from_lang_name = self.languages.get(detected_lang, detected_lang)
to_lang_name = self.languages.get(to_lang, to_lang)
embed = discord.Embed(
title="Translation",
color=0x7289DA,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.add_field(name="Original", value=text, inline=False)
embed.add_field(name="Translated", value=result["translatedText"], inline=False)
embed.add_field(name="From", value=f"{detected_lang} ({from_lang_name})", inline=True)
embed.add_field(name="To", value=f"{to_lang} ({to_lang_name})", inline=True)
view = TranslateView(text, result["translatedText"], detected_lang, to_lang, self)
await self.send_embed(context, embed, view=view)
else:
embed = discord.Embed(
title="Error",
description="Translation failed. Please try again later.",
color=0xE02B2B,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
await self.send_embed(context, embed, ephemeral=True)
class TranslateView(discord.ui.View):
def __init__(self, original_text: str, translated_text: str, from_lang: str, to_lang: str, translate_cog):
super().__init__(timeout=300)
self.original_text = original_text
self.translated_text = translated_text
self.from_lang = from_lang
self.to_lang = to_lang
self.translate_cog = translate_cog
@discord.ui.button(label="Swap Languages", style=discord.ButtonStyle.secondary)
async def swap_languages(self, interaction: discord.Interaction, button: discord.ui.Button):
if self.from_lang == "auto":
embed = discord.Embed(
title="Cannot Swap",
description="Cannot swap when source language is auto-detected. Please specify a source language first.",
color=0xE02B2B,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
await interaction.response.send_message(embed=embed, ephemeral=True)
return
result = await self.translate_cog._translate_with_google_web(
self.translated_text, self.from_lang, "en"
)
if result and result.get("translatedText"):
from_lang_name = self.translate_cog.languages.get(self.from_lang, self.from_lang)
to_lang_name = self.translate_cog.languages.get("en", "English")
embed = discord.Embed(
title="Translation (Swapped)",
color=0x7289DA,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
embed.add_field(name="Original", value=self.translated_text, inline=False)
embed.add_field(name="Translated", value=result["translatedText"], inline=False)
embed.add_field(name="From", value=f"{self.from_lang} ({from_lang_name})", inline=True)
embed.add_field(name="To", value=f"en ({to_lang_name})", inline=True)
new_view = TranslateView(
self.translated_text,
result["translatedText"],
self.from_lang,
"en",
self.translate_cog
)
await interaction.response.edit_message(embed=embed, view=new_view)
else:
embed = discord.Embed(
title="Error",
description="Failed to swap translation. Please try again later.",
color=0xE02B2B,
)
embed.set_author(name="Translate", icon_url="https://yes.nighty.works/raw/8VLDcg.webp")
await interaction.response.send_message(embed=embed, ephemeral=True)
async def on_timeout(self):
for item in self.children:
item.disabled = True
async def setup(bot):
await bot.add_cog(Translate(bot))