Random tips. Discord.py - discord

I want my bot to send random tips out of a list of tips whenever a command is run.
Also, I want it to show the tips only sometimes.
What I mean to say is, for example, a user types the command hi then it should say ofcourse hi. But the tips should be shown only when the command is run a certain amount of times.
So if the command is run 5 times, then what I would like is that every 5 times my command is executed, one tip should be shown.
It is not like I have a command that sends random tips.
For example, if I have an unban command, it could send a tip every 5 times a command is run like, "You can also use kick and ban commands. Use -help for more info."
I hope you get what I am trying to say and this is all the information you need.
This is inspired by Dank Memer

Just store a counter somehow and use the random module to select a random tip
If using functions for commands:
import random
hi_counter = 0
hi_tips = [
"You can also use kick and ban commands. Use `-help` for more info.",
"a tip",
"another tip",
"yet another tip",
]
#bot.command('hi')
async def hi(ctx):
global hi_counter, hi_tips
await ctx.send('hi')
hi_counter += 1
if hi_counter % 5 == 0:
await asyncio.sleep(1)
await ctx.send(random.choice(hi_tips))
If you're using a Cog for commands:
import random
class hi(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.counter = 0
self.tips = [
"You can also use kick and ban commands. Use `-help` for more info.",
"a tip",
"another tip",
"yet another tip",
]
#commands.command('hi')
async def hi(self, ctx):
await ctx.send('hi')
self.counter += 1
if self.counter % 5 == 0:
await asyncio.sleep(1)
await ctx.send(random.choice(self.tips))
def setup(bot):
bot.add_cog(hi(bot))
If you want to make a decorator for this, you can do that too:
import random
def tips(times: int, tips: List[str]):
counter = 0
def decorator(func):
nonlocal counter, tips
async def wrapper(*args, **kwargs):
nonlocal counter, tips
ctx = func(*args, **kwargs)
counter += 1
if counter % times == 0:
await asyncio.sleep(1)
await ctx.send(random.choice(tips))
return wrapper
return decorator
# Use it like:
#bot.command('hi')
#tips(5, [
"You can also use kick and ban commands. Use `-help` for more info.",
"a tip",
"another tip",
"yet another tip",
])
async def hi(ctx):
global hi_counter, hi_tips
await ctx.send('hi')
return ctx # MAKE SURE TO RETURN `ctx` OR THE DECORATOR WON'T WORK

Related

Delete messages from specifc user using Discord py

