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
Related
So, I basically messed up. This is the first time I've ever tried a discord bot and I've done all my code in on_message with it checking the content of the message to see if it matches with the command name (example below). I've added a few commands, which are quite long, and I don't really want to rewrite it. Is there any way around this or do I have to rewrite it?
if message.content.lower().startswith("!test"):
await message.channel.send(db[str(message.author.id)])
Simple example of what I'm doing, just a test command.
I have tried looking inside other questions but I either: don't want to do that or don't understand what people are saying.
Any help would be appreciated and since I'm new to discord.py; I might need it explained in bit easier terms please.
You can do something like this:
import asyncio
users_on_cooldown = [] # Consider renaming this if you are going to have multiple commands with cooldowns.
def on_message(msg):
if msg.content.lower().startswith("!test") and not msg.author.id in users_on_cooldown:
await msg.channel.send(db[str(msg.author.id)])
users_on_cooldown.append(msg.author.id)
await asyncio.sleep(20) # time in seconds
users_on_cooldown.remove(msg.author.id)
Since you said you are a beginner, please note that if you make another command with a separate cooldown, use another variable that users_on_cooldown, maybe something like ban_cmd_cooldown and test_cmd_cooldown.
How It Works When the command is used, the user is added to a list, and after a certain amount of seconds, they are removed. When the command is run, it is checked if the user is on the list.
Note: When the bot is reset, cooldowns will be reset too.
If you have any questions about this, feel free to ask in the comments below.
Here how to use
#client.command()
#commands.cooldown(1, 60, commands.BucketType.user)
async def test(ctx):
await ctx.send(db[str(message.author.id)])
(1, 60, commands.BucketType.user) means 1 msg per 60sec or a 60sec cooldown.
I would recommend you rewrite your bot. It may take some time but it'll be worth it.
I've been trying to figure this out for a little while, but given that I'm mostly just slapping other people's code together and trying to troubleshoot what goes wrong, I lack a lot of the knowledge needed to do this.
I'm trying to make a bot that, when someone in the server uses the word "the" in any context (even without the bot's prefix), it corrects them with "da" (this is a running joke, please don't roast me for it lmfao). With what it does, it can be annoying - so I'd like to have people be able to disable it for something like 5 minutes at a time, and have it not send messages. The problem is, I have so little experience with python that I'm basically just guessing here. How would I go about making a command that, when triggered, would keep the bot from sending messages for a set amount of time?
Right now, the way that it's sending messages is by checking if the message contains "the", so would it be possible to have it also check something like if a boolean is true before sending?
Here's the main block of code that's responsible for the sending. I am aware that it's probably suboptimal, and if you're so inclined, feel free to explain to me how I could make it better!
#client.event
async def on_message(message):
if message.author == client.user:
return
if ('the') in message.content:
await message.channel.send('i think you meant da :rolling_eyes:')
Thanks!
(Also, is there any way that I would be able to only have it respond if "the" is by itself, and not in a word? I tried just making it have spaces before and after, but that didn't work if a message started or ended with it. I figured this probably didn't warrant its own post, since I'm probably just stupid lmao)
You can use a global variable to store a value and edit it from different places
correct_the = True
#client.event
async def on_message(message):
global correct_the
if message.author == client.user:
return
words = message.content.lower().split(" ") # make a list of all words
# like this -> ["the", "dogs", "and", "cats"]
if 'the' in words:
if correct_the: # check if it should correct it
await message.channel.send('i think you meant da :rolling_eyes:')
if message.content.startswith("!disable"): # or make this as command if you use commands.Bot
if not correct_the:
print("already disabled")
else:
correct_the = False
await asyncio.sleep(5*60) # sleeps 5min
correct_the = True
This is a bit of a general question for Discord.py, but how would I check if a role or an emoji has just been created or uploaded in the server? I am using the discord and discord.ext modules and I have the commands.Bot. My code is really long, which is why I will not include it here, and this is a general question anyways, but one of my bot's features is a modlog system. I already have the database and commands set up, but I want an extra feature where my bot can send a message if a new role was just created. Is there any bot.event handler that allows me to do this, like on_role_created or something similar to that?
You may be looking for on_guild_role_create and on_guild_emojis_update.
Here's two quick examples of how you can use them:
#bot.event
async def on_guild_role_create(role):
print(f'Server: {role.guild.name}\nRole: {role.name}'
#bot.event
async def on_guild_emojis_update(before, after):
before = ', '.join([emoji.name for emoji in before])
after = ', '.join([emoji.name for emoji in after])
print(f'Emoji list updated :\nBefore : {before}\nAfter : {after}')
I have been trying to get this to work for about an hour now, but my dumb brain cannot figure it out. basically i want to get my bot to set it's own nickname when someone says (prefix)name (namechangeto)
#client.command(aliases=["nick", "name"])
async def nickname(ctx, name="Bot"):
user = guild.me()
await user.edit(nick=name)
any help appreciated
(also sorry for bad formatting, and i know this code probably makes some people cringe lol im sorry)
For me the problem in your code is that your variable guild is not defined, so you have to use ctx.guild to get the good guild. Besides that, discord.Guild.me is not a function (callable with ()) but an attribute, you just have to use guild.me.
So you can try to make :
user = ctx.guild.me
await user.edit(nick=name)
In addition to that, it's not really the problem but an advice, you can use async def nickname(ctx, *, name="Bot"): instead of async def nickname(ctx, name="Bot"): to allow user to set a nickname with spaces in it.
So your final code for me is that :
#client.command(aliases=["nick", "name"])
async def nickname(ctx, *, name="Bot"):
user = ctx.guild.me
await user.edit(nick=name)
Have a nice day!
Baptiste
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