How to check for user's role on another server? - discord.py

Have a function checking a role on a specific server, but the function is supposed to be sent by a pm to the bot, so I can't use "role code" in [role.id for role in message.author.roles]
What should I do?
Also need to send a message to the specific server
Function in question:
async def on_message(message):
if '%attented' in message.content:
if "561055432748302336" in [role.id for role in message.author.roles]:
msg = message.content.split(' ')
author = message.author
await client.send_message(client.get_channel('560679934209687552'), str(author) + ' has attented a ' + msg[2] + '\nScreenshot:' + msg[1] + '/n***To approve screenshot react with :HYPERS: to dissaprove react with :FeelsBadMan:***')

You can use these two methods for that
#bot.event
async def on_message(msg):
for i in bot.servers:
for x in i.roles:
if x.id == 'the role id': #this can also be done through name via x.name == 'name'
await bot.send_message(discord.Object(id='channel id'), 'the message')
await bot.process_commands(msg)
#bot.command(pass_context=True)
async def role(msg):
for i in bot.servers:
for x in i.roles:
if x.id == ' the role id': #you can also do this by name via x.name
await bot.send_message(discord.Object(id='channel id here'), "The message to send")
#bot.event
async def on_reaction_add(emote,user):
if emote.emoji == '👍':
#Do something here
await bot.send_message(emote.message.channel,f"{user.name} has reacted")
#bot.command(pass_context=True)
async def get_message(msg):
async for i in bot.logs_from(msg.message.channel):
if i.author.id == '185181025104560128' and 'hello' in i.content:
print(i.content)
You can't get the users that reacted to the messages with a regular command function in async and can only be done in rewrite but you can do that with the on_reaction_add event function in both async and rewrite

Related

I want to improve my kick command in discord.py