I wanted to create a clear command where if example .clear #user#0000 100 it will clear the last 100 messages #user#0000 sent. Here is my code:
#commands.command()
#commands.has_permissions(manage_messages=True)
async def clear(self, ctx, amount=1):
await ctx.channel.purge(limit=amount + 1)
#clear.error
async def clear_error(self, ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.send('Sorry, you are missing the ``MANAGE_MESSAGES`` permission to use this command.')
This code i provided only deletes depeneding how many messages will be deleted in a channel. I want to make a code where the bot will delete messages from a specific user. If this is possible, please let me know. I will use the code as future reference. Much appreciated.
You can use check kwarg to purge messages from specific user:
from typing import Optional
#commands.command()
#commands.has_permissions(manage_messages=True)
async def clear(self, ctx, member: Optional[discord.Member], amount: int = 1):
def _check(message):
if member is None:
return True
else:
if message.author != member:
return False
_check.count += 1
return _check.count <= amount
_check.count = 0
await ctx.channel.purge(limit=amount + 1 if member is None else 1000, check=_check)

A discord damage calculator bot

Currently I am working on a discord bot for a Pokemon and I will be running, I have the encounter system down, but have been having trouble with the damage system. Currently this is what the whole code looks like.
import discord
import os
import random
import asyncio
client = discord.Client()
from discord.ext import commands
client = commands.Bot(command_prefix='!')
#client.event
async def on_ready():
print('aaaaand were scuffed'.format(client))
###Biome encounter list###
DesertList2 = ['charmander', 'charmeleon', 'charizard']
###commands###
#desert enc
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!desert'):
mon = random.choice(DesertList2)
print(mon)
await message.channel.send(mon)
#client.event
async def damage(ctx, num1, num2, num3):
result = (num1+num2)/num3
await ctx.send(result)
await client.process_commands(message)
Note(s): I have client.run, just not shown for obvious reasons.
You'd have to create separate argument variables.
#client.command()
async def damage(ctx, num1 : int, num2 : int, num3 : int): # for your 1 2 4 example, 3 number arguments would be sufficient
result = (num1+num2)/num3
await ctx.send(result)
This would do (1+2)/4 and should give you 0.75.
Also, after looking at your imgur image, this is what your on_message function needs to look like:
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!desert'):
mon = random.choice(DesertList2)
print(mon)
await message.channel.send(mon)
await client.process_commands(message)
#2P1XLS I took the liberty of making your desert command an actual command, since it was previously in the on_message event, and it seems to me that you're trying to use it as a command. However, you can still run it how you were running it previously: !desert. I've also added the await client.process_commands(message) in the on_message event, since that's where it belongs. Try this out:
import discord
import os
import random
import asyncio
client = discord.Client()
from discord.ext import commands
client = commands.Bot(command_prefix='!')
#client.event
async def on_ready():
print('aaaaand were scuffed'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
await client.process_commands(message)
###Biome encounter list###
DesertList2 = ['charmander', 'charmeleon', 'charizard']
###commands###
#desert command
#client.command()
async def desert(ctx):
mon = random.choice(DesertList2)
print(mon)
await ctx.send(mon)
#damage command
#client.command()
async def damage(ctx, num1 : int, num2 : int, num3 : int):
result = (num1 + num2) / num3
await ctx.send(result)
If you run !damage 1 2 4, then it would do (1+2)/4 and would return 0.75. I've tried this code out myself, so it should definitely work. Make sure to copy it exactly. Hope this helped you!
Here is a clean and simple effective way of a calculator command, you can give it endless arguments for it to calculate
By using *, you can pass multiple numbers and .join will join each of the arguments you pass. Here's a simple example,
#client.command()
async def calculate(ctx, operation, *nums):
if operation not in ['+', '-', '*', '/']:
await ctx.send('Please use a valid operation type')
return
var = f' {operation} '.join(nums)
await ctx.send(f'{var} = {eval(var)}')

Discord.py bot clear

Alright so guys i need some help. Basically i am making an discord bot. I'm having problems with clear(purge) command. So this is my code so far:
#client.command(aliases= ['purge','delete'])
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount : int):
if amount == None:
await ctx.channel.purge(limit=1000000)
else:
await ctx.channel.purge(limit=amount)
my problem here is this if amount == None .
Please help me!
Im getting an error that i have missing requied argument...
That's because you're not giving amount the default value None. This is how you should define the function:
#client.command(aliases= ['purge','delete'])
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount=None): # Set default value as None
if amount == None:
await ctx.channel.purge(limit=1000000)
else:
try:
int(amount)
except: # Error handler
await ctx.send('Please enter a valid integer as amount.')
else:
await ctx.channel.purge(limit=amount)
This one is working for me
#client.command()
#has_permissions(manage_messages = True)
async def clear(ctx , amount=5):
await ctx.channel.purge(limit=amount + 1)
I got it from a youtuber channel, you can put the number of the messages u want to clear after the clear command, EX:
-clear 10
Try this:
#client.command(aliases = ['purge', 'delete'])
#commands.has_permissions(manage_messages = True)
async def clear(ctx, amount: int = 1000000):
await ctx.channel.purge(limit = amount)
This should work, as I have a clear command that looks almost exactly like this. The amount param is being converted to an int and if the client doesn't give parameters, the amount will be set at 1000000.
This is the one I'm using atm.
#bot.command(name='clear', help='this command will clear msgs')
async def clear(ctx, amount = 50): # Change amount
if ctx.message.author.id == (YOUR USER ID HERE):
await ctx.channel.purge(limit=amount)
else:
await ctx.channel.send(f"{ctx.author.mention} you are not allowed")
I've just added an 'if' statement for being the only one who can use that command. You can also allow an specific role.
import discord
from discord.ext import commands
client = commands.Bot(command_prefix='>')
#client.event
async def on_ready():
print("Log : "+str(client.user))
#client.command()
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount: int):
await ctx.channel.purge(limit=amount+1)
await ctx.message.delete()
client.run("token")
you can do this:
#client.command(aliases= ['purge','delete'])
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount :int = -1):
if amount == -1:
await ctx.channel.purge(limit=1000000)
else:
await ctx.channel.purge(limit=amount)
I think it should work, if the client doesn't give parameters, the amount will be set at "-1"

