Adding member a ticket channel discord.py - python

I need help with the tickets. When someone wants to call for help everything is fine, creates a channel and a message but does not add the author of the command to the ticket channel and does not even see him. I hope you will help me!
#client.command()
async def support(ctx, *, reason = None):
guildid = ctx.guild.id
guild = ctx.guild
user = ctx.author
amount2 = 1
await ctx.channel.purge(limit=amount2)
channel = await guild.create_text_channel(f'Ticket {user}')
await channel.set_permissions(ctx.guild.default_role, send_messages=False, read_messages=False)
perms = channel.overwrites_for(user)
await channel.set_permissions(user, view_channel=not perms.view_channel)
await channel.set_permissions(user, read_message_history=not perms.read_message_history)
await channel.set_permissions(user, send_messages=not perms.send_messages)
await channel.send(f"{user.mention}")
supem = discord.Embed(title=f"{user} Poprosił o pomoc.", description= "", color=0x00ff00)
supem.add_field(name="Powód", value=f"``{reason}``")
supem.set_footer(text=f"Wkrótce przyjdzie do ciebie administrator ")
await channel.send(embed=supem)

You've wasted a lot of code on permissions there, it's much easier.
You can use discord.PermissionOverwrite here and then use it like this:
#client.command()
async def support(ctx, *, reason = None):
guild = ctx.guild
user = ctx.author
await ctx.message.delete() # Deletes the message of the author
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
user: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
channel = await guild.create_text_channel(f'Ticket {user}', overwrites=overwrites)
await channel.send(f"{user.mention}")
supem = discord.Embed(title=f"{user} Poprosił o pomoc.", description= "", color=0x00ff00)
supem.add_field(name="Powód", value=f"``{reason}``")
supem.set_footer(text=f"Wkrótce przyjdzie do ciebie administrator ")
await channel.send(embed=supem)
What did we do/how does the new code work?
guild.default_role: discord.PermissionOverwrite(read_messages=False) excludes the default role.
user: discord.PermissionOverwrite(read_messages=True, send_messages=True) the author, which you defined as user, has the permissions to read and write into the ticket.
We created a new text channel with the condition overwrites=overwrites.
I removed guildid = ctx.guild.id as you do not use it in your code.
Example 2 on the following site explains it also very well: Clik to re-direct

Related

discord.py ticket commandd

I have a ticket command it works but I'm trying to have it create a ticket channel in a specific category
#bot.command()
async def support(ctx, *, reason = None):
guild = ctx.guild
user = ctx.author
await ctx.message.delete() # Deletes the message of the author
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
user: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
channel = await guild.create_text_channel(f'Ticket {user}', overwrites=overwrites)
await channel.send(f"{user.mention}")
supem = discord.Embed(title=f"{user} Created a ticket.", description= "", color=0x00ff00)
supem.add_field(name="reason", value=f"``{reason}``")
supem.set_footer(text=f"staff will be with you shortly")
await channel.send(embed=supem)
If you look at the docs here, the create_text_channel function takes a category parameter. If we pass the category to it; it'll create the channel in the specific category.
#bot.command()
async def support(ctx, *, reason = None):
guild = ctx.guild
user = ctx.author
await ctx.message.delete() # Deletes the message of the author
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
user: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
# categories are just channels, so `get_channel` will get your category
category = await guild.get_channel(YOUR_CATEGORY_ID)
channel = await guild.create_text_channel(f'Ticket {user}', category=category, overwrites=overwrites)
await channel.send(f"{user.mention}")
supem = discord.Embed(title=f"{user} Created a ticket.", description= "", color=0x00ff00)
supem.add_field(name="reason", value=f"``{reason}``")
supem.set_footer(text=f"staff will be with you shortly")
await channel.send(embed=supem)
Or, use category.create_text_channel instead.
#bot.command()
async def support(ctx, *, reason = None):
guild = ctx.guild
user = ctx.author
await ctx.message.delete() # Deletes the message of the author
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
user: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
# categories are just channels, so `get_channel` will get your category
category = await guild.get_channel(YOUR_CATEGORY_ID)
channel = await category.create_text_channel(f'Ticket {user}', overwrites=overwrites)
await channel.send(f"{user.mention}")
supem = discord.Embed(title=f"{user} Created a ticket.", description= "", color=0x00ff00)
supem.add_field(name="reason", value=f"``{reason}``")
supem.set_footer(text=f"staff will be with you shortly")
await channel.send(embed=supem)

Creating private channels and deleting them in the discord

