def safe_send_message(self, dest, content, *, tts=False, expire_in=0, also_delete=None, quiet=False):
msg = None
try:
msg = await self.send_message(dest, content, tts=tts)
if msg and expire_in:
asyncio.ensure_future(self._wait_delete_msg(msg, expire_in))
if also_delete and isinstance(also_delete, discord.Message):
asyncio.ensure_future(self._wait_delete_msg(also_delete, expire_in))
except discord.Forbidden:
if not quiet:
self.safe_print("Warning: Cannot send message to %s, no permission" % dest.name)
except discord.NotFound:
if not quiet:
self.safe_print("Warning: Cannot send message to %s, invalid channel?" % dest.name)
return msg
python类Forbidden()的实例源码
def deletenewschannel(self, ctx, channel: discord.Channel):
"""Removes news functionality for a channel"""
server = ctx.message.server
if server.id not in self.settings:
await self.bot.say("Nothing available for this server!")
return
if channel.id not in self.settings[server.id]:
await self.bot.say("News functionality isn't set up for that channel!")
return
role = [r for r in ctx.message.server.roles if r.id == self.settings[server.id][channel.id]["role_id"]][0]
try:
await self.bot.delete_role(server, role)
except discord.Forbidden:
await self.bot.say("I cannot delete roles!")
return
except discord.HTTPException:
await self.bot.say("Something went wrong!")
return
else:
await self.bot.say("Role removed!")
self.settings[server.id].pop(channel.id, None)
dataIO.save_json("data/newsannouncer/settings.json", self.settings)
def joinnews(self, ctx):
"""Joins the news role for the current channel"""
server = ctx.message.server
channel = ctx.message.channel
if server.id not in self.settings or\
channel.id not in self.settings[server.id]:
await self.bot.say("No news role available here!")
return
author = ctx.message.author
if author.id in self.settings[server.id][channel.id]["joined"]:
await self.bot.say("You already have the role for this channel!")
return
role_id = self.settings[server.id][channel.id]["role_id"]
role_to_add = [r for r in server.roles if r.id == role_id][0]
try:
await self.bot.add_roles(author, role_to_add)
except discord.Forbidden:
await self.bot.say("I don't have permissions to add roles here!")
return
except discord.HTTPException:
await self.bot.say("Something went wrong while doing that.")
return
await self.bot.say("Added that role successfully")
self.settings[server.id][channel.id]["joined"].append(author.id)
dataIO.save_json("data/newsannouncer/settings.json", self.settings)
def unban(self, ctx, member_id: int):
"""Used to unban a member from this server
Due to the fact that I cannot find a user without being in a server with them
only the ID should be provided
EXAMPLE: !unban 353217589321750912
RESULT: That dude be unbanned"""
# Lets only accept an int for this method, in order to ensure only an ID is provided
# Due to that though, we need to ensure a string is passed as the member's ID
member = discord.Object(id=str(member_id))
try:
await self.bot.unban(ctx.message.server, member)
await self.bot.say("\N{OK HAND SIGN}")
except discord.Forbidden:
await self.bot.say("But I can't, muh permissions >:c")
except discord.HTTPException:
await self.bot.say("Sorry, I failed to unban that user!")
def summon(self, ctx):
"""Summons the bot to join your voice channel."""
# This method will be invoked by other commands, so we should return True or False instead of just returning
# First check if the author is even in a voice_channel
summoned_channel = ctx.message.author.voice_channel
if summoned_channel is None:
await self.bot.say('You are not in a voice channel.')
return False
# Then simply create a voice client
try:
success = await self.create_voice_client(summoned_channel)
except (asyncio.TimeoutError, discord.ConnectionClosed):
await self.bot.say("I failed to connect! This usually happens if I don't have permission to join the"
" channel, but can sometimes be caused by your server region being far away."
" Otherwise this is an issue on Discord's end, causing the connect to timeout!")
await self.remove_voice_client(summoned_channel.server)
return False
if success:
try:
await self.bot.say('Ready to play audio in ' + summoned_channel.name)
except discord.Forbidden:
pass
return success
def kick(self, *, member : discord.Member):
"""Kicks a member from the server.
In order for this to work, the bot must have Kick Member permissions.
To use this command you must have Kick Members permission or have the
Bot Admin role.
"""
try:
await self.bot.kick(member)
except discord.Forbidden:
await self.bot.say('The bot does not have permissions to kick members.')
except discord.HTTPException:
await self.bot.say('Kicking failed.')
else:
await self.bot.say('\U0001f44c')
def ban(self, *, member : discord.Member):
"""Bans a member from the server.
In order for this to work, the bot must have Ban Member permissions.
To use this command you must have Ban Members permission or have the
Bot Admin role.
"""
try:
await self.bot.ban(member)
except discord.Forbidden:
await self.bot.say('The bot does not have permissions to ban members.')
except discord.HTTPException:
await self.bot.say('Banning failed.')
else:
await self.bot.say('\U0001f44c')
def softban(self, *, member : discord.Member):
"""Soft bans a member from the server.
A softban is basically banning the member from the server but
then unbanning the member as well. This allows you to essentially
kick the member while removing their messages.
To use this command you must have Ban Members permissions or have
the Bot Admin role. Note that the bot must have the permission as well.
"""
try:
await self.bot.ban(member)
await self.bot.unban(member.server, member)
except discord.Forbidden:
await self.bot.say('The bot does not have permissions to ban members.')
except discord.HTTPException:
await self.bot.say('Banning failed.')
else:
await self.bot.say('\U0001f44c')
def colour(self, ctx, colour : discord.Colour, *, role : discord.Role):
"""Changes the colour of a role.
The colour must be a hexadecimal value, e.g. FF2AEF. Don't prefix it
with a pound (#) as it won't work. Colour names are also not supported.
To use this command you must have the Manage Roles permission or
have the Bot Admin role. The bot must also have Manage Roles permissions.
This command cannot be used in a private message.
"""
try:
await self.bot.edit_role(ctx.message.server, role, colour=colour)
except discord.Forbidden:
await self.bot.say('The bot must have Manage Roles permissions to use this.')
else:
await self.bot.say('\U0001f44c')
#changes the name of the role
#NOTE: Currently CANNOT change default bot role name (BotName=DafaultRoleName)
def on_command_error(self, ctx, error):
"""Error handling"""
error_msg = None
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send(error)
elif isinstance(error, commands.CommandNotFound):
pass
elif isinstance(error, commands.CommandInvokeError):
original = error.original
if isinstance(original, discord.Forbidden):
await ctx.send("I need to have the 'embed links' permission to send messages!")
return
elif isinstance(original, exceptions.Halt):
return
print('{0.created_at}: {0.author}: {0.content}'.format(ctx.message))
print(error)
embed = discord.Embed(title="An unexpected error occured :I", colour=0xCA0147,
description="If you feel like this shouldn't be happening [click here to join my support server](https://discord.gg/UP4TwFX).")
await ctx.send("", embed=embed)
else:
print('{0.created_at}: {0.author}: {0.content}'.format(ctx.message))
print(str(error))
def setavatar(cmd, message, args):
if args or message.attachments:
if message.attachments:
image_url = message.attachments[0].url
else:
image_url = ' '.join(args)
try:
async with aiohttp.ClientSession() as session:
async with session.get(image_url) as image_response:
img_data = await image_response.read()
await cmd.bot.user.edit(avatar=img_data)
response = discord.Embed(color=0x77B255, title=f'? My avatar has been changed.')
except discord.Forbidden:
response = discord.Embed(color=0xBE1931, title=f'? I was unable to change my avatar.')
else:
response = discord.Embed(color=0xBE1931, title='? Give me a link or attach an image, please.')
await message.channel.send(embed=response)
def edit_mod_entry(self, modcfg, data):
"""Edit a moderation entry."""
modlog = data['guild'].get_channel(modcfg['mod_log_id'])
if modlog is None:
raise self.SayException('Moderation channel not found')
try:
action_data = self.cache[data['action_id']]
except KeyError:
raise self.SayException("Can't find action ID in cache, sorry :c")
old_data = action_data['data']
old_data['reason'] = data['reason']
try:
message = await modlog.get_message(action_data['message_id'])
except discord.NotFound:
raise self.SayException('Message to edit not found')
except discord.Forbidden:
raise self.SayException("Can't read messages")
except discord.HTTPException as err:
raise self.SayException(f'fug `{err!r}`')
await message.edit(content=self.modlog_fmt(old_data))
def star(self, ctx, message_id: int):
"""Star a message."""
try:
message = await ctx.channel.get_message(message_id)
except discord.NotFound:
return await ctx.send('Message not found')
except discord.Forbidden:
return await ctx.send("Can't retrieve message")
except discord.HTTPException as err:
return await ctx.send(f'Failed to retrieve message: {err!r}')
try:
await self.add_star(message, ctx.author)
await ctx.ok()
except (StarAddError, StarError) as err:
log.warning(f'[star_command] Errored: {err!r}')
return await ctx.send(f'Failed to add star: {err!r}')
def unstar(self, ctx, message_id: int):
"""Unstar a message."""
try:
message = await ctx.channel.get_message(message_id)
except discord.NotFound:
return await ctx.send('Message not found')
except discord.Forbidden:
return await ctx.send("Can't retrieve message")
except discord.HTTPException as err:
return await ctx.send(f'Failed to retrieve message: {err!r}')
try:
await self.remove_star(message, ctx.author)
await ctx.ok()
except (StarRemoveError, StarError) as err:
log.warning(f'[unstar_cmd] Errored: {err!r}')
return await ctx.send(f'Failed to remove star: {err!r}')
def starrers(self, ctx, message_id: int):
"""Get the list of starrers from a message in the current channel."""
try:
message = await ctx.channel.get_message(message_id)
except discord.NotFound:
return await ctx.send('Message not found')
except discord.Forbidden:
return await ctx.send("Can't retrieve message")
except discord.HTTPException as err:
return await ctx.send(f'Failed to retrieve message: {err!r}')
guild = ctx.guild
await self._get_starconfig(guild.id)
star = await self.get_star(guild.id, message.id)
if star is None:
return await ctx.send('Star object not found')
_, em = make_star_embed(star, message)
starrers = [guild.get_member(starrer_id)
for starrer_id in star['starrers']]
em.add_field(name='Starrers', value=', '.join([m.display_name
for m in starrers]))
await ctx.send(embed=em)
def cmd_cls(self, message, author, server, channel):
"""
Usage: {command_prefix}eval "evaluation string"
runs a command thru the eval param for testing
"""
if author.id == self.config.master_id:
await self.safe_delete_message(message)
def delete_this_msg(m):
return m.author == self.user
try:
await self.purge_from(channel, limit=5000, check=delete_this_msg, before=message)
except discord.Forbidden:
raise CommandError('I cannot delete messages, please give me permissions to do so and'
'try again!')
def send_log(self, server: discord.Server, log: Log):
"""Sends a embed corresponding to the log in the log channel of the server"""
if server.id in self.servers_config["servers"]:
if "log channel" in self.servers_config["servers"][server.id]:
embed = log.get_embed(self.bot)
channel = self.servers_config["servers"][server.id]["log channel"]
try:
await self.bot.send_message(destination=channel, embed=embed)
except discord.Forbidden:
await self.bot.send_message(destination=server.owner, content=\
"I'm not allowed to send embeds in the log channel (#" + \
channel.name + "). Please change my permissions.")
except discord.NotFound:
await self.bot.send_message(destination=server.owner, content=\
"I'm not allowed to send embeds in the log channel because " + \
"it doesn't exists anymore. Please set another log channel " + \
"using the `[p]set_log_channel` command.")
except discord.HTTPException:
pass
except discord.InvalidArgument:
pass
def check_new_comers(self, member):
"""Checks if a new comer is in the b1nzy banlist"""
if member.server.id in self.b1nzy_banlist:
if member.id in self.b1nzy_banlist[member.server.id]:
try:
await self.bot.ban(member)
self.b1nzy_banlist[member.server.id].remove(member.id)
if not self.b1nzy_banlist[member.server.id]:
del self.b1nzy_banlist[member.server.id]
self.save_b1nzy_banlist()
except discord.Forbidden:
await self.bot.send_message(member.server.owner, \
"Couldn't ban " + member.name + "#" + member.discriminator + \
" (" + member.id + ") who's in the b1nzy banlist --> missing permissions")
except discord.HTTPException:
pass
def server_add_role(self, server, role, color):
if re.search(r'^(?:[0-9a-fA-F]{3}){1,2}$', color):
color = discord.Color(int(color, 16))
try:
if not await self.server_has_role(server, role):
await self.bot.create_role(server, name=role, color=color, permissions=discord.Permissions(permissions=0), hoist=False)
if server.id not in self.roles:
self.roles[server.id] = {}
self.roles[server.id][role] = {}
await self.save_role_data()
return 0
else:
return 3
except discord.Forbidden:
return 2
else:
return 1
def say_victory_message(self, msg_winner, msg_no_winner):
serverlist = list(self.bot.servers)
for s in serverlist:
if self.get_victory_messages(s):
try:
msg = msg_winner if self.get_show_result(s) else msg_no_winner
matches_channel = self.bot.get_channel(self.get_matches_channel(s))
if matches_channel:
try:
await self.bot.send_message(matches_channel, msg)
except (discord.Forbidden, discord.NotFound, discord.InvalidArgument):
pass
except discord.HTTPException:
pass
#except Exception as e:
# print("Unable to announce end of match: %s" % e)