discord.py - Send Messages on Specific Channel by Name - python

I want to make so when a message gets deleted, it sends the message that got deleted in #logs
CODE:
#bot.event
async def on_message_delete(message):
data = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("[" + (colored("{}".format(data), 'white')) + "][" +
(colored("{}".format(message.server), 'blue')) + " - " +
(colored("{}".format(message.channel), 'magenta')) + "] " +
(colored("{}".format(message.author), 'cyan', 'on_magenta') +
(colored(": {}".format(message.content), 'red'))))
channel = bot.get_channel("logs")
await bot.say(channel, "ALERT: Message Deleted")
await bot.say(channel, "Message {} got deleted by {} in {}".format(message.content, message.author, channel))
await bot.process_commands(message)

Related

Looping through guild members with discord.py

I have been attempting to make a bot that will give all users in my small guild (<50 members) a role.
I have had a tough time getting the bot to loop through all of the users in the server.
Currently it will output:
02/06/21 17:09:23: Successfully gave john_doe#1234 DJ role. (1 users!).
02/06/21 17:09:23: user john_doe#2234 gave all (1) users DJ role. (placeholder1).
Any advice?
Here is the part of the code I am working on:
if message.content.startswith(prefix + "Give DJ ALL"):
count = 0
for member in message.guild.members:
count = count + 1
await member.add_roles(discord.utils.get(message.guild.roles, name = "DJ"))
print(str(datetime.datetime.now().strftime("%x %X")) + ": " + "Successfully gave " + str(member) + " DJ role. (" + str(count) + " users!).")
await message.channel.send("Successfully gave " + str(count) + " users DJ!")
print(str(datetime.datetime.now().strftime("%x %X")) + ": " + "user " + str(message.author) + " gave all ("+ str(count) + ") users DJ role. (" + str(message.guild.name) + ").")
edit: yes i have enabled intents in my bot settings on the website
alonside this:
async def on_ready():
intents = discord.Intents.default()
intents.presences = True
intents.members = True
Fixed by using proper syntax thanks to Łukasz Kwieciński.
code here:
client = discord.Client(intents = discord.Intents.all())

Discord.py list users in a message when reaction

