Discord.py Why removing roles doesn't work? - python-3.x

Giving roles work correct. But absolutely copied "on_reaction_remove" don't give any results, even exceptions. I tried to choose reactions in second account, yes, bot gave a role, but when I removed reaction bot did not do anything:/
import discord
from discord import utils
from discord.ext import commands
import config
client = commands.Bot(command_prefix = '#')
#client.event
async def on_ready():
print('Logged on as {0}!'.format(client.user.name))
#client.event
async def on_reaction_add(reaction, user):
if str(reaction.message.channel) == 'giving-roles':
try:
channel = reaction.message.channel
role = utils.get(user.guild.roles, id = config.ROLES[str(reaction)])
await user.add_roles(role)
print(f'[SUCCESS] Role [{config.ROLES[str(reaction)]} for [{user}] was added ')
except Exception as e:
print(repr(e))
#client.event
async def on_reaction_remove(reaction, user):
if str(reaction.message.channel) == 'giving-roles':
try:
channel = reaction.message.channel
role = utils.get(user.guild.roles, id = config.ROLES[str(reaction)])
await user.remove_roles(role)
print(f'[SUCCESS] Role [{config.ROLES[str(reaction)]} for [{user}] was removed ')
except Exception as e:
print(repr(e))
# RUN
client.run(config.TOKEN)

I tried this a while back and I found using on_raw_reaction_add(payload) and on_raw_reaction_remove(payload) worked better.
#client.event
async def on_raw_reaction_add(payload):
message_id = payload.message_id
#Soft Ocean
if message_id == 677963887122841625: # This can be changed but i was using an individual message
guild_id = payload.guild_id
guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds) # This gets the guild
if payload.emoji.name == 'tick': #This is the name of the emoji that is used
role = discord.utils.get(guild.roles, name='Soft Ocean') # Enter the role name here
if role is not None: # If role exists
member = discord.utils.find(lambda m : m.id == payload.user_id, guild.members) #Gets the member
if member is not None: # Checks if member is real
await member.add_roles(role) # Gives the role
else:
print("Member not found")
else:
print("Role not found")
#client.event
async def on_raw_reaction_remove(payload):
message_id = payload.message_id
#Soft Ocean
if message_id == 677963887122841625:
guild_id = payload.guild_id
guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
if payload.emoji.name == 'tick':
role = discord.utils.get(guild.roles, name='Soft Ocean')
if role is not None:
member = discord.utils.find(lambda m : m.id == payload.user_id, guild.members)
if member is not None:
await member.remove_roles(role)
else:
print("Member not found")
else:
print("Role not found")

