mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
* Improvements of "serverinfo" command - Added some more informations about the server. (Verification level, AFK channel and timeout, custom emojis and special features). - Added custom texts for Region (and Verification levels). - Added more details about members (Number of humans, bots, and all status). - Show special features only if the server has one. - Show "Verified" logo only if the server is verified. - And changed the footer by adding how many time the bot as join the server. * Black formatting for serverinfo * Black formatting fix and Sinbad suggestions * Fix the discord.errors.NotFound on server command Added exception on server command for the phrase "To leave a server, just type its number.". * Update core_commands.py * Delete core_commands.py * Create core_commands.py * Update core_commands.py * Update core_commands.py * Delete core_commands.py * Create core_commands.py * Update core_commands.py * Update core_commands.py * Little changes on serverinfo command - Adding "lurkers" check, for the new feature that are on bot which allow users to join a server in read-only (Works only on verified servers for now) - Adding streaming status. - Adding mobile status with suggestion of Sinbad. * Black style fix * Add verbose for serverinfo and disable lurkers I've added a bool that are False by default and sent the original serverinfo command, and if set to True send my edited version. And I've disabled the lurkers detection until this bug (https://github.com/discordapp/discord-api-docs/issues/855) isn't fixed. * Add of India region * Code cleanup * Emojis are not needed to be translated * Update serverinfo * Changelog. * Update 2382.enhancement.rst * Adress Jack's requests changes. * oops * Put guild description first + few last nitpicks Co-authored-by: PredaMart <46051820+PredaMart@users.noreply.github.com> Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com> Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
537 lines
21 KiB
Python
537 lines
21 KiB
Python
import datetime
|
||
import time
|
||
from enum import Enum
|
||
from random import randint, choice
|
||
from typing import Final
|
||
import aiohttp
|
||
import discord
|
||
from redbot.core import commands
|
||
from redbot.core.i18n import Translator, cog_i18n
|
||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
||
from redbot.core.utils.chat_formatting import (
|
||
bold,
|
||
escape,
|
||
italics,
|
||
humanize_number,
|
||
humanize_timedelta,
|
||
)
|
||
|
||
_ = T_ = Translator("General", __file__)
|
||
|
||
|
||
class RPS(Enum):
|
||
rock = "\N{MOYAI}"
|
||
paper = "\N{PAGE FACING UP}"
|
||
scissors = "\N{BLACK SCISSORS}"
|
||
|
||
|
||
class RPSParser:
|
||
def __init__(self, argument):
|
||
argument = argument.lower()
|
||
if argument == "rock":
|
||
self.choice = RPS.rock
|
||
elif argument == "paper":
|
||
self.choice = RPS.paper
|
||
elif argument == "scissors":
|
||
self.choice = RPS.scissors
|
||
else:
|
||
self.choice = None
|
||
|
||
|
||
MAX_ROLL: Final[int] = 2 ** 64 - 1
|
||
|
||
|
||
@cog_i18n(_)
|
||
class General(commands.Cog):
|
||
"""General commands."""
|
||
|
||
global _
|
||
_ = lambda s: s
|
||
ball = [
|
||
_("As I see it, yes"),
|
||
_("It is certain"),
|
||
_("It is decidedly so"),
|
||
_("Most likely"),
|
||
_("Outlook good"),
|
||
_("Signs point to yes"),
|
||
_("Without a doubt"),
|
||
_("Yes"),
|
||
_("Yes – definitely"),
|
||
_("You may rely on it"),
|
||
_("Reply hazy, try again"),
|
||
_("Ask again later"),
|
||
_("Better not tell you now"),
|
||
_("Cannot predict now"),
|
||
_("Concentrate and ask again"),
|
||
_("Don't count on it"),
|
||
_("My reply is no"),
|
||
_("My sources say no"),
|
||
_("Outlook not so good"),
|
||
_("Very doubtful"),
|
||
]
|
||
_ = T_
|
||
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.stopwatches = {}
|
||
|
||
@commands.command()
|
||
async def choose(self, ctx, *choices):
|
||
"""Choose between multiple options.
|
||
|
||
To denote options which include whitespace, you should use
|
||
double quotes.
|
||
"""
|
||
choices = [escape(c, mass_mentions=True) for c in choices]
|
||
if len(choices) < 2:
|
||
await ctx.send(_("Not enough options to pick from."))
|
||
else:
|
||
await ctx.send(choice(choices))
|
||
|
||
@commands.command()
|
||
async def roll(self, ctx, number: int = 100):
|
||
"""Roll a random number.
|
||
|
||
The result will be between 1 and `<number>`.
|
||
|
||
`<number>` defaults to 100.
|
||
"""
|
||
author = ctx.author
|
||
if 1 < number <= MAX_ROLL:
|
||
n = randint(1, number)
|
||
await ctx.send(
|
||
"{author.mention} :game_die: {n} :game_die:".format(
|
||
author=author, n=humanize_number(n)
|
||
)
|
||
)
|
||
elif number <= 1:
|
||
await ctx.send(_("{author.mention} Maybe higher than 1? ;P").format(author=author))
|
||
else:
|
||
await ctx.send(
|
||
_("{author.mention} Max allowed number is {maxamount}.").format(
|
||
author=author, maxamount=humanize_number(MAX_ROLL)
|
||
)
|
||
)
|
||
|
||
@commands.command()
|
||
async def flip(self, ctx, user: discord.Member = None):
|
||
"""Flip a coin... or a user.
|
||
|
||
Defaults to a coin.
|
||
"""
|
||
if user is not None:
|
||
msg = ""
|
||
if user.id == ctx.bot.user.id:
|
||
user = ctx.author
|
||
msg = _("Nice try. You think this is funny?\n How about *this* instead:\n\n")
|
||
char = "abcdefghijklmnopqrstuvwxyz"
|
||
tran = "ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz"
|
||
table = str.maketrans(char, tran)
|
||
name = user.display_name.translate(table)
|
||
char = char.upper()
|
||
tran = "∀qƆpƎℲפHIſʞ˥WNOԀQᴚS┴∩ΛMX⅄Z"
|
||
table = str.maketrans(char, tran)
|
||
name = name.translate(table)
|
||
await ctx.send(msg + "(╯°□°)╯︵ " + name[::-1])
|
||
else:
|
||
await ctx.send(_("*flips a coin and... ") + choice([_("HEADS!*"), _("TAILS!*")]))
|
||
|
||
@commands.command()
|
||
async def rps(self, ctx, your_choice: RPSParser):
|
||
"""Play Rock Paper Scissors."""
|
||
author = ctx.author
|
||
player_choice = your_choice.choice
|
||
if not player_choice:
|
||
return await ctx.send(
|
||
_("This isn't a valid option. Try {r}, {p}, or {s}.").format(
|
||
r="rock", p="paper", s="scissors"
|
||
)
|
||
)
|
||
red_choice = choice((RPS.rock, RPS.paper, RPS.scissors))
|
||
cond = {
|
||
(RPS.rock, RPS.paper): False,
|
||
(RPS.rock, RPS.scissors): True,
|
||
(RPS.paper, RPS.rock): True,
|
||
(RPS.paper, RPS.scissors): False,
|
||
(RPS.scissors, RPS.rock): False,
|
||
(RPS.scissors, RPS.paper): True,
|
||
}
|
||
|
||
if red_choice == player_choice:
|
||
outcome = None # Tie
|
||
else:
|
||
outcome = cond[(player_choice, red_choice)]
|
||
|
||
if outcome is True:
|
||
await ctx.send(
|
||
_("{choice} You win {author.mention}!").format(
|
||
choice=red_choice.value, author=author
|
||
)
|
||
)
|
||
elif outcome is False:
|
||
await ctx.send(
|
||
_("{choice} You lose {author.mention}!").format(
|
||
choice=red_choice.value, author=author
|
||
)
|
||
)
|
||
else:
|
||
await ctx.send(
|
||
_("{choice} We're square {author.mention}!").format(
|
||
choice=red_choice.value, author=author
|
||
)
|
||
)
|
||
|
||
@commands.command(name="8", aliases=["8ball"])
|
||
async def _8ball(self, ctx, *, question: str):
|
||
"""Ask 8 ball a question.
|
||
|
||
Question must end with a question mark.
|
||
"""
|
||
if question.endswith("?") and question != "?":
|
||
await ctx.send("`" + T_(choice(self.ball)) + "`")
|
||
else:
|
||
await ctx.send(_("That doesn't look like a question."))
|
||
|
||
@commands.command(aliases=["sw"])
|
||
async def stopwatch(self, ctx):
|
||
"""Start or stop the stopwatch."""
|
||
author = ctx.author
|
||
if author.id not in self.stopwatches:
|
||
self.stopwatches[author.id] = int(time.perf_counter())
|
||
await ctx.send(author.mention + _(" Stopwatch started!"))
|
||
else:
|
||
tmp = abs(self.stopwatches[author.id] - int(time.perf_counter()))
|
||
tmp = str(datetime.timedelta(seconds=tmp))
|
||
await ctx.send(
|
||
author.mention + _(" Stopwatch stopped! Time: **{seconds}**").format(seconds=tmp)
|
||
)
|
||
self.stopwatches.pop(author.id, None)
|
||
|
||
@commands.command()
|
||
async def lmgtfy(self, ctx, *, search_terms: str):
|
||
"""Create a lmgtfy link."""
|
||
search_terms = escape(
|
||
search_terms.replace("+", "%2B").replace(" ", "+"), mass_mentions=True
|
||
)
|
||
await ctx.send("https://lmgtfy.com/?q={}".format(search_terms))
|
||
|
||
@commands.command(hidden=True)
|
||
@commands.guild_only()
|
||
async def hug(self, ctx, user: discord.Member, intensity: int = 1):
|
||
"""Because everyone likes hugs!
|
||
|
||
Up to 10 intensity levels.
|
||
"""
|
||
name = italics(user.display_name)
|
||
if intensity <= 0:
|
||
msg = "(っ˘̩╭╮˘̩)っ" + name
|
||
elif intensity <= 3:
|
||
msg = "(っ´▽`)っ" + name
|
||
elif intensity <= 6:
|
||
msg = "╰(*´︶`*)╯" + name
|
||
elif intensity <= 9:
|
||
msg = "(つ≧▽≦)つ" + name
|
||
elif intensity >= 10:
|
||
msg = "(づ ̄ ³ ̄)づ{} ⊂(´・ω・`⊂)".format(name)
|
||
else:
|
||
# For the purposes of "msg might not be defined" linter errors
|
||
raise RuntimeError
|
||
await ctx.send(msg)
|
||
|
||
@commands.command()
|
||
@commands.guild_only()
|
||
@commands.bot_has_permissions(embed_links=True)
|
||
async def serverinfo(self, ctx, details: bool = False):
|
||
"""
|
||
Show server information.
|
||
|
||
`details`: Toggle it to `True` to show more information about this server.
|
||
Default to False.
|
||
"""
|
||
guild = ctx.guild
|
||
passed = (ctx.message.created_at - guild.created_at).days
|
||
created_at = _("Created on {date}. That's over {num} days ago!").format(
|
||
date=guild.created_at.strftime("%d %b %Y %H:%M"), num=humanize_number(passed),
|
||
)
|
||
online = humanize_number(
|
||
len([m.status for m in guild.members if m.status != discord.Status.offline])
|
||
)
|
||
total_users = humanize_number(guild.member_count)
|
||
text_channels = humanize_number(len(guild.text_channels))
|
||
voice_channels = humanize_number(len(guild.voice_channels))
|
||
if not details:
|
||
data = discord.Embed(description=created_at, colour=await ctx.embed_colour())
|
||
data.add_field(name=_("Region"), value=str(guild.region))
|
||
data.add_field(name=_("Users online"), value=f"{online}/{total_users}")
|
||
data.add_field(name=_("Text Channels"), value=text_channels)
|
||
data.add_field(name=_("Voice Channels"), value=voice_channels)
|
||
data.add_field(name=_("Roles"), value=humanize_number(len(guild.roles)))
|
||
data.add_field(name=_("Owner"), value=str(guild.owner))
|
||
data.set_footer(text=_("Server ID: ") + str(guild.id))
|
||
if guild.icon_url:
|
||
data.set_author(name=guild.name, url=guild.icon_url)
|
||
data.set_thumbnail(url=guild.icon_url)
|
||
else:
|
||
data.set_author(name=guild.name)
|
||
else:
|
||
|
||
def _size(num: int):
|
||
for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
|
||
if abs(num) < 1024.0:
|
||
return "{0:.1f}{1}".format(num, unit)
|
||
num /= 1024.0
|
||
return "{0:.1f}{1}".format(num, "YB")
|
||
|
||
def _bitsize(num: int):
|
||
for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
|
||
if abs(num) < 1000.0:
|
||
return "{0:.1f}{1}".format(num, unit)
|
||
num /= 1000.0
|
||
return "{0:.1f}{1}".format(num, "YB")
|
||
|
||
# Logic from: https://github.com/TrustyJAID/Trusty-cogs/blob/master/serverstats/serverstats.py#L159
|
||
online_stats = {
|
||
_("Humans: "): lambda x: not x.bot,
|
||
_(" • Bots: "): lambda x: x.bot,
|
||
"\N{LARGE GREEN CIRCLE}": lambda x: x.status == discord.Status.online,
|
||
"\N{LARGE ORANGE CIRCLE}": lambda x: x.status == discord.Status.idle,
|
||
"\N{LARGE RED CIRCLE}": lambda x: x.status == discord.Status.do_not_disturb,
|
||
"\N{MEDIUM WHITE CIRCLE}": lambda x: x.status == discord.Status.offline,
|
||
"\N{LARGE PURPLE CIRCLE}": lambda x: x.activity == discord.Streaming,
|
||
"\N{MOBILE PHONE}": lambda x: x.is_on_mobile(),
|
||
}
|
||
member_msg = _("Users online: **{online}/{total_users}**\n").format(
|
||
online=online, total_users=total_users
|
||
)
|
||
count = 1
|
||
for emoji, value in online_stats.items():
|
||
try:
|
||
num = len([m for m in guild.members if value(m)])
|
||
except Exception as error:
|
||
print(error)
|
||
continue
|
||
else:
|
||
member_msg += f"{emoji} {bold(humanize_number(num))} " + (
|
||
"\n" if count % 2 == 0 else ""
|
||
)
|
||
count += 1
|
||
|
||
vc_regions = {
|
||
"vip-us-east": _("__VIP__ US East ") + "\U0001F1FA\U0001F1F8",
|
||
"vip-us-west": _("__VIP__ US West ") + "\U0001F1FA\U0001F1F8",
|
||
"vip-amsterdam": _("__VIP__ Amsterdam ") + "\U0001F1F3\U0001F1F1",
|
||
"eu-west": _("EU West ") + "\U0001F1EA\U0001F1FA",
|
||
"eu-central": _("EU Central ") + "\U0001F1EA\U0001F1FA",
|
||
"europe": _("Europe ") + "\U0001F1EA\U0001F1FA",
|
||
"london": _("London ") + "\U0001F1EC\U0001F1E7",
|
||
"frankfurt": _("Frankfurt ") + "\U0001F1E9\U0001F1EA",
|
||
"amsterdam": _("Amsterdam ") + "\U0001F1F3\U0001F1F1",
|
||
"us-west": _("US West ") + "\U0001F1FA\U0001F1F8",
|
||
"us-east": _("US East ") + "\U0001F1FA\U0001F1F8",
|
||
"us-south": _("US South ") + "\U0001F1FA\U0001F1F8",
|
||
"us-central": _("US Central ") + "\U0001F1FA\U0001F1F8",
|
||
"singapore": _("Singapore ") + "\U0001F1F8\U0001F1EC",
|
||
"sydney": _("Sydney ") + "\U0001F1E6\U0001F1FA",
|
||
"brazil": _("Brazil ") + "\U0001F1E7\U0001F1F7",
|
||
"hongkong": _("Hong Kong ") + "\U0001F1ED\U0001F1F0",
|
||
"russia": _("Russia ") + "\U0001F1F7\U0001F1FA",
|
||
"japan": _("Japan ") + "\U0001F1EF\U0001F1F5",
|
||
"southafrica": _("South Africa ") + "\U0001F1FF\U0001F1E6",
|
||
"india": _("India ") + "\U0001F1EE\U0001F1F3",
|
||
"dubai": _("Dubai ") + "\U0001F1E6\U0001F1EA",
|
||
"south-korea": _("South Korea ") + "\U0001f1f0\U0001f1f7",
|
||
}
|
||
verif = {
|
||
"none": _("0 - None"),
|
||
"low": _("1 - Low"),
|
||
"medium": _("2 - Medium"),
|
||
"high": _("3 - High"),
|
||
"extreme": _("4 - Extreme"),
|
||
}
|
||
|
||
features = {
|
||
"PARTNERED": _("Partnered"),
|
||
"VERIFIED": _("Verified"),
|
||
"DISCOVERABLE": _("Server Discovery"),
|
||
"FEATURABLE": _("Featurable"),
|
||
"PUBLIC": _("Public"),
|
||
"PUBLIC_DISABLED": _("Public disabled"),
|
||
"INVITE_SPLASH": _("Splash Invite"),
|
||
"VIP_REGIONS": _("VIP Voice Servers"),
|
||
"VANITY_URL": _("Vanity URL"),
|
||
"MORE_EMOJI": _("More Emojis"),
|
||
"COMMERCE": _("Commerce"),
|
||
"NEWS": _("News Channels"),
|
||
"ANIMATED_ICON": _("Animated Icon"),
|
||
"BANNER": _("Banner Image"),
|
||
"MEMBER_LIST_DISABLED": _("Member list disabled"),
|
||
}
|
||
guild_features_list = [
|
||
f"✅ {name}" for feature, name in features.items() if feature in guild.features
|
||
]
|
||
|
||
joined_on = _(
|
||
"{bot_name} joined this server on {bot_join}. That's over {since_join} days ago!"
|
||
).format(
|
||
bot_name=ctx.bot.user.name,
|
||
bot_join=guild.me.joined_at.strftime("%d %b %Y %H:%M:%S"),
|
||
since_join=humanize_number((ctx.message.created_at - guild.me.joined_at).days),
|
||
)
|
||
|
||
data = discord.Embed(
|
||
description=(f"{guild.description}\n\n" if guild.description else "") + created_at,
|
||
colour=await ctx.embed_colour(),
|
||
)
|
||
data.set_author(
|
||
name=guild.name,
|
||
icon_url="https://cdn.discordapp.com/emojis/457879292152381443.png"
|
||
if "VERIFIED" in guild.features
|
||
else "https://cdn.discordapp.com/emojis/508929941610430464.png"
|
||
if "PARTNERED" in guild.features
|
||
else discord.Embed.Empty,
|
||
)
|
||
if guild.icon_url:
|
||
data.set_thumbnail(url=guild.icon_url)
|
||
data.add_field(name=_("Members:"), value=member_msg)
|
||
data.add_field(
|
||
name=_("Channels:"),
|
||
value=_(
|
||
"\N{SPEECH BALLOON} Text: {text}\n"
|
||
"\N{SPEAKER WITH THREE SOUND WAVES} Voice: {voice}"
|
||
).format(text=bold(text_channels), voice=bold(voice_channels)),
|
||
)
|
||
data.add_field(
|
||
name=_("Utility:"),
|
||
value=_(
|
||
"Owner: {owner}\nVoice region: {region}\nVerif. level: {verif}\nServer ID: {id}"
|
||
).format(
|
||
owner=bold(str(guild.owner)),
|
||
region=f"**{vc_regions.get(str(guild.region)) or str(guild.region)}**",
|
||
verif=bold(verif[str(guild.verification_level)]),
|
||
id=bold(str(guild.id)),
|
||
),
|
||
inline=False,
|
||
)
|
||
data.add_field(
|
||
name=_("Misc:"),
|
||
value=_(
|
||
"AFK channel: {afk_chan}\nAFK timeout: {afk_timeout}\nCustom emojis: {emoji_count}\nRoles: {role_count}"
|
||
).format(
|
||
afk_chan=bold(str(guild.afk_channel))
|
||
if guild.afk_channel
|
||
else bold(_("Not set")),
|
||
afk_timeout=bold(humanize_timedelta(seconds=guild.afk_timeout)),
|
||
emoji_count=bold(humanize_number(len(guild.emojis))),
|
||
role_count=bold(humanize_number(len(guild.roles))),
|
||
),
|
||
inline=False,
|
||
)
|
||
if guild_features_list:
|
||
data.add_field(name=_("Server features:"), value="\n".join(guild_features_list))
|
||
if guild.premium_tier != 0:
|
||
nitro_boost = _(
|
||
"Tier {boostlevel} with {nitroboosters} boosters\n"
|
||
"File size limit: {filelimit}\n"
|
||
"Emoji limit: {emojis_limit}\n"
|
||
"VCs max bitrate: {bitrate}"
|
||
).format(
|
||
boostlevel=bold(str(guild.premium_tier)),
|
||
nitroboosters=bold(humanize_number(guild.premium_subscription_count)),
|
||
filelimit=bold(_size(guild.filesize_limit)),
|
||
emojis_limit=bold(str(guild.emoji_limit)),
|
||
bitrate=bold(_bitsize(guild.bitrate_limit)),
|
||
)
|
||
data.add_field(name=_("Nitro Boost:"), value=nitro_boost)
|
||
if guild.splash:
|
||
data.set_image(url=guild.splash_url_as(format="png"))
|
||
data.set_footer(text=joined_on)
|
||
|
||
await ctx.send(embed=data)
|
||
|
||
@commands.command()
|
||
async def urban(self, ctx, *, word):
|
||
"""Search the Urban Dictionary.
|
||
|
||
This uses the unofficial Urban Dictionary API.
|
||
"""
|
||
|
||
try:
|
||
url = "https://api.urbandictionary.com/v0/define?term=" + str(word).lower()
|
||
|
||
headers = {"content-type": "application/json"}
|
||
|
||
async with aiohttp.ClientSession() as session:
|
||
async with session.get(url, headers=headers) as response:
|
||
data = await response.json()
|
||
|
||
except aiohttp.ClientError:
|
||
await ctx.send(
|
||
_("No Urban Dictionary entries were found, or there was an error in the process.")
|
||
)
|
||
return
|
||
|
||
if data.get("error") != 404:
|
||
if not data.get("list"):
|
||
return await ctx.send(_("No Urban Dictionary entries were found."))
|
||
if await ctx.embed_requested():
|
||
# a list of embeds
|
||
embeds = []
|
||
for ud in data["list"]:
|
||
embed = discord.Embed()
|
||
embed.title = _("{word} by {author}").format(
|
||
word=ud["word"].capitalize(), author=ud["author"]
|
||
)
|
||
embed.url = ud["permalink"]
|
||
|
||
description = _("{definition}\n\n**Example:** {example}").format(**ud)
|
||
if len(description) > 2048:
|
||
description = "{}...".format(description[:2045])
|
||
embed.description = description
|
||
|
||
embed.set_footer(
|
||
text=_(
|
||
"{thumbs_down} Down / {thumbs_up} Up, Powered by Urban Dictionary."
|
||
).format(**ud)
|
||
)
|
||
embeds.append(embed)
|
||
|
||
if embeds is not None and len(embeds) > 0:
|
||
await menu(
|
||
ctx,
|
||
pages=embeds,
|
||
controls=DEFAULT_CONTROLS,
|
||
message=None,
|
||
page=0,
|
||
timeout=30,
|
||
)
|
||
else:
|
||
messages = []
|
||
for ud in data["list"]:
|
||
ud.setdefault("example", "N/A")
|
||
message = _(
|
||
"<{permalink}>\n {word} by {author}\n\n{description}\n\n"
|
||
"{thumbs_down} Down / {thumbs_up} Up, Powered by Urban Dictionary."
|
||
).format(word=ud.pop("word").capitalize(), description="{description}", **ud)
|
||
max_desc_len = 2000 - len(message)
|
||
|
||
description = _("{definition}\n\n**Example:** {example}").format(**ud)
|
||
if len(description) > max_desc_len:
|
||
description = "{}...".format(description[: max_desc_len - 3])
|
||
|
||
message = message.format(description=description)
|
||
messages.append(message)
|
||
|
||
if messages is not None and len(messages) > 0:
|
||
await menu(
|
||
ctx,
|
||
pages=messages,
|
||
controls=DEFAULT_CONTROLS,
|
||
message=None,
|
||
page=0,
|
||
timeout=30,
|
||
)
|
||
else:
|
||
await ctx.send(
|
||
_("No Urban Dictionary entries were found, or there was an error in the process.")
|
||
)
|