def __init__(self, config: ConfigParser, app: Flask): self.config = config self.app = app self.client = Client() self.loop = asyncio.new_event_loop() self.loop.run_until_complete( self.client.login(config['bot']['token'], bot=True))
async def try_mute_on_rejoin(member: discord.Member, db: db_hlapi, client: discord.Client, log: str, ramfs: lexdpyk.ram_filesystem) -> None: mute_role_id = db.grab_config("mute-role") if mute_role_id and (mute_role := member.guild.get_role(int(mute_role_id))): success: bool try: await member.add_roles(mute_role) success = True except discord.errors.Forbidden: success = False stringcases = { False: "was not able to be remuted (permissions error)", True: "was remuted", } if log and (channel := client.get_channel(int(log))): if isinstance(channel, discord.TextChannel): muted_embed = discord.Embed(title=f"Notify on muted member join: {member}", description=f"This user has an entry in the mute database and {stringcases[success]}.") muted_embed.color = load_embed_color(member.guild, embed_colors.primary, ramfs) muted_embed.set_footer(text=f"uid: {member.id}") await catch_logging_error(channel, muted_embed)
async def complete_log(client: discord.Client, sanction_type: str, author: discord.Member or discord.User, guild: discord.Guild, reason: str, image_url: str = ''): state, results = api_manager.get_data('servers', discord_id=guild.id) if not state: return log_channel_id = results[0]['discord_log_channel_id'] log_channel: discord.TextChannel = client.get_channel(log_channel_id) embed = EmbedsManager.sanction_embed(sanction_type, guild, reason, image_url) embed.description = f"Sanction by {author.display_name}" if log_channel: await log_channel.send(embed=embed) with open('run/config/config.yml', 'r') as file: config = yaml.safe_load(file) main_channel_log = client.get_channel( config['channels']['log_channel']) if main_channel_log: embed.set_thumbnail(url=guild.icon_url) await main_channel_log.send(embed=embed)
async def purge_cli(message: discord.Message, args: List[str], client: discord.Client, **kwargs: Any) -> Any: if args: try: limit = int(args[0]) except ValueError: await message.channel.send("ERROR: Limit is not valid int") return 1 else: await message.channel.send("ERROR: No limit specified") return 1 if limit > 100 or limit <= 0: await message.channel.send( "ERROR: Cannot purge more than 100 messages or less than 1 message" ) return 1 ucheck: Optional[Callable[[discord.Message], bool]] try: if not (user := client.get_user(int(args[1].strip("<@!>")))): user = await client.fetch_user(int(args[1].strip("<@!>"))) ucheck = purger(user.id).check
def get_logging_channel(bot: discord.Client, channel_name: str, guild: int = None) -> discord.TextChannel: logging_channels = { "joins": lambda: bot.get_guild(797308956162392094).get_thread( database.cursor.execute( "select join_thread from log_threads where guild_id=?", (guild, )).fetchone()[0]), "invites": lambda: bot.get_guild(797308956162392094).get_thread( database.cursor.execute( "select invite_thread from log_threads where guild_id=?", (guild, )).fetchone()[0]), "java_repost": lambda: bot.get_guild(739176312081743934).get_channel( 821778423579410433), "bedrock_repost": lambda: bot.get_guild(739176312081743934).get_channel( 821778441133097021), "servers": lambda: bot.get_guild(797308956162392094).get_channel( 867605721424199710) } database.commit() return logging_channels[channel_name]()
def __init__(self, config): Client.__init__(self) self.config = config self.commands = [] for k, v in LoggerBot.__dict__.items(): if hasattr(v, 'command'): self.commands.append(k)
def __init__(self, client: discord.Client): self.command = "./logs/command.csv" self.ban = "./logs/ban.csv" self.client = client self.image_channel = client.get_channel(IMAGE_LOG_CHANNEL) self.command_channel = client.get_channel(COMMAND_LOG_CHANNEL) self.invite_channel = client.get_channel(INVITE_CHANNEL)
async def keyword_input_task(bot: discord.Client, msg: discord.Message, user: discord.User, timeout: float): await msg.add_reaction(Settings.reject_emoji) def check_msg(m: discord.Message): return len(m.content) > 0 and not m.guild and m.author.id == user.id def check_react(react: discord.Reaction, user_got: discord.User): return user_got.id == user.id and str(react) == Settings.reject_emoji try: tasks = [ asyncio.create_task( bot.wait_for('message', timeout=timeout, check=check_msg)), asyncio.create_task( bot.wait_for('reaction_add', timeout=timeout, check=check_react)) ] for future in asyncio.as_completed(tasks): res = await future if type(res) is tuple and type(res[0]) is discord.Reaction: return Response.REJECT elif type(res) is discord.Message: return res.content for task in tasks: task.cancel() return except asyncio.TimeoutError: return Response.TIMEDOUT
def on_message(client: discord.Client, message: discord.Message, args: list): if message.channel.is_private: return False channel = moderate.data.get(message.server.id, {}).get("nsfw-channel") if channel: # Check if message includes keyword nsfw and a link msg = message.content.lower() if "nsfw" in msg and ("http://" in msg or "https://" in msg) and not message.channel == channel: if message.server.me.permissions_in( message.channel).manage_messages: yield from client.delete_message(message) nsfw_channel = message.server.get_channel( moderate.data[message.server.id].get("nsfw-channel")) if nsfw_channel: yield from client.send_message( message.channel, "{}: **Please post NSFW content in {}**".format( message.author.mention, nsfw_channel.mention)) else: yield from client.send_message( message.channel, "{}: **I did not find the specified NSFW channel.** " "If you wish to remove this feature, see `!help " "nsfwchannel`.".format(message.server.owner.mention)) return True return False
async def do_query_message(conn, client: discord.Client, queryer_id: int, message_id: int, reacted_emoji: str) -> bool: # Find the message that was queried msg = await db.get_message(conn, message_id) if not msg: return False # Then DM the queryer the message embed card = await embeds.message_card(client, msg, include_pronouns=True) user = client.get_user(queryer_id) if not user: # We couldn't find this user in the cache - bail return False # Remove the original reaction by the user if we have "Manage Messages" channel = client.get_channel(msg.channel) if isinstance(channel, discord.TextChannel) and channel.permissions_for( channel.guild.get_member(client.user.id)).manage_messages: # We need the message instance itself to remove the reaction, since discord.py doesn't let you # call HTTP endpoints with arbitrary IDs (at least, not without internals-hacking) try: message_instance = await channel.get_message(message_id) member = channel.guild.get_member(queryer_id) await message_instance.remove_reaction(reacted_emoji, member) except (discord.Forbidden, discord.NotFound): # Oh yeah, and this can also fail. yeet. pass # Send the card to the user try: await user.send(embed=card) except discord.Forbidden: # User doesn't have DMs enabled, not much we can do about that pass
async def check_mentions(client: discord.Client, message: discord.Message): if len(message.mentions) < 4 and len(message.role_mentions) == 0: return embed = discord.Embed() embed.set_thumbnail(url=message.author.avatar_url) \ .set_author(name="A message with important notification has been sent.", icon_url="https://cdn4.iconfinder.com/data/icons/infy-interface/300/notification-512.png") embed.add_field(name=f'Message by {message.author.display_name}', value=message.content[:1200]) state, results = api_manager.get_data('servers', discord_id=message.guild.id) if not state: return log_channel_id = results[0]['discord_log_channel_id'] log_channel: discord.TextChannel = client.get_channel(log_channel_id) main_channel_log = client.get_channel(553974648258166800) if log_channel: await log_channel.send(embed=embed) if main_channel_log: embed.set_thumbnail(url=message.guild.icon_url) await main_channel_log.send(embed=embed)
async def timer(client: discord.Client, vote_id: str, notify: bool = False): t_needed = 0 while not client.is_closed(): await asyncio.sleep(60 - t_needed) t_start = time.time() vote = sqlib.votes.get(vote_id) msg_id, options, duration, channel_id = vote duration -= 1 sqlib.votes.update(msg_id, {"duration": duration}) channel = client.get_channel(int(channel_id)) try: message = await channel.get_message(msg_id) except AttributeError: print("AttributeError") continue await refresh_vote_msg(message, json.loads(options), duration, client, notify=notify) if duration == 0: break t_end = time.time() t_needed = t_end - t_start
def on_message(client: discord.Client, message: discord.Message, args: list): if message.channel.is_private: return False channel = moderate.data.get(message.server.id, {}).get("nsfw-channel") if channel: # Check if message includes keyword nsfw and a link msg = message.content.lower() if "nsfw" in msg and ("http://" in msg or "https://" in msg) and not message.channel == channel: if message.server.me.permissions_in(message.channel).manage_messages: yield from client.delete_message(message) nsfw_channel = message.server.get_channel(moderate.data[message.server.id].get("nsfw-channel")) if nsfw_channel: yield from client.send_message(message.channel, "{}: **Please post NSFW content in {}**".format( message.author.mention, nsfw_channel.mention )) else: yield from client.send_message(message.channel, "{}: **I did not find the specified NSFW channel.** " "If you wish to remove this feature, see `!help " "nsfwchannel`.".format(message.server.owner.mention)) return True return False
async def main(): client = Client(intents=Intents(guilds=True)) client.my_cfg = load_config() tree = CommandTree(client) init = False @client.event async def on_ready(): nonlocal init if not init: app = await client.application_info() client.my_owner_id = app.owner.id guild = None # client.get_guild(ID) add_vouch_interactions(tree, guild) if "not guild" and app.bot_public: @tree.command(guild=guild) async def invite(ctx: Interaction): """Give an invite link for this bot""" await ctx.response.send_message( oauth_url( app.id, permissions=Permissions(manage_roles=True), scopes=["bot", "applications.commands"]), ephemeral=True) await tree.sync(guild=guild) init = True async with client: await client.start(client.my_cfg['bot-token'])
def on_command(client: discord.Client, message: discord.Message, args: list): if args[0] == "!nsfwchannel": if message.author.permissions_in(message.channel).manage_server: m = "Please see `!help nsfwchannel`." set_channel = message.server.get_channel(moderate.data.get(message.server.id, {}).get("nsfw-channel")) if len(args) > 1: if args[1] == "set" and len(args) > 2: if message.channel_mentions: nsfw_channel = message.channel_mentions[0] # Initialize the server moderation if not moderate.data.get(message.server.id): moderate.data[message.server.id] = {} moderate.data[message.server.id]["nsfw-channel"] = nsfw_channel.id moderate.save() m = "Set server NSFW channel to {}".format(nsfw_channel.mention) elif args[1] == "remove": if set_channel: moderate.data[message.server.id].pop("nsfw-channel") moderate.save() m = "{0.mention} is no longer the NSFW channel.".format(set_channel) else: if set_channel: m = "NSFW channel is {0.mention}".format(set_channel) yield from client.send_message(message.channel, m) else: yield from client.send_message(message.channel, "You need `Manage Server` permission to use this command.")
def __init__(self, token, bm, loop, working_path): """ SpeakerBot(token, mm, bm) Initializing speaker bot Argument: - token: String - bm: BotManager(bot_manager.py) - loop: event loop - working_path: working directory path :param token, bm, loop, working_path: """ self.info("Lunching SpeakerBot...") # instance status self.enabled = True # init self.google_client = texttospeech.TextToSpeechClient() self.discord_client = Client() self.bm = bm self.vg = VoiceGenerator(self.google_client, working_path="{0}/{1}".format(working_path, self.__hash__())) # prepare Queue self.queue = Queue() # speaker init self.st = Thread(target=self.speak_thread) self.st.start() # run loop.create_task(self.discord_client.start(token)) self.info("launched")
def on_command(client: discord.Client, message: discord.Message, args: list): if args[0] == "!twitch": m = "Please see `!help twitch`." if len(args) > 1: # Assign a twitch channel to your name or remove it if args[1] == "set": if len(args) > 2: twitch_channel = args[2] twitch_channels.data["channels"][message.author.id] = twitch_channel twitch_channels.save() m = "Set your twitch channel to `{}`.".format(twitch_channel) else: if message.author.id in twitch_channels.data["channels"]: twitch_channels.data["channels"].pop(message.author.id) twitch_channels.save() m = "Twitch channel unlinked." # Return the member's or another member's twitch channel as a link elif args[1] == "get": if len(args) > 2: member = client.find_member(message.server, args[2]) else: member = message.author if member: # Send the link if member has set a channel if member.id in twitch_channels.data["channels"]: m = "{}'s twitch channel: https://secure.twitch.tv/{}.".format( member.name, twitch_channels.data["channels"][member.id] ) else: m = "No twitch channel assigned to {}!".format(member.name) else: m = "Found no such member." # Set or get the twitch notify channel elif args[1] == "notify-channel": if message.author.permissions_in(message.channel).manage_server: if len(args) > 2: channel = client.find_channel(message.server, args[2]) if channel: twitch_channels.data["notify-channel"] = channel.id twitch_channels.save() m = "Notify channel set to {}.".format(channel.mention) else: if "notify-channel" in twitch_channels.data: twitch_channel = client.get_channel(twitch_channels.data["notify-channel"]) if twitch_channel: m = "Twitch notify channel is {}.".format(twitch_channel) else: m = "The twitch notify channel no longer exists!" else: m = "A twitch notify channel has not been set." else: m = "You need `Manage Server` to use this command." yield from client.send_message(message.channel, m)
def __init__(self, name): super(ChatBot, self).__init__(name) self.actions = dict() self.client = Client() self.token = self.read_key() # load up the ban list self._load_bans()
def handle_playing(c:discord.Client, message:discord.Message, command:list, pref:Preferences): if len(command) == 4: pref.addGameSaying(command[2], command[3]) yield from c.send_message(message.channel, 'Done.') else: yield from c.send_message(message.channel, 'I don\'t get what you are telling me to do. ' 'Make sure to use quotation marks around the game name' ' and the saying')
def __init__(self, prefix, token): Client.__init__(self) self.prefix = prefix self.token = token self.plugins = [] self.playlist = set() self.load_plugins()
def game(client: discord.Client, message: discord.Message, name: Annotate.Content=None): """ Stop playing or set game to `name`. """ yield from client.change_status(discord.Game(name=name, type=0)) if name: yield from client.say(message, "*Set the game to* **{}**.".format(name)) else: yield from client.say(message, "*No longer playing.*")
def __init__(self, bot, config): self.bot = bot self.config = config self.config["embed_colour"] = get_embed_colour(self.config["logo_url"]) self.client = Client(loop=bot.loop) self.client.event(self.on_ready) self.client.event(self.on_message) bot.loop.create_task(self.client.start(config["token"], bot=False))
def __init__(self, command_prefix): # Init the normal discord client. Client.__init__(self) self.command_prefix = command_prefix self.plugins = [] # Load all of our bot extensions. self._load_plugins()
def __init__(self): Bot.instance = self self.client = Client() # register event listeners self.client.event(self.on_ready) self.client.event(self.on_message) self.client.event(self.on_reaction_add) self.client.event(self.on_reaction_remove) self.database = Database()
def on_message(client: discord.Client, message: discord.Message, args: list): user_id = message.author.id # User alias check if aliases.data.get(user_id): success = False user_aliases = aliases.data[user_id] for name, command in user_aliases.items(): execute = False msg = message.content if not command.get("case-sensitive", False): msg = msg.lower() if command.get("anywhere", False): if name in msg: execute = True else: if msg.startswith(name): execute = True # Add any mentions to the alias mention = "" if message.mentions: mentions = [member.mention for member in message.mentions] mention = " =>(" + ", ".join(mentions) + ")" if execute: if command.get("delete-message", False): if message.server.me.permissions_in( message.channel).manage_messages: asyncio. async (client.delete_message(message)) asyncio. async (client.send_message( message.channel, "{}{}: {}".format(message.author.mention, mention, command.get("text")))) success = True return success # See if the user spelled definitely wrong for spelling in [ "definately", "definatly", "definantly", "definetly", "definently", "defiantly" ]: if spelling in message.clean_content: yield from client.send_message( message.channel, "{} http://www.d-e-f-i-n-i-t-e-l-y.com/".format( message.author.mention)) return True return False
def cmd_game(client: discord.Client, message: discord.Message, name: Annotate.Content): """ """ if name: m = "Set the game to **{}**.".format(name) else: m = "No longer playing." yield from client.change_status(discord.Game(name=name)) yield from client.send_message(message.channel, m)
def handle_removeplaying(c: discord.Client, message: discord.Message, command: list, pref: Preferences): if len(command) == 4: if pref.rmGameSaying(command[2], command[3]): yield from c.send_message(message.channel, 'Removed.') else: yield from c.send_message(message.channel, 'Could not remove that. Check that you wrote it right.') else: yield from c.send_message(message.channel, 'I don\'t get what you are telling me to do. ' 'Make sure to use quotation marks around the game name' ' and the saying')
def handle_write(c:discord.Client, message:discord.Message, command:list, pref:Preferences): if message.server and len(command) == 3: if(command[2] == "here"): toSet = message.channel elif len(message.channel_mentions) > 0 and message.channel_mentions[0].type == discord.ChannelType.text: toSet = message.channel_mentions[0] if not pref.addServerChannel(message.server, toSet): yield from c.send_message(message.channel, 'Something went wrong while saving the setting.') yield from c.send_message(message.channel, 'Ok, I will use {}'.format(toSet))
async def notify_problem(member: discord.Member, ptype: List[str], log: str, client: discord.Client, ramfs: lexdpyk.ram_filesystem) -> None: if log and (channel := client.get_channel(int(log))): if not isinstance(channel, discord.TextChannel): return notify_embed = discord.Embed(title=f"Notify on member join: {member}", description=f"Notifying for: {', '.join(ptype)}", color=load_embed_color(member.guild, embed_colors.primary, ramfs)) notify_embed.set_footer(text=f"uid: {member.id}") await catch_logging_error(channel, notify_embed)
async def attempt_unmute(Client: discord.Client, mute_entry: Tuple[str, str, str, int]) -> None: with db_hlapi(int(mute_entry[0])) as db: db.unmute_user(infractionid=mute_entry[1]) mute_role_id = db.grab_config("mute-role") if (guild := Client.get_guild(int(mute_entry[0]))) and mute_role_id: if (user := guild.get_member(int( mute_entry[2]))) and (mute_role := guild.get_role( int(mute_role_id))):
def __init__(self, prefix, token, cwd): Client.__init__(self) self.prefix = prefix self.token = token self.cwd = cwd self.plugin_manager = PluginManager(self, '%s/plugins' % self.cwd) self.plugin_manager.load_plugins() user_agent = get_resource(self.cwd, 'user_agent') self.client_session = ClientSession(headers={'User-Agent': user_agent})
def ping(client: discord.Client, message: discord.Message): """ Tracks the time spent parsing the command and sending a message. """ # Track the time it took to receive a message and send it. start_time = datetime.now() first_message = yield from client.say(message, "Pong!") stop_time = datetime.now() # Edit our message with the tracked time (in ms) time_elapsed = (stop_time - start_time).microseconds / 1000 yield from client.edit_message(first_message, "Pong! `{elapsed:.4f}ms`".format(elapsed=time_elapsed))
def cmd_help_noargs(client: discord.Client, message: discord.Message): m = "**Commands:**```" for plugin in client.plugins.values(): if plugin.commands: m += "\n" + "\n".join(usage for cmd, usage in plugin.commands.items() if usage and (not getattr(get_command(plugin, cmd), "__owner__", False) or client.is_owner(message.author))) m += "```\nUse `!help <command>` for command specific help." yield from client.send_message(message.channel, m)
def disable(client: discord.Client, message: discord.Message, trigger: str.lower): """ Disable a command. """ # If the specified trigger is not in the blacklist, we add it if trigger not in lambda_config.data["blacklist"]: lambda_config.data["blacklist"].append(trigger) lambda_config.save() yield from client.say(message, "Command `{}` disabled.".format(trigger)) else: assert trigger in lambdas.data, "Command `{}` does not exist.".format(trigger) # The command exists so surely it must be disabled yield from client.say(message, "Command `{}` is already disabled.".format(trigger))
async def on_message(parent, msg, bot: discord.Client): user = msg.author args = msg.content.split() parent.perm.set_failed(False) if args[0] == "$lvl" and await parent.perm.is_permitted(msg, bot): await parent.send_level(bot, msg, args) return elif args[0] == "$xp" and await parent.perm.is_permitted(msg, bot): await parent.send_xp(bot, msg, args) return elif args[0] == "$totalxp" and await parent.perm.is_permitted( msg, bot): await parent.send_total_xp(bot, msg, args) return elif args[0] == "$cooldown" and await parent.perm.is_permitted( msg, bot): await parent.send_timestamp(bot, msg, args) return elif args[0] == "$givexp" and await parent.perm.is_permitted(msg, bot): try: if args[2] == msg.mentions[0].mention: user = msg.mentions[0] else: user = msg.author except IndexError: user = msg.author try: parent.add_xp(user, int(args[1]) + 0) await bot.send_message( msg.channel, "{} received {}xp".format(user.mention, args[1])) except IndexError: await bot.send_message(msg.channel, "Syntax: $givexp [amount] @[user]") elif args[0] == "$setperm" and await parent.perm.is_permitted( msg, bot): if not parent.perm.is_role_prior(parent.get_role(user), args[1]): bot.send_message( msg.channel, "Your role is too low to change permissions for {}".format( args[1])) try: parent.perm.set_role_perm(args[1], args[2], args[3]) await bot.send_message( msg.channel, "Set the {} command for {} to {}".format( args[2], args[1], args[3])) except: await bot.send_message( msg.channel, "Syntax: $setperm [role] [command] [value]") elif args[0].startswith("$") and not parent.perm.get_failed(): await bot.send_message( msg.channel, "The command {} doesnt exist".format(args[0])) return
async def emoji_command(message: discord.Message, client: discord.Client) -> Optional[str]: message_split = message.content.split(' ') emoji_name = message_split[1] async def send_emoji_link(emoji: discord.Emoji) -> str: size = '' if len(message_split) < 3 else f'?size={message_split[2]}' return f'{emoji.url}{size}' if emoji_id := re.search(discord_emoji_re, emoji_name): if emoji := client.get_emoji(int(emoji_id.group(2))): return await send_emoji_link(emoji)
def on_ready(client: discord.Client): while not client.is_closed: try: yield from asyncio.sleep(update_interval) # Go through all set channels (if they're online on discord) and update their status for member_id, channel in twitch_channels.data["channels"].items(): member = discord.utils.find( lambda m: m.status is not discord.Status.offline and m.id == member_id, client.get_all_members()) if member: with aiohttp.ClientSession() as session: response = yield from session.get(twitch_api + "/streams/" + channel) if response: json = yield from response.json( ) if response.status == 200 else {} else: json = {} stream = json.get("stream") if member_id in live_channels: if not stream: live_channels.pop(member_id) else: if stream: live_channels[member_id] = stream # Tell every mutual channel between the streamer and the bot that streamer started streaming for server in client.servers: if member in server.members: m = "{0} went live at {1[channel][url]}.\n" \ "**{1[channel][display_name]}**: {1[channel][status]}\n" \ "*Playing {1[game]}*".format(member.mention, stream) asyncio. async (client.send_message( server, m)) preview = yield from download_file( stream["preview"]["medium"]) yield from client.send_file( server, preview, filename="preview.jpg") # Wait a second before sending a new server request yield from asyncio.sleep(1) except: print_exc()
async def check_member_kick(client: discord.Client, member: discord.Member): guild = member.guild print('!RAN') if not guild.me.guild_permissions.view_audit_log: return entry = await fetch_recent_audit_log_entry(client, member.guild, target=member, action=discord.AuditLogAction.kick, retry=3) if entry is None: return client.dispatch(EVENT_NAME, member, entry)
def __init__(self): Client.__init__(self) self.utils = Utils() self.timeout = Timeout() self.send = self.utils.send self.modules = self.utils.get_modules_info() self.config = self.utils.get_config_info() self.start_time = self.utils.time_now() self.say = self.send_message return
def import_(client: discord.Client, message: discord.Message, module: str, attr: str=None): """ Import the specified module. Specifying `attr` will act like `from attr import module`. """ try: import_module(module, attr) except ImportError: yield from client.say(message, "Unable to import `{}`.".format(module)) except KeyError: yield from client.say(message, "Unable to import `{}` from `{}`.".format(attr, module)) else: # There were no errors when importing, so we add the name to our startup imports lambda_config.data["imports"].append((module, attr)) lambda_config.save() yield from client.say(message, "Imported and setup `{}` for import.".format(attr or module))
def on_message(client: discord.Client, message: discord.Message, args: list): user_id = message.author.id # User alias check if aliases.data.get(user_id): success = False user_aliases = aliases.data[user_id] for name, command in user_aliases.items(): execute = False msg = message.content if not command.get("case-sensitive", False): msg = msg.lower() if command.get("anywhere", False): if name in msg: execute = True else: if msg.startswith(name): execute = True # Add any mentions to the alias mention = "" if message.mentions: mentions = [member.mention for member in message.mentions] mention = " =>(" + ", ".join(mentions) + ")" if execute: if command.get("delete-message", False): if message.server.me.permissions_in(message.channel).manage_messages: asyncio.async(client.delete_message(message)) asyncio.async(client.send_message( message.channel, "{}{}: {}".format(message.author.mention, mention, command.get("text"))) ) success = True return success # See if the user spelled definitely wrong for spelling in ["definately", "definatly", "definantly", "definetly", "definently", "defiantly"]: if spelling in message.clean_content: yield from client.send_message(message.channel, "{} http://www.d-e-f-i-n-i-t-e-l-y.com/".format(message.author.mention)) return True return False
def pp_(client: discord.Client, message: discord.Message, beatmap_url: str.lower, *options): """ Calculate and return the would be pp using `oppai`. Options are a parsed set of command-line arguments: / `([acc]% | [num_100s]x100 [num_50s]x50) +[mods] [combo]x [misses]m scorev[scoring_version]`""" global last_calc_beatmap # This service is only supported on Linux as of yet assert platform.system() == "Linux", "This service is unsupported since the bot is not hosted using Linux." # Make sure the bot has access to "oppai" lib assert os.path.exists(os.path.join(oppai_path, "oppai")), \ "This service is unavailable until the owner sets up the `oppai` lib." # Only download and request when the id is different from the last check if last_calc_beatmap["beatmap_id"] not in beatmap_url and last_calc_beatmap["beatmapset_id"] not in beatmap_url: # Parse beatmap URL and download the beatmap .osu try: beatmap = yield from api.beatmap_from_url(beatmap_url) except Exception as e: yield from client.say(message, e) return # Download and save the beatmap pp_map.osu beatmap_file, _ = yield from utils.download_file(host + "osu/" + str(beatmap["beatmap_id"])) with open(os.path.join(oppai_path, "pp_map.osu"), "wb") as f: f.write(beatmap_file) else: beatmap = last_calc_beatmap last_calc_beatmap = beatmap command_args = [os.path.join(oppai_path, "oppai"), os.path.join(oppai_path, "pp_map.osu")] # Add additional options if options: command_args.extend(options) command_stream = Popen(command_args, universal_newlines=True, stdout=PIPE) output = command_stream.stdout.read() match = re.search(r"(?P<pp>[0-9.e+]+)pp", output) # Something went wrong with our service assert match, "A problem occurred when parsing the beatmap." # We're done! Tell the user how much this score is worth. yield from client.say(message, "*{artist} - {title}* **[{version}] {1}** would be worth `{0:,}pp`.".format( float(match.group("pp")), " ".join(options), **beatmap))
def define(client: discord.Client, message: discord.Message, term: Annotate.LowerCleanContent): """ Defines a term using Urban Dictionary. """ json = yield from utils.download_json("http://api.urbandictionary.com/v0/define", term=term) definitions = json["list"] if "list" in json else [] # Make sure we have something to define assert definitions, "Could not define `{}`.".format(term) # Send any valid definition (length of message < 2000 characters) msg = "" for definition in definitions: # Format example in code if there is one if "example" in definition and definition["example"]: definition["example"] = "```{}```".format(definition["example"]) # Format definition msg = "**{}**:\n{}\n{}".format( definition["word"], definition["definition"], definition["example"] ) # If this definition fits in a message, break the loop so that we can send it if len(msg) <= 2000: break # Cancel if the message is too long assert len(msg) <= 2000, "Defining this word would be a bad idea." # Send the definition yield from client.say(message, msg)
def cmd_help(client: discord.Client, message: discord.Message, command: str.lower) -> cmd_help_noargs: """ Display commands or their usage and description. """ usage, desc = "", "" for plugin in client.plugins.values(): command_func = get_command(plugin, command) if not command_func: continue usage = plugin.commands[command] if command_func.__doc__: desc = command_func.__doc__.strip() else: desc = "Undocumented." # Notify the user when a command is owner specific if getattr(command_func, "__owner__", False): desc += "\n**Only the bot owner can execute this command.**" if usage: m = "**Usage**: ```{}``` **Description**: {}".format(usage, desc) else: m = "Command `{}` does not exist.".format(command) yield from client.send_message(message.channel, m)
def filter_type(client: discord.Client, message: discord.Message, slot_1: str.lower, slot_2: str.lower=None): matched_pokemon = [] assert_type(slot_1) # Find all pokemon with the matched criteria if slot_2: assert_type(slot_2) # If two slots are provided, search for pokemon with both types matching for pokemon in pokedex.values(): if pokemon["types"] == [slot_1, slot_2]: matched_pokemon.append(pokemon["locale_name"]) else: # All pokemon have a type in their first slot, so check if these are equal for pokemon in pokedex.values(): if pokemon["types"][0] == slot_1: matched_pokemon.append(pokemon["locale_name"]) types = [slot_1] if slot_2 is None else [slot_1, slot_2] # There might not be any pokemon with the specified types assert matched_pokemon, "Looks like there are no pokemon of type **{}**!".format(format_type(types)) yield from client.say(message, "**Pokemon with type {}**: ```\n{}```".format( format_type(types), ", ".join(sorted(matched_pokemon))))
def on_command(client: discord.Client, message: discord.Message, args: list): if args[0] == "!wordsearch": word = None if len(args) > 1: if args[1] == "auto": count = 1 if len(args) > 2: try: count = int(args[2]) except ValueError: pass word = yield from auto_word(count) # Start the wordsearch if there are none active in the channel # (starting includes includes waiting for a word from the user) if message.channel.id not in wordsearch: client.loop.create_task(start_wordsearch(client, channel=message.channel, host=message.author, word=word)) if not word: m = "Waiting for {0.mention} to choose a word!".format(message.author) else: m = None else: m = "A wordsearch is already active in this channel!" if m: yield from client.send_message(message.channel, m)
def get_member(client: discord.Client, member_id: str): """ Get a member from the specified ID. """ for member in client.get_all_members(): if member.id == member_id: return member return None
def url(client: discord.Client, message: discord.Message, member: Annotate.Member=Annotate.Self): """ Display the member's osu! profile URL. """ # Member might not be registered assert member.id in osu_config.data["profiles"], "No osu! profile assigned to **{}**!".format(member.name) # Send the URL since the member is registered yield from client.say(message, "**{0.display_name}'s profile:** <https://osu.ppy.sh/u/{1}>".format( member, osu_config.data["profiles"][member.id]))
def reload(client: discord.Client, message: discord.Message, name: str.lower=None): """ Reloads all plugins or the specified plugin. """ if name: assert plugins.get_plugin(name), "`{}` is not a plugin".format(name) # The plugin entered is valid so we reload it yield from plugins.save_plugin(name) plugins.reload_plugin(name) yield from client.say(message, "Reloaded plugin `{}`.".format(name)) else: # Reload all plugins yield from plugins.save_plugins() for plugin_name in plugins.all_keys(): plugins.reload_plugin(plugin_name) yield from client.say(message, "All plugins reloaded.")
def unload(client: discord.Client, message: discord.Message, name: str.lower): """ Unloads a plugin. """ assert plugins.get_plugin(name), "`{}` is not a loaded plugin.".format(name) # The plugin is loaded so we unload it yield from plugins.save_plugin(name) plugins.unload_plugin(name) yield from client.say(message, "Plugin `{}` unloaded.".format(name))
def lambda_(client: discord.Client, message: discord.Message): """ Create commands. See `{pre}help do` for information on how the code works. **In addition**, there's the `arg(i, default=0)` function for getting arguments in positions, where the default argument is what to return when the argument does not exist. **Owner command unless no argument is specified.**""" yield from client.say(message, "**Lambdas:** ```\n" "{}```".format(", ".join(sorted(lambdas.data.keys()))))
def remove(client: discord.Client, message: discord.Message, trigger: str.lower): """ Remove a command. """ assert trigger in lambdas.data, "Command `{}` does not exist.".format(trigger) # The command specified exists and we remove it del lambdas.data[trigger] lambdas.save() yield from client.say(message, "Command `{}` removed.".format(trigger))
def debug(client: discord.Client, message: discord.Message): """ Display some debug info. """ yield from client.say(message, "Sent `{}` requests since the bot started (`{}`).\n" "Members registered for update: {}".format( api.requests_sent, client.time_started.ctime(), utils.format_members(*[d["member"] for d in osu_tracking.values()]) ))
def load(client: discord.Client, message: discord.Message, name: str.lower): """ Loads a plugin. """ assert not plugins.get_plugin(name), "Plugin `{}` is already loaded.".format(name) # The plugin isn't loaded so we'll try to load it assert plugins.load_plugin(name), "Plugin `{}` could not be loaded.".format(name) # The plugin was loaded successfully yield from client.say(message, "Plugin `{}` loaded.".format(name))
def on_ready(client: discord.Client): while not client.is_closed: try: yield from asyncio.sleep(update_interval) # Go through all set channels (if they're online on discord) and update their status for member_id, channel in twitch_channels.data["channels"].items(): member = discord.utils.find(lambda m: m.status is not discord.Status.offline and m.id == member_id, client.get_all_members()) if member: with aiohttp.ClientSession() as session: response = yield from session.get(twitch_api + "/streams/" + channel) if response: json = yield from response.json() if response.status == 200 else {} else: json = {} stream = json.get("stream") if member_id in live_channels: if not stream: live_channels.pop(member_id) else: if stream: live_channels[member_id] = stream # Tell every mutual channel between the streamer and the bot that streamer started streaming for server in client.servers: if member in server.members: m = "{0} went live at {1[channel][url]}.\n" \ "**{1[channel][display_name]}**: {1[channel][status]}\n" \ "*Playing {1[game]}*".format(member.mention, stream) asyncio.async(client.send_message(server, m)) preview = yield from download_file(stream["preview"]["medium"]) yield from client.send_file(server, preview, filename="preview.jpg") # Wait a second before sending a new server request yield from asyncio.sleep(1) except: print_exc()
def eval_(client: discord.Client, message: discord.Message, python_code: Annotate.Code): """ Evaluate a python expression. Can be any python code on one line that returns something. """ code_globals.update(dict(message=message, client=client)) try: result = eval(python_code, code_globals) except Exception as e: result = utils.format_exception(e) yield from client.say(message, "**Result:** \n```{}\n```".format(result))