In newest update, I have a problem with event: on_guild_channel_update.
I mean, in 1.6.0 it was worked, but in 1.7.0 now have a problem
intents = discord.Intents.all()
client = commands.Bot(command_prefix = get_prefix, intents = intents)
#client.event
async def on_guild_role_update(before, after):
global check_ranga
#e = discord.Embed(color = client.get_user(id_arnoldzika).color, timestamp = datetime.datetime.now(datetime.timezone.utc))
async for author in before.guild.audit_logs(limit = 1, oldest_first = False, action = discord.AuditLogAction.role_update):
member = '{0.user.id}'.format(author)
user = await client.fetch_user(member)
print(user)
#client.event
async def on_guild_channel_update(before, after):
global check_position
check = 0
e = discord.Embed(color = client.get_user(id_arnoldzika).color, timestamp = datetime.datetime.now(datetime.timezone.utc))
async for author in before.guild.audit_logs(limit = 1, oldest_first = False, action = discord.AuditLogAction.channel_update):
print('{0.before} {0.after.type}'.format(author))
member = '{0.user.id}'.format(author)
user = await client.fetch_user(member)
When trigger channel update, I don't get anything, but when trigger role update, correctly print user.
What is the problem with this?
Related
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)
FIXED, fix = await ctx.bot.change_presence.
This is my code for a command that worked with #bot.command() but somehow it doesn't work when I use #commands.command()
bot = commands.Bot(command_prefix = !)
#commands.command()
async def playgame(ctx, game: str=None):
game_count = False
game_list = []
if game:
game_list.append(game)
game_activity = discord.Activity(name=game, type=discord.ActivityType.playing)
activity = discord.Activity(name=".commands", type=discord.ActivityType.listening)
if game_count:
await ctx.send("I'm already playing " + str(game_list[0]))
else:
game_count = True
await ctx.send("ok!")
await bot.change_presence(activity=game_activity) #This calls the error
await asyncio.sleep(60)
await ctx.send("Gotta go, imma stop playing " + str(game_list[0]) + ", bye")
await bot.change_presence(status=discord.Status.dnd, activity=activity)
game_count = False
game_lib = []
else:
msg = "I can't play nothing, use .playgame <game>"
await ctx.send(msg)
def setup(bot):
bot.add_command(playgame)
Probably the problem is just that little thing that you didn't put the command prefix in quotation marks so it is not formatted as string and messes up the whole script.
Solution would be:
bot = commands.Bot(command_prefix = "!")
*Just noticed you already fixed it
There is a command to request a role. I don't understand how to set some functions for reactions.
#client.command()
async def role(ctx):
role = ctx.guild.get_role(703596629860548643)
zapros_chanell = client.get_channel(729733881129074768 )
zapros2_chanell = client.get_channel(703596629923725339 )
embed = discord.Embed(title="Запрос роли")
embed.add_field(name='Запросивший роль', value=ctx.message.author.mention)
embed.add_field(name='Роль для выдачи', value=role.mention)
embed.set_thumbnail(url=ctx.guild.icon_url)
message = await zapros_chanell.send(embed=embed)
await zapros2_chanell.send(embed = discord.Embed(description = f'{ctx.message.author.mention}, `запрос на выдачу роли был успешно отправлен, ожидайте его рассмотрения модерацией Discord`', color=discord.Color.purple()))
await message.add_reaction('✅')
await message.add_reaction('❎')
The bottom line is that if when you click on ✅, the role was issued and a text was written to the person in zapros2_chanell.
When you click on ❎, the person was not given a role, therefore, but a certain text was also written in zapros2_chanell.
I used an event called on_raw_reaction_add. Made a check to the reaction, keep in mind the will give the role to any message in the guild with ✅.It it just a proof of concept.
You can make it only accept reactions on certain channel, or even only for given message IDs
#client.command()
async def role(ctx):
zapros_chanell = client.get_channel(729733881129074768)
embed = discord.Embed(title="Запрос роли")
embed.add_field(name='Запросивший роль', value=ctx.message.author.mention)
embed.add_field(name='Роль для выдачи', value=role.mention)
embed.set_thumbnail(url=ctx.guild.icon_url)
message = await zapros_chanell.send(embed=embed)
await zapros2_chanell.send(embed = discord.Embed(description = f'{ctx.message.author.mention}, `запрос на выдачу роли был успешно отправлен, ожидайте его рассмотрения модерацией Discord`', color=discord.Color.purple()))
await message.add_reaction('✅')
await message.add_reaction('❎')
#client.event
async def on_raw_reaction_add(payload):
channel = await client.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
user = await client.fetch_user(payload.user_id)
emoji = payload.emoji.name
guild = client.get_guild(ID_HERE)
role = guild.get_role(703596629860548643)
zapros2_chanell = client.get_channel(703596629923725339 )
if user.id != bot.user.id: # bot to count itself
if emoji == '✅':
await client.add_roles(user, role)
await zapros2_chanell.send(f'{user.name} has been given {role.name}')
elif emoji == '❎':
await zapros2_chanell.send(f'{user.name} did not want {role.name}')
I am currently trying to migrate most of my code into cogs and I have this function that logs commands.
async def logging(self, ctx, command):
output = client.get_channel(channel_id_here)
embed = discord.Embed(title = "{} command used.".format(command), color = 0x40558a)
embed.add_field(name = "User:", value = "{}".format(ctx.message.author.mention))
embed.add_field(name = "Server:", value = "{}".format(ctx.message.guild))
embed.add_field(name = "Channel:", value = "<#{}>".format(ctx.message.channel.id))
embed.add_field(name = "Full Command:", value = "{}".format(ctx.message.content))
await output.send(embed = embed)
However, when I attempt to call on that function in a command by using:
await logging(self = self, ctx = ctx, command = "whatever")
I get an error that says Undefined variable: logging. I am new to using cogs and I would appriciate any help you can give.
I am new to the Discord python API. I am trying to run a method forever as long as the client is still open. I scheduled the method through Client.loop.create_task(), and am running while not client.is_closed. I added a debugging print statement, but the print statement is called 0 times.
I based the code on this post: Discord.py Schedule
import discord
from datetime import datetime
from datetime import timedelta
token = "TOKEN"
s_users = {}
timezon_offset = 5
inac_days = 0
inac_hours = 0
inac_minutes = 1
active_role = "Active"
inac_role = "Inactive"
client = discord.Client()
async def monitor():
for guild in client.guilds:
for user in guild.members:
s_users[user] = datetime(1,1,1)
#client.event
async def on_ready():
print('logged on as {0}'.format(client.user))
#client.event
async def on_message(message):
print('message logged from {0.author}: {0.content} at {0.created_at}'.format(message))
s_users[message.author] = message.created_at - timedelta(hours=timezon_offset)
async def task():
await client.wait_until_ready()
active = None
inactive = None
for guild in client.guilds:
for role in guild.roles:
if (role.name == active_role):
active = role
elif (role.name == inac_role):
inactive = role
while not client.is_closed:
print("here")
for user in s_users:
if datetime.now() - s_users[user] > timedelta(days=inac_days, hours=inac_hours, minutes=inac_minutes):
if not(inac_role in [role.name for role in user.roles]):
await user.remove_roles(active)
await user.add_roles(inactive)
print("gave user: " + user.name + " " + inac_role + " role")
if datetime.now() - s_users[user] <= timedelta(days=inac_days, hours=inac_hours, minutes=inac_minutes):
if not(active_role in [role.name for role in user.roles]):
await user.remove_roles(inactive)
await user.add_roles(active)
print("gave user: " + user.name + " " + active_role + " role")
client.loop.create_task(task())
client.run(token)
It should execute task(), which should run as long as the client is not closed. However, the print statement is executed 0 times.
In version 1.0.0, Client.is_closed was changed from a property to a method. See Property Changes in the Migration guide.
You'll need to add parentheses to call the method:
while not client.is_closed():
...