I want my bot to send an error message if it doesnt have permissions - error-handling

I'm coding a discord bot in discord.py and i have a question.
I want to have a error handler for when the BOT doesn't have permissions and which permissions the bot is missing. This is the error handler i have now, but i don't know how to do it with the bots permissions and which permission he is missing.
async def on_command_error(ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
embe=discord.Embed(title="<:redcross:781952086454960138>Error", description="**Please pass in all required arguments!**", color=0x7289da)
await ctx.send(embed=embe)
elif isinstance(error, commands.MissingPermissions):
embe=discord.Embed(title="<:redcross:781952086454960138>Error", description="**Insufficient permissions!**", color=0x7289da)
await ctx.send(embed=embe)
else:
raise error
So i want the bot to return
embe=discord.Embed(title="<:redcross:781952086454960138>Error", description="**I dont have the right permissions to do that! Please give me {missingpermission}!**", color=0x7289da)

You can use error.missing_perms and by the way, this error is thrown when the invoker doesn't have the permissions not the bot itself.
if isinstance(error, commands.MissingPermissions):
await ctx.send(f"Permissions needed {error.missing_perms}")
If you want the error to be thrown when the bot doesn't have the permissions you need to use the decorator commands.bot_has_permissions(**perms) and in the error handler commands.BotMissingPermissions, here's an example:
#bot.command()
#commands.bot_has_permissions(kick_members=True)
async def kick(ctx, member: discord.Member, *, reason=None):
await member.kick(reason=reason)
#kick.error
async def kick_error(ctx, error):
if isinstance(error, commands.BotMissingPermissions):
await ctx.send(f"I don't have the required permissions, please enable {error.missing_perms}")

It's best to read through the docs once beforehand. You can find them here: Docs.
Generally you can cover many events with the error handler in discord.py.
In your case it is a BotMissingPermissions error.
You can handle it with the bot as follows:
if isinstance(error, commands.MissingPermissions):
await ctx.send(f"Permissions needed {error.missing_perms}")
This is just one of many ways to handle this type of error. You can also output a complete list of missing permissions. (kick, ban, manage_channel etc.)

Related

Twilio mobile number verification - VerificationCheck was not found on Express

The requested resource /Services/serviceSSID/VerificationCheck was not found is the eroor showing in the console
my code is
otpLogin:async (req,res)=>{
console.log(req.body.otp);
try {
const isOTP = await client.verify.services(serviceSSID).verificationChecks.create({
to:`+91${req.body.phone}`,
code:req.body.otp
})
if(isOTP)console.log(isOTP);
return res.status(200).json({message:" mobile number verified"})
} catch (error) {
console.log(error.message)
return res.status(500).json({message:"something went wrong"})
}
}
Twilio developer evangelist here.
From the documentation:
Twilio deletes the verification SID once it’s:
expired (10 minutes)
approved
when the max attempts to check a code have been reached
If any of these occur, verification checks will return a 404 not found error like this:
Unable to create record: The requested resource /Services/VAXXXXXXXXXXXXX/VerificationCheck was not found
If you’d like to double check what happened with a given verification - please use the logs found in the Twilio Console under your Verification Service:
I've found that if you submit a form twice by clicking a submit button twice quickly, that the verification is successfully checked and then because it was a success deleted, then the second check fails with a 404 like this and that is the error result you see. To avoid this, you should stop users from being able to submit the form twice by disabling the submit button after the first attempt.
I can confirm that philnash 2nd statement is correct. However wouldn't it have been handled way better if instead we just get a response from client.verify.services(serviceSSID).verificationChecks that the 2nd (and so on checks) failed??

Disconnecting users from a Channel if guess is wrong DiscordPy

I'm coding a Discord bot. I made this command where it plays a little guessing game with a random integer from 1 to 10. If the guess from the user is correct, just a message pops out. If not, it disconnects the user from the voice channel, if it's in one.
This is the code I'm working on:
#bot.command()
async def adivinar(ctx: commands.Context):
user = discord.Member
aleatorio = random.randint(1,10)
await ctx.send(f"Guess a number from 1 to 10")
msg = await bot.wait_for("message")
if int(msg.content) == aleatorio:
await ctx.send(f"Congrats! My number was {aleatorio}")
else:
await ctx.send(f"Nope. My number was {aleatorio}")
await user.move_to(None)
This code doesn't work. It shows this error in the terminal:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: move_to() missing 1 required positional argument: 'channel'
In order to make the "adivinar" command, I look into this piece of code as reference that works wonderfully:
#bot.command()
async def kick1(ctx: commands.Context, user: discord.Member):
await ctx.send(f'{user.mention} has been kicked from {user.voice.channel.mention}')
await user.move_to(None)
I'm pretty sure this is very easy to solve. But at the moment it's kinda hard for me to figure it out. Thanks!
you assigned user to the discord.Member class, not to a real member
user = discord.Member
you need to do something like ⬇ to can move it
user = ctx.guild.get_member(1234) # user id
in your case you can also use user = msg.author

Hey could someone show me some code on a discord.py API? Using an api from a website

Im trying to create a fortnite API to give me all of the Leaked cosmetics with a discord bot and I just don't know where to get started! Could someone help! Thankyou
Here's an example of a simple bot that repeats what you say.
import discord # importing the discord.py library
from discord.ext import commands # extension of said library
# This defines the bot's command prefix and if the commands are case insensitive
bot = commands.Bot(command_prefix='-', case_insensitive='True')
#bot.event =
async def on_ready():
```
This is an event that prints to the console that the bot is online and ready to go.
```
print('Bot is ready!') # prints to console that the bot is ready.
#bot.command()
async def echo(ctx, *, msg):
```
This is a command that repeats what you say. Echo is the name. *, msg means that all the words listed after the command are repeated
```
await ctx.message.delete() # delete the command message the the user said
await ctx.send(msg) # say whatever the user wanted to say.
# bot token here. found in the discord developer website
bot.run(YOUR BOT'S TOKEN GOES HERE)
Here's an example of using a api inside a Cog
Necessary Imports:
from discord.ext import commands
from discord import Embed, Color
from aiohttp import ClientSession
from ast import literal_eval
A command to fetch random Chuck Norris jokes
#commands.command()
async def chuck(self, ctx):
ad = Embed(color=Color.dark_gold())
base = "https://api.chucknorris.io/jokes/random"
async with ClientSession() as session:
data = await get(session, base)
data = literal_eval(data)
ad.set_author(name="Chuck Norris",
icon_url="https://i.ibb.co/swZqcK7/norris.gif",
url=data['url'])
ad.description = data['value']
return await ctx.send(embed=ad)
If you're getting information from Fortnite, chances are they already have a Python Module on PyPi, alternatively you can look for a JSON endpoint and apply what I did above to get what you need.

KeystoneJS: where are callHook hooks defined?

I want to add logic to the pre:signin and post:signin hooks, but can't find where they are defined. In admin/server/api/session/signin.js, I find the callHook()s for both, but can't find the actual hooks. Help greatly appreciated!
KeystoneJS is using grappling-hook . and thats why you can use callHook.
in node_modules/keystone/index.js you can see this code
var grappling = require('grappling-hook');
grappling.mixin(this).allowHooks('pre:static', 'pre:bodyparser', 'pre:session', 'pre:routes', 'pre:render', 'updates', 'signout', 'signin', 'pre:logger');
I am not sure but you are not finding the actual hooks because they really don't exist.
The methods are defined in keystone and grapple simply makes them hoockable. e.g signin is the method defined in keystone instance and grapple made it hoockable.
And here is the way you will just tell what to do after signing is completed.
keystone.callHook(user, 'post:signin', function (err) {
if (err) return res.json({ error: 'post:signin error', detail: err });
res.json({ success: true, user: user });
});
So in layman term you r saying.. Hay keystone, call my function after This user is signed in. and for that there is really no code inside keystone.
MY knowledge is limited here how the user is passed and how it happens that only when this user logged in. I think, we still need some experts light here.
I had a use-case that required a function be called every time a specific model was added to the database. I found out that you can use the Mongoose middleware specifically the post middleware to achieve such results. So in my case I had a Product schema in which I wanted a function to run everytime a new product was added or updated. It was as easy as adding the following:
keystone.lists.Product.schema.post('save',function(){
console.log('called after new item saved');});

How to tell whether Accounts.addEmail succeeded or failed, and if it failed, the reason why

I have a page where the user can type in a new email address and then this method attempts to add it to their account:
Meteor.methods({
add_new_email: function(address)
{
Accounts.addEmail(Meteor.userId(), address);
}
});
I'm using the accounts-password package in Meteor.
I'd like to give the user meaningful feedback after they try to add the new address, in particular if it failed why did it fail? I have looked at the docs but there doesn't seem to be any method to find out failure reason.
I know that I can count the user's email addresses before and after trying to add the new one, but that doesn't tell me if the address already belongs to another user, or if it's an existing address of the user's, or whatever is the failure reason.
Is there any way to find out the result of an API call like this?
You can read the information about what this method does here:
https://github.com/meteor/meteor/blob/master/packages/accounts-password/password_server.js#L847
As you can see, the method will fail only in one case:
The operation will fail if there is a different user with an email
only differing in case
Therefore if the method fails you can tell to the user that the email is already registered.
After experimenting some more, it seems that all I need to do is add a callback to my client when I call the method, and check there for an error. Any error is automatically returned to the callback.
Server:
Meteor.methods({
add_new_email: function(address)
{
Accounts.addEmail(Meteor.userId(), address);
}
});
Client:
Meteor.call('add_new_email', 'me#example.com', function(error){
if (error) console.log("got an error " + error.reason);
});
I had not realised that the error from the API would be passed up into my method. Meteor - it's always more clever than I expect!
Note also that you can use Meteor.Error in your methods to throw errors which will be passed up to client callbacks in exactly the same way, see the docs:
if (!Meteor.userId()) {
throw new Meteor.Error("not-authorized", "You must be signed in to write a new post");
}
I know I'm a bit late to the party but I ran into this problem today and found your post.
I needed to be able to tell on the server side whether it failed or not so what I did was put it in a try-catch like so:
let addSucceeded = false;
try{
Accounts.addEmail(user._id, newEmailAddress);
addSucceeded = true;
} catch(err) {}
console.log(addSucceeded);
Only if the Accounts.addEmail does not fail will addSucceeded be set to true. To make sure I don't run into the "fail because it replaced the same user's email address in a different case" scenario, I always toLowerCase() the email address when saving.