Discord.py snipe command is sniping messages from other channels - discord

I recently made a snipe command for my discord bot but I have one problem. Snipe command snipes a message from other channels when I for example want to snipe a message in general. Here is my code:
#bot.event
async def on_message_delete(message):
if message.attachments:
bob = message.attachments[0]
bot.sniped_messages[message.guild.id] = (bob.proxy_url, message.content, message.author, message.channel.name, message.created_at)
else:
bot.sniped_messages[message.guild.id] = (message.content,message.author, message.channel.name, message.created_at)
#bot.command(aliases=['s'])
async def snipe(ctx):
try:
bob_proxy_url, contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
except:
contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
try:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_image(url=bob_proxy_url)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
except:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)

snipe_message_author = {}
snipe_message_content = {}
#client.event
async def on_message_delete(message):
snipe_message_author[message.channel.id] = message.author
snipe_message_content[message.channel.id] = message.content
#client.command(name = 'snipe')
async def snipe(ctx):
channel = ctx.channel
try:
em = discord.Embed(description = f"`{snipe_message_content[channel.id]}`\nMessage sent by {snipe_message_author[channel.id]}!", color = 0x00c230)
em.set_author(name = f"Last deleted message in #{channel.name}")
em.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
em.set_footer(text = f"Snipe requested by {ctx.message.author}")
await ctx.send(embed = em)
except:
embed = discord.Embed(colour = 0x00c230)
embed.set_author(name=f"There are no deleted messages in #{ctx.channel}!")
embed.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
embed.set_footer(text=f"Snipe requested by {ctx.message.author}")
await ctx.channel.send(embed=embed)
Thats what I use and it works properly.
Since I added [message.channel.id] to the variables it only checks for snipes in that channel. This is how it looks like in Discord

Related

How to stop a while loop in Discord.py

I have made a Discord Bot that pings members(spam Bot). It uses a while loop. It automatically stops in a few hours(IDK Why But probably because the host I use resets the connection after a few hours).
I wanna make a command so that the bot stops pinging members but still be online. Basically I wanna end the while loop I use. Can anyone help me?
import discord
from keep_alive import keep_alive
client = discord.Client()
roleid = os.environ["#PingersRoleID"]
CategoryID = os.environ["PingsCategoryID"]
PingChannels = [
"ping1",
"ping2",
"ping3",
"ping4",
"ping5",
"ping6",
"ping7",
"ping8",
"ping9",
"ping10",
]
PingBotToken = os.environ["PingBotToken"]
#client.event
async def on_ready():
print("{0.user} has joined the chat".format(client))
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
# guild = client.get_guild(CategoryID)
print("{} sent {} in {}".format(username, user_message, channel))
if user_message.lower() == "!activatepings":
for _ in PingChannels:
if message.channel.name == str(_):
while True:
await message.channel.send("<#&{}>".format(roleid))
keep_alive()
client.run("...")
You can use a task that can be started and canceled at any time:
from discord.ext import tasks
#client.tasks(seconds=3600) #set to any amount
async def ping_task():
for channel in client.get_all_channels():
if channel.name in PingChannels:
await channel.send("<#&{}>".format(roleid))
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
# guild = client.get_guild(CategoryID)
print("{} sent {} in {}".format(username, user_message, channel))
if user_message.lower() == "!activatepings":
for _ in PingChannels:
if message.channel.name == str(_):
ping_task.start() #The task starts here
#client.command()
async def someCommand(ctx):
ping_task.cancel() #The task ends with this command
You can find an example of how to use tasks here: https://github.com/Rapptz/discord.py/blob/v2.0.0/examples/background_task.py
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
# guild = client.get_guild(CategoryID)
print("{} sent {} in {}".format(username, user_message, channel))
if user_message.lower() == "!activatepings":
for _ in PingChannels:
if message.channel.name == str(_):
while True:
if message.content == "STOP": ## replace it with the command you want to stop the bot
break
else:
await message.channel.send("<#&{}>".format(roleid))

Discord.py commands wont work after i switched from Nextcord to Discord v2

