I have been trying to create a bot for Discord using the discord.py library however when I am running the program it is not sending the message as expected. It is a simple bot that is suppose to send a message every 10 minutes to a channel. I am not getting any error messages in the command line and can't seem to see any obvious errors? Any help would be greatly appreciated.
import asyncio
client = discord.Client()
async def my_background_task():
await client.wait_until_ready()
counter = 0
channel = discord.Object(id='my channel ID goes here')
while not client.is_closed:
counter += 1
await message.channel.send("TEST")
await asyncio.sleep(5) # task runs every 60 seconds
#client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
client.loop.create_task(my_background_task())
client.run('My token goes here')
Although creating a task could work, I wouldn't recommend it when there are better options. Dpy's command.ext addon has a task based system built in directly, so let's look into using that instead.
import discord
from discord.ext import tasks
client = discord.Client()
#tasks.loop(minutes=10)
async def my_background_task():
"""A background task that gets invoked every 10 minutes."""
channel = client.get_channel(754904403710050375) # Get the channel, the id has to be an int
await channel.send('TEST!')
#my_background_task.before_loop
async def my_background_task_before_loop():
await client.wait_until_ready()
my_background_task.start()
client.run('Your token goes here')
The time until which the above loop will run is dependent upon human psychology, laws of energy and cosmos.
That is:
• You get bored of it
• The power goes down and your script stops working
• The universe explodes
Read more about it here:
https://discordpy.readthedocs.io/en/latest/ext/tasks/
If the channel ID is a string, It should be an integer.
Turn this:
channel = discord.Object(id='my channel ID goes here')
into:
channel = discord.Object(id=101029321892839) # an example ID
If that doesn't solve your problem, try setting 'message.channel.send' to 'channel.send' and client.is_closed should be
client.is_closed() # put brackets
Instead of client.loop.create_task(my_background_task()), just put the background function in the on_ready event. And take out await client.wait_until_ready() and just put the function in the on_ready event as well.
I have also changed the client variable, taken out unnecessary code, and added some modules.
import asyncio, discord
from discord.ext import commands
client = commands.Bot(command_prefix = ".") # If you don't want a prefix just take out the parameter.
async def my_background_task():
channel = discord.Object(id='my channel ID goes here')
while True:
await channel.send("TEST")
await asyncio.sleep(5) # task runs every 60 seconds
#client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
my_background_task()
client.run('My token goes here')
Also in future when posting a question, please tag the python version as I don't know which version it is and then this and other answers could be wrong.
Related
I am trying to send a message to a specific channel and I can run the code below just nothing show up on the channel and I have no idea why... I put the channel Id in the get_channel input, just putting a random number here.
import discord
client = discord.Client()
async def send_msg(msg):
channel = client.get_channel(123456456788)
await channel.send('hello')
Is the function even called somewhere? Otherwise there could also be an issue with the discord permissions or the Intents.
This is one of many ways to call the function and post 'hello' in some specific channel. No msg parameter is required.
#client.event
async def on_ready():
await send_msg()
async def send_msg():
channel = client.get_channel(123456456788)
await channel.send('hello')
Here's my code but it seems like it doesn't work. I'm so sorry but, I'm still a newbie but, I would very much appreciate your help and critics.
import discord
from discord.ext import commands
client = commands.Bot(command_prefix=prefix,
intents=discord.Intents.all())
#client.event
async def on_message_join(member):
channel = client.get_channel(channelid)
count = member.guild.member_count
embed=discord.Embed(title=f"Welcome to {member.guild.name}", description=f"Hello there {member.name}!", footer=count)
embed.set_thumbnail(url=member.avatar_url)
await channel.send(embed=embed)
time.sleep(5)
message.delete(embed)
The correct discord event to catch that a person joins your discord is:
async def on_member_join(member: discord.Member):
rather than on_message_join
To easily delete the message you can first make it a string:
msg = await channel.send(embed=embed)
then get it's id by:
msg_id = msg.id
then fetch it:
msg_todel = await channel.fetch_message(int(msg_id))
then delete it:
await msg_todel.delete()
Just use delete_after=seconds, this exactly what's your wanted
import discord
from discord.ext import commands
client = commands.Bot(command_prefix=prefix,
intents=discord.Intents.all())
#client.event
async def on_message_join(member):
channel = client.get_channel(channelid)
count = member.guild.member_count
embed=discord.Embed(title=f"Welcome to {member.guild.name}", description=f"Hello there {member.name}!", footer=count)
embed.set_thumbnail(url=member.avatar_url)
await channel.send(embed=embed, delete_after=5)
According to the discord.py docs, you could edit the message object after 5 seconds and then just set the new embed parameter to None, this seems to be what you're after here.
Below is a way you can alter your code to do this.
import discord
import asyncio # You will need to import this as well
from discord.ext import commands
client = commands.Bot(command_prefix=prefix,
intents=discord.Intents.all())
#client.event
async def on_message_join(member):
channel = client.get_channel(channelid)
count = member.guild.member_count
embed=discord.Embed(title=f"Welcome to {member.guild.name}", description=f"Hello there {member.name}!", footer=count)
embed.set_thumbnail(url=member.avatar_url)
message_object = await channel.send(embed=embed) # You can save the message sent by attaching it to a variable. You don't need to send more calls to refetch it.
'''
time.sleep(5) <--- You should not use time.sleep() as it will stop your entire bot from doing anything else during these 5 seconds.
Use asyncio.sleep() as a better alternative. Does the same thing as time.sleep() but other functions of your bot will still function, this is called a blocking function.
'''
asyncio.sleep(5)
await message_object.edit(embed = None)
Unless you want the entire message deleted, then you can just use delete_after in order to obtain this.
import discord
from discord.ext import commands
client = commands.Bot(command_prefix=prefix,
intents=discord.Intents.all())
#client.event
async def on_message_join(member):
channel = client.get_channel(channelid)
count = member.guild.member_count
embed=discord.Embed(title=f"Welcome to {member.guild.name}", description=f"Hello there {member.name}!", footer=count)
embed.set_thumbnail(url=member.avatar_url)
await channel.send(embed=embed, delete_after = 5) # Just add this parameter at the end.
I am brand new to making discord bots, and I'm wanting to make a bot that sends coding challenges for 5 different languages (python, java, javascript, c#, and html). I have set the channels up in my test discord, and I've given the bot admin to be able to read and write in channels, etc. I am trying to figure out how to get it to be on a 24 hour timer, and when that timer reaches zero, it sends out the code challenges for each language to it's corresponding discord channel.
import random
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
TOKEN = ''
#bot.event
async def on_ready():
print(f'{bot.user.name} has connected to Discord!')
#bot.command()
async def hello(ctx, member: discord.member):
await ctx.send(f"Hello {member.name}")
#bot.command()
async def
bot.run(TOKEN)
so far I've been able to bring the bot online, and I've learned how to give it custom commands, but I have zero idea on where to start for what I'm trying to do, and any advice or tips would be greatly appreciated :) TYIA
You can use discord.ext.tasks for a loop that runs every 24 hours. If you have the guild object you can use for channel in guild.channels: and then send the message. You can get the guild object with the id: bot.get_guild(id). All together it would look like this:
import random
import discord
from discord.ext import commands, tasks # Import the tasks module
bot = commands.Bot(command_prefix='!')
TOKEN = ''
#bot.event
async def on_ready():
print(f'{bot.user.name} has connected to Discord!')
challenge.start() # Start the loop
#bot.command()
async def hello(ctx, member: discord.member):
await ctx.send(f"Hello {member.name}")
#tasks.loop(seconds=86400) # Loops every 24h
async def challenge():
guild = await bot.get_guild(id) # Gets the guild object by the id
for channel in guild.channels: # Runs a command in every channel
await channel.send(message) # Says the message
bot.run(TOKEN)
I did not test this and it may not work.
E.g I'm trying to write hello in general chat every 10 seconds. How do I do that? I'm using the task feature.
channel = client.get_channel('channel id')
#tasks.loop(seconds=10)
async def sendmessage():
await channel.send("hello")
You can Start the task with `.start()
channel = client.get_channel('channel id')
#tasks.loop(seconds=10)
async def sendmessage():
await channel.send("hello")
sendmessage.start()
Make sure your "channel id" is an integer, and your code should work as is, assuming you have sendmessage.start() somewhere.
An extra note: you probably want to put your get_channel inside your task. get_channel gets the channel object from the internal cache, so if the cache expires your channel object will too.
You might want to try moving channel into the function, like this:
import discord
import datetime
from discord.ext import commands, tasks
TOKEN = 'token'
client = discord.Client()
#tasks.loop(seconds=10)
async def sendmessage():
channel = client.get_channel('channel id')
await channel.send("hello")
sendmessage.start()
client.run(TOKEN)
The get_channel function only takes integer as input.
import discord
from discord.ext import commands, tasks
bot = commands.Bot('!') # ! = PREFIX
#tasks.loop(seconds=10)
async def sendmessage():
channel = bot.get_channel(123456789) #Channel ID
await channel.send("hello")
sendmessage.start()
bot.run("TOKEN")
You need to put sendmessage.start on your on_ready event.
Example:
#client.event
async def on_ready():
sendmessage.start()
I am trying to make the bot send a message every minute in discord.py. I do acknowledge that this is a easy thing to do but I have tried multiple times but resulting with no luck. I have not gotten any error messages.
Here is my code:
import discord
from discord.ext import tasks
client = discord.Client()
#tasks.loop(minutes=1)
async def test():
channel = client.get_channel(CHANNEL_ID)
channel.send("test")
test.start()
client.run(TOKEN)
You try to get channel with get_channel(), but your bot is not ready yet. So you get NoneType object, not channel. Try to this solution:
#tasks.loop(minutes=1)
async def test():
channel = client.get_channel(CHANNEL_ID)
await channel.send("test")
#client.event
async def on_ready():
test.start()