Discord.py Bot send messages at certain times - python

I host a discord.py bot on a server for me and some friends, and have been trying to get a certain 'feature', where the bot will send a message every day, twice daily, once in the morning, once in the night, just saying general "good morning" and "good night!" I have spent hours looking through other peoples codes, and similar questions, and this is the best I can find/have gotten (It's taken from another user's 'python alarm', and I tried to hook it up to the bot.
from datetime import datetime
from threading import Timer
x = datetime.today()
y = x.replace(hour=21, minute=45, second=40, microsecond=0)
delta_t = y - x
secs = delta_t.seconds + 1
channel = client.get_channel(806702411808768023)
async def Goodnight():
await channel.send("Good night! Make sure to go to sleep early, and get enough sleep!")
print("Night Working")
t = Timer(secs, Goodnight)
t.start()
I keep getting the same error(s), usually about the message not being async or await-'able' (?). I am fairly new to coding/python, sorry if anything is obvious. I really do not know what to do, and I have found some promising solutions, though those make the whole bot the alarm, and force it to 'sleep' while waiting, while I want mine to still function normally (run other commands), if possible? Any help appreciated

This can be done using the tasks extension:
import datetime
import discord
from discord.ext import tasks
client = discord.Client()
goodNightTime = datetime.time(hour=21, minute=45, second=40) #Create the time on which the task should always run
#tasks.loop(time=goodNightTime) #Create the task
async def Goodnight():
channel = client.get_channel(806702411808768023)
await channel.send("Good night! Make sure to go to sleep early, and get enough sleep!")
print("Night Working")
#client.event
async def on_ready():
if not Goodnight.is_running():
Goodnight.start() #If the task is not already running, start it.
print("Good night task started")
client.run(TOKEN)
Note that for that to work you need to have the latest version of either discord.py or a fork which supports version 2.0. If you don't have it yet, you can install it via
pip install -U git+https://github.com/Rapptz/discord.py

Related

Discord bot, current date as status

i have looked a bit and tried multiple things and im stumped. Im going to be hosting a discord bot 24/7 and i want the Status to display the current date and time, as example. 11/30/22, 10:51 PM, in eastern time. Thanks!
tried methods such as "
activity=discord.Game(datetime.datetime.utcnow().strftime("%H:%M")),"
You can use tasks.loop, creating a task that updates every minute and changes the bot's Status to the current time.
tasks.loop is a decorator which executes the decorated function repeatedly at a defined interval. Then you just need to spawn the loop in an asynchronous context, of which I personally use setup_hook in this example.
from discord.ext import tasks
import datetime
#tasks.loop(minutes=1):
async def set_status(): # name is unimportant, but it must not take arguments
name = datetime.datetime.utcnow().strftime("%H:%M")
activity = discord.Game(name=name)
await client.change_presence(activity=activity)
#client.event
async def setup_hook(): # name is important, and it must not take arguments
set_status.start()
Replacing client with the name of your client as appropriate (usually client or bot).

Discord Bot, Sending A Message Every 24 Hours

I would like to ask anyone who knows Python. I plan to make my discord bot send a certain message at a certain time. I was planning on making it remind me and other people for a certain occasion. On my end, I would like the bot to send that message every 24 hours. My code works when looping the message however, it only works when I use minutes or seconds. If I try to input days or hours, it won't work. I also tried to input the number of minutes/seconds for 24 hours and it wouldn't work as well. Below this text would be my code. Does anyone here know how to solve this, or at least find an alternate solution? I'm quite unsure of how to work with tasks and loops. I give you my thanks in advance.
#tasks.loop(hours=24)
async def e():
await client.get_channel(channel id here).send("#everyone It's A New Day!")
#e.before_loop
async def before_e():
await client.wait_until_ready()
e.start()
You can use Advanced Python Scheduler for doing it in a better way.
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
async def sendNewDayMessage():
await client.get_channel(channel_id).send("#everyone It's A New Day!")
sched = AsyncIOScheduler()
sched.start()
sched.add_job(sendNewDayMessage, CronTrigger(hour=0, minute=0, second=0)) #on 00:00

Discord Rich presence

So basically I'm trying to have my account on discord online 24/7 so I wrote a bit code for that in python, now I want to add a rich presence, with a timer (how much time elapsed since I started the game) a game title, a large image key and all of that stuff and I have no idea how to write it, anyone knows how to help?
My code so far in main.py...
from discord.ext import tasks, commands
client = commands.Bot(
command_prefix=':',
self_bot=True
)
game = discord.Game("Game Title")
#client.event
async def on_connect():
await client.change_presence(status=discord.Status.online, activity=game)
keep_alive.keep_alive()
client.run(os.getenv("TOKEN"), bot=False)```
Using self bots is actually against the terms of service. Instead of using discord.py use pypresense You can do a lot more with it.
This is an example of time elapsed
from pypresence import Presence
import time
"""
You need to upload your image(s) here:
https://discordapp.com/developers/applications/<APP ID>/rich-presence/assets
"""
client_id = "client_id" # Enter your Application ID here.
RPC = Presence(client_id=client_id)
RPC.connect()
# Make sure you are using the same name that you used when uploading the image
start_time=time.time() # Using the time that we imported at the start. start_time equals time.
RPC.update(large_image="LARGE_IMAGE_HERE", large_text="Programming B)",
small_image="SMALL_IMAGE_HERE", small_text="Hello!", start=start_time) # We want to apply start time when you run the presence.
while 1:
time.sleep(15) #Can only update presence every 15 seconds
You can install it using pip install pypresence
I know this is an old question, and I am sorry if this is not what you are looking for, but discord.py is not made for user-bots (atleast not intended), I recommend using something like lewdneko's pypresence. It has bizzare compatibility/detection (Linux, especially Arch) issues but when it works, it works very well actually. It also has an attribute for time_elapsed, which you can use with something like time.time(). (afaik)

Running multiple commands with discord.py

Using discord.py and python:
Ok so basically I have this bot that updates the best prices for a certain game every minute. However, while I am doing that, other people cannot access the bot. For example, lets just say I have a command called "hello" that when called prints hello out in the chat. Since the code always runs, the user cant call the command hello because the code is too busy running the code that updates every minute. Is there any way to like make it so that the updateminute code runs while others can input commands as well?
import discord
import asyncio
import bazaar
from discord.ext import commands, tasks
client = commands.Bot(command_prefix = '.')
#client.command()
async def calculate(ctx):
while True:
await ctx.send(file2.calculate())
await asyncio.sleep(210)
#client.command()
async def hello(ctx):
await ctx.send("Hello")
client.run(token)
In file2.py:
def updateminute():
for product in product_list:
#Grab Api and stuff
#check to see whether it is profitable
time.sleep(0.3) #cause if i don't i will get a key error
#calculate the stuff
#return the result
To sum up, since the bot is too busy calculating updateminute and waiting, other people cannot access the bot. Is there any way I can try to fix this so that the bot calculates its stuff and so people can use the bots commands? Thanks!
You can look into threading! Basically, run two separate threads: one for taking requests and one for updating the prices.
You could also look into turning it into an async function, essentially making it easier to run things concurrently.
So your standard def will become async def and then to call the function you simply add an await before it so await file2.calculate()
Hope it helps and is also somewhat easier to understand

Make bot automatically quit after it has done its work

I'd like to use my bot not as a daemon that runs forever, but as a kind of "shell script". So it should automatically quit after it has done its work.
My approach so far in Python 3.5 / Python 3.6:
import discord
TOKEN = '<redacted>'
client = discord.Client()
#client.event
async def on_ready():
for member in client.get_all_members():
print(member.display_name)
# please, please quit now!
client.run(TOKEN)
What I want here is, that the script should just quit after printing all the members' display_names, so I can further process them elsewhere. At the moment it DOES print the desired information, but continues to run forever.
Answering my question myself:
Just replace the line # please, please quit now! with await client.logout() does the job.

Categories