Getting the URL of an attachment in Discord.py - discord

I am trying to get the URL of the file that the user attaches so I can use it later on in my code however I'm not too sure on how to go about doing so.
#client.command(pass_context=True)
async def readURL(ctx, url):
# Do something
References:
discord.ext.commands
Attachment.url

If I'm understanding the question correctly, it would go like this:
#client.command() # context is automatically passed in rewrite
async def readURL(ctx):
attachment = ctx.message.attachments[0] # gets first attachment that user
# sent along with command
print(attachment.url)
References:
Attachment.url
Message.attachments

Related

discord.ext.commands.errors.CommandNotFound: Command is not found [solved]

I finished a bot after a couple of hours and while trying to run it I get this error message 'discord.ext.commands.errors.CommandNotFound: Command "play" is not found' I don't know why/ how to fix this could anyone help?
The chunk of code with the error will be below this text:
#commands.command()
async def play(self,ctx,url):
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format':"bestaudio"}
vc = ctx.voice_client
ask me if you need more of the code/more of the terminal output
I tried running the bot multiple times and I've looked around overflow for an answer and found nothing :/
(Comments mentioned you didn't load your cogs)
discord.py can't just "know" that it has to load your cogs, you have to do this yourself. This works through the process of extensions.
Extensions are loaded using load_extension. The best place to do this is setup_hook (don't use something like on_ready!). An extension is a file with a setup() method, which is invoked by the library when you call load_extension(). You can use this function to attach the cog to your bot.
Loading the extension in your bot's file:
class MyBot(commands.Bot):
...
async def setup_hook(self):
# This is typically done by looping over a directory of Cog files
# instead of 1 by 1, but this is just an example
await self.load_extension("path.to.your.extension")
Attaching the Cog in your extension's file:
class MyCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
async def setup(bot):
await bot.add_cog(MyCog(bot))

How to create a specific Discord bot that can create a note on a discord account which anyone/any admins can read

I want to create a discord bot in which you can create a note on accounts. Say i wanna make a not on user user#1111, i would do something like !note #user#1111 New note. I want to make it in python but im not too sure if i can do it on there? Thanks!
Edit: Anyways, my answer was really bad since I provided a false example. Well, it is because I don’t really use SQL, I only know how to use to replit database. And if you are on replit, the following code will work for you; if not, you can’t use this code.
import discord
from replit import db
from discord.ext import commands
bot = commands.Bot(command_prefix="n!")
#bot.event
async def on_ready():
print(f"Logged in as {bot.user}")
#bot.command()
async def note(ctx, user: discord.User, *, content):
if str(user.id) not in db.keys(): # If the user ID is not in the keys of the database:
db[str(user.id)] = {str(ctx.author.id):content}
else:
dic = db[str(user.id)]
dic[str(ctx.author.id)] = content
db[str(user.id)] = dic
await ctx.send(f"Saved your note for {user}: {content}")
bot.run("TOKEN")
Old answer (bad)
You can use a database like SQL. You can just make a command and saves the content entered after the command to the database. This is my example (I am using replit instead of SQL. **Don’t use this.**):
import discord
from replit import db
from discord.ext import commands
bot = commands.Bot(command_prefix="n!")
#bot.event
async def on_ready():
print(f"Logged in as {bot.user}")
#bot.command()
async def note(ctx, user: discord.User, content):
db[str(user.id)] = {str(ctx.author.id):content}
bot.run("TOKEN")
MY EXAMPLE IS REALLY BAD. IT WILL OVERRIDE THE DATABASE EVERYTIME SOMEONE USES THE COMMAND. DON’T COPY THIS CODE. TRY TO CODE IT YOURSELF.

Discord.py client.commands send mentioned user

I have this command called p!slap and I want it so that my bot will say {message.author} slapped {message.mention} and a random gif but I have no idea how to. Can anyone help? Thanks!
#client.command()
async def slap(ctx, message.mention):
embedVar = discord.embed(title=f"<#{message.author.id}> slapped {message.mention}")
list = [
#gif links and stuff
]
await ctx.channel.send(random.choice(list))```
Your code has a few problems.
At first, I couldn't understand what you're trying to do with naming a parameter message.mention but I guess what you're trying to do is "slapping" the person you mentioned in command. For that, you have to get the member object in parameter. Then, you can mention this member.
Also, you shouldn't define a variable named list. This might cause a error because of the built-in method list.
An another thing is, there's no embed method for discord module, it must be discord.Embed. You have to pay attention to the uppercase letters.
You never sent the embed you defined, you must send it for your command to work.
For the last one, I don't know what'll be in the list lst but I guess there will be files. If you're going to send a file, you cannot just send it. You have to pass a parameter in .send() method. But this is only for the files. If you're just going to send a link, then you don't have to pass any parameters.
#client.command()
async def slap(ctx, member: discord.Member):
embedVar = discord.Embed(title=f"{ctx.author.mention} slapped {member.mention}")
lst = [
#gif links and stuff
]
await ctx.channel.send(file=discord.File(random.choice(lst)), embed=embedVar)

discord.py-rewrite - How to use custom checks in cogs?

So, on my bot.py main file, I have:
class Bot(commands.Bot):
# BOT ATTRIBUTES
class default_cooldown:
maxcommands = ...
seconds = ...
mode = ...
class my_exception(commmands.CommandError): pass
def my_check(self):
def predicate(ctx):
if ctx.author in a_list: return True
raise self.my_exception
bot = Bot(...)
Now I also have a cog file where I want to use the Bot().my_check() check and my Bot().default_cooldown() class:
class Cog(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
#self.bot.my_check()
#commands.cooldown(self.bot.default_cooldown().maxcommands, self.bot.default_cooldown().seconds, self.bot.default_cooldown().mode)
async def a_command(self, ctx):
pass
But I get an error, saying that self is not defined on my check and cooldown. Can anyone please help me fix this problem?
Methods are created once when the class object is created, not individually for each instance. You have a couple of options:
Factor out the code that need to appear in both places to a third module that contains just that code, then import that into both of your other files
Move your Bot definition into a separate module from the execution of your bot, and make my_check a staticmethod. Then you can access it through Bot.my_check instead of through the specific instance.
Define your cog inside setup so that the class is aware of the bot instance when it is created.

How can I manage authorization in GAE using Google Accounts?

So far I have used oauth2 to manage authentication using Google Accounts for my app, which gives me some data to complete a basic profile. The problem is that I now want to manage permissions to view and edit a lot of the content in the app, with different groups of people being able to view/edit different parts of the app.
I want some parts of my application to be accessed by users with permission for A, some for B, C, etc. The way I started doing this was using a decorator in the get and post method of each handler, like this:
class SomeHandler(Handler):
#validate_access
def get(self):
pass
#validate_access
def post(self):
pass
Where #validate_access executes the code in the function only if the user has permission for it, and returning an authorization error if not. This seemed to be a good solution a while back, but since there are many handlers I have to use that decorator everywhere, which is annoying and dangerous, since I may forget to put it in some functions.
Is there a way to put this validations in the initialization of the base handler, so that I don't have to use that decorator everywhere? I imagine something like this:
class BaseHandler(webapp2.RequestHandler):
def initialize(self, request, response):
super(Handler, self).initialize(request, response)
self.user = users.get_current_user()
employee = Employee.query(user_id=self.user.user_id).get()
if employee.auth_level > 3:
#See the content: Do whatever the "get" method of the corresponding handler does.
pass
else:
#Raise authorization error
pass
Or is there a better way to do this? (Sorry if it's a basic question, I've never done this before)
Yes, you can overwrite the webapp2 dispatch handler for this purpose. I used this method to enforce role based access control (RBAC).
Example code:
class BaseHandler(webapp2.RequestHandler):
""" webapp2 base handler """
def dispatch(self):
# UserAccess aborts if the user does not have permission to use a handler
UserAccess(self.request)
super(BaseHandler, self).dispatch()
....
class ExampleHandler(BaseHandler):
def get(self):
.....
I use a config file with the allowed roles for a handler. This file is also used to create the webapp2 routes and the dynamic user menu.

Resources