def spam(self, ctx, user : discord.Member, spamtext, number : int=0):
"""Spams x times, default is 4."""
if user.id == "96987941519237120":
await self.bot.say("Hell nah, I ain't spamming him.")
return
if user.id == settings.owner:
await self.bot.say("Hell nah, I ain't spamming him. If you want to spam my owner use the `suggest` command!")
return
if number >> 8:
await self.bot.say("Hell nah, not past 8 for fck sakes.")
return
if number == 0:
number = 4
counter = 0
while counter < number:
try:
await self.bot.send_message(user, "{}, sent by **{}**".format(spamtext, ctx.message.author))
except discord.Forbidden:
await self.bot.say("{} blocked me :sob:".format(user.mention))
return
counter = counter + 1
if counter == 1:
await self.bot.say("Hehe, {} got spammed {} time!".format(user.mention, counter))
else:
await self.bot.say("Hehe, {} got spammed {} time!".format(user.mention, counter))
python类Forbidden()的实例源码
def fixroles(self, ctx):
"""Adds the role members were supposed to get when they joined but didn't."""
counter = 0
role = discord.utils.get(ctx.message.server.roles, id=self.settings[ctx.message.server.id]['role'])
if role == None:
await self.bot.say("The role set doesn't exist anymore.")
return
status = await self.bot.say("Adding roles...")
for m in ctx.message.server.members:
if [r.name for r in m.roles] == ["@everyone"]:
try:
await self.bot.add_roles(m, role)
counter += 1
except discord.Forbidden:
await self.bot.say("I am not allowed to add roles.")
return
await self.bot.edit_message(status, "Added the **{}** role to **{}** members.".format(role.name, str(counter)))
def on_member_join(member):
with open("database/storage2.json", "r") as infile:
storage2 = json.loads(infile.read())
if member.server.id not in storage2:
storage2[member.server.id] = 'message0'
with open("database/storage2.json", "w+") as outfile:
outfile.write(json.dumps(storage2))
if storage2[member.server.id] == 'message0':
try:
for i in member.server.channels:
if i.name in ['logs', 'logging', 'log', 'mod-log', 'mod_log', 'server-log', 'server_log']:
await client.send_message(i, "{0.mention} has joined {0.server.name} give them a warm welcome!".format(member))
try:
await client.send_message(member.server.default_channel,"{0.name} has joined {0.server.name} give them a warm welcome!".format(member))
except discord.Forbidden:
print('Couldn\'t welcome {} in server {} due to perms error.'.format(member, member.server))
except discord.Forbidden:
print('Couldn\'t welcome {} in server {} due to perms error.'.format(member, member.server))
def _generate_messages(self, channel: discord.Channel):
""" Generates and pins the messages for the given channel.
:param channel: The channel in which the messages will be
generated and pinned.
:type channel: discord.Channel
:raises: discord.errors.Forbidden: if the client doesn't have
permissions to pin messages.
"""
interface = self.get_interface(channel)
if interface.timer is None:
return
interface.time_message = await self.send_message(
channel, "Generating status...")
interface.list_message = await self.send_message(
channel, interface.timer.list_periods())
# The last message pinned ends up in the top
await self.pin_message(interface.time_message)
await self.pin_message(interface.list_message)
def removerole(self, ctx, rolename, user: discord.Member=None):
"""Removes a role from user, defaults to author
Role name must be in quotes if there are spaces."""
server = ctx.message.server
author = ctx.message.author
role = self._role_from_string(server, rolename)
if role is None:
await self.bot.say("Role not found.")
return
if user is None:
user = author
if role in user.roles:
try:
await self.bot.remove_roles(user, role)
await self.bot.say("Role successfully removed.")
except discord.Forbidden:
await self.bot.say("I don't have permissions to manage roles!")
else:
await self.bot.say("User does not have that role.")
def whisper(self, ctx, id, *, text):
author = ctx.message.author
target = discord.utils.get(self.bot.get_all_members(), id=id)
if target is None:
target = self.bot.get_channel(id)
if target is None:
target = self.bot.get_server(id)
prefix = "Hello, you're getting a message from {} ({})".format(
author.name, author.id)
payload = "{}\n\n{}".format(prefix, text)
try:
for page in pagify(payload, delims=[" ", "\n"], shorten_by=10):
await self.bot.send_message(target, box(page))
except discord.errors.Forbidden:
log.debug("Forbidden to send message to {}".format(id))
except (discord.errors.NotFound, discord.errors.InvalidArgument):
log.debug("{} not found!".format(id))
else:
await self.bot.say("Done.")
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 cycler(ev):
poll_coll = ev.db[ev.db.db_cfg.database].ShadowPolls
while True:
now = arrow.utcnow().timestamp
poll_files = await poll_coll.find({'settings.expires': {'$lt': now}, 'settings.active': True}).to_list(None)
for poll_file in poll_files:
poll_id = poll_file['id']
poll_file['settings'].update({'active': False})
await ev.db[ev.db.db_cfg.database].ShadowPolls.update_one({'id': poll_id}, {'$set': poll_file})
author = discord.utils.find(lambda x: x.id == poll_file['origin']['author'], ev.bot.get_all_members())
if author:
response = discord.Embed(color=0xff3333, title=f'? Your poll {poll_file["id"]} has expired.')
try:
await author.send(embed=response)
except discord.Forbidden:
pass
await asyncio.sleep(1)
def update(self, parent):
if self.needs_reinit:
self.reinit(parent)
t_config = self.parent.plugin_config[str(self.guild.id)]
if t_config["spam_role"] and time.time() - self.update_time > t_config['spam_role_timeout'] and self.muted:
for t_role in self.member.roles:
if t_role.id == int(t_config["spam_role"]):
try:
await self.member.remove_roles(t_role, reason="Mute time ran out.")
except Forbidden:
self.parent.logger.warning(f"Can't edit member {self.member.display_name}")
else:
self.muted = False
break
if time.time() - self.update_time > t_config['infraction_timeout']:
self.infractions = max(0, self.infractions-1)
self.update_time = time.time()
def clean(ctx, message):
"""
Cleans the previous messages
:param ctx:
:param message:
:return:
"""
try:
message_bucket = []
async for entry in ctx.logs_from(message.channel):
if entry.author == ctx.user:
message_bucket.append(entry)
await ctx.delete_messages(message_bucket)
await ctx.send_message(message.channel, ':sweat_drops: `Cleaned.`')
except discord.Forbidden:
await ctx.send_message(message.channel, '**Error**: `I do not have permissions to get channel logs`')
return
except discord.NotFound:
await ctx.send_message(message.channel, '**Error**: `The channel you are requesting for doesnt exist.`')
return
except discord.HTTPException:
return
def kick(ctx, message):
"""
Kick a member
:param ctx:
:param message:
:return:
"""
if not message.mentions:
await ctx.send_message(message.channel, "**Error** `Need to mention a user.`")
return
try:
await ctx.kick(message.mentions[0])
await ctx.send_message(message.channel, "**Kicked**: `{}` from `{}` :thumbsup:"
.format(message.mentions[0].name, message.server.name))
return
except discord.Forbidden:
await ctx.send_message(message.channel, "**Error** `I do not have 'Kick Users' Permission.`")
return
except discord.HTTPException:
await ctx.send_message(message.channel, "**Error* `Kicking failed.`")
return
def ex(dclient, channel, author, mention, a, cmd_char):
a = a.split(' ')
if channel.permissions_for(author):
try:
if len(a) == 1 and is_valid(a[0]):
purge_limit = int(a[0])
if 2 <= purge_limit <= 100:
msgs = list()
async for msg in dclient.logs_from(channel, limit=purge_limit):
msgs.append(msg)
await dclient.delete_messages(msgs)
await dclient.send_message(channel, '{}, `{}` messages has been removed from this channel.'
.format(mention, purge_limit))
else:
await dclient.send_message(channel, '{}, you can only delete messages between `2` and `100`!'
.format(mention))
else:
await dclient.send_message(channel, '{}, **USAGE** {}purge <#-of-messages>'.format(mention, cmd_char))
except discord.Forbidden:
await dclient.send_message(channel, "{}, I don't have access to `manage_messages`! Please notify an "
"admin!".format(mention))
else:
await dclient.send_message(channel, '{}, you must be an administrator!'.format(mention))
def convert(self, ctx: commands.Context, argument):
def finder(entry):
try:
user_id = int(argument)
except ValueError:
user_id = None
return (str(entry.user) == argument or # username#discriminator
entry.user.name == argument or # username
entry.user.id == user_id) # id
try:
entry = discord.utils.find(finder, await ctx.guild.bans())
if entry is None:
raise commands.BadArgument(
'Banned user not found. You can specify by ID, username, or username#discriminator.'
)
return entry.user
except discord.Forbidden:
raise commands.BadArgument("I can't view the bans for this server.")
def ok(self, emoji: str = '\N{OK HAND SIGN}'):
"""
Adds a reaction to the command message, or sends it to the channel if
we can't add reactions. This should be used as feedback to commands,
just like how most bots send out `:ok_hand:` when a command completes
successfully.
"""
try:
await self.message.add_reaction(emoji)
except Forbidden:
# can't add reactions
await self.send(emoji)
except NotFound:
# the command message got deleted somehow
pass
def on_member_join(self, member):
if not await self.bot.config_is_set(member.guild, 'welcome_message'):
return
welcome_message = (await self.bot.redis.get(f'{member.guild.id}:welcome_message')).decode()
transformations = {
'%{mention}': member.mention,
'%{user}': str(member),
'%{server}': member.guild.name,
'%{id}': str(member.id)
}
for var, value in transformations.items():
welcome_message = welcome_message.replace(var, value)
try:
channel = discord.utils.get(member.guild.text_channels, name='welcome')
await channel.send(welcome_message)
except discord.Forbidden:
logger.warning("Couldn't send welcome message for guild %d, no perms.", member.guild.id)
def ban(self, ctx, member: converters.RawMember, delete_days: DeleteDays=2, *, reason=None):
"""
Bans someone.
This command is special in that you may specify an ID to ban, instead of regularly specifying a
member to ban. Banning users outside of the server is called "hackbanning", and is handy for banning
users who are not present in the server.
If you don't want to delete any messages, specify 0 for delete_days. delete_days has a
maximum of 7. By default, 2 days worth of messages are deleted.
"""
try:
reason = reason or 'No reason provided.'
await ctx.guild.ban(member, delete_message_days=delete_days, reason=f'(Banned by {ctx.author}) {reason}')
ctx.bot.dispatch('member_dog_ban', member, ctx.author, reason)
except discord.Forbidden:
await ctx.send("I can't do that.")
except discord.NotFound:
await ctx.send("User not found.")
else:
banned = await ctx.bot.get_user_info(member.id) if isinstance(member, discord.Object) else member
await ctx.send(f'\N{OK HAND SIGN} Banned {describe(banned)}.')
def get_responsible(self, guild: discord.Guild, action: str, *, target: discord.Member=None) -> discord.AuditLogEntry:
"""
Checks the audit log for recent action performed on some user.
:param guild: The :class:`discord.Guild` to look at.
:param action: The name of the :class:`discord.AuditLogAction` attribute to check for.
:param target: The targeted user to check for.
:returns: The audit log entry.
"""
try:
# get the audit logs for the action specified
entries = await guild.audit_logs(limit=1, action=getattr(discord.AuditLogAction, action)).flatten()
# only check for entries performed on target, and happened in the last 2 seconds
def check(entry):
created_ago = (datetime.datetime.utcnow() - entry.created_at).total_seconds()
return (entry.target == target if target else True) and created_ago <= 2
return discord.utils.find(check, entries)
except discord.Forbidden:
pass
def stop(self, ctx):
"""Stop the current game night session.
Usage: gamenight stop"""
or_check_perms(ctx, ['manage_guild', 'manage_channels', 'manage_messages', 'manage_roles'])
if ctx.channel.id in self.games:
game = self.games[ctx.channel.id]
if game['role']:
try:
await game['role'].delete(reason='Deleting game night session-specific role')
except discord.Forbidden:
pass
del self.games[ctx.channel.id]
await ctx.send('**Ended the current game night session at round ' + str(game['round']) + '.**')
del game
else:
await ctx.send(ctx.mention + ' There\'s no game night session active here!')
def topic(self, ctx, *, topic: str):
"""Start the current round with a topic."""
or_check_perms(ctx, ['manage_guild', 'manage_channels', 'manage_messages', 'manage_roles'])
if ctx.channel.id in self.games:
try:
await ctx.message.delete(reason='Deleting message sent to change the topic, so players don\'t see and prepare before the round')
except discord.Forbidden:
await ctx.send('? **I work best with the Manage Messages permission.**')
game = self.games[ctx.channel.id]
r_mention = game['r_mention']
game['topic'] = topic
await ctx.send('''Starting **round {}** in 30 seconds!
{}Get your butts in here, and grab your dankest memes!'''.format(str(game['round']), r_mention))
await asyncio.sleep(28.6, loop=self.loop)
game['active'] = True
game['round_active'] = True
await ctx.send(f'''{r_mention}The **meme war** is now starting for the topic `{topic}`!
Get your memes in already! :clap::clap:
Leaders: when you're ready, select a winner (and end the round) with `{ctx.prefix}gamenight winner`!''')
else:
await ctx.send(ctx.mention + ' There isn\'t a game night session in this channel!')
def mute(self, ctx, *, member: discord.Member):
"""Mute someone on voice and text chat.
Usage: mute [person's name]"""
or_check_perms(ctx, ['mute_members', 'manage_roles', 'manage_channels', 'manage_messages'])
status = await ctx.send('Muting... ??')
pg_task = self.loop.create_task(asyncio.wait_for(self.progress(status, 'Muting'), timeout=30, loop=self.loop))
try:
ch_perms = discord.PermissionOverwrite(**{p: False for p in muted_perms})
for channel in ctx.guild.channels:
await channel.set_permissions(member, ch_perms)
await member.__redit(mute=True, deafen=None, reason='Mute command was used on user')
pg_task.cancel()
await status.delete(reason='Deleting progress/status message')
await ctx.send('Successfully muted **%s**!' % str(member))
except (discord.Forbidden, discord.HTTPException):
pg_task.cancel()
await status.delete(reason='Deleting progress/status message')
await ctx.send('**I don\'t have enough permissions to do that!**')
def unmute(self, ctx, *, member: discord.Member):
"""Unmute someone on voice and text chat.
Usage: unmute [person's name]"""
or_check_perms(ctx, ('mute_members', 'manage_roles', 'manage_channels', 'manage_messages'))
status = await ctx.send('Unmuting... ??')
pg_task = self.loop.create_task(asyncio.wait_for(self.progress(status, 'Unmuting'), timeout=30, loop=self.loop))
role_map = {r.name: r for r in member.roles}
try:
if 'Muted' in role_map:
await member.remove_roles(role_map['Muted'], reason='Unmute command was used on user')
ch_perms = discord.PermissionOverwrite(**{p: None for p in muted_perms})
for channel in ctx.guild.channels:
await channel.set_permissions(member, ch_perms)
await member.__redit(mute=False, deafen=None, reason='Unmute command was used on user')
pg_task.cancel()
await status.delete(reason='Deleting progress/status message')
await ctx.send('Successfully unmuted **%s**!' % str(member))
except (discord.Forbidden, discord.HTTPException):
pg_task.cancel()
await status.delete(reason='Deleting progress/status message')
await ctx.send('**I don\'t have enough permissions to do that!**')
def on_guild_join(self, guild):
"""Send the bot introduction message when invited."""
self.logger.info('New guild: ' + guild.name)
if self.selfbot: return
try:
await self.send_message(guild.default_channel, join_msg)
except discord.Forbidden:
satisfied = False
c_count = 0
try_channels = list(guild.channels)
channel_count = len(try_channels) - 1
while not satisfied:
with suppress(discord.Forbidden, discord.HTTPException):
await self.send_message(try_channels[c_count], join_msg)
satisfied = True
if c_count > channel_count:
self.logger.warning('Couldn\'t announce join to guild ' + guild.name)
satisfied = True
c_count += 1
def _notify_subscribers_of_streamer(self, streamer: Streamer):
subscribers = await self.bot.database.get_subscribers_from_streamer(streamer.db_id)
for (subscriber_id,) in subscribers:
if subscriber_id in self.disabled_users:
continue
subscriber = await self._get_subscriber(subscriber_id)
if subscriber:
notification_embed = streamer.create_notification_embed()
try:
await subscriber.send(embed=notification_embed)
log.info('Notified %s that streamer %s is online on %s',
subscriber, streamer.channel_name, streamer.service_name)
except discord.Forbidden as e:
log.exception('_notify_subscribers_of_streamer: No permissions to send the message.\n%s', e)
except discord.HTTPException as e:
log.exception('_notify_subscribers_of_streamer: Sending the message failed.\n%s', e)
except Exception as e:
log.exception('_notify_subscribers_of_streamer: General exception.\n%s', e)
else:
log.error('_notify_subscribers_of_streamer: Subscriber not found: %s', subscriber_id)
def kick(self, ctx, user: discord.Member):
"""Kicks user."""
author = ctx.message.author
server = author.server
try:
await self.bot.kick(user)
logger.info("{}({}) kicked {}({})".format(
author.name, author.id, user.name, user.id))
await self.new_case(server,
action="Kick \N{WOMANS BOOTS}",
mod=author,
user=user)
await self.bot.say("Done. That felt good.")
except discord.errors.Forbidden:
await self.bot.say("I'm not allowed to do that.")
except Exception as e:
print(e)
def channel_mute(self, ctx, user : discord.Member):
"""Mutes user in the current channel"""
channel = ctx.message.channel
overwrites = channel.overwrites_for(user)
if overwrites.send_messages is False:
await self.bot.say("That user can't send messages in this "
"channel.")
return
self._perms_cache[user.id][channel.id] = overwrites.send_messages
overwrites.send_messages = False
try:
await self.bot.edit_channel_permissions(channel, user, overwrites)
except discord.Forbidden:
await self.bot.say("Failed to mute user. I need the manage roles "
"permission and the user I'm muting must be "
"lower than myself in the role hierarchy.")
else:
dataIO.save_json("data/mod/perms_cache.json", self._perms_cache)
await self.bot.say("User has been muted in this channel.")
def colour(self, ctx, role: discord.Role, value: discord.Colour):
"""Edits a role's colour
Use double quotes if the role contains spaces.
Colour must be in hexadecimal format.
\"http://www.w3schools.com/colors/colors_picker.asp\"
Examples:
!editrole colour \"The Transistor\" #ff0000
!editrole colour Test #ff9900"""
author = ctx.message.author
try:
await self.bot.edit_role(ctx.message.server, role, color=value)
logger.info("{}({}) changed the colour of role '{}'".format(
author.name, author.id, role.name))
await self.bot.say("Done.")
except discord.Forbidden:
await self.bot.say("I need permissions to manage roles first.")
except Exception as e:
print(e)
await self.bot.say("Something went wrong.")
def edit_role_name(self, ctx, role: discord.Role, name: str):
"""Edits a role's name
Use double quotes if the role or the name contain spaces.
Examples:
!editrole name \"The Transistor\" Test"""
if name == "":
await self.bot.say("Name cannot be empty.")
return
try:
author = ctx.message.author
old_name = role.name # probably not necessary?
await self.bot.edit_role(ctx.message.server, role, name=name)
logger.info("{}({}) changed the name of role '{}' to '{}'".format(
author.name, author.id, old_name, name))
await self.bot.say("Done.")
except discord.Forbidden:
await self.bot.say("I need permissions to manage roles first.")
except Exception as e:
print(e)
await self.bot.say("Something went wrong.")
def clearrole(self, ctx):
"""Clears all self assigned roles from you, or the listed members
"""
message = ctx.message
server = message.server
db_roles = await self.database.get_all(server)
listed_roles = []
for role_id, alias in db_roles:
listed_roles.append(role_id)
members = await self._get_members_from_message(message)
for m in members:
member_roles = m.roles
for r in m.roles:
if r.id not in listed_roles:
member_roles.remove(r)
bot_message = await self.bot.say(
"This will clear all roles for: {0.mention}. Are you sure you want to do that? Y/N".format(m))
reply = await self.bot.wait_for_message(timeout=5.0, author=message.author)
if reply and reply.content.lower() in ["yes", "y"]:
try:
await self.bot.remove_roles(m, *member_roles)
except Forbidden:
await self.bot.say("Oops, something happened, I don't have permission to clear your roles.")
else:
await self.bot.delete_message(bot_message)
def clean(ctx, message):
"""
Cleans the previous messages
:param ctx:
:param message:
:return:
"""
try:
message_bucket = []
async for entry in ctx.logs_from(message.channel):
if entry.author == ctx.user:
message_bucket.append(entry)
await ctx.delete_messages(message_bucket)
await ctx.send_message(message.channel, ':sweat_drops: `Cleaned.`')
except discord.Forbidden:
await ctx.send_message(message.channel, '**Error**: `I do not have permissions to get channel logs`')
return
except discord.NotFound:
await ctx.send_message(message.channel, '**Error**: `The channel you are requesting for doesnt exist.`')
return
except discord.HTTPException:
return
def kick(ctx, message):
"""
Kick a member
:param ctx:
:param message:
:return:
"""
if not message.mentions:
await ctx.send_message(message.channel, "**Error** `Need to mention a user.`")
return
try:
await ctx.kick(message.mentions[0])
await ctx.send_message(message.channel, "**Kicked**: `{}` from `{}` :thumbsup:"
.format(message.mentions[0].name, message.server.name))
return
except discord.Forbidden:
await ctx.send_message(message.channel, "**Error** `I do not have 'Kick Users' Permission.`")
return
except discord.HTTPException:
await ctx.send_message(message.channel, "**Error* `Kicking failed.`")
return