Im trying to make a Discord Bot that is able to Timeout users.
The general idea is that my friends and I can timeout eachother with tickets for about a minute.
But I cant get the discord.Member.timeout() to work.
I looked into the Discord.py doc but I cant find my mistake.
Down below I have put the important code as bold.
The error occures at
print("1")
await member1.timeout(timeout)
print("2")
The program prints "1" and thats it.
The only error message I get is from Discord (This interaction wasnt succesfull)
Please help me.
import discord
from discord.ext import commands
import json
import random
from discord import app_commands
import datetime
member1 = discord.Member
class SelectMenu3(discord.ui.View):
options1 = [
discord.SelectOption(label="Timeouten", value="1", description="Timeout someone"),
discord.SelectOption(label="Enttimeouten", value="2", description="Opposite")
]
#discord.ui.select(placeholder="Options", options=options1)
async def menu_callback3(self, interaction: discord.Interaction, select):
with open("cogs/eco.json", "r") as f:
user_eco = json.load(f)
global member1
member = interaction.user
select.disabled = True
eco_embed = discord.Embed(title="Timeouts", description="", colour=discord.Color.blue())
eco_embed.add_field(name="Amount Timeout:", value=f"{user_eco[str(member.id)]['Timeout']}")
**if select.values[0] == "1":
if user_eco[str(member.id)]['Timeout'] >= 1:
timeout = datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=1, hours=0, weeks=0)
print("1")
await member1.timeout(timeout)
print("2")
else:
await interaction.response.send_message(content="Du hast nicht genug Timeout-Tickets für diese Aktion",
ephemeral=True)
**
elif select.values[0] == "2":
if user_eco[str(member.id)]['Timeout'] >= 1:
pass
else:
await interaction.response.send_message(content="Du hast nicht genug Timeout-Tickets für diese Aktion",ephemeral=True)
**#app_commands.command(name="timeout", description="")
async def timeout(self, interaction: discord.Interaction, member: discord.Member):
global member1
member1 = member
view = SelectMenu3()
await interaction.response.send_message(content="Choose", view=view,
ephemeral=True)
**
I just found the problem, in Discord Roles exist and a User whos Role is lower in the hierarchy cant timeout any users that are higher up.
Therefore I just had to move up my Bots Role to be at the top (still below my own role as a safety measure) and everything is working just fine now.
Related
Edit: I probably should have added that I did all of the following code on repl.it, though I doubt it makes any difference.
Edit 2: I don't know what I did, but now absolutely nothing works. The 'ready' message won't show in the console. It might have to do with the 'keep_alive' file I added in.
So I was going about my day, trying to figure out what the problem is with this snippet of code, until I realized 'Hey, I could try to ask Stack Overflow'!
For context, whenever I run the bot and type in a command (i.e. '!rank'), the bot doesn't seem to recognize the command. The console is just empty of red words, unless I use a nonexisting command. This is the console after I used three commands: '!rank', '!leaderboard', and '!yeet', which purposefully doesn't exist.
In case you're too lazy to open the image, the console goes:
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "yeet" is not found
Here's the code:
from keep_alive import keep_alive
from discord.ext import commands
import discord
import os
import levelsys
cogs = [levelsys]
client = commands.Bot(command_prefix="!", intents = discord.Intents.all())
token = os.environ.get("DISCORD_BOT_SECRET")
client.run(token)
keep_alive()
token = os.environ.get("DISCORD_BOT_SECRET")
client.run(token)
for i in range(len(cogs)):
cogs[i].setup(client)
import discord
from discord.ext import commands
from pymongo import MongoClient
general = [806613968684318720]
level = ["Sperm Whale", "Artillery General", "Commander", "Supreme General",]
levelnum = [1,5,10,15]
cluster = MongoClient("mongodb+srv://[Username]:[Password]#kingdom-kun.lffd9.mongodb.net/Kingdom-kun?retryWrites=true&w=majority")
client = discord.Client
leveling = cluster["discord"]["levelling"]
class levelsys(commands.Cog):
def _init_(self, client):
self.client = client
#commands.Cog.listener()
async def on_ready(self):
print("Kingdom-kun is ready to come!")
#commands.Cog.listener()
async def on_message(self, message):
if message.channel == general:
stats = leveling.find_one({"id" : message.author.id})
if not message.author.bot:
if stats is None:
newuser = {"id": message.author.id, "xp": 100}
leveling.insert_one(newuser)
else:
xp = stats["xp"] +5
leveling.update_one({"id": message.author.id}, {"$set": {"xp"}})
lvl = 0
while True:
if xp < {(50*(lvl**2))+(50*(lvl-1))}:
break
lvl +=1
xp -= {(50*(lvl-1)**2)+(50*(lvl-1))}
if xp == 0:
await message.channel.send(f"Well done {message.author.mention}! You were promoted to **Level: {lvl}**")
for i in range(len(level)):
if lvl == levelnum[i]:
await message.author.add_roles(discord.utils.get(message.author.guild.roles, name=level[i]))
embed = discord.Embed(description=f"{message.author.mention} you have gotten role **{level[i]}**!!!")
embed.set_thumbnail(url=message.author.avatar_url)
await message.channel.send(embed=embed)
#This is rank command
#commands.command()
async def rank(self, ctx):
if ctx.channel.id == general:
stats = leveling.find_one({"id": ctx.author.id})
if stats is None:
embed = discord.Embed(description = "You haven't sent any messages, no rank!!!")
await ctx.channelsned(embed=embed)
else:
xp = stats["xp"]
lvl = 0
rank = 0
while True:
if xp < {(50*(lvl**2))+(50*(lvl-1))}:
break
lvl += 1
xp -= {(50*(lvl-1)**2)+(50*(lvl-1))}
boxes = [(xp/(200*((1/2) * lvl)))*20]
rankings = leveling.find().sort("xp",-1)
for x in rankings:
rank += 1
if stats("id") == x["id"]:
break
embed = discord.Embed(title="{}'s level stats".format(ctx.author.name))
embed.add_field(name="Name", value = ctx.author.mention, inline=True)
embed.add_field(name="XP", value = f"{(xp/(200*((1/2)* lvl)))*20}", inline=True)
embed.add_field(name="Rank", value = f"{rank}/{ctx.guild.member_count}", inline=True)
embed.add_field(name="Progress Bar[lvl]", value = boxes * ":blue_square:" * (20-boxes) * ":white_large_square:", inline=False)
embed.set_thumbnail(url=ctx.author.avatar_url)
await ctx.channel.send(embed=embed)
#This is leaderboard command
#commands.command()
async def leaderboard(self, ctx):
if (ctx.channel.id == general):
rankings = leveling.find().sort("xp",-1)
i=1
embed = discord.Embed(title = "Rankings:")
for x in rankings:
try:
temp = ctx.guild.get_member(x["id"])
tempxp = x["xp"]
embed.add_field(name=f"(i): {temp.name}", value=f"Total XP: {tempxp}", inline=False)
i == 1
except:
pass
if i == 11:
break
await ctx.channel.send(embed=embed)
def setup(client):
client.add_cog(levelsys(client))
(This is the keep_alive file I added on that somehow screwed everything up)
from flask import Flask
from threading import Thread
app = Flask('')
#app.route('/')
def home():
return "OwO mode pog?"
def run():
app.run(host='0.0.0.0',port=8080)
def keep_alive():
t = Thread(target=run)
t.start()
I've tried a lot of things - changing brackets to parentheses then back again, retyping the entire thing... again, and more, yet nothing changes. If anyone could answer this conundrum, I'd be very thankful.
Anyway, have a nice day!
Hello I tried to make a bot with Discord.py and I tried implementing this to my code but I get the error in the title. I don't know a lot of Python yet and I'm very new so I don't know what may cause this error. Any help would be great, thanks!
import discord
import os
import requests
import json
import random
from keep_alive import keep_alive
import asyncio
client = discord.Client()
basura = ["rezero"]
verdad = [
"es una mierda",
"no debería existir",
"VIVA K-ON",
]
def get_quote():
response = requests.get("https://zenquotes.io/api/random")
json_data = json.loads(response.text)
quote = json_data[0]['q'] + " - " + json_data[0]['a']
return (quote)
#client.event
async def on_ready():
print ('We logged in as {0.user}'.format(client))
#client.event
async def on_message(self,message):
if message.author.id == self.user.id:
return
if message.content.startswith('Hola'):
await message.channel.send('Sup nerd')
if message.content.startswith('Inspirame'):
quote = get_quote()
await message.channel.send(quote)
if any(word in message.content for word in basura):
await message.channel.send(random.choice(verdad))
if message.content.startswith('^Guess'):
await message.channel.send('Adivina un numero del 1 al 10')
def is_correct(m):
return message.content.author == message.author and m.content.isdigit()
answer = random.randint(1,10)
try:
guess = await self.wait_for('message',check=is_correct,timeout=5.0)
except asyncio.TimeoutError:
return await message.channel.send('Se acabó el tiempo, la respuesta era {}.'.format(answer))
if int(guess.content) == answer:
await message.channel.send('Acertaste')
else:
await message.channel.send('Fallaste, la respuesta era {}.'.format(answer))
keep_alive()
client.run(os.getenv('TOKEN'))
Giving the full error log and the exact code run is good practice here.
This error indicates that the 'on_message' function was not given its 'message' argument. In this case, I would presume that you forgot to delete the 'self' argument when extracting this method from an object to make a stand-alone function out of it.
I have made a Leveling system but i can't figure out to make a cooldown in on_message
i want to add a BucketType.member cooldown and as im using MondoDB for database so i can't afford to store the last time they send message instead im looking for a cooldown for on_message which works similar to commands cooldown so it can automatically take any action
This is the code so far
#commands.Cog.listener()
async def on_message(self , message):
if message.channel.id in talk_channels:
stats = leveling.find_one({"id":message.author.id})
if not message.author.bot:
if stats is None:
new_user = {"id" : message.author.id, "xp" : 0}
leveling.insert_one(new_user)
else:
xp = stats["xp"] + 5
leveling.update_one({"id" : message.author.id}, {"$set" : {"xp" : xp}})
lvl = 0
while True:
if xp < ((50*(lvl**2))+(50*lvl)):
break
lvl += 1
xp -= ((50*((lvl-1)**2))+(50*(lvl-1)))
if xp == 0:
await message.channel.send(f"Congo you leveled up {message.author.mention} to **level: {lvl}**")
for i in range(len(level_role)):
if lvl == levelnum[i]:
await message.author.add_roles(discord.utils.get(message.author.guild.roles, name=level_role[i]))
embed = discord.Embed(title="LEVEL UP", description=f"You have reached a mile stone of {lvl} and has got role **{level_role[i]}**", color=0x00ffff)
embed.set_thumbnail(url=message.author.avatar_url)
await message.channel.send(embed=embed)
You should use CooldownMapping.from_cooldown to add cooldowns to the on_message event, example:
import typing
import discord
from discord.ext import commands
class SomeCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self._cd = commands.CooldownMapping.from_cooldown(1, 6.0, commands.BucketType.member) # Change accordingly
# rate, per, BucketType
def get_ratelimit(self, message: discord.Message) -> typing.Optional[int]:
"""Returns the ratelimit left"""
bucket = self._cd.get_bucket(message)
return bucket.update_rate_limit()
#commands.Cog.listener()
async def on_message(self, message):
if "check something":
# Getting the ratelimit left
ratelimit = self.get_ratelimit(message)
if ratelimit is None:
# The user is not ratelimited, you can add the XP or level up the user here
else:
# The user is ratelimited
My Discord Bot doesnt respond to Commands, but it logs the User ID when someone writes something. Why is this the Case? What have i done wrong? Is there something missing in the on_message listener? The last thing i added to my Code was the Rank System which i am working on, but even when i comment it out, the Bot still doesnt respond to commands like +macarena. Here is the Code:
import os
import discord
from dotenv import load_dotenv
from discord.ext import commands
from user import User
############## Init Variables #############
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')
DATA = os.getcwd() + '\\data\\'
bot = commands.Bot(command_prefix='+')
bot.remove_command('help')
rank_list = []
############## Main Code #############
#bot.event
async def on_ready():
for guild in bot.guilds:
if guild.name == GUILD:
break
print(
f'{bot.user} is connected to the following guild:\n'
f'{guild.name}(id: {guild.id})'
)
if(os.path.isfile(DATA + 'database.txt')):
print('Database File for Rank System exists and is ready for processing!')
else:
print('Database File doesnt exist and will be created....')
create_file()
print('File is created and ready for use!')
#bot.event
async def on_message(message):
#rank_system(message)
pass
#bot.command(name='help')
async def help_command(ctx):
embed = discord.Embed(
title = "Bot Commands",
description = "Hier werden alle Commands von diesem Bot aufgelistet. Alle nachfolgenden Commands müssen mit dem Präfix '+' aufgerufen werden.",
color = discord.Color.blue()
)
embed.add_field(name="Algorithmen", value="Lexikon", inline=True)
embed.add_field(name="Datenstrukturen", value="Lexikon", inline=True)
embed.add_field(name="macarena", value="Fun Commands", inline=True)
await ctx.send(embed=embed)
#Rank System
def rank_system(message):
author = str(message.author)
userid = str(message.author.id)
time = str(message.created_at)
channel = str(message.channel)
user = search_user(userid)
if user == None:
rank_list.append(User(author,userid,time,channel))
else:
user.add_xp()
print(userid)
#bot.command(name='rank')
async def get_rank(message):
print("I am Here")
id = str(message.author.id)
user = search_user(id)
response = f"You are Rank {user.get_rank()} and you have {user.get_xp()}."
await message.channel.send(response)
#Lexikon Commands
#bot.command(name='Algorithmen')
async def algo_command(message):
response = "Es gibt viele verschiedene Algorithmen hier eine kurze Auflistung von den bekanntesten:\n\n- Bubble Sort\n- Quick Sort\n- Merge Sort"
await message.channel.send(response)
#bot.command(name='Datenstrukturen')
async def datenstrukturen_command(message):
response = "Es gibt viele verschiedene Datenstrukturen hier eine kurze Auflistung von den bekanntesten:\n\n- Stack\n- Queue\n- List"
await message.channel.send(response)
#Vote Commands
#Fun Commands
#bot.command(name='macarena')
async def makarena_command(message):
print("Funktioniert")
response = "Hast du ernsthaft so viel Langeweile, dass du diesen Command ausprobierst....Schäm dich ;)"
await message.channel.send(response)
#Sound Board
#Helper Class
def create_file():
open(os.path.join(DATA, "database.txt"), "x")
def read_file():
pass
def write_file(text):
pass
def search_user(id):
for x in rank_list:
print("Loop User %s",x.get_userID())
if x.get_userID() == id:
return x
return None
bot.run(TOKEN)
Thanks for the Help in advance :) I am really confused and cant figure out what i am doing wrong
You need to use process_commands() at the end of on_message events to make other commands work. Read more
#bot.event
async def on_message(message):
#some code if you want, if you want to pass then don't make on_message event
await bot.process_commands(message)
Try and change your command names like this
#bot.command()
async def macarena(message):
#code
It will run when using {prefix}macarena
New python-enthusiast here.
I am currently making a discord bot that responds with 16 pictures in a 4x4-grid when a specific user types in the chat:
XXXX
XXXX
XXXX
XXXX
This is my current code:
import discord
from secrets import TOKEN
from emotes import *
# user IDs
bonvang_ID = "417010736988946444"
djursing_ID = "124806046568022016"
jonathan_ID = "151788707760832512"
alex_ID = "151745760935936001"
snuffles_ID = "221360712222507009"
# bot = commands.Bot(command_prefix='!')
client = discord.Client()
# prints message in terminal when bot is ready
#client.event
async def on_ready():
print(f"Logged in as {client.user}")
# #client.event
# async def on_member_join(member):
# await message.channel.send(f"""Welcome to the server {member}!\n
# I'm just a simple bot made by Mr.Nofox.\n
# If you want to know more about the commands, ask him or try your luck with the others! :)""")
def member_amount():
# create a variable that contains all the servers
active_servers = client.servers
# create a variable to store amount of members per server
sum = 0
# loop through the servers, get all members and add them up, this includes bots
for s in active_servers:
sum += len(s.members)
return sum
def picture_grid():
return (f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n)
#client.event
async def on_message(message):
# print(f"{message.channel}: {message.author}: \"{message.content}\"")
guild = client.get_all_members()
if "!count()" == message.content:
await client.send_message(message.channel, f"```py\nTotal members: {member_amount()}```")
elif "!report()" == message.content:
online = 0
idle = 0
offline = 0
for member in guild:
if str(member.status) == "online":
online += 1
if str(member.status) == "offline":
offline += 1
if str(member.status) == "idle" or str(member.status) == "dnd":
idle += 1
await client.send_message(message.channel, f"```Online: {online}\nIdle/busy.dnd: {idle}\nOffline: {offline}```")
#TODO: Make a neat function for the pictures in message that responds with 4x4 image in chat when a given user types
if (message.author.id == alex_ID or message.author.id == snuffles_ID):
await client.send_message(message.channel, "DET ER MIN SØN!")
await client.send_message(message.channel, picture_grid())
# add bot-token found on website
client.run(TOKEN)
All the emotes are in a file called "emotes.py" which I import.
Each emote is a string-code, example:
pic01 = '<:1_:543049824644235265>'
The line I am using to get this to work atm. is:
await client.send_message(message.channel, f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n")
This is awful coding practice and therefore I want to make a function that returns:
f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n"
My initial thought was something like:
def picture_grid():
return (f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n")
This does the trick and converts the first code to:
await client.send_message(message.channel, picture_grid())
But merely moves the bad code to another place.. I am currently stuck by what should be a simple task.
Any ideas?