discord.py restart the command - discord

I am making a discord bot and I tried to make a status command that will make my bot's status start changing, so I thought its working pretty well until I realized that I need it to restart and that I have no idea how to do that, so here is my code without the restart part:
#client.command()
async def status(ctx):
await client.change_presence(activity=discord.Streaming(name='firststatus', url='https://www.twitch.tv/my-channel-name'))
await asyncio.sleep(5)
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name='Secondstatus'))
so I did that but I don't know what to put at the end so it'll restart I guess it will be something like client.command.restart.

You can use a simple while loop or the built-in discord.py extension tasks
from discord.ext import tasks
#tasks.loop(seconds=5)
async def change_status():
await client.change_presence(activity=discord.Streaming(name='firststatus', url='https://www.twitch.tv/my-channel-name'))
await asyncio.sleep(5)
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name='Secondstatus'))
#client.command()
async def status(ctx):
change_status.start()
The change_status function will loop every 5 seconds and change the presence. You can stop it with change_status.stop()
Reference:
tasks.loop
Loop.start
Loop.stop

Related

DIscord Slash Commands Interaction Failed on discord py

async def _ping(ctx): # Defines a new "context" (ctx) command called "ping."
async def command_hi(ctx):
await ctx.defer()
await ctx.send("Pong!")
pass
I was making slash commands and first time it worked but secondtime, it does not work.
I tried await ctx.defer() but it's not working either
Hey #Justnoob I recommend you to use Pycord, It has inbuilt Buttons, Slash, Dropdowns and much more but for now the discord api with application commands is a bit complicated we usually use ctx.send but in app commands it is ctx.respond so here is the code:-
async def ping(ctx): #Don't use _ping too.
await ctx.respond("Pong!")
And I still don't understand why you created two async def in one command. There should be only one and you already specified it.

#client.command not running, discord.py [duplicate]

Basically, everything appears to work fine and start up, but for some reason I can't call any of the commands. I've been looking around for easily an hour now and looking at examples/watching videos and I can't for the life of me figure out what is wrong. Code below:
import discord
import asyncio
from discord.ext import commands
bot = commands.Bot(command_prefix = '-')
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
#bot.event
async def on_message(message):
if message.content.startswith('-debug'):
await message.channel.send('d')
#bot.command(pass_context=True)
async def ping(ctx):
await ctx.channel.send('Pong!')
#bot.command(pass_context=True)
async def add(ctx, *, arg):
await ctx.send(arg)
The debug output I have in on_message actually does work and responds, and the whole bot runs wihout any exceptions, but it just won't call the commands.
From the documentation:
Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message. For example:
#bot.event
async def on_message(message):
# do some extra stuff here
await bot.process_commands(message)
The default on_message contains a call to this coroutine, but when you override it with your own on_message, you need to call it yourself.
Ascertained that the problem stems from your definition of on_message, you could actually just implement debug as a command, since it appears to have the same prefix as your bot:
#bot.command()
async def debug(ctx):
await ctx.send("d")

how to add reaction to a specifc user?

I've been working on this piece of code:
#client.event
async def lol(message,ctx):
if ctx.author.id == <user_id>:
await message.add_reaction('❤️')
else:
return
I am pretty sure that it is developed correctly, yet I am not getting the desired results.
I am pretty sure that if you check the console, an HTTP error would have been encountered. That's because you directly pasted the emoji in the function parameter. You have to add its unicode value. In your case:
await message.add_reaction(u'\u2764')
You are using an event decorator rather than a command, unless you were trying to detect if the user reacted, but its still completely off. What it looks like, the command that is called will send a message and the bot will react to it.
#client.command()
async def lol(ctx):
message = await ctx.send(f"{ctx.author.mention}, lol")
await message.add_reaction('😂')
If you then want to detect if the user had reacted to the emoji, you can use a event, but an on_reaction_add:
#client.event
async def on_reaction_add(reaction, user):
if reaction.emoji == '😂':
await user.send("Lol")

tasks.loop timer is repeatedly executing in discord.py