hard worker, I certainly understand that you have already solved your problem, but I still found a way to solve it much easier than our comrades. For example see and taste this code:
#bot.event
async def on_reaction_add(reaction, member):
Channel = bot.get_channel(id ur channel)
if not member.bot:
if reaction.message.channel == Channel:
if reaction.emoji == 'ur emoji':
zxc = discord.utils.get(member.guild.roles, name="zxc")
await member.add_roles(zxc)
else:
pass
#bot.event
async def on_reaction_remove(reaction, member):
Channel = bot.get_channel(ur id )
if reaction.message.channel == Channel:
if reaction.emoji == 'ur emoji':
zxc = discord.utils.get(member.guild.roles, name="zxc")
await member.remove_roles(zxc)
Of course, brother, I understand everything (absolutely everything), the code is primitive (well, easy), but he will solve your problem like a finger on the asphalt (that is, for one or two (I hope you understand (I'm just not an Omerican))). lets giritTT

Related

Discord bot not recognizing messages

I'm new to creating bots and I wanted to try and make a bot that would greet me when I said hi and say goodbye when I said bye.
When I activated it, it seemed to not be able to recognize that I sent a message
I checked permissions and it should be able to see it but it doesn't look like it can
here's the code
import os
import discord
client = discord.Client()
#client.event
async def on_ready():
print("We are {0.user} and we are on a cruise".format(client))
#client.event
async def on_messsage(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if message.author == client.user:
return
if channel == 'general':
if user_message.lower() == 'hello':
await message.channel.send(f'Hello {username}')
return
elif user_message.lower() == 'bye':
await message.channel.send(f'Bye {username}')
return
client.run(os.environ['taisho-secret'])
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if message.author == client.user:
return
if channel == 'general':
if user_message.lower() == 'hello':
await message.channel.send(f'Hello {username}')
return
elif user_message.lower() == 'bye':
await message.channel.send(f'Bye {username}')
return
your problem is that you wrote on_messsage and its on_message

Translation with reactions not working on python

I'm trying to do a bot translation using reactions. Although something is not working.
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
if user == self.client:
return
if reaction.emoji == ":flag_us:":
text = reaction.message.id
translate_text = google_translator.translate(text, lang_tgt='en')
await self.client.send_message(translate_text.channel)
elif reaction.emoji == ":flag_cn:":
text = reaction.message.id
translate_text = google_translator.translate(text, lang_tgt='zh')
await self.client.send_message(translate_text.channel)
else:
return
No error returned and no action made
This is because reaction.emoji isn't a string, but is an object itself. You're probably looking for reaction.emoji.name.
Also, there are a few issues within the if/elif clauses that would prevent your code from running, even if the original issue was fixed.
reaction.message.id is an integer, so passing it to google_translator.translate() will result in an error.
The name of an emoji tends not to be the name you would enter in Discord. The best practice would be to put the unicode of the emoji.
To send a message to channel, you should use TextChannel.send()
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
if payload.member == self.client:
return
if payload.emoji.name == u"\U0001f1fa\U0001f1f8":
message = await self.client.fetch_message(payload.message_id)
translate_text = google_translator.translate(message.content, lang_tgt='en')
channel = await self.client.fetch_channel(payload.channel_id)
await channel.send(translate_text)
elif payload.emoji.name == u"\U0001F1E8\U0001F1F3":
message = await self.client.fetch_message(payload.message_id)
translate_text = google_translator.translate(message.content, lang_tgt='zh')
channel = await self.client.fetch_channel(payload.channel_id)
await channel.send(translate_text)
This would work, but I would recommend taking all of the various calls outside of the if/elif clauses:
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
if payload.member == self.client:
return
emoji_to_language = {
u"\U0001f1fa\U0001f1f8": "en",
u"\U0001F1E8\U0001F1F3": "zh"
}
lang = emoji_to_language.get(payload.emoji.name)
if lang is None:
break
message = await self.client.fetch_message(payload.message_id)
translate_text = google_translator.translate(message.content, lang_tgt=lang')
channel = await self.client.fetch_channel(payload.channel_id)
await channel.send(translate_text)

Why does the add_roles() method from discord.py fail here?

The following method is called on a discord bot thread from a flask application. All the print checks display the correct data so the method is being run successfully, however the final fstring
f'{role} added to {member}'
Does not get outputted to the console, which makes me think the
await member.add_roles(role)
Is not executing properly. No errors show up in the console. Every other line seems to run properly. Ive included the relevant methods below including the way the threads are structured in the flask app
client_loop = asyncio.get_event_loop()
intents = discord.Intents(messages=True, guilds=True, members=True)
client = commands.Bot(command_prefix='$', help_command=None, intents = intents)
#client.event
async def on_ready():
print(f'{client.user} is online!')
return
async def start_bot():
print(os.getenv("TOKEN"))
await client.start(os.getenv("TOKEN"))
def run_it_forever(loop):
loop.run_forever()
async def api_add_role(user, role_to_assign):
guild = client.guilds[0]
members = await guild.fetch_members(limit=None).flatten()
role = discord.utils.get(guild.roles, name=role_to_assign)
print("role")
print(role)
member = [m for m in members if m.name == user][0]
print("member")
print(member)
await member.add_roles(role)
print(f'{role} added to {member}')
app = Flask(__name__)
#app.route("/add_role")
def add_role_to_member():
name = request.args.get('name')
role = request.args.get('role')
coroutine = asyncio.run_coroutine_threadsafe(api_add_role(name, role), client_loop)
return "okay"
if __name__ == '__main__':
asyncio.get_child_watcher()
client_loop.create_task(start_bot())
botThread = threading.Thread(target=run_it_forever, args=(client_loop,))
def interrupt():
global botThread
botThread.join()
atexit.register(interrupt)
botThread.start()
print("server starting....")
app.run(host='0.0.0.0', port=5000)
I haven't seen anyone using your method to get the member object. There is get_member_named which is meant for that.
async def api_add_role(user, role_to_assign):
guild = client.guilds[0]
role = discord.utils.get(guild.roles, name=role_to_assign)
print(f"role: {role}")
member = guild.get_member_named(user) # name or name#tag
print(f"Member: {member}")
if member and role: # if both exist
await member.add_roles(role)
print(f'{role.name} added to {member.name}')

Why is discord.Client.wait_for is asking for event when it has one?

The problem i'm having is the code never getting through "0004" since it gets stuck on wait_for which wants additional positional argument: 'event', which should be the 'message' in bracket right next to it from what I've seen on examples from discord.py site & inside the code itself.
'''
class Test(commands.Cog):
def __init__(self, spreadsheeter):
self.spreadsheeter = spreadsheeter
#commands.command()
async def apply(self, ctx):
a_list = []
submit_channel = spreadsheeter.get_channel(718698172293316608)
channel = await ctx.author.create_dm()
def check(m):
return m.content is not None and m.channel == channel
for question in q_list:
print("0001")
sleep(.5)
print("0002")
await channel.send(question)
print("0003")
msg = await Client.wait_for('message', timeout=60, check=check)
print("0004")
a_list.append(msg.content)
print("0005")
submit_wait = True
print("0006")
while submit_wait:
print("0007")
await channel.send("End of questions 'submit' to finish.")
print("0008")
msg = await Client.wait_for("message", check=check)
print("0009")
if "submit" in msg.content.lower():
print("0010")
submit_wait =False
print("0011")
answers = "\n".join(f"{a}. {b}" for a, b in enumerate(a_list, 1))
print("0012")
submit_msg = f"Apllication from {msg.author} \nThe answers are:\n{answers}"
print("0013")
await submit_channel.send(submit_msg)
print("0014")
Error:
What I've unsuccessfully tried:
discord.client.wait_for('message', check=check)
Error: discord.client has no attribute 'wait_for'
Same for discord.member, ctx.member, ctx.client
Replacing "message" to 'message' (doesn't change anything)
Moving around the position of 'message'
Raises ton of other errors...
Giving the line bracket at start (self, "message", check=check)
Error: 'Test' object has no attribute 'loop'
#client.event instead of cog style commands.command
Error: Unresolved reference 'client'
Intent of the code:
Be called from DM as a command, then start a series of questions from q_list in that DM and then store them into a_list. Then after its done it should submit the a_list into as submit_msg into discord channel.
What it does so far?:
Asks first question from q_list
q_list = [
"Question one",
"Question two ha-ha-haaa",
"Question three ha-ha-haaa"
]
"""
After that it immediately after trying to await answer gives error.
2 Things at the beginning, you should only make a dm channel if there isn't any yet.
ctx.author.chreate_dm() doesn't return a channel, so instead of assigning the dm channel to channel you can check it's in the right channel by using ctx.author.dm_channel
#commands.command()
async def apply(self, ctx):
a_list = []
submit_channel = self.spreadsheeter.get_channel(718698172293316608)
if not ctx.author.dm_channel:
await ctx.author.create_dm()
def check(m):
return m.content is not None and m.channel == ctx.author.dm_channel
Instead of Client use spreadsheeter as that is your client
msg = await self.spreadsheeter.wait_for('message', timeout=60, check=check)
Figured it out, the thing being is it might work in cogs, but I think it won't or something is just missing...
The way i made it to work is to use it in
#Client.event (in my case #spreadsheeter.event)
Instead of ctx. I used payload.
"""
#spreadsheeter.event
async def on_raw_reaction_add(payload):
print("Hell-Yeah")
message_id = payload.message_id
if message_id == 739153263907176480:
guild_id = payload.guild_id
guild = discord.utils.find(lambda g : g.id == guild_id, spreadsheeter.guilds)
print (payload.emoji.name)
if payload.emoji.name == "No1":
role = discord.utils.find(lambda r: r.name == 'RAIDERS', guild.roles)
print(role)
if role in payload.member.roles:
print("You really want to leave?")
else:
print("Kick")
await payload.member.kick()
elif payload.emoji.name == "Yes1":
print("Yo, we got a potential raider over here..")
channel = await payload.member.create_dm()
await channel.send("This is still Work/Bot is under Development (Not actuall application yet).")
await channel.send("Whenever you are ready, please start replaying to the questions.")
print("0000")
submit_channel = spreadsheeter.get_channel(718698172293316608)
if not payload.member.dm_channel:
await payload.member.create_dm()
channel = payload.member.dm_channel
print(channel)
def check(m):
return m.content is not None and m.channel == channel
for question in q_list:
print("0001")
sleep(.5)
print("0002")
await channel.send(question)
print("0003")
msg = await spreadsheeter.wait_for(event='message', timeout=60, check=check)
print("0004")
a_list.append(msg.content)
print("0005")
submit_wait = True
print("0006")
while submit_wait:
print("0007")
await channel.send("End of questions 'submit' to finish.")
print("0008")
msg = await spreadsheeter.wait_for("message", timeout=60, check=check)
print("0009")
if "submit" in msg.content.lower():
print("0010")
submit_wait = False
print("0011")
answers = "\n".join(f"{a}. {b}" for a, b in enumerate(a_list, 1))
print("0012")
submit_msg = f"Apllication from {msg.author} \nThe answers are:\n{answers}"
print("0013")
await submit_channel.send(submit_msg)
print("0014")
elif payload.emoji.name == "Need_more_info":
print("Yo, we got a potential diplomat over here..")
channel = await payload.member.create_dm()
await channel.send("This is still Work/Bot is under Development (Not actuall application yet).")
await channel.send("Whenever you are ready, please start with \n_apply")
"""
It still doesn't have the handling for multiple users, but works fine with one at a time at this moment, which solves the original problem of wait_for not waiting for anything else then timeout to run out.

Discord bot in python, check if a user is in a channel

#client.command(pass_context=True)
async def solodab(context):
user = context.message.author
channel = user.voice_channel
if user == channel:
author = context.message.author
channel = author.voice_channel
vc = await client.join_voice_channel(channel)
print("3")
time.sleep(1)
print("2")
time.sleep(1)
print("1")
time.sleep(1)
await vc.disconnect()
else:
print("Dab")
await client.say("User is not in channel: ")
I'm making a solosnipe bot, but i would like to make it so if someone is writing this it should give a message to the person telling them to join the channel. But i don't know what to do
I found out the issue, i need to add a try/except block. And some if statment's
if voice_channel == None:
voice_channel = author.voice_channel
if server == author:
await client.say("This just needs to be here dabdab")
else:
try:
vc = await client.join_voice_channel(voice_channel)
except:
await client.say("You are not in a channel, join one!!" + author.mention)

Resources