i have been trying to fix a problem for days. I want to send an embet naricht and this should be edited as soon as someone has made a reaction.
here my snipped code:
embed = discord.Embed(title='General Information', color=16769251)
embed.set_footer(text='General information')
embed.set_thumbnail(url=message.guild.icon_url)
embed.add_field(name='Text Header ', value=all_lines[1], inline=False)
embed.add_field(name='Text Header 2: ', value=all_lines[2], inline=False)
embed.add_field(name='Accepted Users: ', 'HERE ALL USERS WITH ✅', inline=False)
mess = await message.send(embed=embed)
await mess.add_reaction('✅')
await mess.add_reaction('❌')
I have already tried a lot of things but unfortunately without success I think it would be just too much to really put everything in here I still hodde that someone can help me
Here an example :
Before ( without reactions )
https://i.gyazo.com/1518bc2bfe8b55e2e790ff6481c261f7.png
After with reactions:
https://i.gyazo.com/8bf97513e1eaf567ca9dda66f54fa2f0.png
Final Version with 1 little refresh bug:
async def ReportRaid(self, message, bot):
name = message.author
if message.author.bot:
return
else:
await message.delete()
args = message.content.split(' ')
# raid <type> <name> <setting> <min>
# 0 1 2 3 4
if args[0] == "/raid" or args[0] == "/Raid":
embed = discord.Embed(title='Raid meldung von ' + str(message.author.display_name))
embed.add_field(name='Raid Typ: ', value=args[1], inline=True)
embed.add_field(name='Name: ', value=args[2], inline=True)
embed.add_field(name=settings.RaidSetings[args[3]], value=args[4] + " Minuten", inline=True)
embed.add_field(name='Zusagen:', value='Keine Zusagen', inline=True)
if not args[2].lower() in pkm.pokeDir[args[1].lower()]:
await message.channel.send('Das pokemon konnte nicht gefunden werden.', delete_after=30.0)
return
else:
embed.set_thumbnail(
url=settings.ServerSettings["ImageURL"] + pkm.pokeDir[args[1].lower()][args[2].lower()] + '.png')
try:
with open('accounts/Ac' + str(name) + '.txt', "r") as fp:
all_lines = fp.readlines()
embed.set_footer(text='Trainer name: {} \nTrainer Code: {}'.format(all_lines[1], all_lines[3]))
tgName = all_lines[3]
except IOError:
embed.set_footer(text='Keine Informationen gefunden')
tgName = "Keinen Trainer code gefunden"
channel = bot.get_channel(int(await guild_setings.LoadGuildSettings().get_raid_channel(message)))
mess = await channel.send(embed=embed, delete_after=int(args[4]) * 60)
tg.TelegramBot(message, '**\nRaid Typ: ' + args[1] + "\nName: " + args[2] + "\n" + settings.RaidSetings[args[3]] + " " + args[4] + ' Minuten\nTriainer Code: ' + tgName + '\nRaid Meldung von: ' + str(message.author.display_name)).SendToTelegramm()
re_time = int(args[4]) * 60
emoji_list = ['✅', '❌']
for i in emoji_list:
await mess.add_reaction(i)
while True:
users = ""
try:
reaction, user= await bot.wait_for("reaction_add", timeout=re_time)
if str(reaction) == '✅':
mess = await channel.fetch_message(mess.id)
reaction_list = mess.reactions
for reactions in reaction_list:
if str(reactions) == "✅":
user_list = [user async for user in reactions.users() if user != bot.user]
for user in user_list:
users = users + user.mention + "\n"
embed_1 = discord.Embed(title='Raid meldung von ' + str(message.author.display_name))
embed_1.add_field(name='Raid Typ: ', value=args[1], inline=True)
embed_1.add_field(name='Name: ', value=args[2], inline=True)
embed_1.add_field(name=settings.RaidSetings[args[3]], value=args[4] + " Minuten", inline=True)
embed_1.add_field(name='Zusagen:', value=users, inline=True)
if not args[2].lower() in pkm.pokeDir[args[1].lower()]:
await message.channel.send('Das pokemon konnte nicht gefunden werden.', delete_after=30.0)
return
else:
embed_1.set_thumbnail(
url=settings.ServerSettings["ImageURL"] + pkm.pokeDir[args[1].lower()][args[2].lower()] + '.png')
try:
with open('accounts/Ac' + str(name) + '.txt', "r") as fp:
all_lines = fp.readlines()
embed_1.set_footer(text='Trainer name: {} \nTrainer Code: {}'.format(all_lines[1], all_lines[3]))
except IOError:
embed_1.set_footer(text='Keine Informationen gefunden')
await mess.edit(embed = embed_1)
except asyncio.TimeoutError:
break
If I understand you correctly, you want something like this. I've tried putting comments in the code along the way so you can understand better what's going on.
As the code is right now, it will not update if a user removes the reaction. If user_1 and user_2 adds reaction, and then user_1 removes reaction, they will both still show, when user_3 adds reaction, it will update to show only user_2 and user_3
You can add the code between *** in the exception as well, to update the embed one final time as the loop ends.
Another thing is that I don't know what your all_lines is, so I had that just as a string during testing.
#client.command() # Correct this according to your code, if you're using bot or client
async def rtest(ctx):
message = ctx.message
# At first we create create the embed
embed = discord.Embed(title='General Information', color=16769251)
embed.set_footer(text='General information')
embed.set_thumbnail(url=message.guild.icon_url)
embed.add_field(name='Text Header ', value=all_lines[1], inline=False)
embed.add_field(name='Text Header 2: ', value=all_lines[2], inline=False)
embed.add_field(name='Accepted Users: ', value='HERE ALL USERS WITH ✅', inline=False)
mess = await ctx.send(embed=embed)
# And add our reactions to the embed
emoji_list = ['✅', '❌']
for i in emoji_list:
await mess.add_reaction(i)
# Create a while loop that will wait for users to react
while True:
users = "" # Create empty string that we need later
try:
reaction, user= await client.wait_for("reaction_add", timeout=60)
# Check that if the reaction added is ✅, and if it is:
if str(reaction) == "✅":
mess = await ctx.channel.fetch_message(mess.id) #*** Need to fetch message again to get updated reaction information
reaction_list = mess.reactions
# Check our reactions on the message, get user list for the ✅ reaction, ignoring the bot
for reactions in mess.reactions:
if str(reactions) == "✅":
user_list = [user async for user in reactions.users() if user != client.user]
# Update the users string, to add user that reacted
for user in user_list:
users = users + user.mention + "\n"
# Create an updated embed with different name, it's the same as before, but with users in last field
embed_1 = discord.Embed(title='General Information', color=16769251)
embed_1.set_footer(text='General information')
embed_1.set_thumbnail(url=message.guild.icon_url)
embed_1.add_field(name='Text Header ', value=all_lines[1], inline=False)
embed_1.add_field(name='Text Header 2: ', value=all_lines[2], inline=False)
embed_1.add_field(name='Accepted Users: ', value='HERE ALL USERS WITH ✅\n'+users, inline=False)
await mess.edit(embed = embed_1) # Edit message to be the updated embed
#***
# End the loop after the set amount of time (from timeout earlier)
except asyncio.TimeoutError:
break
What you're looking for is bot.wait_for, here a simple example
#bot.command()
async def react(ctx):
# Sending the message
message = await ctx.send('React with ✅')
def check(reaction, user):
# Checking if the user that reacted is the same as the one that invoked the command
# also checking if the reaction is `✅` and if the reacted message is the one sent before
return user == ctx.author and str(reaction) == '✅' and reaction.message == message
try:
# Waiting for the reaction
reaction, user = await bot.wait_for('reaction_add', check=check, timeout=60.0)
except asyncio.TimeoutError:
# If the timeout is over, deleting the message
await message.delete()
await ctx.send('Timeout is over')
else:
# If the reaction is not the one we're waiting for, send this
await ctx.send('Bad reaction')
Reference

