How to add Time in Discord Bot? - python

How do you make a bot function so that the bot deletes the chat at 0 o'clock (the channel) how do you include times in the bot (Discord.py)
Please with example :)
thanks
I tried it with google but didnt work so please help

Just use the discord.ext.tasks extension! Just implement this example in your code and modify it so that it fits your variables!
from discord.ext import tasks
from datetime import time #This at your import statements
purge_loop.start() # This cog_load function
#tasks.loop(time=time(hour=0, minute=0)) #this function in your cog
async def purge_loop(self):
await channel.purge(limit=1000)

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.py 8ball command but without bot prefix

I'm coding a bot for a friend and they have asked me to make an 8ball command. You think it seems easy.. but they don't want the prefix included the command. So it would be like this:
BotName, do you think today will be a good day?
I've tried using #client.event but I don't know how to make it so that the user can say their own question, but have the bots name at the front of the question.
So like this:
BotName, do you think today will be a good day?
The BotName part will need to be included to trigger the event. Then they can say what they want. Like this (example was already given above):
BotName, do you think today will be a good day?
Here is some code I tried:
import discord
from discord.ext import commands
import random
class eightball(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_message(self,message):
#botname = [f"BotName, {message}?"] #tried this too
# if message.content in botname: #tried this too
if f'BotName, {message.author.content}?' in message.content:
responses = ['Responses here.']
await message.channel.send(f'{random.choice(responses)}')
await self.client.process_commands(message)
def setup(client):
client.add_cog(eightball(client))
If it's not possible then do not worry! (Sorry if I didn't explain as well as I could and if I sound dumb or something.)
I guess you can make it work with a bit more logic.
if message.content.startswith('BotName,'):
#rest of the code
Consider that if they # your bot, the string would be <#1235574931>, do you think today will be a good day?
So, it'll only work if they add specifically whatever BotName would be.
Also, cog listeners doesn't need await self.client.process_commands(message)
You might use events for your bot. Try to do this.
#command.Cog.listener()
async def on_message(self, message, question):
if message.content.startswith("8ball"):
answers=["yes", "no", "maybe"]
await message.channel.send(random.choice(answers)
Don’t forget to import random like this:
import random

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

Call function from another file - Discord bot

I am not familiar with Discord bots or much of Python so here's a simple question I can't figure out the answer to.
I have two files; discord_bot.py and test.py
How do I forward a message from test.py to send it to a channel in Discord?
test.py
import discord_bot
discord_bot.signal(msg = "Hi")
discord_bot.py
import discord
from discord.ext import commands
TOKEN = '1234567890'
bot = commands.Bot(command_prefix='!')
#bot.command()
async def signal(ctx, *, msg):
await ctx.send(msg)
The Discord bot works fine but calling the signal function from test is not the correct way to do it. Any help here please?
This is a lot to unpack.
0. Never post your discord token online. Discord may automatically invalidate your token if it's posted online.
1. You are not running your bot at the moment, add bot.run(TOKEN) at the end
2. How the commands of the discord bot extension work
#bot.command() is a decorator, if you do not know how they work, read up on it. Overly simplified, they take your function and register in the bot.
The inner workings of the commands extension are basically:
Register all commands by loading the decorators
Whenever a message arrives, check if it contains a prefix and if so, check if it fits a command.
If both checks from 2 passed, construct a Context object, then pass that object to the function. Something like the following:
signal(ctx, *args)
This is why the ctx object can't be positional, because the way the function is called in the inner workings of the bot as a normal argument.
4. Do not try to mess with creating your own context object, unless you know what you're doing. You only need to create context objects if you're overriding the default message parser.
5. Don't use commands for this.
What you want to do, as far as I can tell:
Call a command yourself. This is easy enough:
file 1:
#bot.command()
async def signal(ctx, *, msg):
print(msg)
file 2:
from file1 import signal
import asyncio # if you don't know asyncio, read up on it
asyncio.run(signal(None, 'This is an argument'))
This works easily, it prints your stuff. But you don't want it to be printed, right? You want it to be sent in a channel. This is what you need the context object for, which I said before, to not construct yourself. So how do we actually do this?
The answer is: Don't use commands. They are used for reacting to messages, not to be called by themselves.
6. The solution you (probably) want
So the major changes here are:
signal is now a normal async function with no decorator
We actually specify a channel where we want the stuff to be sent in as an argument of the function
file 1:
import discord
from discord.ext import commands
TOKEN = 'do not share your token online'
bot = commands.Bot(command_prefix='!')
# as the channel_id, pass the channel_id you want the message to be sent in
async def signal(msg, channel_id):
global bot # getting our bot variable from the global context
channel = bot.get_channel(channel_id)
await channel.send(msg)
bot.run(TOKEN)
Major changes here are:
We use asyncio.run to call the function. Async functions cannot be called with regular syntax.
You'll probably need to run file2.py to start the program. Running file1 will not load file2.
file 2
from file1 import signal
from time import sleep
import asyncio
sleep(5) # We need to give our bot time to log in, or it won't work
asyncio.run(signal('hi!', 123))

Categories