Making a bot that sends messages at a scheduled date with Discord.py
Question:
I’m trying to make a bot that sends a scheduled message to a specific text channel.
for example at the date of my birthday saying “happy birthday”, or also every morning saying “Good morning”.
The bot seems to don’t work since nothing appears in my text channel.
import discord,random,asyncio,os
from datetime import datetime
from discord.ext import commands
token = '#mytokenhere'
bot=commands.Bot(command_prefix='!')
send_time='01:41' #time is in 24hr format
message_channel_id='0000000000000' #channel ID to send images to
@bot.event
async def on_ready():
print(bot.user.name)
print(bot.user.id)
async def time_check():
await bot.wait_until_ready()
message_channel=bot.get_channel(message_channel_id)
while not bot.is_closed:
now=datetime.strftime(datetime.now(),'%H:%M')
if now.hour() == 1 and now.minute() == 52:
message= 'a'
await message_channel.send(message)
time=90
else:
time=1
await asyncio.sleep(time)
bot.loop.create_task(time_check())
bot.run('token')
Answers:
Here’s how you would do something like this using the tasks
extension
from discord.ext import commands, tasks
bot = commands.Bot("!")
target_channel_id = 1234
@tasks.loop(hours=24)
async def called_once_a_day():
message_channel = bot.get_channel(target_channel_id)
print(f"Got channel {message_channel}")
await message_channel.send("Your message")
@called_once_a_day.before_loop
async def before():
await bot.wait_until_ready()
print("Finished waiting")
called_once_a_day.start()
bot.run("token")
You can also try to use aiocron.
pip install aiocron
https://github.com/gawel/aiocron
Add below to your bot code before the bot.run(TOKEN)
import aiocron
CHANNEL_ID=1234
@aiocron.crontab('0 * * * *')
async def cornjob1():
channel = bot.get_channel(CHANNEL_ID)
await channel.send('Hour Cron Test')
If you are using discord 2.0 Read the docs.
https://discordpy.readthedocs.io/en/latest/migrating.html#asyncio-event-loop-changes
from discord.ext import commands
import aiocron
TOKEN = 'YOUR TOKEN'
BOT_CHANNELS = 000000000000000000
# you can also import this from else where.
class cronjobs():
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
# print Hello world 20secs.
@aiocron.crontab("* * * * * */20")
async def HelloWorld():
await bot.get_channel(BOT_CHANNELS).send("Hello World!")
class aBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix='>', help_command=None)
async def setup_hook(self):
cron = cronjobs(self)
async def close(self):
await super().close()
bot = aBot()
bot.run(TOKEN)
You can also do it like this (in case someone stomps on this post):
import discord
import os
import asyncio
from discord.ext import commands, tasks
from datetime import datetime, timedelta
client = discord.Client()
def seconds_until_midnight():
now = datetime.now()
target = (now + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0)
diff = (target - now).total_seconds()
print(f"{target} - {now} = {diff}")
return diff
@tasks.loop(seconds=1)
async def called_once_a_day_at_midnight():
await asyncio.sleep(seconds_until_midnight())
message_channel = client.get_channel(CHANNEL_ID)
print(f"Got channel {message_channel}")
await message_channel.send("Your message here")
@called_once_a_day_at_midnight.before_loop
async def before():
await client.wait_until_ready()
print("Finished waiting")
client = discord.Client()
called_once_a_day_at_midnight.start()
client.run(os.environ['BOT_TOKEN'])
discord.py
supports scheduling tasks at a specific time after 1.1.0
release. I explained the details in the below answer.
discord.py how to send a message everyday at a specific time
I’m trying to make a bot that sends a scheduled message to a specific text channel.
for example at the date of my birthday saying “happy birthday”, or also every morning saying “Good morning”.
The bot seems to don’t work since nothing appears in my text channel.
import discord,random,asyncio,os
from datetime import datetime
from discord.ext import commands
token = '#mytokenhere'
bot=commands.Bot(command_prefix='!')
send_time='01:41' #time is in 24hr format
message_channel_id='0000000000000' #channel ID to send images to
@bot.event
async def on_ready():
print(bot.user.name)
print(bot.user.id)
async def time_check():
await bot.wait_until_ready()
message_channel=bot.get_channel(message_channel_id)
while not bot.is_closed:
now=datetime.strftime(datetime.now(),'%H:%M')
if now.hour() == 1 and now.minute() == 52:
message= 'a'
await message_channel.send(message)
time=90
else:
time=1
await asyncio.sleep(time)
bot.loop.create_task(time_check())
bot.run('token')
Here’s how you would do something like this using the tasks
extension
from discord.ext import commands, tasks
bot = commands.Bot("!")
target_channel_id = 1234
@tasks.loop(hours=24)
async def called_once_a_day():
message_channel = bot.get_channel(target_channel_id)
print(f"Got channel {message_channel}")
await message_channel.send("Your message")
@called_once_a_day.before_loop
async def before():
await bot.wait_until_ready()
print("Finished waiting")
called_once_a_day.start()
bot.run("token")
You can also try to use aiocron.
pip install aiocron
https://github.com/gawel/aiocron
Add below to your bot code before the bot.run(TOKEN)
import aiocron
CHANNEL_ID=1234
@aiocron.crontab('0 * * * *')
async def cornjob1():
channel = bot.get_channel(CHANNEL_ID)
await channel.send('Hour Cron Test')
If you are using discord 2.0 Read the docs.
https://discordpy.readthedocs.io/en/latest/migrating.html#asyncio-event-loop-changes
from discord.ext import commands
import aiocron
TOKEN = 'YOUR TOKEN'
BOT_CHANNELS = 000000000000000000
# you can also import this from else where.
class cronjobs():
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
# print Hello world 20secs.
@aiocron.crontab("* * * * * */20")
async def HelloWorld():
await bot.get_channel(BOT_CHANNELS).send("Hello World!")
class aBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix='>', help_command=None)
async def setup_hook(self):
cron = cronjobs(self)
async def close(self):
await super().close()
bot = aBot()
bot.run(TOKEN)
You can also do it like this (in case someone stomps on this post):
import discord
import os
import asyncio
from discord.ext import commands, tasks
from datetime import datetime, timedelta
client = discord.Client()
def seconds_until_midnight():
now = datetime.now()
target = (now + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0)
diff = (target - now).total_seconds()
print(f"{target} - {now} = {diff}")
return diff
@tasks.loop(seconds=1)
async def called_once_a_day_at_midnight():
await asyncio.sleep(seconds_until_midnight())
message_channel = client.get_channel(CHANNEL_ID)
print(f"Got channel {message_channel}")
await message_channel.send("Your message here")
@called_once_a_day_at_midnight.before_loop
async def before():
await client.wait_until_ready()
print("Finished waiting")
client = discord.Client()
called_once_a_day_at_midnight.start()
client.run(os.environ['BOT_TOKEN'])
discord.py
supports scheduling tasks at a specific time after 1.1.0
release. I explained the details in the below answer.
discord.py how to send a message everyday at a specific time