I just switched to Discord.py v2 after switching using nextcord for 1 or 2 months.
Im having a issue where no commands work
like no commands at all
i changed everything from "nextcord" to "discord" and even changed the setups in the cogs to the new async versions
events work, but commands themselves dont
i tried everything i knew but still didnt fix it
i tried looking in the discord doc but still couldnt find a soloution
my current code:
import discord
from discord.ext import commands
from discord.ext.commands.core import has_permissions
import asyncio
import os
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix='+', intents=intents)
##COGS
#bot.event
async def on_ready():
await asyncio.sleep(1)
print(f'We have logged in as {bot.user}')
await bot.change_presence(activity=discord.Game(name="in the Mountains"))
#bot.command()
#has_permissions(administrator = True)
async def load(ctx, arg, extension):
if ctx.author.id == 498839148904579092:
bot.load_extension(f"{arg}.{extension}")
embed = discord.Embed(description=f"{extension} module loaded!", colour=discord.Colour.dark_green())
await ctx.send(embed = embed)
print(f"{extension} loaded")
#bot.command()
#has_permissions(administrator = True)
async def unload(ctx, arg, extension):
if ctx.author.id == 498839148904579092:
bot.unload_extension(f"{arg}.{extension}")
embed = discord.Embed(description=f"{extension} module unloaded!", colour=discord.Colour.dark_green())
await ctx.send(embed = embed)
print(f"{extension} unloaded")
#bot.command()
#has_permissions(administrator = True)
async def reload(ctx, arg, extension):
if ctx.author.id == 498839148904579092:
bot.reload_extension(f"{arg}.{extension}")
embed = discord.Embed(description=f"{extension} module reloaded!", colour=discord.Colour.dark_green())
await ctx.send(embed = embed)
print(f"{extension} reloaded")
#load.error
async def alreadyloaded(ctx, error):
if isinstance(error, commands.CommandInvokeError):
embed = discord.Embed(colour=discord.Colour.dark_red())
embed.set_author(icon_url="https://cdn.discordapp.com/attachments/883349890921545748/927946906271887430/W0019f8UlvqD3dDC5.png", name="Command Invoke Error! [LOAD]")
embed.set_thumbnail(url="https://cdn.discordapp.com/attachments/883349890921545748/927946906271887430/W0019f8UlvqD3dDC5.png")
embed.add_field(name="commands.CommandInvokeError", value=error, inline=True)
embed.add_field(name="Maybe...", value="The Extension is Non-Exsistant or cannot be Loaded", inline=True)
embed.set_footer(text="get a list of Modules with [+modules]!")
await ctx.send(embed = embed, delete_after = 10)
elif isinstance(error, commands.MissingPermissions):
await ctx.message.delete()
await ctx.send(f"{ctx.author.mention}, that Command is Admin only!", delete_after = 3)
return
#unload.error
async def alreadyunloaded(ctx, error):
if isinstance(error, commands.CommandInvokeError):
embed = discord.Embed(colour=discord.Colour.dark_red())
embed.set_author(icon_url="https://cdn.discordapp.com/attachments/883349890921545748/927946906271887430/W0019f8UlvqD3dDC5.png", name="Command Invoke Error! [UNLOAD]")
embed.set_thumbnail(url="https://cdn.discordapp.com/attachments/883349890921545748/927946906271887430/W0019f8UlvqD3dDC5.png")
embed.add_field(name="commands.CommandInvokeError", value=error, inline=True)
embed.add_field(name="Maybe...", value="The Extension is Non-Exsistant or cannot be Unloaded", inline=True)
embed.set_footer(text="get a list of Modules with [+modules]!")
await ctx.send(embed = embed, delete_after = 10)
return
elif isinstance(error, commands.MissingPermissions):
await ctx.message.delete()
await ctx.send(f"{ctx.author.mention}, that Command is Admin only!", delete_after = 3)
return
#bot.command()
async def online(ctx):
print("1")
await ctx.channel.send("online")
print("hello")
async def main():
async with bot:
#await load_extensions()
await bot.start("bot auth code")
asyncio.run(main())
Discord.py v2.0 has migrated to api v10, and with this has come the introduction of Intents.message_content, which is disabled by default.
This means that you will need to explicitly enable it in code and in the panel, at https://discord.com/developers/applications.
intents = discord.Intents.default()
intents.members = True
intents.message_content = True
bot = commands.Bot(command_prefix='+', intents=intents)

When I use the play command on my discord bot nothing happens