So I'm making a bot that'll post the Wednesday Frog meme every Wednesday. To do this, I'm using discord.py's tasks.loop function which in theory should run once every 24 hours in the finished version. Thing is though no matter how many hours, minutes or seconds I set it to, It spams my chat with either the meme or "It's not Wednesday," almost every second.
The code:
import discord
import datetime
from discord.ext import tasks, commands
client = commands.Bot(command_prefix = ')')
#client.event
async def on_ready():
wednesdayCheck.start()
print("Lets see if it's wednesday.")
#tasks.loop(hours=2)
async def wednesdayCheck():
if datetime.datetime.today().weekday() == 2:
for guild in client.guilds:
for channel in guild.text_channels:
await channel.send(file=discord.File('Meme.jpg'))
elif datetime.datetime.today().weekday() != 2:
for guild in client.guilds:
for channel in guild.text_channels:
await channel.send("It's not Wednesday")
Any help with making the function follow the timer as intended will be much apreciated.
Try putting the .start() outside of the on_ready() function, just above the bot.run().
There is no guarantee that the on_ready() function only runs once.
https://discordpy.readthedocs.io/en/latest/api.html?highlight=on_ready#discord.on_ready
Here is a possible solution to your problem:
Create a global boolean variable that ensures the block is only run once in on_ready
ON_READY_FIRST_RUN = True
#client.event
async def on_ready():
global ON_READY_FIRST_RUN
if ON_READY_FIRST_RUN:
wednesdayCheck.start()
print("Lets see if it's Wednesday.")
ON_READY_FIRST_RUN = False
I have been trying to set up a bot to send a message every weekday morning but for some reason can't get the #tasks.loop to execute. Hope this helps you though!
Edit: I was trying to use #tasks.before_loop but I just threw that code in my #tasks.loop and now this works perfectly!

Discord.py - Tag a random user

I recently started working with Discord.py.
My question is: How can I tag a random user, for example if you write !tag in the chat? I haven't found an answer yet.
if message.content.startswith('+best'):
userid = '<# # A RANDOM ID #>'
yield from client.send_message(message.channel, ' : %s is the best ' % userid)
Thank´s
Here's how I'd do it:
Generate a list of users in your server
Use random.choice to select a random user from the list
Mention that user using the API (or if you'd like, do it manually) along with your message
Here's the implementation:
from random import choice
if message.content.startswith('+best'):
user = choice(message.channel.guild.members)
yield from client.send_message(message.channel, ' : %s is the best ' % user.mention)
Elaborating on aeshthetic's answer, you can do something like this:
import random
if message.content.startswith('+best'):
channel = message.channel
randomMember = random.choice(channel.guild.members)
await channel.send(f'{randomMember.mention} is the best')
Please note that the code is in the rewrite version of discord.py and not the async version - if you're using the async version, I'd recommend you migrate to rewrite as support for the async version of discord.py has ceased. To learn more about that, refer to the migrating documentation found here.
Let me know if you need help - happy coding!
I was playing around a bit and got this to work, you can try it.
#client.command(pass_context=True)
async def hug(ctx):
user = choice(ctx.message.channel.guild.members)
await ctx.send(f'{ctx.message.author.mention} hugged {user.mention}')
First of all, I suggest you install discord.py-rewrite, as it is more advanced.
Then, I suggest you create bot commands using the #client.command() decorator, like this:
#client.command()
async def testcommand(ctx):
pass
Now that you have done both things, there are several ways to do it. For example, if you don't want the bot to mention the command invoker or other bots, you can write:
from random import choice
from discord.ext import commands
#client.command()
#commands.guild_only()
async def tag(ctx):
try:
await ctx.send(choice(tuple(member.mention for member in ctx.guild.members if not member.bot and member!=ctx.author)))
except IndexError:
await ctx.send("You are the only human member on it!")
If you don't want the bot to mention other bots, but it can mention the command invoker, use:
from random import choice
from discord.ext import commands
#client.command()
#commands.guild_only()
async def tag(ctx):
await ctx.send(choice(tuple(member.mention for member in ctx.guild.members if not member.bot)))
If you want the bot to mention any guild member, human or bot, use:
from random import choice
from discord.ext import commands
#client.command()
#commands.guild_only()
async def tag(ctx):
await ctx.send(choice(tuple(member.mention for member in ctx.guild.members)))

Resources