Channel does not receive dms from User to Bot - discord

I created a ticket system, where a user needs to dm the bot with "ticket". A ticket_channel will be created on the server and the function of all this is, that all the messages, that the user is sending to the bot, the bot sends these messages to the channel in my server. And reversed:
The problem here is that the command "ticket" is working (a new text channel has been created) if the user sends a message, the channel in the server recieves nothing
Can someone help me?
import discord
import asyncio
intents = discord.Intents.all()
client = discord.Client(intents = intents)
ticket_users = {}
#client.event
async def on_message(message):
if message.channel.type == discord.ChannelType.private and message.content.startswith("ticket"):
user = message.author
if user.id in ticket_users:
await user.send("Du hast bereits ein Ticket erstellt. Bitte warte auf eine Antwort oder schließe das Ticket mit close.")
return
else:
ticket_users[user.id] = True
guild = client.get_guild(ID) # Replace GUILD_ID with the ID of the server where you want to create the channel
channel = await guild.create_text_channel(f"ticket-{user.name}")
await channel.send(f"{user.mention} hat ein Ticket erstellt.")
await user.send("Dein Ticket wurde erstellt. Ein Teammitglied wird sich in Kürze bei dir melden.")
def check(m):
return m.author == user and m.channel == channel
while True:
msg = await client.wait_for('message', check=check)
if msg.attachments:
await user.send(msg.content, file=msg.attachments[0])
else:
await user.send(msg.content)
if msg.content.startswith == "close":
del ticket_users[user.id]
await channel.send("Ticket wurde geschlossen.")
await user.send("Dein Ticket wurde geschlossen.")
await channel.delete()
break
client.run("My Token")

Your check function is wrong - you're checking for messages sent in the newly created channel and not the direct message channel.
def check(m):
return m.author == user and m.channel == message.channel.id
Personally, though, I wouldn't be using a while True loop in an on_message function. I would do something like the below.
#client.event
async def on_message(message: discord.Message):
if message.channel.type == discord.ChannelType.private:
user = message.author
if message.content.startswith("ticket"):
if user.id in ticket_users:
await user.send("Du hast bereits ein Ticket erstellt. Bitte warte auf eine Antwort oder schließe das Ticket mit close.")
return
else:
ticket_users[user.id] = {"open": True}
guild = client.get_guild(ID)
channel = await guild.create_text_channel(f"ticket-{user.name}")
await channel.send(f"{user.mention} hat ein Ticket erstellt.")
await user.send("Dein Ticket wurde erstellt. Ein Teammitglied wird sich in Kürze bei dir melden.")
ticket_users[user.id]["channel_id"] = channel.id
else:
# doesn't start with 'ticket'
guild = client.get_guild(ID)
channel_id = ticket_users[user.id]["channel_id"]
channel = guild.get_channel(channel_id)
attachments = None
if msg.attachments:
attachments = msg.attachments[0]
await user.send(msg.content, file=attachments)
if msg.content.startswith == "close":
del ticket_users[user.id]
await channel.send("Ticket wurde geschlossen.")
await user.send("Dein Ticket wurde geschlossen.")
await channel.delete()
I would do something like this; this still retains the original functionality I think.

Related

Bot won't play next song automatically, when the last one ends

I created a simple Music Bot, but there is one problem. When I run the "?play" Command, the Youtube Link is actually playing. Also, if I run the "?play" Command a second time, the link has been safed in the array. So when I run the "?skip" Command, the next YouTube Link has been shown, but if I do the same thing, just without the "?skip" Command, the Bot won't play the new Link automatically, after the first Link ended. Can someone help me please?
import discord
import asyncio
from discord.ext import commands
import youtube_dl
client = commands.Bot(intents=discord.Intents.all(), command_prefix="?", help_command=None)
voice_clients = {}
yt_dl_opts = {'format': 'bestaudio/best'}
ytdl = youtube_dl.YoutubeDL(yt_dl_opts)
ffmpeg_options = {'options': "-vn"}
queue = []
async def play_next(guild_id):
try:
url = queue[0]
loop = asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=False))
song = data['url']
player = discord.FFmpegPCMAudio(song, **ffmpeg_options)
voice_clients[guild_id].play(player)
asyncio.ensure_future(play_next(guild_id))
except Exception as err:
print(err)
#client.command()
async def play(ctx, url: str = None):
print(queue)
if url == None:
await ctx.send("Ich brauche schon irgend ein Link")
return
try:
voice_client = await ctx.author.voice.channel.connect()
voice_clients[voice_client.guild.id] = voice_client
except:
print("Bot ist schon im Voice")
url = url
queue.append(url)
if len(queue) == 1:
await play_next(ctx.guild.id)
else:
await ctx.send("Dein Link wurde erfolgreich in die Warteschlange hinzugefügt!")
print(queue)
#client.command()
async def skip(ctx):
try:
voice_clients[ctx.guild.id].stop()
except Exception as err:
print(err)
queue.pop(0)
if len(queue) >= 1:
await play_next(ctx.guild.id)
else:
await ctx.reply("Es gibt nix abzuspielen")

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 snipe command is sniping messages from other channels

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

Send Server Message after Track Users Status (discord.js)

I try to send a Message in a Server. This Server ID is logged in MongoDB and the Channel ID too. But everytime i'll try it, it does not working. Here's my Code:
The Error is the return console.log Text
//This is the guildMemberUpdate file
const client = require("../index.js")
const {MessageEmbed} = require("discord.js")
const {RED, GREEN, BLUE} = require("../commands/jsons/colors.json")
const Schema = require("../models/StatusTracker.js")
client.on("guildMemberUpdate", async(member) => {
const data = await Schema.findOne({Guild: member.guild.id})
let channel = member.guild.channels.cache.get(data.Channel)
if(!channel) return console.log("Es wurde kein Channels gefunden");
if(member.user.presence.status === "offline") {
let offlineEmbed = new MessageEmbed()
.setColor(RED)
.setDescription(member.user.toString() + " ist jetzt offline!")
.setAuthor(member.user.tag, member.user.avatarURL({ dynamic: true }))
channel.send(offlineEmbed)
} else if(member.user.presence.status === "dnd" || member.user.presence.status === "online" || member.user.presence.status === "idle"){
let onlineEmbed = new MessageEmbed()
.setColor(GREEN)
.setDescription(member.user.toString() + " ist jetzt online!")
.setAuthor(member.user.tag, member.user.avatarURL({ dynamic: true }))
channel.send(onlineEmbed)
}
})```
//This is the MongoDB File
"Guild": "851487615358337065",
"Channel": "859444321975009290"
The problem is that you're using the guildMemberUpdate event, but that only tracks nickname and role changes. The one that you're looking for is presenceUpdate. That'll trigger when any user goes offline etc.
Check the docs for more details: here
Note: You'll probably need to enable 'Presence intent' in 'Privileged Gateway Intents' in your bot's settings page for this to work. (https://discord.com/developers/applications)

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)

Resources