I am new to using discord.py but have experience using python. I am currently working on a discord music bot using discord.py and when I use the command "*play (song name)" nothing happens even though the bot is in the VC. I want the bot to be able to search youtube for the user's request and play it like any other music bot on discord like Rythum or Groovy. Any other suggestions you have for the code would be greatly appreciated as well. Thanks!
here is my code:
import discord
from discord.ext import commands, tasks
import youtube_dl
import asyncio
from random import choice
client = commands.Bot(command_prefix='*')
queue=[]
status = '18 Naked Cowboys'
#client.event
async def on_ready():
print("Rancher is online!")
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching,name=status))
#client.command(name='ping',help='This command will show that my ping is superior than yours!')
async def ping(ctx):
await ctx.send(f'**Pong!** Latency: {round(client.latency * 1000)}ms')
#client.command(name='hello',help='This command returns a random the welcome message!')
async def hello(ctx):
responses = ['***grumble*** Why you wake me up?!','Penis']
await ctx.send(choice(responses))
youtube_dl.utils.bug_reports_message = lambda: ''
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
#classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
#client.command(name='join', help='This command makes the bot join the voice channel')
async def join(ctx):
if not ctx.message.author.voice:
await ctx.send("You are not connected to a voice channel")
return
else:
channel = ctx.message.author.voice.channel
await channel.connect()
#client.command(name='queue', help='This command adds a song to the queue')
async def queue_(ctx, url):
global queue
queue.append(url)
await ctx.send(f'`{url}` added to queue!')
#client.command(name='remove', help='This command removes an item from the list')
async def remove(ctx, number):
global queue
try:
del(queue[int(number)])
await ctx.send(f'Your queue is now `{queue}!`')
except:
await ctx.send('Your queue is either **empty** or the index is **out of range**')
#client.command(name='play', help='This command plays songs')
async def play(ctx):
global queue
server = ctx.message.guild
voice_channel = server.voice_client
async with ctx.typing():
player = await YTDLSource.from_url(queue[0], loop=client.loop)
voice_channel.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send('**Now playing:** {}'.format(player.title))
del(queue[0])
#client.command(name='pause', help='This command pauses the song')
async def pause(ctx):
server = ctx.message.guild
voice_channel = server.voice_client
voice_channel.pause()
#client.command(name='resume', help='This command resumes the song!')
async def resume(ctx):
server = ctx.message.guild
voice_channel = server.voice_client
voice_channel.resume()
#client.command(name='view', help='This command shows the queue')
async def view(ctx):
await ctx.send(f'Your queue is now `{queue}!`')
#client.command(name='leave', help='This command stops makes the bot leave the voice channel')
async def leave(ctx):
voice_client = ctx.message.guild.voice_client
await voice_client.disconnect()
#client.command(name='stop', help='This command stops the song!')
async def stop(ctx):
server = ctx.message.guild
voice_channel = server.voice_client
voice_channel.stop()
client.run('')
You haven't assign anything to queue list. So you might need to modify play function a bit and append the url from user input to your queue. Here is an example of what the user will input *play https://youtube.com/watch?v=abcdefghij. And here's the code:
#client.command(name='play', help='This command plays songs')
async def play(ctx, *, search_url):
global queue
queue.append(search_url)
server = ctx.message.guild
voice_channel = server.voice_client
async with ctx.typing():
player = await YTDLSource.from_url(queue[0], loop=client.loop)
voice_channel.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send('**Now playing:** {}'.format(player.title))
del(queue[0])

Reroll Giveaway command not responding when command run?