I have made a bot in discord.py which has a kick command. But I want the bot to say "please tell me whom to kick" when someone uses the command without saying whom to kick. I mean if someone uses the kick command without mentioning whom to kick, the bot will say "please tell me whom to kick".
I am trying to make a good bot so please help me.
async def kick(ctx, member : discord.Member, *, reason=None):
if (ctx.message.author.permissions_in(ctx.message.channel).kick_members):
await member.kick(reason=reason)
await ctx.send(f"{member.mention} has successfully been kickded for {reason}")
if not (ctx.message.author.permissions_in(ctx.message.channel).kick_members):
await ctx.send("You don't perms to play football with Araforce and kick them. Sed")
if not user:
await ctx.message.delete()
msg = await ctx.send("You are a bit idiot, don't you know I can't kick anyone if you don't tell whom to kick? Tell me whom to kick and the go away.")
await sleep(4.7)
await msg.delete()
return
if not reason:
await ctx.message.delete()
msg2 = await ctx.send("Hmm.. Why I will kick him? Specify a reason please.")
await sleep(4.7)
await msg2.delete()
return```
async def kick(ctx, user: discord.User = None, *, reason=None):
if not user:
await ctx.message.delete()
msg = await ctx.send("You must specify a user.")
await sleep(4.7)
await msg.delete()
return
if not reason:
await ctx.message.delete()
msg2 = await ctx.send("You must specify a reason.")
await sleep(4.7)
await msg2.delete()
return
I changed ifs to the error handler, which is necessary because if you won't pass one of the arguments (user or reason) you would get an error.
Full code:
#client.command()
async def kick(ctx, member: discord.Member, *, reason): #if you will change "member" and "reason" to something else remember to also change it in error handler
await member.kick(reason=reason)
await ctx.send(f"{member.mention} has successfully been kicked for {reason}")
#kick.error #cool mini error handler
async def kick_error(ctx, error):
if isinstance(error, discord.ext.commands.errors.MissingRequiredArgument):
if str(error) == "member is a required argument that is missing.": #change this if you changed "member"
await ctx.message.delete()
await ctx.send("You are a bit idiot, don't you know I can't kick anyone if you don't tell whom to kick? Tell me whom to kick and then go away.", delete_after=4.7) #you don't have to use "await sleep" you can use "delete_after" parameter
elif str(error) == "reason is a required argument that is missing.": #change this if you changed "reason"
await ctx.message.delete()
await ctx.send("Hmm.. Why I will kick him? Specify a reason please.", delete_after=4.7)
elif isinstance(error, discord.ext.commands.errors.MissingPermissions):
await ctx.send("You don't have perms to play football with Araforce and kick them. Sed")
Discord error handling example

Discord.py Verification System

I am making a verification system where if you type !verify "1. John 2. Mr. Teacher 3. Somewhere 4. Freshman 5. The Cool Mascot" it will send an embed in a channel looking like this: https://gyazo.com/ab808bafcd4a5f3ed05f63e007da20c1.
If someone reacts with the checkmark I want to dm the user saying that they have been accepted and if they get denied it will send a dm saying they have been denied but I seem to not get a dm when reacting and they do not get the Member role right after, and there are no tracebacks.
Code:
#bot.command(pass_context=True)
async def verify(ctx, message):
logem = discord.Embed(color=discord.Color.red())
logem.set_author(name=f"Verification Request!")
logem.add_field(name="User", value=f"{ctx.author.mention}")
logem.add_field(name="Application", value=f"{message}")
logem.set_footer(text=f"React with ✅ to accept the application and ❌ to deny the application",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Exclamation_mark_red.png/50px-Exclamation_mark_red.png")
logemlog = bot.get_channel(820840787645956123)
msg = await logemlog.send(embed=logem)
await msg.add_reaction('✅')
await msg.add_reaction('❌')
async def on_raw_reaction_add(payload):
msgid = await ctx.fetch_message(msgID)
ourMessageID = msgid
if ourMessageID == payload.message_id:
member = payload.member
guild = member.guild
emoji = payload.emoji.name
if emoji == '✅':
role = discord.utils.get(guild.roles, name="Member")
print ('Accepted Someones Application')
em = discord.Embed(color=discord.Color.red())
em.set_author(name="Verified!")
em.set_footer(text=f"You Have Been Accepted Into The Official WHS Discord Server!",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Exclamation_mark_red.png/50px-Exclamation_mark_red.png")
await member.send("You have been accepted!")
await member.add_roles(role)
elif emoji == '❌':
em = discord.Embed(color=discord.Color.red())
em.add_field(name="Denied!", value=f"{message}")
em.set_footer(text=f"You Have Been Denied Access Into The Official WHS Discord Server!",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Exclamation_mark_red.png/50px-Exclamation_mark_red.png")
await ctx.member.send("You have been Denied!")
Use this instead of async def on_raw_reaction_add:
def check(reaction, user):
return reaction.emoji in ['✅', '❌'] and user == ctx.author
while True:
try:
reaction, user = await bot.wait_for('reaction_add', check=check)
except Exception as e:
print(e)
else:
if reaction.emoji == '✅':
role = discord.utils.get(guild.roles, name="Member")
print ('Accepted Someones Application')
em = discord.Embed(color=discord.Color.red())
em.set_author(name="Verified!")
em.set_footer(text=f"You Have Been Accepted Into The Official WHS Discord Server!",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Exclamation_mark_red.png/50px-Exclamation_mark_red.png")
await member.send("You have been accepted!")
await member.add_roles(role)
if reaction.emoji == '❌':
em = discord.Embed(color=discord.Color.red())
em.add_field(name="Denied!", value=f"{message}")
em.set_footer(text=f"You Have Been Denied Access Into The Official WHS Discord Server!",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Exclamation_mark_red.png/50px-Exclamation_mark_red.png")
await ctx.member.send("You have been Denied!")
Test it and let me know if it doesn't work.

How to make multiple reaction roles

So I'm working on a reaction role cog, and the commands work so far. There's just one problem. When I create two different reaction roles, it only works for the second one. It's because I only have one dictionary and it updates that every time. I think I've seen people use a payload for reaction roles, but I have no idea what that does and if it would fix my problem. Is there a way to use payload to fix my problem? Thanks!! Here's my code:
import discord
from discord.ext import commands
from discord.ext.commands import BucketType, cooldown, CommandOnCooldown
import random
import json
reaction_title = ""
reactions = {}
reaction_message_id = ""
class ReactionRoles(commands.Cog):
"""Reaction roles!!\nYou need manage roles permissions to use these"""
def __init__(self, bot):
self.bot = bot
# Bot Commands
#commands.command(aliases=['rcp'])
async def reaction_create_post(self, ctx):
"""Creates an embed that shows all the reaction roles commands"""
embed = discord.Embed(title="Create Reaction Post", color=discord.Colour.dark_purple())
embed.set_author(name="Botpuns")
embed.add_field(name="Set Title", value=".rst [New Title]", inline=False)
embed.add_field(name="Add Role", value=".rar [#Role] [EMOJI]", inline=False)
embed.add_field(name="Remove Role", value=".rrr [#Role]", inline=False)
embed.add_field(name="Reaction Send Post", value=".rsp", inline=False)
await ctx.send(embed=embed)
await ctx.message.delete()
#commands.command(aliases=['rst'])
async def reaction_set_title(self, ctx, *, new_title):
global reaction_title
reaction_title = new_title
await ctx.send(f"The title for the message is now `{new_title}`")
await ctx.message.delete()
#commands.command(aliases=['rar'])
async def reaction_add_role(self, ctx, role: discord.Role, reaction):
global reactions
reactions[role.name] = reaction
await ctx.send(f"Role `{role.name}` has been added with the emoji {reaction}")
await ctx.message.delete()
print(reactions)
#commands.command(aliases=['rrr'])
async def reaction_remove_role(self, ctx, role: discord.Role):
if role.name in reactions:
del reactions[role.name]
await ctx.send(f"Role `{role.name}` has been deleted")
await ctx.message.delete()
else:
await ctx.send("That role wasn't even added smh")
print(reactions)
#commands.command(aliases=['rsp'])
async def reaction_send_post(self, ctx):
description = "React to add roles\n"
for role in reactions:
description += f"`{role}` - {reactions[role]}\n"
embed = discord.Embed(title=reaction_title, description=description, color=discord.Colour.purple())
embed.set_author(name="Botpuns")
message = await ctx.send(embed=embed)
global reaction_message_id
reaction_message_id = str(message.id)
for role in reactions:
await message.add_reaction(reactions[role])
await ctx.message.delete()
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
if not user.bot:
message = reaction.message
if str(message.id) == reaction_message_id:
# Add roles to user
role_to_give = ""
for role in reactions:
if reactions[role] == reaction.emoji:
role_to_give = role
role_for_reaction = discord.utils.get(user.guild.roles, name=role_to_give)
await user.add_roles(role_for_reaction)
#commands.Cog.listener()
async def on_reaction_remove(self, reaction, user):
if not user.bot:
message = reaction.message
if str(message.id) == reaction_message_id:
# Add roles to user
role_to_remove = ""
for role in reactions:
if reactions[role] == reaction.emoji:
role_to_remove = role
role_for_reaction = discord.utils.get(user.guild.roles, name=role_to_remove)
await user.remove_roles(role_for_reaction)
def setup(bot):
bot.add_cog(ReactionRoles(bot))

How to make lockdown and unlock commands discord.py

Im trying to make a lockdown and unlock command using discord.py rewrite. I have the code but it doesn't work at all. Can someone help me?
#client.command()
#commands.has_permissions(manage_channels = True)
async def lockdown(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=False)
await ctx.send( ctx.channel.mention + " ***is now in lockdown.***")
#client.command()
#commands.has_permissions(manage_channels=True)
async def unlock(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=True)
await ctx.send(ctx.channel.mention + " ***has been unlocked.***")
I found out the issue. The commands work on every other server except for the one I'm testing it on. It turns out that That server makes everyone admin as soon as they join.
Try this, to enable the necessary bot permissions:
#client.command()
#has_permissions(manage_channels=True)
async def lockdown(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role,send_messages=False)
await ctx.send( ctx.channel.mention + " ***is now in lockdown.***")
#client.command()
#has_permissions(manage_channels=True)
async def unlock(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=True)
await ctx.send(ctx.channel.mention + " ***has been unlocked.***")
this is my unlock command hope it helps you
you have to use overwrites TextChannel.set_permissions
#client.command()
async def unlock(ctx, role:Optional[Role], channel:Optional[TextChannel]):
role = role or ctx.guild.default_role
channel = channel or ctx.channel
async with ctx.typing():
if ctx.author.permissions_in(channel).manage_permissions:
await ctx.channel.purge(limit=1)
overwrite = channel.overwrites_for(role)
overwrite.send_messages = True
await channel.set_permissions(role, overwrite=overwrite)
unlock_embed = discord.Embed(
title= ("UNLOCKED"),
description= (f"**{channel.mention}** HAS BEEN UNLOCKED FOR **{role}**"),
colour=0x00FFF5,
)
unlock_embed.set_footer(text=ctx.author.name, icon_url=ctx.author.avatar_url)
unlock_embed.set_author(name=client.user.name, icon_url=client.user.avatar_url)
unlock_embed.set_thumbnail(url=ctx.guild.icon_url)
await ctx.channel.send(embed=unlock_embed, delete_after=10)
print("unlock")
else:
error3_embed=discord.Embed(title="ERROR", description="YOU DONT HAVE PERMISSION", colour=0xff0000)
error3_embed.set_thumbnail(url='https://images.emojiterra.com/google/android-11/512px/274c.png')
error3_embed.set_footer(text=ctx.author.name, icon_url=ctx.author.avatar_url)
error3_embed.set_author(name=client.user.name, icon_url=client.user.avatar_url)
await ctx.channel.send(embed=error3_embed, delete_after=10)

How to do a prisoner role in discord.py 1.5.0?

I've tried 3 times to do this code, my plan is removing all roles from an user, writing the roles in an ctx.send() to send a message with the old roles in the channel, after that, send a message that says the user was imprisoned and the reason and give the prisoner role.
'BabaYaga' is the adm's role; 'D 001' is the prisoner role
Code 01:
# Detentos 3
#client.command()
#commands.has_any_role('BABAYAGA')
async def det(ctx, member: discord.Member = None, role = discord.Guild.roles, *, reason = None):
if member == None:
await ctx.send('Say the user')
return
if reason == None:
await ctx.send('Say the reason')
return
Roles = member.roles
for _ in Roles:
print(Roles)
await client.remove_roles(member, *Roles)
await member.add_role(ctx, member, role)
await ctx.send(f'{member} was arrested for {reason}')
Code 02:
# Detentos 2
#client.command()
#commands.has_any_role('BABAYAGA')
async def det(ctx, member: discord.Member, *,reason):
role = discord.utils.get(ctx.guild.roles, name = 'D 001')
await ctx.send(f'{member.roles}')
for _ in member.roles:
await member.remove_roles(member.top_role)
await ctx.message.add_reaction(emoji=self.tick)
await member.add_roles(role)
await ctx.send(f'{member} was arrested for {reason}')
Code 03:
# Detentos
#client.command()
#commands.has_any_role('BABAYAGA')
async def det(self, ctx, member: discord.Member, *, reason = None):
if reason == None:
await ctx.send('Say the reason!')
return
roles = discord.utils.get(member.guild.roles) # member's roles
role = discord.utils.get(ctx.guild.roles, name = 'D 001') # Det's role
await ctx.message.add_reaction(emoji=self.tick)
await member.edit(member.guild.roles)
await ctx.send(f'{discord.Member} preso por {reason}')
await ctx.send(f'cargos do {discord.Member}: {member.roles}')
Code 04:
# Detentos
#client.command()
#commands.has_any_role('BABAYAGA')
async def det(self, ctx, member: discord.Member = None, *, reason = None):
if reason == None:
await ctx.send('Say the reason! :angry: :angry:')
return
if member == None:
await ctx.send('Say the user')
return
rolesserver = ['D 001', 'D 002', 'D 003', 'D 004', 'testers']
await ctx.send(f'{member.roles}')
for roles in rolesserver:
await client.remove_roles(member, *roles)
await ctx.send(f'<#{member.id}> was arrested for {reason}')
I don't know what is my error there. Can anyone help me?
There are a lot of mistakes in your code snippets. Here's a correct way of doing it:
#client.command()
#commands.has_any_role('BABAYAGA')
async def det(ctx, member: discord.Member, *, reason):
await ctx.send(f'Removed ", ".join([role.name for role in member.roles])')
for role in member.roles:
await member.remove_roles(role)
await ctx.message.add_reaction(emoji=self.tick)
role = discord.utils.get(ctx.guild.roles, name = 'D 001')
await member.add_roles(role)
await ctx.send(f'{member} was arrested for {reason}')
Some advices:
The get method returns a single item from an iterable so writing get(member.guild.roles) won't work, you can just type roles = member.guild.roles
You must set a variable in your for loops or else, you can't cycle through your member's roles, so your for _ in member.roles must become for role in member.roles.
To have a nice message with all your member's roles, you can use the join method combined with list comprehension (eg. ', '.join([role.name for role in member.roles]))
remove_roles is a discord.Member method so you have to use it this way: member.remove_roles(role)

Resources