#discord-bots
1 messages Β· Page 302 of 1
Probably looks wacky as a d.py dev
But I ran into hard limits with their command system
I cant directly modify its internals
I'm stuck with the functions and arguments they give me
It's either this, write my own lib, or use Go/TS
The latter of which allow you to modify internals and be more low-level with how things are implemented
One limit, checks have to return true/false, and cannot be passed anything except context, you can't supply your own data
iirc wants to learn how to make a discord bot lib
When defining a command, all you have to give the command itself variables/attributes are by passing a named dictionary in the decorator, you cant pass unnamed arguments
u can acess the bot via context
The strings in the decorator are set to command.endpoint, can access that with ctx.command.endpoint
ideally ur bot class should have access to all the other data like db and api calls to maybe third party apis
That's a core reason I did this ^
I dont want to pass a named dictionary to make a command have an endpoint string
Which afaik, can only be accessed inside of the command
I need to built an API url with those per-command endpoint strings
sorry but, Command.extras is made for that, and the thing you're describing about checks, it's possible to do that without rewriting the entire library
Main cmd: prefix
Sub cmd: add
Url: main+sub+guildid
Makes things like this easy as possible
I know, but it doesn't function in the way I need it to, and I need to rewrite the event system regardless
is it for your discord clone?
So the bot can control incoming events (stop accepting before they can even be read fully)
For my security bot, most anti raid bots fail because of the massive amount of events pouring in
They start slowing down and coming to a grind, I will be preventing those events from even being processed to try and minimize that
I really should be using a low level language like go, but I'm trying to stick with python for this bot
it sounds like you have to optimize your bot, not the framework itself. unless you have concrete data (i am referring to statistical analysis and compiling all of the numbers to prove mathematically that the framework is slowing down) to prove otherwise, I am not convinced you need to do all of this
also please analyize your marginal costs when it comes to this
Once I finish this, I'm actually going to perform that analysis to a point
Its hard to do in the real world because you need to have 1000s of users spamming as fast as the discord API lets them
And then actually have your bot defend against that
But that is still a big point of failure, I've been on both ends of that field, and I know that even just processing thousands of events per second can slow things down
hmm, perhaps for that goal i think you'd be better off working to make your bot scalable with sharding rather than prematurely optimizing a single process
Oh it is, but i go the full length when it comes to optimization
If it can be improved, and I can improve it, I'm gonna attempt
Even as far as I've gotten with that, my bots memory usage went from 41-49mb, to 29mb
For me that alone is enough to keep going and not just optimize on my bots end when I can go a step higher and get better gains
I studied their source code and it does extra things that aren't needed in my usage, and keeping copies of everything in 2, sometimes 3 dicts, lots of bloat my bot doesn't need, and will never need
keeping copies were done to prevent race conditions and what not that happened in the past, i remember when even reading message cache could trigger it
Ye, I saw that, looks like it's not gonna be an issue for me, especially with the design of my logic
if you're willing to rewrite, this might be a good candidate for developing a more bare-bones wrapper over the discord API
I mean, even if it ends up being fucked, I'll have some experience for my discord clones py lib, so it's a gain in my book
Yeah I'm thinking of that, but that would be near when I'm doing my own lib for my clone
Looking at d.py source has been putting me off on that a little, looks like it's a massive job
I would probably end up forking it instead of from-scratch
I love bare bones esque libs, I loved d.js for it, so its definitely on the backburner
Honestly, you might be right
I've looked at well over 15k lines of code and that's not even half of their source
The hardest part was figuring out what a function does, because its defined 2/3+ times in 2/3 classes, in 2/3 different files
yeah, you also need to understand all the code and to think to a better alternative that could be difficult to find when looking at the source code, instead if you create a library from scratch you are free to design everything
obviusly every class works in conjunction with others so working from scratch it's definetely easier
I've never been as confused in my life I cant lie
mh could you mention the files?
For the most part I based what I have from their code, but now that core things work, I'm going from scratch
Take a peep at ext.commands.py
you mean the overloads and the typings?
Then search for command in the sidebar
That too, but nah
Its just hard to figure out what things do when you cant find the right function, and when you do, its calling another function that takes more time to figure out, and you keep repeating
If anyone wants to see what I've come up with I can drop the repo, super bare bones
A little monkey patching with copying the command dictionary to the bots internal one, but that's about it
you mean in ext/commands/core.py?
Yeah sorry, on phone rn, hard to type
as @silent @golden portal said, most of them are typing overloads for the actual command decorator
sigh no silent mention
me when
Oh yeah ik, it was just hard to traverse and find the real function and whatnot
oh yeah ik that feeling, this happens a lot in the logic to invoke the commands and to fill the commands.Context or Interaction objects with actual data
the actual function is always the last, since overloads must be before the actual function definition
I had an aneurysm trying to backwards engineer it, but its alot more fun now that I have everything needed and can write stuff from scratch
Tbh idk what overloads are, I learned about them reading the source
Never learned how to make decorators until I started this either, never gone this deep with python
!d typing.overload
@typing.overload```
Decorator for creating overloaded functions and methods.
The `@overload` decorator allows describing functions and methods that support multiple different combinations of argument types. A series of `@overload`-decorated definitions must be followed by exactly one non-`@overload`-decorated definition (for the same function/method).
`@overload`-decorated definitions are for the benefit of the type checker only, since they will be overwritten by the non-`@overload`-decorated definition. The non-`@overload`-decorated definition, meanwhile, will be used at runtime but should be ignored by a type checker. At runtime, calling an `@overload`-decorated function directly will raise [`NotImplementedError`](https://docs.python.org/3/library/exceptions.html#NotImplementedError).
πΏ when the bot doesn't even know what it is
for example you use an overload when the function could return different types based on the types of the arguments
Ahh
but it depends on the complexity, in some cases you could also use a TypeVar
I've only recently gotten into typing, I used to never define types or return types, it was pure spaghetti
π
Gonna bookmark that and head off to bed, getting real late here, ty for the talk
Gonna drop this before I sleep incase anyone's interested https://github.com/Serbirial/discommand
Discord.py Custom command logic, from the ground up. - GitHub - Serbirial/DisCommand: Discord.py Custom command logic, from the ground up.
Not really any documentation, just got it fully working today, but it works
I checked mine and only 79MB is being ran. Unsharded so there isn't a need to optimize for ram
And considering the bot that I'm running spans over 10,000 lines of code, it's still pretty decent that it's only taking that much
I already know optimizing the lib itself would be a complete waste of time in my case, so I chose not to
mh the on_ready event could be called multiple times during the life cycle of a Bot, if a cog is already loaded you should handle the logic to reload it, so are you already handling it?
I'd rather load the cogs in setup_hook to begin with
Hey everyone. I am wondering, if anyone has an example of using lavalink on a bot. Specifically how to just call the py file on the server and inside let the java jar being executed. The issue on my side with subprocess seems to be, that it needs to be called from within the jar folder while the python script is on the root folder of the project. I am quite new to python and java integration, so any help is greatly appreciated
me too
@spotify.command(name="test", description="Get spotify track info")
@app_commands.describe(link = "Spotify track link")
async def test(interaction: discord.Interaction, link: str = None):
await interaction.defer(ephemeral=False)
guild = interaction.guild
guild_member = guild.get_member(interaction.user.id)
activities = guild_member.activities
for activity in activities:
if isinstance(activity, discord.Spotify):
track_id = activity.track_id
break
else:
track_id = await extract_spotify_id(link)
interaction.followup.send(f"Track ID: {track_id}")
is this the correct way to get track ID from user activity?
its throwing Hybrid command raised an error: Command 'test' raised an exception: AttributeError: 'Context' object has no attribute 'user', so I guess not, any fix?
your interaction is just a Context object, it's Context.author, not .user
should rename that variable and the typehint tbh, it's misleading
thank you
Context is always given for hybrids
i believe they wrote it like that so hybrid commands could smooth over the transition to slash commands for some people, i.e. interactions get turned into context objects with methods being adapted to their equivalent interaction methods, plus a few extra interaction-specific attributes/methods if you're willing to use them
Don't they have a separate class for that?
for actual application commands yes
src/thestarboard/cogs/stars/commands.py lines 136 to 140
async def config_set_channel(
self,
interaction: discord.Interaction,
channel: discord.TextChannel | None,
):```
hybrid commands try to work the same as prefix commands, going as far as to provide the same API
https://discordpy.readthedocs.io/en/stable/ext/commands/commands.html#hybrid-commands
!d discord.ext.commands.Context.interaction is there if you want to use the real interaction when it's available
The interaction associated with this context.
New in version 2.0.
embed.set_image(url="https://cdn.discordapp.com/attachments/1099693772608122982/1104408296967897170/fall-autumn.gif")```
Normally when I run the bot, this would post the gif, but for some reason the gif is not posting, idk what to do
share the entire relevant code, because this line in itself isn't wrong
@client.tree.command(name = "help", description="shows the command list")
async def help(interaction: discord.Interaction):
user_id = interaction.user.id
user_name = interaction.user.name
embed = discord.Embed(title= " Command List ",
description= " </help:1135286623223959672> - shows the list of commands \n"+
" </info:1135286623223959673> - shows the list of available aesthetics \n"+
" </light:1135286623429468250> - shows the light academia related themes \n",
color=discord.Color.dark_orange())
embed.set_image(url="https://cdn.discordapp.com/attachments/1099693772608122982/1104408296967897170/fall-autumn.gif")
embed.set_footer(text="Have a nice day!")
data = {"content": f"User {user_name}({user_id}) used help."}
response = requests.post(webhook_url, json=data)
await interaction.response.send_message( embed = embed, ephemeral=False)```
is the indentation correct?
yep, in the code it is correct
It is not with just this gif, the commands where some other pictures are supposed to be posted, even they aren't posting
does the bot have permissions for embed links? I'm not sure if that could be a reason or not though
and what does it show in the embed
nothing at all?
Only the texts, and not the image part, it does have perms for embed links. In two of my commands, the gifs posted, but in other one's it isn't posting, that's why I can't figure out what's going wrong
the same code is working for me
all i changed was the spaces, discord -> disnake (shouldnt matter) and the description
It doesn't post the gif in the embed or the message at all?
How do you make a pull bot on discord? Like restore cord?
gif in the embed
spaces where?
just the weird discord wrapping
all this extra whitespace u see
They don't change something
The code is working fine tho, i also checked it Β―_(γ)_/Β―
is something wrong with my system then? idk, the images aren't posting and thats the only issue, the images where posting fine a few days ago even
this is what its supposed to show yeah
honestly couldn't tell you, the code seems to be fine
maybe try it in another server? restart your bot? worth a shot
How do you make a pull bot on discord? Like restore cord?
what does restore cord do?
Ill try, thank you all
not documentation
You give permissions to allow the bot to join servers for you, so if the discord gets nuked or deleted or something you can make a new server and pull everyone that gave permissions to the other server
Like, it joins servers for you
It's made with guilds.join scope
But I never used it so can't tell something more, maybe someone else will or you can just google how to use it
Ya need a site to obtain user oauth token and then use some endpoint
wdym?
that's very brief, i'm not sure what the sentence was supposed to tell me
ik guilds.join give the bot permission
you need a web server running to redirect user to and then catch his token then exchange it with discord api for token to access users data
if you are new, i dont recommend going into this its pretty complicated
why would i need a web server for this?
i could store his token within my bot files
i just don't know the endpoint to use the token
i've been looking it up but could not find it
You get a link from url generator, set there your website which will receive access tokens when user uses it, then you use that token in the request https://discord.com/developers/docs/resources/guild#add-guild-member
Because for guilds.join you need a url where you will receive requests from discord
If the endpoint for using token is actually the only problem by you, then there is the link ^
- User goes to your site (optional)
- Your site redirects to discord oauth2 link
- Discord redirects back to your site and passes code for exchanging it to token
- You exchange code for token and can make user join server by making a request to "add user to guild" endpoint
ok that makes sense
that makes sense but it so hard to make π
I made it for bobux bot dashboard in next.js βΊοΈ
It still regularly throws some cookie errors but nothing too bad happens
i will be making dashboard with next soon too
you know when you click on certain discord profiles it says "Hi! im new to discord" is there a way to check if an account has this tag
no, but u can just check when their account was created if you want
Just check the joined at datetime of a member and compare it to see if it's less than 7 days old
!d discord.Member.created_at
property created_at```
Equivalent to [`User.created_at`](https://discordpy.readthedocs.io/en/latest/api.html#discord.User.created_at)
Joined at
doesn't your profile say "hi I'm new to discord" only if you recently joined discord and not the server?
thats not what they are talking about
There is new to discord too?
your profile has a message "Hi im new to discord" here if you are new to discord
somewhere around this region
ok
then created, yeah
why not just look at the date below member since :/
lmao
I was just curious , let's say I sent a message in a server and they banned me and I can't access the server to delete my message , can I still delete the message via discords API endpoint if im not joined in that channel? ( btw this didnt actually happened im just wondering incase it did )
No
Doesn't work like that
Oh alr
Well if I wanna delete a message in a channel I'm joined in will this work ?
import requests
def delete_message(token, channel_id, message_id):
headers = { 'Authorization': f'Bearer token'
}
response = requests.delete(f'https://discord.com/api/v10/channels/{channel_id}/messages/{message_id}', headers=headers)
if response.status_code == 204:
print("Message deleted successfully.")
else:
print("Failed to delete the message.")
( it didnt work for me for some reason)
requests.delete(url, **kwargs)```
Sends a DELETE request.
Also you can only do this for bots, not users
Hm?
I tried it both for bot and user token
Neither worked
Bot had perm to delete the msg btw
What's the point in doing this with raw requests
What's the response
Status code?
Content of what??
The response...
Bro wym
property text```
Content of the response, in unicode.
If Response.encoding is None, encoding will be guessed using `charset_normalizer` or `chardet`.
The encoding of the response content is determined based solely on HTTP headers, following RFC 2616 to the letter. If you can take advantage of non-HTTP knowledge to make a better guess at the encoding, you should set `r.encoding` appropriately before accessing this property.
Oh
Yeah lemme add it to my code
Oh
401 unauthorized πππ
Bro why is it unauthorized...
?
Someone help, I keep getting JSON Decode Errors on this and it keeps saying something about expected value mane
@bot.command()
async def operator(ctx, operator_name):
response = requests.get(f'https://r6tab.com/api/operators?name={operator_name}')
data = response.json()
if data['totalresults'] > 0:
operator_data = data['results'][0]
embed = discord.Embed(title=f"Operator Information - {operator_data['name']}", color=discord.Color.blue())
embed.add_field(name="Role", value=operator_data['role'])
embed.add_field(name="CTU", value=operator_data['ctu'])
embed.add_field(name="Armor", value=operator_data['armor'])
embed.add_field(name="Speed", value=operator_data['speed'])
await ctx.send(embed=embed)
else:
await ctx.send("Operator not found.")```
You're definitely doing something to break TOS, especially since you mentioned you were trying to use your user token
I won't be apart of it
Share the error
Also, you deleted the screenshot for a reason
Firstly That wasn't even for discord, secondly why tf you looking at my files π
cam_hackers was another one iirc
Could you print the content?
Because I fucking showed my directory for no reason ...that was weird to do
Not gonna help
I don't know how to
That tool was just a list of public ip cameras .... And??
bro shut up, you have white hat hacker in your about me, it's obvious you're a Discord ToS breaker.
!d requests.Response.text
property text```
Content of the response, in unicode.
If Response.encoding is None, encoding will be guessed using `charset_normalizer` or `chardet`.
The encoding of the response content is determined based solely on HTTP headers, following RFC 2616 to the letter. If you can take advantage of non-HTTP knowledge to make a better guess at the encoding, you should set `r.encoding` appropriately before accessing this property.
that dosent help
Also, requests is blocking, so you should be using aiohttp instead
Bro just ask that guy @final iron he saw my directory , most of my folders were pentesting tools
See if it's proper json
And btw no one asked ur opinion
get() returns a Response object
I'm not stupid, I saw the files and they are for malicious purposes
Blame android
Send the error
2023-09-14 22:35:06 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: c3f1e7dfcafe225d41616c9989fa9541).
Logged in as Warden (1151983781658509382)
------
2023-09-14 22:35:14 ERROR discord.ext.commands.bot Ignoring exception in command stats
Traceback (most recent call last):
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/discord/ext/commands/core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
File "<string>", line 24, in stats
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/aiohttp/client_reqrep.py", line 1104, in json
raise ContentTypeError(
aiohttp.client_exceptions.ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: text/html; charset=utf-8', url=URL('https://r6tab.com/api/search.php?platform=uplay&search=nwgo')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
await ctx.command.invoke(ctx)
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/discord/ext/commands/core.py", line 1029, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/discord/ext/commands/core.py", line 244, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: text/html; charset=utf-8', url=URL('https://r6tab.com/api/search.php?platform=uplay&search=nwgo')```
idk what to do
They are not for gods sake
Use json.loads instead
What do you even know about pentesting, lemme guess, nothing
Send that same screenshot and I'll pick everything out that's malicious
Put the text into json.loads(), see if it converts into proper json/dicts
where do I put that
yea but like where abouts in the command
Wherever you need it?
I can't read your mind, I don't know how the command is structured
bud done deleted most of his files
lmao
I didnt delete anything bro π
Yeah I did move that to "dump" directory cuz idk if someone report me to discord for it might get false banned
Aight bud
Could I pass an interaction object into a loop after it has already started?
Yea that's ToS Breaking.
I'm gonna go ahead and report you to discord for that one buddy.
Why is it
Firstly your a fucking asshole for doing that secondly , what's wrong with it
If you was so innocent, why are you swearing at me?
is it possible to get a reference of a reference in d.py?
like message.reference.reference?
Calling another member of our server a "fucking asshole" is very much a violation of the #code-of-conduct that you agreed to when you joined us.
What are you trying to do
i'm planning to get the message reference of the message refered
message reference
refered to the message with reference
So you're trying to get the first message in a string of replies
yes, i think
if that is the correct name
!warn 1144977842250203227 using a user account token to run a discord bot (self-botting) and calling other people "fucking assholes" are not allowed. Please review the rules if you want to be able to keep using the server.
:incoming_envelope: :ok_hand: applied warning to @slate swan.
Message.reference is only applicable to pinned messages
!d discord.Message.reference
The message that this message references. This is only applicable to messages of type MessageType.pins_add, crossposted messages created by a followed channel integration, or message replies.
New in version 1.5.
What you'd have to do is something like - if MessageType.reply, get that message, if that has the same then go to the next... something along that route
Does commands.cooldown work on application commands
You want app_commands.checks.cooldown
!d discord.app_commands.checks.cooldown
@discord.app_commands.checks.cooldown(rate, per, *, key=...)```
A decorator that adds a cooldown to a command.
A cooldown allows a command to only be used a specific amount of times in a specific time frame. These cooldowns are based off of the `key` function provided. If a `key` is not provided then it defaults to a user-level cooldown. The `key` function must take a single parameter, the [`discord.Interaction`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.Interaction) and return a value that is used as a key to the internal cooldown mapping.
The `key` function can optionally be a coroutine.
If a cooldown is triggered, then [`CommandOnCooldown`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.CommandOnCooldown) is raised to the error handlers.
Examples
Setting a one per 5 seconds per member cooldown on a command:
Can I use BucketType?
I think so? Not sure
One sec I think I used that in a project
message_cooldown = commands.CooldownMapping.from_cooldown(1.0, 5.0, commands.BucketType.user)
@bot.event
async def on_message(message):
bucket = message_cooldown.get_bucket(message)
That's the only time I've used it
Apparently not
Checks out
File "C:\Users\Tikho\PycharmProjects\MainBot\venv\Lib\site-packages\discord\ext\commands\cooldowns.py", line 66, in get_key
return msg.author.id
^^^^^^^^^^
AttributeError: 'Interaction' object has no attribute 'author'
I don't have member intents though
Possibly what's causing it
Interactions have users not authors
Yup lol
Do you know if I could pass objects into a tasks.loop after it's started?
You can, it's not suggested though
Mainly for update purposes
okay so, how do i grab the message embed?
You're just trying to put a cooldown on an interaction?
Yes
like, i'm planning to grab the embed of a message in a reference
BucketType.user
This is an issue with discord.py though, not my code
@app_commands.checks.cooldown(1, 5.0, key=commands.BucketType.user)
!d discord.Message.embeds
A list of embeds the message has. If Intents.message_content is not enabled this will always be an empty list unless the bot is mentioned or the message is a direct message.
The key for your cooldown is another cooldown?
if self is BucketType.user:
try:
return msg.author.id
except AttributeError:
return msg.user.id
meh
Simple fix
wdym
!d discord.ext.commands.BucketType.user
The user bucket operates on a per-user basis.
Thought the key was what you wanted a cooldown on.
key (Optional[Callable[[discord.Interaction], collections.abc.Hashable]]) β A function that returns a key to the mapping denoting the type of cooldown. Can optionally be a coroutine. If not given then defaults to a user-level cooldown. If None is passed then it is interpreted as a βglobalβ cooldown.
Not sure what you mean tbh
Idk what I mean tbh. Lol
key is BucketType.user so it's tracked by user, not by guild or member/whatever
So don't give it a key? Defaults to user level
It's a good find and simple fix
Nice
how do i convert an embed object into an embed?
An embed object is an embed...
huh
It's an embed object, why would you need to convert it
Are you trying to like find items inside the embed? You do like embed.description or whatever you're trying to get
This will return a list of embeds, you select which from the list and you can grab whatever attribute you're looking for
If you're just trying to re-send it you just add it to a new message with the embed argument
Does anyone have any guides for hosting on Linux (Raspberry PI)?
Finally can put this damn bot into beta testing
just yesterday i re-flashed my rpi4 with the 64-bit lite OS, it should give you more compatibility with compiled wheels on pypi (see my pains here #tools-and-devops message) and cut out desktop software that you don't need (it also appears to have fixed my rpi undervolting too so it might as well be some magic sauce to me)
I will do that
my two older bots dont use docker so i copied over my systemd services to keep them up
alr lol
I have no clue what to do, but that sets me on the right track
Are there any good montioring tools I should use?
I was thinking about adding some owner commands for tracking things such as memory, CPU usage, temperature of components etc
Good idea or nah?
im definitely not the guy for that, all i do is login to run htop and journalctl -f -u thegamebot whenever i notice issues
oh if you want them as bot commands, psutil could help you there
And my whole setup wouldn't be ideal for logging onto a monitor
It'll be in a soundproofed box in the basement lol
you might be able to setup xrdp if you do want a GUI, although it seems to be more difficult on a lite installation
https://pysselilivet.blogspot.com/2017/11/raspbian-lite-with-gui-rdp-vnc.html
https://www.reddit.com/r/raspberry_pi/comments/qw1cdw/raspberry_pi_4_xrdp_windows_10_remote_desktop/jjii4fv/
after following the above fix i still only see a terminal and no desktop, so that's probably more trouble than it's worth
okay so, is there a reaction listener?
like:
@commands.cog.listener
async def on_reaction(self, reaction):
...
This is something you should just check the documentation for
Event reference in the dpy docs
uhmm:
Ok so I need help, I've made a command that adds all the channels, and roles, server name, and icon to a .txt file, I now want it to restore that backup file and change the server name, icon etc, like how the Xeon bot works, but I want my own, I don't know how to figure out how to read the channel names and roles etc
Why would I be getting nan when accessing the bots latency?
embed.add_field(name="Latency", value=f"{self.bot.latency * 1000} ms")
Why not use a database?
Reading the names out of the text file, or before inputting them?
Storing data directly to a db
I'd rather use .txt files, as I tried using mongoDB before and it didn't go well
you rather
I want it to read them, and creates channels based on the names it gets from the .txt
Who the hell rathers stores persistent data to a txt file ?
You're going to run into many, many issues using txt files
Filtering, sorting, updating and inserting data is going to be an absolute pain
breh
File corruption, file locking, non-atomic reads and writes, poor filtering options, significantly worse to using a database
It's like bringing a spoon to a gunfight. You literally have no good reason to not use SQL databases
but idk how to connect to a database tho, e.g MongoDB
SQLite
Mongo is not suited for the task of dbots
Is it paid for?
SQLite is a file-based lightweight database perfect for small discord bots
Oh completely free
can I have a website where I can look?
A lightweight SQL database library that uses one file per database. Useful for small bots (for larger scale bots consider using PostgreSQL instead). To use it in asyncio, consider using aiosqlite[1] or Danny's wrapper library, asqlite[2]:
[1]: https://pypi.org/project/aiosqlite/
[2]: https://github.com/Rapptz/asqlite
See the drivers above
So looking at source code it seems the websocket is None
Which is strange, and the docs don't mention anything about it
It's also returning nan in other commands
Where is this piece of code located?
the latency is NaN when the bot is not connected to discord with a websocket connection
Client.latency will be an actual float/int only after bot is running
Itβs just in a command
The embed sends fine, and there are no errors
The value is just nan
weird, do you have multiple bot instances by chance?
Shouldnβt, I also reset my bot token, which shouldβve removed any other instances
I mean multiple instance of Bot class in the same project
Nope
I have my bot class and the cog itself in the same file if that matters
I'm using discord.ext.commands.Bot.start() if that matters as well
Why don't you simply use bot directly instead of self.bot then
or is the instance in a different file
Can you show full code
commands.Bot is subclassed, code is in a cog
I got it partially solved in the dpy server, ended up just accessing by bot object with Context.bot
did it work? I think it should cause ctx.bot will always return the active bot
Yeah it did, itβs still kind of a workaround though
Hey I have been trying to see how to sync a slash command that is in a cog to a guild and I can't figure it out. Can someone help?
async def load_cogs():
await bot.load_extension("cogs.utils")
print("done")
@bot.event
async def on_ready():
try:
await bot.tree.sync()
except Exception as e:
print(e)
print(f"{bot.user} is now online!")
changepresence.start()
bot.db = await aiosqlite.connect('level.db')
async with bot.db.cursor() as cursor:
await cursor.execute("CREATE TABLE IF NOT EXISTS levels (level INTEGER, xp INTEGER, user INTEGER, guild INTEGER)")
await bot.db.commit()
await load_cogs()
example how I make my slash commands:
lass utils(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
@discord.app_commands.command(name="userinfo", description="list everything about the user!")
async def userinfo(interaction: discord.Interaction, member :discord.Member):
roles = []
if not member:
member = interaction.user
for role in member.roles:
roles.append(str(role.mention))
roles.reverse()
embed = discord.Embed(title=f"{member}'s user info")
embed.add_field(name="Username:", value=member.name)
embed.add_field(name="ID:", value=member.id)
embed.add_field(name="discriminator:", value=member.discriminator)
embed.add_field(name="Created at:", value=datetime.strftime(member.created_at, "%A, %B, %D-, %Y"))
embed.add_field(name="Joined in:", value=datetime.strftime(member.joined_at, "%A, %B, %D-, %Y"))
if len(str(" | ".join([x.mention for x in member.roles]))) > 1024:
embed.add_field(name=f"Roles: {len(member.roles)}", value="Uh oh our system says that this person has too many roles!")
else:
embed.add_field(name=f"Roles: {len(member.roles)}", value=" | ".join(roles))
embed.add_field(name="Role Color:", value=member.color)
embed.set_thumbnail(url=member.avatar)
await interaction.response.send_message(embed=embed)
async def setup(bot):
await bot.add_cog(utils(bot)) ```
just a rushed example, i personally use a bool thats set to True when cogs are loaded, so they cant be loaded again
First of all never do anything in on_ready event if you are using dpy
Secondly do you want this command to only appear in 1 guild or all guilds?
There's no law against it
there isn't but it's consider really bad practice
This function is not guaranteed to be the first event called. Likewise, this function is not guaranteed to only be called once. This library implements reconnection logic and thus will end up calling this event whenever a RESUME request fails.
As per docs
ASYNCPG (postgres)
I'm wanting to store my user's messages in a db (the users who use my discord bot). The issue is I want to store the server_id + message_id and message in one table with all the users.
For example, say billy uses my bot, I'll store his user_id, the message_id, and the server_id. The issue is the bot can be used in any server, so I'd have to be able to add it, I want to avoid creating columns for each server as well.
do you not know how SQL works?
each server is a row on your table, with columns being the data that you want to store about that server
would recommend learn SQL from the ground up bc to me it seems like you don't understand it
If discord bot can make only 5 actions per second how big bots manage to serve all users?
clusters if i'm not wrong
uh techincially correct but that's the wrong def for dpy
sharding
clustering is more of a djs thing
right right, a group of shards is called a cluster
So 5 action per second per shard?
just to note, sharding is not needed until you get to 1000 guilds, and enforced by discord once you reach to 2,500
pretty sure dpy handles all of that for you already
me who has sharded my bot which is in 20 servers
very useless i know
if bot is used actively it could get to 5a/s even on one server
!d discord.ext.commands.AutoShardedBot
class discord.ext.commands.AutoShardedBot(command_prefix, *, help_command=<default-help-command>, tree_cls=<class 'discord.app_commands.tree.CommandTree'>, description=None, intents, **options)```
This is similar to [`Bot`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot) except that it is inherited from [`discord.AutoShardedClient`](https://discordpy.readthedocs.io/en/latest/api.html#discord.AutoShardedClient) instead.
async with x Asynchronously initialises the bot and automatically cleans.
New in version 2.0.
you aren't getting any benfits out of it
should handle everything for u i believe
yes
i knowww
then why continue?
ok then
Drop in?
what?
If i made discord.ext.commands.Bot bot i could just replace bot = line and it will work?
first determine if you need sharding at all to begin with
But i don't want my bot to be rate limited, but it reaches 5a/s easily
if your bot = commands.Bot right now, then yes it'll change to bot = commands.AutoShardedBot
sharding doesn't help with bypassing rate limits
i would say it's something to do your with your code than anything else
add cooldowns
Like if 5 users will ask it to execute command simultaneously
yea that's normal
And then 6th it won't be able to respond
sounds like blocking operations to me
Or that is per channel limit?
depends if you have cooldowns set for that
but more than likely you have blocking code
There's still no law against it. You can also just check if it was called before or not
Just let them do whatever they want
yes you can, but for loading cogs, it's highly discouraged. better options exist
not helping
They did not ask for help regarding the cog loading stuff
bc if you keep on letting bad practices slide, then you aren't teaching them anything. you need to look at other factors other than the problem because it could be valuable insight to them
in that case you just give them advice and let them do whatever they want
If they run into the next problem in the future, they will ask about it
@bot.event
async def on_message(m):
if m.content == "!roll":
await m.reply(random(1,10))
And suddenly 6 people decide to !roll, won't it get rate limited?
on_message gets rate limited very easily. you should use ext.commands instead
Just focus on helping with the current problems they're facing
you can provide the insight and prevent these in the future
like slash commands?
Uh no ic
slash commands use app_commmands, where there is a whole guide on it. ext.commands is meant to handle prefixed commands (eg !roll) instead
And it can handle more than 5/s?
oh yea it can. if R. Danny is in 9,000 guilds and still using prefixed commands, then a bot that has 5/s commands definitely can if using ext.commands
r.danny isnt sharded?
R. Danny is
the code for R. Danny is open source btw
One bot on 270k is forced to use slash commands
it's because discord forced them to
then thats probably the reason it can handle a lot of commands at once, I'd say you can just shard your bot. BUT it wont be of any use if the 6 people using your bot, use it in the same server @hallow kernel
no dont
sharding your bot in this case provides no benfits. and also stop suggesting nonsense
hope youre able to give them a better alternative then
i already did
Anyway i could make it respond with webhook so it won't have limit
great
up to you
I do know how sql works, I don't think you understand what I'm trying to accomplish.
then explain how would you design a schema representing your servers and the relations
i already gave my answer. will just wait for yours
Sorry this has nothing to do with discord bots, and I donβt know where to ask π but does anyone know of anyone here creates discord servers?
what do you need? templates?
you create another table "messages" with 4 columns: user_id, server_id, message_id and message_content
you could set the user_id as a foreign key to get a full user object from your database when fetching a message
you dont really need that foreign key. just point a reference to it
btw idk if this was already said before but i don't reccommend to store messages
Everyone does, just go ahead and press "create server" button
It's especially useless to store all messages
Just a great way to fill up storage with garbage and eventually end up paying more for hosting
Bobux bot has such a way to fill up storage with garbage
In fact, we add 576 useless numbers to a table every day
576 numbers is not really a lot
but storing content of every message from every server...
I wonder how much discord pays for hosting discord
Stocks π€
@bot.event
async def on_ready():
global pool
print("1")
await pool_connection()
print("2")
async with pool.acquire() as c:
print("3")
await c.execute("CREATE TABLE IF NOT EXISTS users (user_id BIGINT, messages BIGINT, connections TEXT)")```
For some reason it doesn't get to 3
pool = False
async def pool_connection():
pool = await asyncpg.create_pool(user='postgres', password='root', database='discord', host='localhost')
return```
And you don't get an error? You should get AttributeError
You have some error handlers maybe
And the reason of the error is because pool is still just False. You did change just a local variable
....
that's not how you store and use pools....
see this example on how to proper do it
Anyone wants to work on a project together?
It might help us learn new things.
(I just have 8 months of experience and I am not really good with discord.py)
zero knowledge here sorry
dw
if u need any help just hit me up, i will try my best to help. Okay?
@rough shuttle can I text you right now?
Why my webhook message is not being erased, and also why it's not entering my program and my code?
@commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
if not reaction.message.webhook_id:
return
print('is a webhook')
if await self.client.database.webhook_log_confirm(user_id=user.id, message_id=reaction.message.id) and reaction.emoji == ':x:':
print('entered')
webhooks = await reaction.message.channel.webhooks()
webhook = discord.utils.find(lambda webhook: webhook.token is not None,
webhooks)
if webhook:
print('deleted')
await webhook.delete_message(reaction.message.id)
It's not even coming to is a webhook, if i remove the reaction.message.webhook_id it still don't work but prints 'is a webhook'
Called when a message has a reaction added to it. Similar to on_message_edit(), if the message is not found in the internal message cache, then this event will not be called. Consider using on_raw_reaction_add() instead.
- if it doesn't print out
is a webhookthen it's 1. or it's not a webhook. reaction.emojican't be equal to:x:because it will receive the actual emoji for the built-in emojis
'β'
!d discord.Reaction.emoji
The reaction emoji. May be a custom emoji, or a unicode emoji.
import threading
class KeyboardThread(threading.Thread):
def __init__(self, input_cbk = None, name='keyboard-input-thread'):
self.input_cbk = input_cbk
super(KeyboardThread, self).__init__(name=name)
self.start()
def run(self):
while True:
self.input_cbk(input()) #waits to get input + Return
def my_callback(inp):
asyncio.run(channel.send(inp))
print(f"Sent: \"{inp}\"")
#start the Keyboard thread
kthread = KeyboardThread(my_callback)
Traceback (most recent call last):
File "/usr/local/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
self.run()
File "/home/container/bot.py", line 33, in run
self.input_cbk(input()) #waits to get input + Return
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/bot.py", line 45, in my_callback
asyncio.run(channel.send(inp.replace(answer, "")))
File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.11/site-packages/discord/abc.py", line 1664, in send
data = await state.http.send_message(channel.id, params=params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.11/site-packages/discord/http.py", line 718, in request
async with self.__session.request(method, url, **kwargs) as response:
File "/home/container/.local/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.11/site-packages/aiohttp/client.py", line 467, in _request
with timer:
File "/home/container/.local/lib/python3.11/site-packages/aiohttp/helpers.py", line 701, in __enter__
raise RuntimeError(
RuntimeError: Timeout context manager should be used inside a task```
Why does this happen in here?
how do i compare if the emoji is β?
can i just want the message being deleted if the emoji is β
emoji == "β"
uhmm that's curious
i can't copy it to my code being it an emoji β
what did you use for that?
all guilds
ik, but, i can't copy it to my vsc
i don't know if it accepts it
bump
!charinfo β
\u274c : CROSS MARK - β
!e print("\u274c")
@vale wing :white_check_mark: Your 3.11 eval job has completed with return code 0.
β
Less understandable but resolves all "compatibility issues" if such arise (they shouldn't)
channel.send should be inside the async task, not with just asyncio.run
you can do this mb
bot.loop.create_task(channel.send(inp))
they should use asyncio.run_coroutine_threadsafe instead of loop.create_task tbh, since asyncio objects aren't threadsafe
tho they should've just used aioconsole
False
True
strange...
@commands.Cog.listener()
async def on_raw_reaction_add(self, reaction):
if reaction.emoji == "β":
print("True")
else:
print("False")
if await self.client.database.webhook_log_confirm(user_id=reaction.member.id, message_id=reaction.message_id):
print("True")
else:
print("False")
if await self.client.database.webhook_log_confirm(user_id=reaction.member.id, message_id=reaction.message_id) and reaction.emoji == "β":
print('entered')
webhooks = await reaction.message.channel.webhooks()
webhook = discord.utils.find(lambda webhook: webhook.token is not None,
webhooks)
if webhook:
print('deleted')
await webhook.delete_message(reaction.message.id)
emoji in reaction_add returns Union[Emoji, PartialEmoji, str]
emoji in raw_reaction_add returns PartialEmoji only
I'm gonna have to learn how to use discord bot's in classes and cogs
i see
guess i have two ways of gathering the emoji
by name or by id
@buoyant quail which one you recomend, by name or by id?
oh so name
i need to make a test to see what β will return as name
okay so, according to this:
ERROR discord.client Ignoring exception in on_raw_reaction_add
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\client.py", line 441, in _run_event
await coro(*args, **kwargs)
File "c:\Users\User\Documents\GitHub\RP-Utilities\cogs\ActionCog.py", line 191, in on_raw_reaction_add
webhooks = await reaction.message.channel.webhooks()
^^^^^^^^^^^^^^^^
AttributeError: 'RawReactionActionEvent' object has no attribute 'message'
Since raw reaction don't have message i will need another way. And rawreaction just display message_id but not message
They have the channel_id
wait, somehow there is a way to gather webhook using channel id but the way to do it i don't know
how i will do it i have no idea
You are using the message only to get the channel where it was sent
You don't need the message at all
await channel.webhooks()
Get the channel by id
and... i'm lost, i'm trying to find discord.channel for reference but i'm not finding:
!d discord.Client.get_channel
get_channel(id, /)```
Returns a channel or thread with the given ID.
Changed in version 2.0: `id` parameter is now positional-only.
There is no such thing as "a channel"
There are DM channels, text channels, voice channels, etc but no "just a channel"
okay now it's workin'
how I can disable the mention in the message reply?
await send(content=None, *, tts=False, embed=None, embeds=None, file=None, files=None, stickers=None, delete_after=None, nonce=None, allowed_mentions=None, reference=None, ...)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).
Sends a message to the destination with the content given.
The content must be a type that can convert to a string through `str(content)`. If the content is set to `None` (the default), then the `embed` parameter must be provided.
To upload a single file, the `file` parameter should be used with a single [`File`](https://discordpy.readthedocs.io/en/latest/api.html#discord.File) object. To upload multiple files, the `files` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list) of [`File`](https://discordpy.readthedocs.io/en/latest/api.html#discord.File) objects. **Specifying both parameters will lead to an exception**.
To upload a single embed, the `embed` parameter should be used with a single [`Embed`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed) object. To upload multiple embeds, the `embeds` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list) of [`Embed`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed) objects. **Specifying both parameters will lead to an exception**.
!d discord.ext.commands.Context.reply
await reply(content=None, **kwargs)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).
A shortcut method to [`send()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context.send) to reply to the [`Message`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Message) referenced by this context.
For interaction based contexts, this is the same as [`send()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context.send).
New in version 1.6.
Changed in version 2.0: This function will now raise [`TypeError`](https://docs.python.org/3/library/exceptions.html#TypeError) or [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) instead of `InvalidArgument`.
if you're curious, i just finished my first wrapper for the discord gateway in a couple of days
https://github.com/thegamecracks/discord-ws ruby $ python -m discord_ws --env-token TOKEN --no-intents discord_ws.client.client ( DEBUG) => Requesting gateway URL discord_ws.client.client ( DEBUG) => Starting connection loop discord_ws.client.client ( DEBUG) => Creating websocket connection discord_ws.client.stream ( DEBUG) => Received 124 chars discord_ws.client.client ( DEBUG) => Received hello from gateway discord_ws.client.heartbeat ( DEBUG) => Waiting 42.17s for heartbeat discord_ws.client.client ( DEBUG) => Sending identify payload discord_ws.client.stream ( DEBUG) => Received 1855 chars discord_ws.client.client ( DEBUG) => Received READY event of course it's only got a few features and isn't really practical to use, but you can check out the source to understand how it handles heartbeating, session resumption, zlib transport compression, etc.
...
Why reinvent the wheel
There is something called the ui
U know u can ban members using the UI right
also with a built-in slash
Why
What does your bot offer over the built in UI or slash command?
Whatβs the error youβre getting
but the bot is giving me an error.
You said there was an error though

Your bot hasn't permission to kick that user
He has a better role or admin perms
Is there another way to check if my bot can successfully ban/kick someone before calling the method, other than manually checking roles/permissions/hierarchy?
I think you would have to check the role hierarchy yourself as well as the bot's guild permissions, but you should be able to just do something along the lines of ctx.guild.me.top_role > member.top_role quite easily
If your bot can't it will just receive an error
I think that'll work. I was a bit skeptical at first due to some edge cases where someone might try to ban the guild owner for example, but I just realized I can safely dismiss that
probably easier to just handle the errors as they happen though but it depends on what you're doing I guess
I want to do some stuff before performing the task, and I want to ensure that it'll correctly ban/kick the user so the bot doesn't have to waste time doing extra things that won't be used
I can't do it later either, because banning/kicking changes the state of the member
I see
Hey I got a little issue and I can't figure out what is wrong, this is my code under
For some reason the bot responds to the command in DM but doesn't on servers even tho I gave it Administrator
Any idea of what may be happening?
import discord
from discord.ext import commands
from discord.ext.commands import check
import json
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix = "!", intents=intents)
TOKEN = open("TOKEN.txt", "r").read()
# on_ready
@client.event
async def on_ready():
await client.change_presence(status=discord.Status.online)
print(">> BOT IS RUNNING")
print(">> Name: {}".format(client.user.name))
print(">> ID: {}".format(client.user.id))
# COMMAND: ping
@client.command(aliases=["Ping","PING", "p", "P"], help="Shows you the ping of the Bot")
async def ping(ctx):
ping = round(client.latency * 1000)
await ctx.send(f"**{ping}ms**")
# Client Run
client.run(TOKEN)
What does your create function look like? Might be triggering it when you hop into a new vc
I think you need message content intents
on_voice_state_update event
I have it enabled :/
Not in your code
oh I see what you mean, let me try
Only intents.members
unabled?
typo my bad
that fixed it, thanks β¨
Tbh I'm not super familiar with vc actions, maybe throw some print() statements around and see what's getting triggered
Deletion works when press the disconnect button, but when entering another channel (if have already been in another), most likely returns only the after value
But you're checking the id of the channel they entered correct? Not sure why that would be true if they're entering a different channel
no
If they did, they could just scroll up to where you were in here asking about how to build it
Sounds like you worked really hard to make one function and use it 100 times
reported π
I've implemented some of the code into my command and I was wondering, is the memory and CPU usage system wide, or for only the program?
Don't change your presence in on_ready
Don't change_presence (or make API calls) in on_ready within your Bot or Client.
Discord has a high chance to completely disconnect you during the READY or GUILD_CREATE events (1006 close code) and there is nothing you can do to prevent it.
Instead set the activity and status kwargs in the constructor of these Classes.
bot = commands.Bot(command_prefix="!", activity=..., status=...)
As noted in the docs, on_ready is also triggered multiple times, not just once.
Thank you for all the info
psutil.Process() only provides info for the current process, for system stats you'd probably want this
!d psutil.virtual_memory
psutil.virtual_memory()```
Return statistics about system memory usage as a named tuple including the following fields, expressed in bytes.
Main metrics:
β’ **total**: total physical memory (exclusive swap).
β’ **available**: the memory that can be given instantly to processes without the system going into swap. This is calculated by summing different memory metrics that vary depending on the platform. It is supposed to be used to monitor actual memory usage in a cross platform fashion.
β’ **percent**: the percentage usage calculated as `(total - available) / total * 100`.
Other metrics:
and https://psutil.readthedocs.io/en/latest/#cpu for cpu
ive never timed them but i would hope that the system calls dont take that long
I've been getting weird outputs with cpu_percent(), varies from 0.1, to 74%
Also, in my requirments.txt file, do I need to specify anything if a package can only be installed from git?
asqlite doesn't have a pypi package
https://peps.python.org/pep-0440/#direct-references
you can specify it as one of: git+https://github.com/Rapptz/asqlite@fcd8ce0672562e440f99eb4b7a56eba16f6abf4e asqlite @ git+https://github.com/Rapptz/asqlite@fcd8ce0672562e440f99eb4b7a56eba16f6abf4e
Cool and how should I setup my ssh keys on my raspberry pi lol
i think you have to average it out yourself, or use psutil.getloadavg() instead
I'm flashing it's OS to lite right now
there's an option in the raspberry pi imager where you can paste it there, just note that it looks like a single-line input but you can still paste all the contents of your .ssh/authorized_keys
p.s. if you don't have an authorized_keys prepped, grab each public key from your *.pub files and combine them into one file, e.g. ssh-rsa256 ... ssh-ed25519 ... then copy that to the imager
is there a place for help with twitch bots?
hmm im not sure twitch bots apply to any topical channel here, #1035199133436354600 seems to be the most common place for asking about them
Seems like I lost my SD to USB card reader
Guess I'll have to do this another day
Nevermind actually
Sorry, I've never done this before
Where could I find the *.pub files?
%USERPROFILE%/.ssh on windows given that openssh client is installed and you ran ssh-keygen -t ed25519 with the default location
this is getting off topic but im not which topical channel applies so ping me in an off-topic channel
Ok so I made a few error handlers, I wanna know if these would work how I hope in the actual error message it sends
@bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
embed = discord.Embed(title="Permission Error", description="You don't have enough permissions to use this command.", color=discord.Color.red())
await ctx.send(embed=embed)
elif isinstance(error, commands.BotMissingPermissions):
embed = discord.Embed(title="Permission Error", description="I don't have enough permissions to use this command.", color=discord.Color.red())
await ctx.send(embed=embed)
elif isinstance(error, commands.MissingRole):
embed = discord.Embed(title="Role Error", description="Your role is not high enough to use this command.", color=discord.Color.red())
await ctx.send(embed=embed)
elif isinstance(error, commands.MissingAnyRole):
embed = discord.Embed(title="Role Error", description="I don't have enough role to perform this command.", color=discord.Color.red())
await ctx.send(embed=embed)
else:
embed = discord.Embed(title="Command Error", description="Oops! An error occurred while executing the command.", color=discord.Color.red())
await ctx.send(embed=embed)```
the first four look fine, but i would suggest adding a raise error at the end so it shows up in your console, otherwise you won't know what the error is
where do I put that π€
oh the message for commands.MissingAnyRole is misleading, since that exception is for the user - the equivalent error for @commands.bot_has_any_role() would be commands.BotMissingAnyRole
after your ctx.send() in the else: block
π€
import asyncio
import logging
import logging.handlers
import os
from typing import List, Optional
import asyncpg # asyncpg is not a dependency of the discord.py, and is only included here for illustrative purposes.
import discord
from discord.ext import commands
from aiohttp import ClientSession
import json
with open('./Discord Logger/config.json', 'r') as c:
c = json.load(c)
token = c['token']
class CustomBot(commands.Bot):
def __init__(self, *args, db_pool: asyncpg.Pool, web_client: ClientSession, testing_guild_id: Optional[int] = None, **kwargs,):
super().__init__(*args, **kwargs)
self.db_pool = db_pool
self.web_client = web_client
self.testing_guild_id = testing_guild_id
def add_data(self, user_id, message_id, server_id, message_content, date):
c.execute("INSERT INTO messages (user_id, message_id, server_id, message_content, date)")
def add_task(self, user_id, message_id, server_id, message_content, date):
with asyncio.TaskGroup() as tg:
tg.create_task(self.add_data(user_id, message_id, server_id, message_content, date))
def on_ready(self):
print("1")
with self.db_pool.acquire() as con:
print("2")
con.execute("CREATE TABLE IF NOT EXISTS users (user_id BIGINT, messages BIGINT, connections TEXT)")
print("3")
con.execute("CREATE TABLE IF NOT EXISTS messages (user_id BIGINT, message_id BIGINT, server_id BIGINT, message_content TEXT, date BIGINT)")
print("4")
print("5")
print(f"Connected to {self.bot.user}")
def on_message(self, message):
self.add_task(message.author.id, message.id, message.guild.id, message.content, message.created_at)
async def main():
async with ClientSession() as our_client, asyncpg.create_pool(user='postgres', password='root', database='discord', host='localhost', command_timeout=30) as pool:
#exts = ['general', 'mod', 'dice']
async with CustomBot(commands.when_mentioned, db_pool=pool, web_client=our_client) as bot:
await bot.start(token)
asyncio.run(main())```
This only prints "1" what am I doing wrong?
did you not read the examples?
I did
your code says otherwise
anyways, don't do it in on_ready
I was thinking to do it in setup_hook
you dont even need to do it there. just make migrations and run it manually
make your sql code when creating tables into an actual sql file, and then create a migrations runner in order to apply those changes. every single time there is a new migration or new schema, just bump the rev version and run the migrations runner again
i dont know what your add_task coro does and why you need it
Making it a task so it's asynchronous
you should not do this within every single message u know that?
Traceback (most recent call last):
File "c:\Users\m\Desktop\G-OSINT\Discord Logger\example.py", line 56, in <module>
asyncio.run(main())
File "C:\Users\m\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "C:\Users\m\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\m\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "c:\Users\m\Desktop\G-OSINT\Discord Logger\example.py", line 54, in main
await bot.start(token)
File "C:\Users\m\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\client.py", line 857, in start
await self.login(token)
File "C:\Users\m\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\client.py", line 701, in login
await self.setup_hook()
File "c:\Users\m\Desktop\G-OSINT\Discord Logger\example.py", line 41, in setup_hook
with self.db_pool.acquire() as con:
TypeError: 'PoolAcquireContext' object does not support the context manager protocol```
Moved the `CREATE TABLE` executions to the hook for now and I get this error
What would be a more proper way of going about it?
oh boy you are doing a message logger
do you not know how much privacy violations and legal laws in regards to consumer privacy you just broke?
?
GDPR, US Federal privacy laws, and probably ones in your country
message logger
Yes, I'm logging my users commands but I'm learning how to go about it
then why do that to begin with?
Do what to begin with?
why are you logging messages to begin with?
I'm not logging all messages, this is for testing reasons which will be limited to my server which only has me and 2 friends. But I want to store all the data so I can make statistics / just see my bots usage
i present you... interaction checks
Isn't that for slash commands?
yes
ok
Hey I wanna know, when I'm using cogs, and there's an error in the cogs for the commands, let's say, the user dosent have permission because it's a ban command, can I use command error handlers in the main bot.py where the handler isn't located?
I need help with cogs
I keep getting 'BotBase.load_extension' was never awaited
but when I add the await, it dosent work
send your code
@bot.event
async def on_ready():
print(f'Logged in as {bot.user.name} ({bot.user.id})')
print('------')
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
try:
bot.load_extension(f'cogs.{filename[:-3]}')
print(f'Loaded {filename[:-3]} cog.')
except Exception as e:
print(f'Failed to load {filename[:-3]} cog. Error: {str(e)}')```
Can you help @twilit grotto ?
u need to await it
aka await bot.load_extension(...) @desert kiln
also u should prob do in setup hook or smth as on_ready gets fired mutliple times and u will get an error says that everything is already loaded
Like this
import discord
from discord.ext import commands
TOKEN = "MTE1MjQxO*****************************"
class Solaris(commands.Bot):
def __init__(self):
# initialize our bot instance, make sure to pass your intents!
# for this example, we'll just have everything enabled
super().__init__(
command_prefix="!",
intents=discord.Intents.all()
)
# the method to override in order to run whatever you need before your bot starts
async def setup_hook(self):
await self.load_extension("cog_ext")
Solaris().run(TOKEN)```
but when I run this it dosent load the extensions
ur meant to add bot = Solaris after
cuz normally u define bot as bot = commands.Bot this is the same thing but since u named the class Solaris then u gotta do bot = Solaris()
that's not what I'm struggling with
I'm struggling with the thing not loading the extension
i think that is the fix to it
can you help recode what I made to help fix the issue;-;
cuz im guessing all ur commands have the deco @bot.tree.command
this?
Idk how to do what you said
cog_ext?
yea?...
put this for loop in the setup_hook
import discord
from discord.ext import commands
TOKEN = "MTE1MjQxOTE0ODczNTk3MTM1OA.*******************************************"
class Solaris(commands.Bot):
def __init__(self):
# initialize our bot instance, make sure to pass your intents!
# for this example, we'll just have everything enabled
super().__init__(
command_prefix="!",
intents=discord.Intents.all()
)
# the method to override in order to run whatever you need before your bot starts
async def setup_hook(self):
@bot.event
async def on_ready():
print(f'Logged in as {bot.user.name} ({bot.user.id})')
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
try:
bot.load_extension(f'cogs.{filename[:-3]}')
print(f'Loaded {filename[:-3]} cog.')
except Exception as e:
print(f'Failed to load {filename[:-3]} cog. Error: {str(e)}')
Solaris().run(TOKEN)
With this I'm not getting
Name: 'bot' is not defined
@vocal laurel
remove the @bot.event
and also i told u to put the for loop not the whole thing
with?
it's not working
show me the code u tried
srry cant help, i dont use pycord
anyone know markdown for discord how can i put something like this
/command <- but have it highlight in blue and when pressed it moves it into the discord message box
similar to channel linking or @ ing someone
#channelname etc
yes
huh.. mine is discord.py
sorry i mean nextcord
oh
import discord
from discord.ext import commands
TOKEN = "MTE1MjQxOT"
class Solaris(commands.Bot):
def __init__(self):
# initialize our bot instance, make sure to pass your intents!
# for this example, we'll just have everything enabled
super().__init__(
command_prefix="!",
intents=discord.Intents.all()
)
# the method to override in order to run whatever you need before your bot starts
async def setup_hook(self):
async def on_ready():
print(f'Logged in as {bot.user.name} ({bot.user.id})')
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
try:
bot.load_extension(f'cogs.{filename[:-3]}')
print(f'Loaded {filename[:-3]} cog.')
except Exception as e:
print(f'Failed to load {filename[:-3]} cog. Error: {str(e)}')
Solaris().run(TOKEN)
With this, it's logging in, but not attempting to load cogs, or posting the bots username for the on_ready event
i told you to put the FOR loop in the SETUP_HOOK
were you answering me with that yes?
not the ON_READY
yes
u select the slash command with this
then u right click on it
then u copy id
and follow this format name:id
okay thank you
visible confusion
but aren't they like similar
nope
oh π
on_ready fires mutliple times while setp_hook only does once which is when bot starts
bru
@old vine sorry i mixed u up with the wrong person
nextcord and d.py are silimar
remove py for filename in os.listdir('./cogs'): if filename.endswith('.py'): try: bot.load_extension(f'cogs.{filename[:-3]}') print(f'Loaded {filename[:-3]} cog.') except Exception as e: print(f'Failed to load {filename[:-3]} cog. Error: {str(e)}') from ur on_ready and put it in setup_hook
so can you help me ?
ill see ig
tysm
import discord
from discord.ext import commands
import os
TOKEN = "MTE1MjQxOTE0ODczNTk3MTM1OA.**********"
class Solaris(commands.Bot):
def __init__(self):
# initialize our bot instance, make sure to pass your intents!
# for this example, we'll just have everything enabled
super().__init__(
command_prefix="!",
intents=discord.Intents.all()
)
# the method to override in order to run whatever you need before your bot starts
async def setup_hook(self):
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
try:
Solaris.load_extension(f'cogs.{filename[:-3]}')
print(f'Loaded {filename[:-3]} cog.')
except Exception as e:
print(f'Failed to load {filename[:-3]} cog. Error: {str(e)}')
Solaris().run(TOKEN)```
This worked apart from, this error
2023-09-16 03:32:47 INFO discord.client logging in using static token
Failed to load cog_ext cog. Error: load_extension() missing 1 required positional argument: 'name'
Failed to load moderation cog. Error: load_extension() missing 1 required positional argument: 'name'
2023-09-16 03:32:48 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: e6f24d8a05bc4397a2d0146afd93ea59).```
who??
: D
π
okk
yes
Question, in the cogs can I use just normal commands after I've put everything I need to inside it?
ye instead of @app_commands.command you would use @commands.command
could I use
@bot.command()
async def ping(ctx):
embed = discord.Embed(title="Ping", description=f"Pong! Latency: {round(bot.latency * 1000)}ms", color=discord.Color.green())
await ctx.send(embed=embed)```
nope
u would replace @bot.command with @commands.command and would put self just before ctx (eg, async def ping(self, ctx)
?
is it @command.command
Or @commands.command?
It's fine, you've helped alot
π
Ok well, I've added a ping command, and now the cog isn't loading
Show the cog, and you loading the cog
Can u show how u are loading the cog and your setup function in the cog
Cog:
from discord import app_commands
from discord.ext import commands
class moderation(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def ping(self, ctx):
embed = discord.Embed(title="Ping", description=f"Pong! Latency: {round(bot.latency * 1000)}ms", color=discord.Color.green())
await ctx.send(embed=embed)
async def cog_load(self):
print(f"{self.__class__.__name__} loaded!")
async def setup(bot):
async def cog_unload(self):
print(f"{self.__class__.__name__} unloaded!")
await bot.add_cog(moderation(bot=bot))```
Cog loader
import discord
from discord.ext import commands
import os
TOKEN = ""
class Solaris(commands.Bot):
def __init__(self):
# initialize our bot instance, make sure to pass your intents!
# for this example, we'll just have everything enabled
super().__init__(
command_prefix="!",
intents=discord.Intents.all()
)
# the method to override in order to run whatever you need before your bot starts
async def setup_hook(self):
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
try:
await self.load_extension(f'cogs.{filename[:-3]}')
except Exception as e:
print(f'Failed to load {filename[:-3]} cog. Error: {str(e)}')
Solaris().run(TOKEN)```
Fix it then
I can't fix discord can I?
well, I can't even upload the file
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
!paste
too slow buster
Show the cog
Ok well, I fixed it, it loads the cog, but the command didn't work
how many select menus can you have per message?
trying to put 3 menus and a button and i can only get 2 menus and the button to pop up
getting no errors
Indentation is wrong
how- wouldn't it give me an error?
I'm not sure about that but i think you can only have 3 rows
Welp I'm not pretty sure how to implement those 5 cuz i have only seen 3 so far
Do you have message intents
Can u send a link to page
I have them all enabled
He does
What's the error that's showing
That's why he's getting no command found error
!d discord.ui.select
@discord.ui.select(*, cls=discord.ui.select.Select[+ V], options=..., channel_types=..., placeholder=None, custom_id=..., min_values=1, max_values=1, disabled=False, row=None)```
A decorator that attaches a select menu to a component.
The function being decorated should have three parameters, `self` representing the [`discord.ui.View`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View), the [`discord.Interaction`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.Interaction) you receive and the chosen select class.
To obtain the selected values inside the callback, you can use the `values` attribute of the chosen class in the callback. The list of values will depend on the type of select menu used. View the table below for more information.
That ^
ngl I can't see shit
Also as a side note in the ping command make sure to do self.bot.latency
The quality is terrible
2023-09-16 04:11:25 INFO discord.client logging in using static token
moderation loaded!
2023-09-16 04:11:26 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: 94754ef283ec30ac21483bfba09eca2d).
2023-09-16 04:11:34 ERROR discord.ext.commands.bot Ignoring exception in command None
discord.ext.commands.errors.CommandNotFound: Command "ping" is not found```
Try using the row param
class selectview(discord.ui.View):
def __init__(self, interaction1:discord.Interaction):
super().__init__()
self.inter1 = interaction1
self.team = ''
self.first = ''
self.difficulty = ''
@discord.ui.select(
options= [
discord.SelectOption(label='X'),
discord.SelectOption(label= 'O'),
discord.SelectOption(label= 'RANDOM')],
placeholder= 'X',
row = 0)
async def selectteam(self, interaction:discord.Interaction, select:discord.SelectOption):
await interaction.response.defer()
self.team = select.label
@discord.ui.select(
options= [
discord.SelectOption(label='Me'),
discord.SelectOption(label= 'Goblins'),
discord.SelectOption(label= 'RANDOM')],
placeholder= 'Me',
row= 1)
async def selectfirst(self, interaction:discord.Interaction, select:discord.SelectOption):
await interaction.response.defer()
self.first = select.label
@discord.ui.select(
options= [
discord.SelectOption(label='Too Easy'),
discord.SelectOption(label= 'Easy'),
discord.SelectOption(label= 'Medium'),
discord.SelectOption(label= 'Hard'),
discord.SelectOption(label= 'Too Hard'),
discord.SelectOption(label= 'RANDOM')],
placeholder= 'Too Hard',
row= 2)
async def selectteam(self, interaction:discord.Interaction, select:discord.SelectOption):
await interaction.response.defer()
self.difficulty = select.label
@discord.ui.button(style= discord.ButtonStyle.green, label= 'Start Game', row = 3)
async def startbutton(self, interaction:discord.Interaction, button:discord.ui.Button):
await interaction.response.defer()```
make sure that cog_unload part is inside the cog and not the setup func
It is
no it is not
Try and see
async def cog_load(self):
print(f"{self.__class__.__name__} loaded!")
async def setup(bot):
async def cog_unload(self):
print(f"{self.__class__.__name__} unloaded!")
await bot.add_cog(moderation(bot=bot))
from discord import app_commands
from discord.ext import commands
class moderation(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def ping(self, ctx):
embed = discord.Embed(title="Ping", description=f"Pong! Latency: {round(bot.latency * 1000)}ms", color=discord.Color.green())
await ctx.send(embed=embed)
async def cog_load(self):
print(f"{self.__class__.__name__} loaded!")
async def setup(bot):
async def cog_unload(self):
print(f"{self.__class__.__name__} unloaded!")
await bot.add_cog(moderation(bot=bot))```
I gave a suggestion only
i havent changed anything since i asked lol
and where is the cog_unload?
thats how i had it
It's clearly not
Ah
ok
Well I don't know man, I was following @vocal laurel instructions
u have never shown me the cog_unload thingy
and now im am telling u but u r denying it
sooo, what the heck do I do
also like i said make it self.bot.latency
move it above the setup func which is on line 17
Where do I move the unload cog, which line do I put it on?
maybe above line 17
Moved it, still no difference
show code again
from discord import app_commands
from discord.ext import commands
class moderation(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def ping(self, ctx):
embed = discord.Embed(title="Ping", description=f"Pong! Latency: {round(self.bot.latency * 1000)}ms", color=discord.Color.green())
await ctx.send(embed=embed)
async def cog_load(self):
print(f"{self.__class__.__name__} loaded!")
async def cog_unload(self):
print(f"{self.__class__.__name__} unloaded!")
async def setup(bot):
await bot.add_cog(moderation(bot=bot))```
!paste
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
put it in there cuz ur indentation might be messed up
also you don't need to do bot = bot instead just do bot
which line?
last
I changed it, check that @vocal laurel
ok i see why now
the @commands.command (aka the ping command) is inside of the _init_
u gotta make it inline with it not inside
I made it inline, and now it's throwing errors
show code
So the @ needs to line up with the def?
yes
it's now 4:37am
ok
now I need to make all my other commands π
its ok
@client.command()
async def ytcom(ctx, *, comment: str):
params = {
'username': ctx.author.display_name[:25],
'avatar': str(ctx.author.avatar.url),
'comment': comment[:1000]
}
response = requests.get('https://some-random-api.com/canvas/misc/youtube-comment', params=params)
if response.status_code == 200:
data = response.json()
image_url = data["comment"]
await ctx.send(file=discord.File(image_url))
else:
await ctx.send(f'Error: {response.status_code}')
idk why, but this code refuses to work lol
any error?
yeah, here:
f the following exception:
Traceback (most recent call last):
File "/home/runner/Python-2/venv/lib/pyt
hon3.10/site-packages/discord/ext/commands
/bot.py", line 1350, in invoke
await
ctx.command.invoke(ctx)
File "/home/runner/Python-2/venv/lib/pyt
hon3.10/site-packages/discord/ext/commands
/core.py", line 1029, in invoke
await injected(*ctx.args, **ctx.kwargs
) # type: ignore
File "/home/runner/Python-2/venv/lib/pyt
hon3.10/site-packages/discord/ext/commands
/core.py", line 244, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeE
rror: Command raised an exception: JSONDec
odeError: Expecting value: line 1 column 1
(char 0)```
but idk what should i do with this info
is that all?
well, almost. it just prints me the same error above
hm ok
!rule 6
I'm gonna make it look better and stuff, but it's a start
Also, ignore the fact my bots got 7336ms ping
it's because I'm hosting on phone, it will fix when it's on my server
hm ok
for testing purposes it's on my phone temporarily
makes sense
Discord shows the user information already
Why duplicate a built in function
why not
listen, it's my bot, why do you gotta be so negative every time I do something?
its not a bad feature a lot of people have it
ay chill dw its alright
Dyno even has that feature bruh
Unkown
even r danny (the oldest bot on discord) has it
Unknown
its in d.py server
ah, I'm not there lmao
Yes, and they use it to artificially inflate its usefulness
Mirroring default functions is redundant at best, usually the functionality is worse
Stop bothering me, before I contact a mod, you've done this 2 times now.
Saying an opinion is against the rules?
This is a commonly held position, by multiple people in this channel
Youβre free to mirror default functions if you want, im not stopping you
So stop attacking me for it.
Iβm not lmao