I am trying to make a discord giveaway reroll command.
The problem is that when the command is run it is not responding/rerolling the giveaway.
I've looked on multiple sites with the same command and all of them did not work/have a fix for this.
I also tried without the embeds to see if that was the problem with the code.
Below is the reroll command code -
(if the giveaway command code is needed I can provide it)
#client.command()
#commands.has_permissions(kick_members=True)
async def reroll(ctx, channel : discord.TextChannel, id_ : int):
try:
new_msg = await channel.fetch_message(id_)
except:
embed = discord.Embed(title="Command Error ⛔ - GameBot", description=f"**The Id Of A Channel Was Entered Incorrectly!** 🎉", color=0x992d22)
await ctx.send(embed=embed)
return
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(client.user))
winner = random.choice(users)
embed = discord.Embed(title="Giveaways 🎉 - GameBot", description=f"**Giveaway Has Been Rerolled!** \n \n**Winner -** \n`{winner.mention}`", color=0xe74c3c)
await ctx.send(embed=embed)
Below is the giveaway command code -
#client.command()
#commands.has_permissions(kick_members=True)
async def giveaway(ctx):
embed = discord.Embed(title="Giveaway Setup 🎉 - GameBot", description=f'**{ctx.author.mention} Giveaway Setup Is Now Starting... Please Answer These Questions Within 30 Seconds!**', color=0xe74c3c)
await ctx.send(embed=embed)
questions = ["**What Channel Should The Giveaway Be Hosted In?** `EX : #general` 🎉",
"**What Is The Duration Of The Giveaway?** `EX : S/M/H/D` 🎉",
"**What Is The Giveaway Prize?** `EX : Gift Card` 🎉"]
answers = []
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
for i in questions:
await ctx.send(i)
try:
msg = await client.wait_for('message', timeout=30.0, check=check)
except asyncio.TimeoutError:
embed = discord.Embed(title="Command Error ⛔ - GameBot", description=f"**Please Answer All Of The Questions In Time... Be Prepared!** 🎉", color=0x992d22)
await ctx.send(embed=embed)
else:
answers.append(msg.content)
try:
c_id = int(answers[0][2:-1])
except:
embed = discord.Embed(title="Command Error ⛔ - GameBot", description=f"**Please Provide A Valid Channel For Me To Host The Giveaway In!** `EX : #general` 🎉", color=0x992d22)
await ctx.send(embed=embed)
return
channel = client.get_channel(c_id)
time = convert(answers[1])
if time == -1:
embed = discord.Embed(title="Command Error ⛔ - GameBot", description=f"**The Time Constraint You Answered With Was Not A Valid Unit!** `EX : S/M/H/D` 🎉", color=0x992d22)
await ctx.send(embed=embed)
return
elif time == -2:
embed = discord.Embed(title="Command Error ⛔ - GameBot", description=f"**The Time Must Include An Integer!** `EX : 1S, 1M, 1H, 1D` 🎉", color=0x992d22)
await ctx.send(embed=embed)
return
prize = answers[2]
embed = discord.Embed(title="Giveaway Setup 🎉 - GameBot", description=f'**Giveaway Channel -** \n`{channel.mention}` \n**Duration -** \n`{answers[1]}`', color=0xe74c3c)
await ctx.send(embed=embed)
givembed = discord.Embed(title="Giveaways 🎉 - GameBot", description=f'**Giveaway Prize/Description -** \n`{prize}`', color=0x2ecc71)
givembed.add_field(name = "**Host -**", value=ctx.author.mention)
givembed.set_footer(text = f"Ending {answers[1]} From Now! 🎉")
my_msg = await channel.send(embed=givembed)
await my_msg.add_reaction("🎉")
await asyncio.sleep(time)
new_msg = await channel.fetch_message(my_msg.id)
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(client.user))
winner = random.choice(users)
embed = discord.Embed(title="Giveaways 🎉 - GameBot", description=f"**Giveaway Has Ended!** \n \n**Winner -** \n`{winner.mention}` \n**Prize -** \n`{prize}`", color=0xe74c3c)
await ctx.send(embed=embed)
Almost everything about the code is correct. However I guess you are requesting the users in a wrong/not working way. You can try to request the users in another way, this seems to be the source where the error comes from.
Try out the following:
users = [u for u in await new_msg.reactions[0].users().flatten() if u != client.user]
winner = random.choice(users)
The full code would be:
#client.command()
#commands.has_permissions(kick_members=True)
async def giveaway(ctx):
# Giveaway code
#client.command()
#commands.has_permissions(kick_members=True)
async def reroll(ctx, channel: discord.TextChannel, id_: int):
try:
new_msg = await channel.fetch_message(id_)
except:
embed = discord.Embed(title="Command Error ⛔ - GameBot",
description=f"**The Id Of A Channel Was Entered Incorrectly!** 🎉", color=0x992d22)
await ctx.send(embed=embed)
return
user_list = [u for u in await new_msg.reactions[0].users().flatten() if u != client.user]
winner = random.choice(user_list)
embed = discord.Embed(title="Giveaways 🎉 - GameBot",
description=f"**Giveaway Has Been Rerolled!** \n \n**Winner -** \n`{winner.mention}`",
color=0xe74c3c)
await ctx.send(embed=embed)

Discord bot ctx is being displayed as argument

Thats a test code where im trying to work in classes. Even tho in commands it displayes ctx as required arg instead and it works only if i put it before self.
class Quiz:
def __init__(self, question, answer):
self.question = question
self.answer = answer
#bot.command(pass_context=True)
async def quiz(self, ctx):
fido = Quiz("Starter mass?", "yeah")
nope = Quiz("WHAT?", "lel")
await ctx.send(fido.question)
def check(m):
return m.content == 'heh'
msg = await bot.wait_for('message', check=check)
await ctx.send('Right {.author}!'.format(msg))
Error:
discord.ext.commands.errors.MissingRequiredArgument: ctx is a required argument that is missing.
How can I fix this?
As crazy as it sounds, remove the self argument from your method. The commands decorator will take care of this. (You can also use a command cog)
class Quiz:
def __init__(self, question, answer):
self.question = question
self.answer = answer
#bot.command(pass_context=True)
async def quiz(ctx):
fido = Quiz("Starter mass?", "yeah")
nope = Quiz("WHAT?", "lel")
await ctx.send(fido.question)
def check(m):
return m.content == 'heh'
msg = await bot.wait_for('message', check=check)
await ctx.send('Right {.author}!'.format(msg))
Also your check function doesn't work correctly. It always uses the fido question and says you are correct only after responding with 'heh'.
#bot.command(pass_context=True)
async def quiz(ctx):
fido = Quiz("Starter mass?", "yeah")
nope = Quiz("WHAT?", "lel")
question = random.choice((fido, nope))
await ctx.send(question.question)
check = lambda m: m.content.lower() == question.answer
msg = await bot.wait_for('message', check=check)
await ctx.send(f'Right **{msg.author.name}**!')

Resources