Bot saying only one word in string

As in title. I'm trying to get my bot to send an announcement, without having to use "" to capture the whole sentence. What the hell do you mean?
Here's my code:
#bot.command(pass_context=True)
#discord.ext.commands.has_permissions(administrator=True)
async def announce(ctx, message : str):
if message == None:
return
else:
embed = discord.Embed(title='yBot | ANNOUNCEMENT', description='', color= 0xFF0000)
embed.add_field(name="ANNOUNCEMENT: ", value="{}".format(message))
embed.set_footer(text="© 2020 - Powered by yanuu ;k#2137")
await ctx.send("||#everyone||")
await ctx.send(embed=embed)
Your issue is in the way you defined the command it self. It should be with a * so that it will take everything after
async def announce(ctx,*, message : str):
Have a look at this doc

How do functions work in cogs (discord.py)?

An error occurs using this code it says bot is not defined. I don't understand cogs that much but I understand a bit of classes too. I wanted to know how functions work in a cog and how variables are assigned like guildstats = ... below.
This is my code: (I am trying to make a database using the discord bot in a guild. The code works without using cogs but I wanted it to be easier to debug any errors so I went for cogs.)
class Boot(commands.Cog):
def __init__(self, bot):
self.bot = bot
guildstats = pd.read_excel('DiscordStats.xlsx',sheet_name=0)
userstats = pd.read_excel('DiscordStats.xlsx',sheet_name=1)
def dataframe_to_excel(df1 = guildstats, df2 = userstats):
with pd.ExcelWriter('DiscordStats.xlsx', mode = 'w') as writer:
df1.to_excel(writer, index=False, sheet_name = 'GuildStats')
df2.to_excel(writer, index=False, sheet_name = 'UserStats')
def guildstats_writer():
guild_row_data = []
for guild in self.bot.guilds:
if '\''+str(guild.id) not in guildstats['GuildID'].to_list():
guild_row_data.append([guild.name,'\''+str(guild.id),'','',False])
else:
pass
guild_row = pd.DataFrame(guild_row_data,columns = guildstats.columns.to_list())
guildstats1 = guildstats.append(guild_row,ignore_index=True)
Boot.dataframe_to_excel(df1=guildstats1)
#commands.Cog.listener()
async def on_ready(self):
Boot.guildstats_writer(self)
await sbot.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name="for MeepMop ~help"))
print(f'{bot.user} is connected to the following guild:')
for guild in bot.guilds:
print(f'{guild.name} (id: {guild.id})')
def setup(bot):
bot.add_cog(Boot(bot))
You're trying to call the variable bot when you never defined it, your program has no idea what the variable "bot" is, try changing all the times you called bot to instead call self.bot instead
For example your on_ready function should look like this:
#commands.Cog.listener()
async def on_ready(self):
Boot.guildstats_writer(self)
await self.bot.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name="for MeepMop ~help"))
print(f'{self.bot.user} is connected to the following guild:')
for guild in self.bot.guilds:
print(f'{guild.name} (id: {guild.id})')

Resources