How can i make presences loop? - python

How can i make presences loop? I want it to change presence every 5-10 sec.
client = commands.Bot(command_prefix=commands.when_mentioned_or(","))
async def presenced():
presences = ["Prefix: ,", "Over people!"]
activity = discord.Activity(
name=random.choice(presences), type=discord.ActivityType.watching)
await client.change_presence(activity=activity)
client.loop.create_task(presenced())

If you didn't already find an answer I got something that should work.
import discord
from discord.ext import commands
import asyncio
import random
client = commands.Bot(command_prefix=commands.when_mentioned_or(","))
async def on_ready():
print("client is online!") # you can add other things to this on_ready listener
client.loop.create_task(presenced()) # start the presenced task when the bot is ready
client.add_listener(on_ready)
async def presenced():
while True:
presences = ["Prefix: ,", "Over people!"]
await client.change_presence(activity=discord.Activity(name=random.choice(presences), type=discord.ActivityType.watching))
await asyncio.sleep(10) # you can of course add some randomizer to this delay
client.run("bot token here :)")

Related

How do you make a bot that sends a welcome embed and deletes the embed after a few seconds in discord.py

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.

How to make a constantly changing Discord bot rich presence in discord.py?

So, I'm making a Discord bot. It works fine and the commands work too. What I'm trying to do is make the status, aka rich presence, constantly changing. For example, /h > 1 sec later > /he > 1 sec later > /hel > one sec later > /help and then just keep repeating that. So, I thought I would put it in a while True: loop. But, that would obviously stop the rest of the bot from functioning. Then, I thought I would use threading, but that also doesn't work(or maybe I'm doing it wrong). Then, I put the forever loop in the on_ready() function, and the status works, but it pauses for 15 seconds after it goes through a few characters. Also, it stops the rest of the bot meaning commands wouldn't work either. I'm not really sure what else to do.
Code:
import os
import random
import discord
from dotenv import load_dotenv
import time
from threading import Thread
from website import main
load_dotenv()
TOKEN= os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('GUILD_NAME')
print(TOKEN)
client = discord.Client()
async def update_presence():
while True:
await client.change_presence(activity=discord.Game(name='/h'))
time.sleep(1)
await client.change_presence(activity=discord.Game(name='/he'))
time.sleep(1)
await client.change_presence(activity=discord.Game(name='/hel'))
time.sleep(1)
await client.change_presence(activity=discord.Game(name='/help'))
time.sleep(1)
#client.event
async def on_ready():
await client.change_presence(activity=discord.Game('/help'))
print(f'{client.user} has connected to Discord!')
main()
t = Thread(target=update_presence)
t.start()
client.run(TOKEN)
Mixing coroutines and Threading is a bad idea, also time.sleep is a blocking function, use asyncio.sleep instead:
import asyncio
async def update_presence():
while True:
await client.change_presence(activity=discord.Game(name='/h'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game(name='/he'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game(name='/hel'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game(name='/help'))
await asyncio.sleep(1)
And then use loop.create_task to create a background task
bot.loop.create_task(update_presence())
Another option would be to use the discord.py extension tasks
from discord.ext import tasks
#tasks.loop(seconds=1)
async def update_presence():
await client.change_presence(activity=discord.Game(name='/h'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game(name='/he'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game(name='/hel'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game(name='/help'))
update_presence.start()
References:
asyncio.sleep
loop.create_task
tasks.loop
Loop.start

Programming a Discord bot in Python- How do I make it send a message every day at a certain time?

I want to make the bot send a message every day at 1pm. Here's my code:
#tasks.loop(hours=24)
async def called_every_day():
channel = client.get_channel(800476409587171369)
print(f"Got channel {channel}")
await channel.send("Your message")
#called_every_day.before_loop
async def before():
await client.wait_until_ready()
print("Finished waiting")
called_every_day.start()
This works, if I start up the bot at 1pm. However, any time I edit the code and restart the bot, it restarts the loop. I want to prevent this from happening, how would I go about doing so? I'm new to programming, so any insight would be greatly appreciated.
You can use APScheduler and Cron to schedule your commands to be sent at a specific time, like 12:00 PM
Docs: https://apscheduler.readthedocs.io/en/stable/, https://apscheduler.readthedocs.io/en/stable/modules/triggers/cron.html
Here is an example:
# Async scheduler so it does not block other events
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
from discord.ext import commands
import discord
bot = commands.Bot(command_prefix="!")
async def func():
await bot.wait_until_ready()
c = bot.get_channel(800476409587171369)
await c.send("Your Message")
#bot.event
async def on_ready():
print("Ready")
# Initializing scheduler
scheduler = AsyncIOScheduler()
# Executes your function at 24:00 (Local Time)
scheduler.add_job(func, CronTrigger(hour="24", minute="0", second="0"))
# Starting the scheduler
scheduler.start()

change discord.py bot status

it may hard to me, but i believe on stackoverflow power,
i need to put a number as bot status on my bot.
Here : http://gamers-control-2.000webhostapp.com/count.txt
Also Pic of it : Picture
#time to show status = text that founded in blank website = "41"
#http://gamers-control-2.000webhostapp.com/count.txt
#some how, you say i can type the number, i say the number in web it
change everytime, so i need to get that number to show it as bot status.
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
import time
import random
from discord import Game
Client = discord.client
client = commands.Bot(command_prefix = '!')
Clientdiscord = discord.Client()
#client.event
async def on_ready():
await client.change_presence(game=discord.Game(name=http://gamers-control-2.000webhostapp.com/count.txt, type=3))
print('test ready')
client.run("....")
im new with discord.py
You need to first import requests at the beginning
import requests
Then before the ready event
count = requests.get('http://gamers-control-2.000webhostapp.com/count.txt')
And then you set it to
await client.change_presence(game=discord.Game(name=count.text, type=3))
I use await bot.change_presence() like this:
NOTICE:
I am leaving out part of my code
#bot.event
async def on_ready():
replit.clear()
print(f'Logged in as {bot.user.name} - {bot.user.id}')
bot.remove_command('help')
await bot.change_presence(status=discord.Status.online, activity=discord.Game("mod help"))
This is what i use
async def on_ready():
print(f'We have logged in as {bot.user}')
print('Ready!')
return await bot.change_presence(activity=discord.Activity(type=3, name='Add status here'))```

Commands with arguments using Discord.py

import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
import time
import random
from PIL import Image
Client = discord.Client()
client = commands.Bot(command_prefix = "-")`
#client.command
async def spam(ctx, arg):
count = 0
await Context.send(message.channel, "Wait for it....")
time.sleep(3)
while count < 20:
await ctx.send(arg)
time.sleep(3)
count = count + 1
This code is supposed to mention the person specified in the argument. For example if someone typed -spam #Bob the bot should say
#Bob
#Bob 20 times
There's no need to instantiate both discord.Client and commands.Bot. Bot is a subclass of Client.
Bot.command is a function that returns a decorator, not itself a decorator. You need to call it to use it to decorate a coroutine:
#client.command()
You should probably be using a converter to acquire the user you're pinging.
Context is the class that ctx is an instance of. You should be accessing all of the methods through ctx.
Don't use time.sleep, as it blocks the event loop. Await asyncio.sleep instead.
from discord.ext.commands import Bot
from asyncio import sleep
from discord import User
client = Bot(command_prefix = "-")
#client.command()
async def spam(ctx, user: User):
await ctx.send("Wait for it....")
await sleep(3)
for _ in range(20):
await ctx.send(user.mention)
await sleep(3)
client.run("token")

Categories