bot sends the message to the group several times

def telegram_bot_sendtext():
bot_token = 'bot token'
bot_chatID = 'chat id'
text = ['done!','save']
for i in text:
send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + i
requests.get(send_text)
time.sleep(4)
#client.on(events.NewMessage(chats=[chat id]))
async def handler(event):
print(event)
event_message = event.message
telegram_bot_sendtext()
client.run_until_disconnected()
I wrote this code but the bot sends the message to the group several times, what should I do?
Even if I do not list and send a single message, it sends the message continuously

Python - open() isn't working

#BLACKLIST PROFILE CREATION COMMAND
#bot.command(pass_context=True)
async def blacklist(ctx, removeoradd, user: discord.Member, *, reason):
if ctx.message.author.id == developerID:
if removeoradd == "add":
case_id = "BL-" + id_generator(10, "1234567890")
blacklist_template = "{\"" + user.id + "\": {\"userid\": \"" + user.id + "\", \"reason\": \"" + reason + "\", \"banned_by\": \"" + ctx.message.author.id + "\", \"case_id\": \"" + case_id + "\", \"active\": \"True\"}}"
# with open("C:/Blacklisted/{}.json".format(ctx.message.author.id), "w") as json_file:
# json.dump(blacklist_template, json_file)
blacklist = open(os.path.expanduser("~/Blacklisted/{}.json".format(ctx.message.author.id)), "x")
blacklist.write("{}".format(blacklist_template))
blacklist.close()
embed = discord.Embed(title="Admin Control", description="Blacklisted:\n``{}/{}``".format(user.name, user.id))
embed.add_field(name="Reason", value=reason)
embed.add_field(name="Case ID", value=case_id)
embed.set_footer(text="v" + version + " | " + localtime)
await bot.say(embed=embed)
embed = discord.Embed(title="You can no longer create a profile.", description="If you think this is a mistake do {}appeal <reason>".format(prefix))
embed.add_field(name="Reason", value=reason)
embed.add_field(name="Case ID", value=case_id)
embed.set_footer(text="v" + version + " | " + localtime)
await bot.send_message(ctx.message.author, embed=embed)
elif removeoradd == "remove":
pass
else:
embed=discord.Embed(title="An error occured", description="Invalid argument.\nInsert ``add`` or ``remove``.", color=0xc20000)
await bot.say(embed=embed)
else:
embed=discord.Embed(title="An error occured", description="No permission.\nYou need to be a verified developer to do this.", color=0xc20000)
await bot.say(embed=embed)
File "run.py", line 126, in blacklist
blacklist = open(os.path.expanduser("/Blacklisted/{}.json".format(ctx.message.author.id)), "x")
FileNotFoundError: [Errno 2] No such file or directory: '/Blacklisted/182288858782629888.json'
so basically im trying to create a file with the blacklist_template contents. I thought that when you use the "w" mode, it creates a new file for you. What am I doing wrong?

discord.py and private messages

I am trying to make discord-bot on phyton. Although I have understood discord API, I can't get the robot to send messages to members of server in private mail. Could you help me please
if message.content.startswith(myname + '!btcprice'):
print('[command]: btcprice ')
btc_price_usd, btc_price_rub = get_btc_price()
msg = 'USD: ' + str(btc_price_usd) + ' | RUB: ' + str(btc_price_rub)
await client.send_message(message.channel, msg)
I'm assuming you are calling this from the on_message event, in which case to send a PM you can get the member object from message.author. You can PM the user with this.
#client.event
async def on_message(message):
if message.content.startswith(myname + '!btcprice'):
print('[command]: btcprice ')
btc_price_usd, btc_price_rub = get_btc_price()
msg = 'USD: ' + str(btc_price_usd) + ' | RUB: ' + str(btc_price_rub)
await client.send_message(message.author, msg)

Categories