I want to make a system where when a user enters the private creation channel, a text channel and a voice channel are created, in the text the creator can give and take away the rights to enter the private, and if the owner leaves the private, then in a minute the channels should be deleted, as well as data about them from the database. I use MongoDB.
I have done almost all the code, but the code with the removal of channels does not work, namely, checking for the channel id. I also want to make sure that the timer for 30 is canceled if the creator returns, but there is some more convenient way to create this timer.
#bot.event
async def on_voice_state_update(member, before, after):
if after.channel is not None:
if after.channel.id == 992120556256247808:
guild = bot.get_guild(642681537284014080)
category = discord.utils.get(guild.categories, name='Приват')
v_channel = await guild.create_voice_channel(name=f'Приват ({member.display_name})', category=category)
t_channel = await guild.create_text_channel(name=f'Выдача прав ({member.display_name})', category=category)
await v_channel.set_permissions(member, connect=True, speak=True, view_channel=True, stream=True, kick_members=True, mute_members=True, priority_speaker=True)
role = discord.utils.get(guild.roles, id=642681537284014080)
await v_channel.set_permissions(role, view_channel=False)
await t_channel.set_permissions(role, view_channel=False)
private_post = {
'_id': member.id,
'text_id':t_channel.id,
'voice_id':v_channel.id,
}
private.insert_one(private_post)
await member.move_to(v_channel)
if before.channel == v_channel: #This one and the lines below it don't work
await bot.get_channel(private.find_one({'_id':member.id})['text_id']).send(f'`[PRIVATE]`: {member.mention}, Your private will be deleted in 1 minute!')
time.sleep(60000)
await t_channel.delete()
await v_channel.delete()
roles.delete_one({'_id': member.id})
#bot.command()
async def perm(ctx, member: discord.Member):
if ctx.channel.id == private.find_one({'text_id': ctx.channel.id})['text_id']:
v_channel = bot.get_channel(private.find_one({'text_id': ctx.channel.id})['voice_id'])
await v_channel.set_permissions(member, connect=True, speak=True, view_channel=True, stream=True)
#bot.command()
async def unperm(ctx, member: discord.Member):
if ctx.channel.id == private.find_one({'text_id': ctx.channel.id})['text_id']:
v_channel = bot.get_channel(private.find_one({'text_id': ctx.channel.id})['voice_id'])
await v_channel.set_permissions(member, connect=False, speak=False, view_channel=False, stream=False)
if member in v_channel.members:
await member.move_to(None)
you're using normal sleep in async code. use async sleep.
try using discord.ext.tasks to create timer. instead of sleep.
and the channel deletion. This should work :
#bot.event
async def on_voice_state_update(member, before, after):
if after.channel is not None:
if after.channel.id == 992120556256247808:
guild = bot.get_guild(642681537284014080)
category = discord.utils.get(guild.categories, name='Приват')
v_channel = await guild.create_voice_channel(name=f'Приват ({member.display_name})', category=category)
t_channel = await guild.create_text_channel(name=f'Выдача прав ({member.display_name})', category=category)
await v_channel.set_permissions(member, connect=True, speak=True, view_channel=True, stream=True, kick_members=True, mute_members=True, priority_speaker=True)
role = discord.utils.get(guild.roles, id=642681537284014080)
await v_channel.set_permissions(role, view_channel=False)
await t_channel.set_permissions(role, view_channel=False)
private_post = {
'_id': member.id,
'text_id': t_channel.id,
'voice_id': v_channel.id,
}
private.insert_one(private_post)
await member.move_to(v_channel)
if before.channel is not None:
channels = private.find_one({'_id':member.id})
t_channel = bot.get_channel(channels['text_id'])
v_channel = bot.get_channel(channels['voice_id'])
if before.channel.id != v_channel.id:
return
await t_channel.send(f'`[PRIVATE]`: {member.mention}, Your private will be deleted in 1 minute!')
await asyncio.sleep(60000)
await t_channel.delete()
await v_channel.delete()
roles.delete_one({'_id': member.id})

How to add role by reacting in DM to a bot message

Im trying to make a bot that send me a message with a reaction button, when I click it, give me a role in the server. Im trying to use on_raw_reaction_add event but I cant reach a solution to make it, Im always getting errors at getting guild roles and this stuff.
In this case, guild is none, I dont know what Im doing wrong.
My code:
#client.command()
async def test(ctx):
global member
global message__id
global channel_id
channel_id = (ctx.channel.id)
member = ctx.message.author
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
mesg = await member.send(embed=embed)
await mesg.add_reaction("✅")
message__id = mesg.id
print("EXECUTED")
#client.event
async def on_raw_reaction_add(payload):
print("reacted")
print("messageid accepted")
guild = client.get_guild(payload.guild_id)
if guild is not None:
print("messageid accepted")
reactor = payload.guild.get_member(payload.member.id)
role = discord.utils.get(guild.roles, name="Member")
if payload.emoji.name == '✅':
print("emoji accepted")
await reactor.add_roles(role)
EDIT:
I changed my on_raw_reaction_add event:
#client.event
async def on_raw_reaction_add(payload):
print("reacted")
print("messageid accepted")
guild = client.get_guild(payload.guild_id)
if guild is not None:
print("guild not none ")
reactor = payload.guild.get_member(payload.member.id)
role = discord.utils.get(guild.roles, name="Verified")
if payload.emoji.name == '✅':
print("emoji accepted")
await reactor.add_roles(role)
else:
print("guild none")
And this is what happen when I try the method:
First three words are the prints of the bot reacting his own message, the "EXECUTED" is the print of test method and the last three messages. are when I react the bot message
In this case, I suggest using a wait_for rather than on_raw_reaction_add.
Example, as seen in the docs:
#client.command(aliases=["t"])
async def test(ctx):
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
# sends message to command author
mesg = await ctx.author.send(embed=embed)
await mesg.add_reaction("✅")
#check if the reactor is the user and if that reaction is the check mark
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == '✅'
try:
#wait for the user to react according to the checks
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
# 60 seconds without reaction
await ctx.send('Timed out')
else:
await ctx.send('✅')
docs- https://discordpy.readthedocs.io/en/stable/api.html?highlight=wait_for#discord.Client.wait_for
async def test(ctx):
global member
global message__id
global channel_id
channel_id = (ctx.channel.id)
member = ctx.message.author
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
mesg = await member.send(embed=embed)
await mesg.add_reaction("✅")
message__id = mesg.id
print("EXECUTED")
role = get(ctx.guild.roles, id=role id here)
done = False
while done == False:
reaction, user = await client.wait_for(“reaction_add”, check=check)
if user == client.user:
continue
await member.add_roles(role)
done = True
I am pretty sure something like this would work :D
When you do guild is not None, it will never fire because you are reacting in a DM channel context - where the guild is None. To access the guild information from the DM, you'll need to save it somewhere in the message (or save it yourself internally). Then, you have the guild object and you're able to add roles or do things to it.
#client.command()
async def testrole(ctx):
member = ctx.author
# ...
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
mesg = await member.send(str(ctx.guild.id), embed=embed) # we need the guild information somewhere
await mesg.add_reaction("✅")
#client.event
async def on_reaction_add(reaction, user): # there's really no need to use raw event here
if user.id == client.user.id:
return
if reaction.message.guild is None:
if reaction.emoji == '\u2705':
# we have to get the guild that we saved in the other function
# there is no other way to know the guild, since we're reacting in the DM
# that's why it was saved inside of the message that was sent to the user
guild_id = int(reaction.message.content)
guild = client.get_guild(guild_id)
member = guild.get_member(user.id)
await member.add_roles(...) # change this with your roles

I want to sort channels out under the category, how to move it? discord.py

I want to move the 2 newly created text and voice channels under the newly created category
#bot.command()
async def room(ctx, name):
guild = ctx.guild
member = ctx.author
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
member: discord.PermissionOverwrite(read_messages=True),
}
channel = await guild.create_category_channel(name, overwrites=overwrites)
channel = await guild.create_text_channel(name, overwrites=overwrites)
channel = await guild.create_voice_channel(name, overwrites=overwrites)
channel = ctx.channel
name = discord.utils.get(ctx.guild.category, name)
await ctx.channel.edit(category=name)
Like this
How can I move two channels (chat, voice) below the category?
name = discord.utils.get(ctx.guild.category, name)
await ctx.channel.edit(category=name)
This code is not working
#bot.command()
async def room(ctx, roomname):
guild = ctx.guild
member = ctx.author
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
member: discord.PermissionOverwrite(read_messages=True),
}
channel = await guild.create_category_channel(roomname, overwrites=overwrites)
text_channel = await guild.create_text_channel(roomname, category=channel, overwrites=overwrites)
voice_channel = await guild.create_voice_channel(roomname, category=channel, overwrites=overwrites)
I just entered the category=channel assignment in the channel parameter
then solved it.

discord.py trying to remove all roles from a user

I have a problem that I`m trying to remove all roles a user has for some kind of mute role but it gives me this error discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NotFound: 404 Not Found (error code: 10011): Unknown Role
Here`s my code
#client.command(aliases=['m'])
#commands.has_permissions(kick_members = True)
async def mute(ctx,member : discord.Member):
muteRole = ctx.guild.get_role(728203394673672333)
for i in member.roles:
await member.remove_roles(i)
await member.add_roles(muteRole)
await ctx.channel.purge(limit = 1)
await ctx.send(str(member)+' has been muted!')
I know that this kind of questiion was alredy asked here: How to remove all roles at once (Discord.py 1.4.1).
But it wasn`t answered and did not help me at all
The problem is that all users have an "invisible role", #everyone. You will see it show up if you try
for i in member.roles:
print(i)
remove_roles is a high level function and it will try to remove #everyone, which is causing your error.
To clear all current roles from the user, you can do:
#client.command(aliases=['m'])
#commands.has_permissions(kick_members = True)
async def mute(ctx, member : discord.Member):
muteRole = ctx.guild.get_role(775449115022589982)
await member.edit(roles=[muteRole]) # Replaces all current roles with roles in list
await ctx.channel.purge(limit = 1)
await ctx.send(str(member)+' has been muted!')
await member.edit(roles=[]) Replaces all the current roles with the roles you have in the list. Leave the list empty to remove all roles from the user.
discord.Member.edit
Although if you want to do it with a for loop, you can use try
#client.command(aliases=['m'])
#commands.has_permissions(kick_members = True)
async def mute(ctx, member : discord.Member):
muteRole = ctx.guild.get_role(775449115022589982)
for i in member.roles:
try:
await member.remove_roles(i)
except:
print(f"Can't remove the role {i}")
await member.add_roles(muteRole)
await ctx.channel.purge(limit = 1)
await ctx.send(str(member)+' has been muted!')

Categories