#discord-bots

1 messages · Page 419 of 1

quick gust
#

does a PartialMessage have a author?

gritty inlet
#

fetch message should not return partial though

quick gust
#

I'm not really sure then, because even if it was a PartialMessage object, it wouldn't return "None" for the author attribute, it would simply just raise an attributeerror on author and not id

gritty inlet
#

He either caught the rest of the exceptions or didn't look at them

#

I think

quick gust
#

Maybe the error is not originating where they think it is

gritty inlet
#

This check is failing from time to time (not for me, but I see in logs)
Without having a full traceback, can you see if I'm doing something wrong?

#

Perhaps I shouldn't do async calls in a check

fast osprey
#

Why not just leave this to the native permissioning system

gritty inlet
#

Wdym

#

The permission checks?

fast osprey
#

No the integrations tab

gritty inlet
#

So you say I should let the admins / owner choose who can use it?

#

I can do that but it's not such an obvious thing if you ask me

#

I didn't even know you could do that until I checked (now)

fast osprey
#

That's very standard across bots

#

And the way server admins are trained to permission commands

#

Your bot can set default required permissions though which work in that system, then the admins can fine tune if they want

gritty inlet
#

Setting an empty permissions field, including via calling this with no arguments, will disallow anyone except server administrators from using the command in a guild.
"disallow"

This serves as a hint and members are not required to have the permissions given to actually execute this command. If you want to ensure that members have the permissions needed, consider using ~discord.app_commands.checks.has_permissions instead.
"hint"
(@app_commands.default_permissions())

#

So this only does a UI change? In that case I don't want to use just this

fast osprey
#

What do you mean "only" a UI change?

#

People cannot execute commands they can't see. There's not a back door here

gritty inlet
#

Ah okay it makes it disappear

fast osprey
#

The "hint" part means that server owners can override the defaults you set

gritty inlet
fast osprey
#

So in theory you could say "by default you need manage messages" and the server owners can say "yeah but also allow this role"

gritty inlet
#

But alright

fast osprey
#

It's not the best wording

#

It's far from a perfect system but it goes a long way to standardizing things and letting server owners manage stuff rather than every bot creator making their own opaque system

gritty inlet
#

Why do the API docs also not say what exactly happens cRy

heavy peak
#

is there a way for the bot to make notifications when user uses the bots tag?

finite salmon
heavy peak
#

oops

finite salmon
#

Oh

#

What do you mean by notification tho

#

Cuz you can't send client notifications through discord

heavy peak
#

like can the bot announce when someone uses the guild tag

gritty inlet
#

Probably not

young dagger
#
if existing_account:
    # Prepare embed
    embed = discord.Embed(
        title='',
        description=f'{check_mark_emoji} You already have a Riot ID linked to your Discord account.',
        color=discord.Color.green()
    )

    # Remove the role
    async def remove_unverified_role():
        role = interaction.guild.get_role(unverified_role_id)
        if role and role in interaction.user.roles:
            await interaction.user.remove_roles(role)

    # Run both sending embed and removing role concurrently
    await asyncio.gather(
        interaction.response.send_message(embed=embed, ephemeral=True),
        remove_unverified_role()
    )
    return
gritty inlet
#

Actually maybe it's on member update

finite salmon
finite salmon
gritty inlet
gritty inlet
#

Nope (:

#

Unless it costs an import of asyncio

fast osprey
#

!d discord.Member.primary_guild

unkempt canyonBOT
#

property primary_guild```
Equivalent to [`User.primary_guild`](https://discordpy.readthedocs.io/en/stable/api.html#discord.User.primary_guild)
fast osprey
finite salmon
gritty inlet
#

Is it passed on member events?

#

I mean to say, do you get full user object in the member object - on member events?

finite salmon
#

on_member_update yeah

gritty inlet
#

Oh yeah then it's obviously there

gritty inlet
#

Wasn't sure, alright

gritty inlet
#

Wait no

#

Does that fire a gateway event

#

Even tho it's a user thing

#

Does member update fire on user changes

fast osprey
#

could tias

gritty inlet
#

Good point

fast osprey
#

Pretty sure it does but wouldn't bet my life on it without trying rq

timber dragon
#

Wouldn't it be on_user_update

#

Which is not a real event but discord.py has it and calls it user updated stuff

gritty inlet
fast osprey
#

The internet bigbrain

gritty inlet
#

It's not a real event - where does it pull that specific data from

#

Cache?

fast osprey
#

User is just a subset of member

timber dragon
#

^

#

Member has an inner user

narrow hazel
#
 try:
    for m in message.content:
      if count["Count"] == int(m):
        count["Count"] += 1``` does anyone know why this section only sees the initial number at the beginning of a message and ignores strings all together?
timber dragon
#

Probably because you're ignoring the error when casting none digits to int

#

!d str.isdigit

unkempt canyonBOT
#

str.isdigit()```
Return `True` if all characters in the string are digits and there is at least one character, `False` otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the property value Numeric\_Type=Digit or Numeric\_Type=Decimal.
timber dragon
#

That loop could be done much faster and efficiently, if interested:

coint["Count"] = sum(1 for m in message.content if m.isdigit())
narrow hazel
#

Im not just trying to check if its only a digit. I wanna check if the count is inside the message content to allow the full message

timber dragon
#

Is the count not an integer?

narrow hazel
#

it is

#

This is basically what im trying to do

timber dragon
#

So you want to get all digits from that string right

woeful hill
#

.startswith() ?

narrow hazel
#

like anywhere in the string

woeful hill
#

Then you loop it over like soheab

timber dragon
#

for character in string
int(character) <- will only work for the first character

int(" ") will raise an error, stopping the loop
int("w") will raise an error, stopping the loop
...

narrow hazel
#

ooo that explains why it only worked for the first character

timber dragon
#

Maybe don't blindly catch all exceptions

narrow hazel
#

ima try something then, thanks

mild kiln
#

some one wanna develop a discord bot with me

tropic kelp
timber dragon
#

Aren't the built-in tools sufficient for that, or all the other hundreds that try to do that

tropic kelp
timber dragon
#

Probably a bot with some of the built-in commands like ban, but without permission checks or logs

And most likely also something called “anti raid“

tropic kelp
young dagger
#

Why is Wordle on every single server?

fast osprey
#

Because discord decided it would be

young dagger
#

What if I say I don't like it?

#

And there is no way to turn it off

fast osprey
#

If you don't like it don't use it?

young dagger
#

It's not like it's a built-in function

gritty inlet
#

It's not in your server

#

They made it user installed for every user

#

It's a 💸 thing (promotion)

timber dragon
#

Holy that's shitty

#

I always thought it was a builtin app

gritty inlet
#

Anyway I'm pretty sure you can deauthorize it via Authorized Apps

gritty inlet
#

If I use default_permissions, can a user that doesn't have those permissions use the command via its mention? (</cmd:id>)

gritty inlet
#

You must use it once for it to even be added there though

#

Ah oof that doesn't remove it from commands list (it's really not that serious)

heavy peak
#

how to make hybrid command group i forgot:)

fast osprey
unkempt canyonBOT
#

@discord.ext.commands.hybrid_group(name=..., *, with_app_command=True, **attrs)```
A decorator that transforms a function into a [`HybridGroup`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HybridGroup).

This is similar to the [`group()`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.group) decorator except it creates a hybrid group instead.
gritty inlet
timber dragon
#

You can click and run it afaik

#

But it'll error out

gritty inlet
# timber dragon But it'll error out

Makes the docstring of app_commands.default_permissions even more misleading:

This serves as a hint and members are not required to have the permissions given to actually execute this command. If you want to ensure that members have the permissions needed, consider using ~discord.app_commands.checks.has_permissions instead.
Unless there's something I fail to understand?
Is there any other way for a user to run that command??

timber dragon
#

The server can change it via integrations

#

It sets the default permissions

gritty inlet
#

The docstring, if even, describes this very badly

fast osprey
#

Then make a pr to improve it

gritty inlet
fast osprey
#

you've complained about this doc like 3 times now

gritty inlet
#

Fair, might try..

#

Just wanted to figure if that's something only I see as weird

fast osprey
heavy peak
#

is it possible to change the server description via bot

gritty inlet
#

I'm actually so lost in making a PR, never done this before, neither have I got experience in any git things besides the basics xD

#

I'll save my text aside for the day I can do it properly

fast osprey
#

the github ui for making simple edit PRs is pretty good

fast osprey
unkempt canyonBOT
#
await edit(*, reason=..., name=..., description=..., icon=..., banner=..., splash=..., discovery_splash=..., community=..., afk_channel=..., owner=..., afk_timeout=..., ...)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Edits the guild.

You must have [`manage_guild`](https://discordpy.readthedocs.io/en/stable/api.html#discord.Permissions.manage_guild) to edit the guild...
gritty inlet
#

I might just read Github's guide sometime later

fast osprey
#

it's a good skill to learn to be able to make a branch and push it yourself

#

on the command line

gritty inlet
#

I also didn't understand, I gotta make a fork to make edits for the PR?

fast osprey
#

not a fork, just a branch

gritty inlet
#

I'll learn this some time but I just think the top section is not clear for someone without experience

fast osprey
#

Actually depends on the repo settings

#

i don't know if they let people make branches on that repo

gritty inlet
#

Doesn't seem like it

#

It looks like people use forks in the PRs

fast osprey
#

ah then yes

gritty inlet
#

This PR fixes misleading wording in the warning found at the doc of app_commands.default_permissions:

This serves as a hint and members are not required to have the permissions given to actually execute this command.

This would be true only in case an administrator has changed the default permissions for the command via the guild's Integrations tab.
But since the warning says "hint" and "not required to have the permissions given", it sounds as if using this does not stop a user with missing permissions from executing the command to begin with, and it is not clear enough that the user may not need the permissions that the bot set as default exactly (which may happen only in the condition mentioned above).

Note: I also think that it would be convenient to describe the visual outcome of using this:
The user can neither see the command on the command list, nor can they run it using its mention, as they would get a "Missing Permissions" error on the client side.

Something I wrote in a few mins, probably not perfect
Any changes I should make?

#

It's getting less and less related to the topic of this channel but I'd rather just end it quickly over here while I'm at it

fast osprey
#

what was your suggested wording change?

gritty inlet
#

O yea right, if i write those changes in the changed code, should i copy to the summary too?

fast osprey
#

Confused

gritty inlet
# fast osprey what was your suggested wording change?

A decorator that sets the default permissions needed to execute this command.

When this decorator is used, by default users must have these permissions to execute the command. However, an administrator can change the permissions needed to execute this command using the official client. Therefore, this only serves as a hint.

Users with missing permissions will not see the command on their command list, and if a user executes the command using its mention, they will be met with a "Missing Permissions" error from the client's side, and the bot has no control of this behavior.

Setting an empty permissions field, including via calling this with no arguments, will disallow anyone except server administrators from using the command in a guild.

This is sent to Discord server side, and is not a check(). Therefore, error handlers are not called.

Due to a Discord limitation, this decorator does nothing in subcommands and is ignored.

Warning:

This serves as a hint and members are not required to have the permissions given to actually execute this command. If you want to ensure that members have the permissions needed, consider using has_permissions() instead.
This shouldn't be used if you want to ensure that members have the exact permissions that are passed to this decorator - due to administrators being able to modify these permissions for their servers - consider using has_permissions() instead.

#

Format:
New
Removed

#

"If a user manages to execute the command in other ways," might just say that using mention is the only other way instead of saying this

Also, I feel like I could make the whole thing sound less repeating but I didn't want to completely change it

viscid oracle
burnt quiver
#

the hint part makes sense, but the wording can be misleading

#

I would say change the hint part to 'This can serve as a hint to inform users that this command...'

#

something like that

gritty inlet
#

I don't like saying it's a hint considering that it's functional as long as nothing was changed

#

So yeah the "can" could work but then you can just make the sentence without really saying "hint"

#

But I'll see

stark ingot
#

It is not a hint at all. It is a default that can be overridden

gritty inlet
#

I say that too yeah

#

The "serves as a hint" is misleading so it definitely needs to be changed
The other part describing what users see isn't that necessary but I personally like it..

#

I don't even think the warning itself is very necessary, but I'm not going to completely change something

burnt quiver
#

hence a hint

fast osprey
#

"Hint" is much softer language than "default". That could imply there is a way for a user to bypass those requirements on their own which isn't true

#

I believe the language "hint" is also used in the autocomplete documentation which a user can just bypass and put in what they want, and this is something entirely different

burnt quiver
#

oh that does make sense

olive dirge
#

Hey all!
My name is Mishka133, I'm just starting my journey into the Discord.py world!

Wanted to throw this out there to see if anyone had any pointers or ideas on how to implement this:

    This dialog would be pinned to the top of a workboard channel so mods and admin know who is available at a glance and who they can message.
    This application should be general purpose and usable with individual roles, maybe multiple roles later on.

Hope this is something i can ask here, if not let me know, TIA!

fast osprey
#

FWIW there's already a built in mechanism for users to push a button and get a role, you don't need a bot for that

olive dirge
#

understood - the idea is like apollo's event posts - where users can click a reaction and get added to the message. then, if they decide to leave for the day they would click another to signify they are not available for tasks.
something pinnable for admins to come into, say, a mod room and quickly see available mods (who's down for work or who is off gaming or something else)

#

even if discord statuses are used, something to pin into a channel

fast osprey
#

There are a lot of moving parts here. You'd have to be specific with what you're stuck on

gritty inlet
#

I tried being more precise

olive dirge
grizzled trail
#

just made a role play bot and its fun lol 😂 ,

viscid oracle
gritty inlet
#

Might try later

slender vale
#

Does anyone know how to change the Python version in the terminal? I keep getting the same Python version when I check, even when I select a different interpreter.

gritty inlet
young dagger
#

Can you add cooldown for discord.ui.button?

gritty inlet
young dagger
#

I want to put a cooldown to my interaction button

gritty inlet
#

I'd assume you'll need to make that function yourself

#

I don't see a reason for dpy to have something for that idk

fast osprey
#

There's nothing built in, no. You could use CooldownMapping but it is deliberately not documented

gritty inlet
#

It should be pretty simple to manually do it, make a dict that stores either time since last allowed interaction or that stores time when you're allowed to interact again,
then on interaction compare the current time to that

#

Maybe there's a better way, Idk

#
cooldown_times: dict[int, int] = {} # user_id, last_use
COOLDOWN_TIME = 5 * 60 # minutes

async def cooldown_check(interaction: discord.Interaction) -> bool:
    now = int(discord.utils.utcnow().timestamp())
    last = cooldown_times.get(interaction.user.id, 0)

    if now - last > COOLDOWN_TIME:
        cooldown_times[interaction.user.id] = now
        return True

    return False```

Example
young dagger
# fast osprey There's nothing built in, no. You could use CooldownMapping but it is deliberate...

Would commands.CooldownMapping work for inside discord.ui.View?

class RiotIDView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)
        self.cooldown = commands.CooldownMapping.from_cooldown(1, 10, commands.BucketType.member)

    @discord.ui.button(label="Link Riot Account", style=discord.ButtonStyle.success, custom_id="riot_button",
                       emoji=discord.PartialEmoji(name="riot_games", id=riot_emoji_id))
    async def submit_riot_id(self, interaction: discord.Interaction, button: discord.ui.Button):
        try:
            # Check cooldown
            bucket = self.cooldown.get_bucket(interaction.user)
            retry = bucket.update_rate_limit()
            if retry:
                embed = discord.Embed(
                    title="",
                    description=f"{x_emoji} This command is on cooldown. Try again in "
                                f"{max(1, round(retry))} seconds.",
                    color=discord.Color.red()
                )
                return await interaction.response.send_message(embed=embed, ephemeral=True)
gritty inlet
#

Sure CooldownMapping isn't some internal thing to stop user from hitting rate limits?

#

If so, you should not use it

young dagger
#

So my method will not work?

gritty inlet
#

I wouldn't mess with internals in general

gritty inlet
#

Though sometimes it's more than just "works" or "doesn't work"

gritty inlet
gritty inlet
#

You can very easily modify it to return the remaining time, if you'd like

young dagger
gritty inlet
#

now is assigned to your cooldown_times after the check, and now is "recalculated" every time

young dagger
gritty inlet
young dagger
#

Yes

gritty inlet
#

you dont want that?

young dagger
#

That's not the behavior I want

#

Nvm thanks

gritty inlet
#

You want a global cooldown?

#

Anyway you get the point, it's simple

fast osprey
gritty inlet
fast osprey
#

What the class does is simplify how you sort those times into buckets

#

otherwise yes you'll need to make your own data structure

young dagger
last arrow
#

how are drop downs INSIDE embeds made? there are no tutorials and i saw someone say something about it i thought it wasn't real but now i see it myself the dropdown is inside an embed not below.

#

like so

timber dragon
#

Because it's not an embed

#

It's a container, part of cv2

gritty inlet
#

wdym

#

now = ...
last = ...
This only happens once

#

ahh i see

#

lemme simplify it for ya hold on

#
def cooldown_check(interaction: discord.Interaction) -> tuple[bool, int]:
    now = int(discord.utils.utcnow().timestamp())
    last = cooldown_times.get(interaction.user.id, 0)
    remaining = max(0, COOLDOWN_TIME - (now - last))

    if remaining == 0:
        cooldown_times[interaction.user.id] = now
        return True, 0

    return False, remaining```

(note: it *was* async for no reason lol)

And if you want to get timestamp of when it's done instead of remaining seconds:
```python
def cooldown_check(interaction: discord.Interaction) -> tuple[bool, int]:
    now = int(discord.utils.utcnow().timestamp())
    last = cooldown_times.get(interaction.user.id, 0)
    expires_at = last + COOLDOWN_TIME

    if now >= expires_at:
        cooldown_times[interaction.user.id] = now
        return True, now + COOLDOWN_TIME

    return False, expires_at```

With this one, you can do f"Expires <t:{expires_at}:R>" and such
quick gust
#

Don't see why you wouldn't just use CooldownMapping

young dagger
young dagger
gritty inlet
gritty inlet
#

I see no problem with that, i just dunno how it works

quick gust
#

It's what the library uses to manage the cooldowns

#

It's very handy, and there's nothing stopping you from making your own decorator for a button cooldown

young dagger
gritty inlet
#

can u show what get_bucket takes?

#

and what from_cooldown takes

quick gust
#

get_bucket takes interaction, not interaction.user

gritty inlet
#

Time to enable your type checker buddy

young dagger
#

Still same error

quick gust
#

Show the entire traceback please

gritty inlet
young dagger
#

'Interaction' object has no attribute 'author'

gritty inlet
#

(:

quick gust
#

Oh lol I forgot I use disnake

gritty inlet
#

I see it being used internally with ctx

quick gust
#

My bad, just give it the Message then

gritty inlet
quick gust
#

Yes disnake is a fork

gritty inlet
#

Aight

quick gust
#

Although this should be the same for both disnake and discord.py, I don't remember why it worked for me

gritty inlet
#

Yer a wizard

last arrow
#

thank you

narrow hazel
#

There's not a lot of tutorials on it yet

fast osprey
#

You shouldn't be using anything that's not in the official docs and examples

#

and that already exists

#

"tutorials" are hot garbage

timber dragon
alpine kelp
#

hi, i was wondering how can i have an embed with two full width images like this?

fast osprey
#

That's not an embed, that's a container

#

Probably with MediaGallery -> TextDisplay -> MediaGallery

alpine kelp
alpine kelp
timber dragon
#

That's not possible with an embed

alpine kelp
narrow hazel
#

not possible any other way unless its just an image

narrow hazel
#

custom activity is fun

narrow hazel
#

Finally using a formatter and it added 50 lines xD

gritty inlet
#

Ngl you should just keep your format clean to begin with

#

What IDE are you using

narrow hazel
#

VSC

#

im bad at keeping it clean because I usually have a command/event idea so then I just go off and write it all down and never format it

gritty inlet
#

Do you use spaces for indentions or something

#

You can just press tab

narrow hazel
#

This is what it looks like when I dont

gritty inlet
#

But yeah use tab for line indentions

narrow hazel
#

meh I only need to format it if I need help

#

im the only dev and I can read it so it's all gucci

gritty inlet
#

It's easier than manual spaces

#

Your choice but I think it's bad practice

narrow hazel
#
class persistant(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        
    async def cog_load(self):
        self.bot.add_view(submissions(user=None))

class partnership(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @app_commands.command(
        name="partnership",
        description="Apply for partnership with the server.",
    )
    async def partnership(self, interaction: discord.Interaction):
        guild = interaction.guild
        user = interaction.user
        submission = datetime.datetime.now().timestamp()
        try:
            await interaction.response.send_modal(modal(guild, user, submission))
        except Exception as f:
            print(f)

        
async def setup(bot):
    await bot.add_cog(partnership(bot))
    await bot.add_cog(persistant(bot))
    print("Partnership Buttons Restarted")``` I also finally figured out persistant buttons
#

that was a fun 20 minutes

gritty inlet
#

Ah that's cool

#

I tend to use dynamic items

narrow hazel
#

whats that

gritty inlet
#

An item that you set a regex template for, that indicates how its custom id can look
And you add callback

narrow hazel
#

ew regex

#

I depise regex

gritty inlet
#

I like using those because I don't really need persistent views usually

narrow hazel
#

meh I guess theres a different way for everything

#

mine is just the easiest to remember

gritty inlet
#

alright

narrow hazel
#

I dont even remember basic regex for a http link

#

only regex I know is

discord.gg``` ![FunCool](https://cdn.discordapp.com/emojis/1376871513537646723.webp?size=128 "FunCool")
gritty inlet
#

the thing is, if ur custom id is static then it's not complicated at all

#

if it changes, dynamic item is the good use case
but i also use it where it's static

narrow hazel
#

no my custom ID doesnt change

gritty inlet
#

persistent views is fine though
I just like knowing i dont got view instances stacking up or whatever

#

but it doesn't matter that much

narrow hazel
#

fair

gritty inlet
#

Persistent views make it easier to pass data without depending on the custom id.
With dynamic items, usually, you make the data embedded in the custom id

narrow hazel
#

I think I get what you're saying, you can put data on the custom ID even if it changes

gritty inlet
#

ye

#

then in dynamic item there's a method "from_custom_id" which gives you a cls object, interaction, item, and re.Match
you must use any of these to somehow return an instance of your dynamic item

narrow hazel
#

yeah now you lost me xD

gritty inlet
#

The logic is that the library should be able to create the instance of the item using the data in the custom id

gritty inlet
#

i could explain it better but meh I'm on mobile

narrow hazel
#

maybe if I actually get into different custom IDs but currently its all static

gritty inlet
#

alrighty

narrow hazel
#

How hard is it to create an overflow embed if the first one exceeds the charcount?

burnt quiver
#

use pagination

narrow hazel
#

I dont even know how I acheived that

#

nvm I figured it out

#

maybe I do need to start formatting cuz I got lost 😅

finite salmon
#

pip install it

#

and do ruff format

#

in your terminal

narrow hazel
#

I just turned off my computer for the night I'll look into what ruff is tomorrow

finite salmon
#

if you want you can use this configuration-

[tool.ruff]
line-length = 79
lint.extend-select = ["ANN", "I"]
lint.ignore = ["ANN401", "F"]
lint.fixable = ["I", "F401"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = true
docstring-code-line-length = 72

Make a pyproject.toml file at the root of your project and place this in it

finite salmon
#

additionally you could use makefiles to run them for you

gritty inlet
#

Same for embed timestamp

#

Maybe you can tell me

narrow hazel
#

Add what

#

The footer?

gritty inlet
#

But whatever you find convenient (:

narrow hazel
#

The embed timestamp is pretty useless since discord will give you the time right above it

gritty inlet
narrow hazel
#

It just looks cleaner imo than a reply

gritty inlet
#

In your command response

narrow hazel
#

Cuz prefix is trash and I hate it

gritty inlet
#

Reread lol

#

I asked why put "requested by" in a slash command response

#

Just wondering

narrow hazel
#

I changed it from an interaction to a channel

#

It was just a reply during testing

young dagger
quick gust
#

No?

#

Will it?

young dagger
#

Yes?

#

I'm using a global persistent view

#

Not one button per user

quick gust
#

I see

It worked for me because I gave it a MessageInteraction which does have the author of the interaction (in disnake)

#

Someone who uses dpy could probably help you with it

timber dragon
#

You can pass anything to it

#

Like a callable

#

And handle it yourself

young dagger
woeful hill
#

You can tho 🤔

#

Not directly direct

#

But by checking with interaction_check

young dagger
young dagger
woeful hill
#

Yeah because you dont know who will be interacting with it, so no interaction object

idle current
#

Anyone has dm spammer code?

woeful hill
#

We dont give code here and it is bad to spam someone's dm

#

And people can easily press the Block button if they find someone annoying

narrow hazel
#

pretty sure its also against TOS to misuse the bot like that

timber dragon
#

Discord will catch and limit the bot anyways

gritty inlet
#

Yep it will be quarantined eventually

young dagger
#

Would it technically be possible for someone to spam a button and cause the bot to hit the rate limit?

#

If yes, how could you protect against it?

gritty inlet
young dagger
gritty inlet
gritty inlet
burnt quiver
#

Iirc interactions don't contribute to global ratelimits

#

lemme find the sauuce

fast osprey
#

I mean it entirely depends on what you do in the callback

#

if every time someone clicks a button you make a channel, discord doesn't know or care that it was in the context of an interaction

finite salmon
#

Any form of interaction or a direct response to the interaction doesn't go towards the rate limit, not even the global rate limit if I'm not wrong

#

I remember seeing that was the biggest selling point discord was advertising trying to convert devs from prefix to slash

finite salmon
timber dragon
#

Pretty sure it only goes the global ratelimit?

#

But users can't ratelimit as they get a cooldown iirc?

Can't find any source for this

nova shuttle
#

i need help, my images i set on my embed in my command arent showing anymore even tho its clearly set

timber dragon
#

Code?

gritty inlet
# nova shuttle i need help, my images i set on my embed in my command arent showing anymore eve...

For discord.py, make sure you follow this logic:

async def t(c):
    embed = discord.Embed(...)

    # Case 1: an image URL that can be resolved:
    embed.set_image("your_image_url")

    await c.send(embed=embed)

    # Case 2: an image file, either local or from bytes:
    image_bytes = ...
    filename = ...
    file = discord.File(image_bytes, filename)

    embed.set_image(f"attachment://{filename}")

    await c.send(embed=embed, file=file)
#

But we'll have to see the code in order to help you

nova shuttle
#

yea ik, i fixed it

gritty inlet
nova shuttle
#

no

gritty inlet
#

Alrighty then

nova shuttle
#

i just reput the image link in set_image

#

maybe the old one was too old and expired

gritty inlet
nova shuttle
#

yea well ig ill see if it happens again

#

hopefully not

gritty inlet
nova shuttle
#

no, media discord attachment

timber dragon
#

Well then it is expired

#

Discord url's are only valid for one day

gritty inlet
#

They expire if message is deleted

nova shuttle
#

ok

timber dragon
#

They do refresh in the client, but obviously not if the message is deleted or you stored the url

nova shuttle
#

will pinning them help?

gritty inlet
#

Yuh, pretty sure theres a user endpoint for refresh even xD (irrelevant)

timber dragon
nova shuttle
#

oh

timber dragon
#

The link will expire

gritty inlet
#

I be hanging around in the network tab so so much

nova shuttle
#

so what should i do

gritty inlet
timber dragon
#

Store the image yourself

nova shuttle
timber dragon
#

Don't rely on the discord's cdn

nova shuttle
#

im not on pc rn so i cant

gritty inlet
nova shuttle
#

and paste it into url=""

gritty inlet
#

Don't do it like that lol

nova shuttle
#

oh

gritty inlet
nova shuttle
#

okok

gritty inlet
#

If you need help with getting the image to bytes I can help

nova shuttle
#

alr

nova shuttle
gritty inlet
#
from io import BytesIO

with open("image_path", "rb") as f:
    image_bytes = f.read()

filename = ...
file = discord.File(BytesIO(image_bytes), filename=filename)
nova shuttle
#

ok

gritty inlet
gritty inlet
nova shuttle
#

ok

vocal plover
#

Even though your image likely isn't that big, ideally you'd use a library like aiofiles to read the data from disk, because reading from disk can (for various reasons) block for a while, which means nothing on the event loop is being executed aside from the IO read. In general if you're using an async library then the things you do in/around it should also be async (so you wouldn't use requests either, you'd use aiohttp or httpx)

nova shuttle
#

yea alr

gritty inlet
#

xD

nova shuttle
#

i have a question

gritty inlet
#

Go ahead

nova shuttle
#

could i just use discord cdn url?

#

and if it doesnt get deleted its fine

gritty inlet
#

No, as those may not last forever

nova shuttle
#

ah ok

gritty inlet
#

You could use another permanent CDN like Imgur or whatever

nova shuttle
#

was looking at one of my other bots, it uses a cdn and it hasnt expired for a long time

vocal plover
# gritty inlet No, as those may not last forever

No? CDN images are permanent until deleted, they require a signature to be able to use them but within messages/embeds discord will do this refresh in the background and give you back a valid link, so they should be fine to use

nova shuttle
#

so only media attachment is temp correct

vocal plover
#

no content that you upload to discord is temporary except in ephemeral interaction responses

gritty inlet
timber dragon
hollow venture
#

!user

unkempt canyonBOT
#

You are not allowed to use that command here. Please use the #bot-commands channel instead.

narrow hazel
#

does .remove just remove the value and leaves no value behind? by that I mean

variable  = "HellobWorld"
variable.remove("b")
output: "Hello World?" or "HelloWorld"
quick gust
#
  1. Not related to discord bots
  2. There's no such thing as "remove" for a string
narrow hazel
#

im asking because im making a permissions for a role information. there's a string inside the permissions I wanna remove

#
 @discord.ui.button(label="View Roles Permissions(Not Working)", style=discord.ButtonStyle.grey)
    async def viewpermissions(self, interaction: discord.Interaction, button: discord.ui.Button):
      if self.role is None:
        return await interaction.response.send_message("No roles were selected")

      b = self.role.permissions
      if b is None:
        return await interaction.response.send_message("The role has no permissions")
      
      allowed_perms = [name for name, value in b if value ]
      for a in allowed_perms:
        a.remove(value="_")
     
      embed = discord.Embed(
     title=f"Permissions List ({len(a)})",
     description="\n".join(a)
      ) 
      await interaction.response.send_message(embed=embed, ephemeral=True)```
burnt quiver
narrow hazel
#

oooo

#

thank you

burnt quiver
#

!eval

variable  = "HellobWorld"
new_var = variable.strip("b")
print(new_var)
unkempt canyonBOT
burnt quiver
#

uhh

#

oh right

#

cuz it's touching

#

!eval

variable  = "HellobWorld"
new_var = variable.replace("b", "")
print(new_var)
unkempt canyonBOT
narrow hazel
#

Okay im gonna keep testing xD

quick gust
#

That's due to how you're forming the description of the embed

#

You're giving join() a string

narrow hazel
#

I got it

#

I just had to add replace here

#

thanks all

gritty inlet
#

Yea I do that too in my code and I also capitalize (looks better)

#

!eval

s = "manage roles"
print(s.capitalize())```
#

Wrong one, title() it is

narrow hazel
#

I just write lower case strings and then I can capitalize them later if I need

#

What does title do?

gritty inlet
gritty inlet
narrow hazel
#

Impressive

#

I may have to look into that Sus

gritty inlet
#

so an empty list will work with the if not

#

is None is for checking if it's explicitly None

#

Because of how is works

narrow hazel
#

Yeah I just looked into that

#

I thought permissions was an array but it's an object

gritty inlet
#

Isn't it

still pine
#

Pls bal

narrow hazel
#

I believe so

gritty inlet
#

Idk

narrow hazel
#

Yeah

#

I'm trying to see if i can convert it so I can just check if it's empty unless there's a way I'm too dumb to know if you fan check if it's empty

#

It can be converted to a dic I know that

#

Wait

gritty inlet
narrow hazel
#

im already looping it so I could just check if that variable is less than or equal to 0

gritty inlet
#

Or, do bool(x) for testing

gritty inlet
gritty inlet
#

bool(discord.Permissions())

#

See if it fails

narrow hazel
#

yeah your way does work actually

#
  b = self.role.permissions
      if not b:
        return print("Empty")```
gritty inlet
#

They definitely implemented a bool

narrow hazel
#

which it did return it

#

so cool

#

all 3 ways work

gritty inlet
#

Yeah bool for empty types is cool

#

But in Permissions it's a custom implementation xD

narrow hazel
#

yeah permissions is pretty much my first time messing with objects it's interesting

gritty inlet
#

!eval

print(bool([]))```
#

(:

#

How do I remove these buttons brah

unkempt canyonBOT
narrow hazel
#

Works great

gritty inlet
narrow hazel
#

Good suggestion

gritty inlet
#

Additionally. Just looks nice, your choice

#

If you wanna get more advanced, you can add a role select menu to change the role you're viewing without rerunning the command

narrow hazel
#

I thought about a role menu but that's way out of my leauge

#

I don't even know basic menus yet

#

I learned and created them once but I already forgot how to make them

gritty inlet
#

What restrictions are you talking about

#

why not use purge

#

it's for deleting multiple messages

#

Did you just go into the source code and removed limits?

#

If discord.py implements any limits then I believe it's to ensure you don't get rate limited by Discord

#

Therefore what you're doing is probably risky

woeful hill
#

why would you want to wipe chat history tho

#

the platform isnt meant to be used like that

timber dragon
#

I mean

#

You can already clear messages older than 14 days with purge using dpy

#

If it's too slow, that's dpy making sure you don't get ratelimited

gritty inlet
#

Yep

woeful hill
#

^ purge is great for old messages

#

much faster i believe

burnt quiver
#

I always get ratelimited stil tho

#

well last time since now I do a check

gritty inlet
#

Wait is purge manual?

#

I don't remember if there was an endpoint for that or not

burnt quiver
#

api allows bulk deletion of 2-100 messages, dpy handles it for u if there are more than 100 messages

#

and the messages being older than 14 days part

gritty inlet
#

So it's just manual deletion?

#

Ohhh my bad

burnt quiver
#

if it's older than 14 days yes

gritty inlet
#

Misread

#

Very ineffective

#

If you don't use purge

#

I also agree with the point that this isn't something necessary

#

Just delete the whole channel atp

#

Then disable Read Message History permission for unverified members

#

Not like that

#

Verification as a general thing; People you know

woeful hill
#

what spies if your private server is uuh, private

gritty inlet
#

If you want private conversations then use a private channel or dms

#

Then don't add bots who might "spy"

#

I've already mentioned ways to avoid that

#

And this isn't a real concern, unless spies "like you" for whatever reason

fast osprey
#

If you don't want people reading history don't give them perms to do so. It's really just that simple

dapper drift
#

Hi guys😅

#

Good evening can i ask a lil bit of help?

fast osprey
#

Sure, what's the question?

dapper drift
#

I still haven't come up with an essential title idea

fast osprey
#

If it's not python related at all I'm not sure why you'd ask it in the python community server miku_what

dapper drift
#

I don't know why i am here

#

But im learning python tho

fast osprey
#

I can guarantee you there is a community more related to whatever it is

dapper drift
#

Thank you so much

fast osprey
#

if it's around python learning/research/communication, #pedagogy might be the place

heavy peak
#

is it possible to let server owners change how the bot appears in there servers such as server avatar bio and such? how?

gritty inlet
#

You can let users change your avatar,banner,bio

heavy peak
#

asking other people so much easier though :)

gritty inlet
#

idk Gave you something to start with.. (:

lethal field
#

most basic discord bot?

gritty inlet
#

?

ancient carbon
#

Hi

#

Can someone help.me run a shh file
I'm on mobile so I can't do it

fast osprey
#

People aren't going to run files that a rando gives them

#

Or rather they really shouldn't

gritty inlet
#

If you want to have a hard time for some reason, then use JuiceSSH

#

Orrr just wait until you can do that on desktop

#

Anyway what the hell is an SSH file ☠️

#

SSH is a protocol

ancient carbon
gritty inlet
#

Then download it

ancient carbon
#

I'm on my.phone

gritty inlet
#

Where are you trying to download "it" from

fast osprey
#

This not only is sketchy but what does this have anything to do with discord bots

ancient carbon
#

I have a file on my.vps I can't run shh on my mobile

ancient carbon
fast osprey
#

So why are you asking people to run a file for you and then you say you need to "download" it

ancient carbon
gritty inlet
#

Or use JuiceSSH, a mobile app for SSH managing that I use rarely as it just sucks on mobile

ancient carbon
#

I did it but the downloading doesn't work

#

I'll send package.json if I can

#

I got a commission due and I gotta edit like 10linee

gritty inlet
#

Does your VPS allow any protocols for connection

#

Or do you gotta edit everything through their system

gritty inlet
fast osprey
#

So you are getting paid to do something, and due to your own oversight you now want someone to clean up your mistake for free

#

by downloading some random file

#

from some random person

gritty inlet
#

Anyway if you use a certain VPS you should definitely know how to interact with it. Yes even from mobile

fast osprey
#

dang, should have thought of that when you got paid to do something

ancient carbon
#

Like bru it ain't a virus

gritty inlet
#

Can you not even edit the file?

#

Directly

fast osprey
#

Right. Trust the rando telling you to download a file

ancient carbon
#

I can but I rafer vibecode ir

#

Gotta edit like 10 lines of code

gritty inlet
#

Well you got a deadline and money on the line, this isn't about preferences

gritty inlet
#

What I personally do is:

  1. Code on PC
  2. When I'm away and desperately need to edit code / run files I use SSH protocol to my Raspberry Pi through a mobile app.
  3. Option 2 pretty much never happens
ancient carbon
#

Fair

gritty inlet
#

What can I tell you man

ancient carbon
#

Bru

#

It's just a mirror script I need

#

Nvm bad idea

#

He's stealing all my confidential files

#

NGL your a bad person you deleted all my files

fast osprey
#

can yall roleplay in dms instead of here

prime sequoia
#

is there a scientist I can talk too that knows python I need there input on something.

feral timber
prime sequoia
#

I have something that might freak out the scientific community and need input on a extension to theory of relativity

feral timber
#

Have a snack while you're there

narrow hazel
#

Do i use discord.Member or discord.User for timeouts?

vast gale
#

Member

narrow hazel
#

thank you

narrow hazel
#
       try:
            mute = self.b.value.lower()
            if mute.endswith("m"):
                minutes = int(mute.replace("m", ""))
                mute_time = datetime.timedelta(minutes=minutes)
                await self.user.timeout(mute_time)
                await interaction.response.send_message(
                        f"{self.user} was timedout for {mute}")
            if mute.endswith("h"):
                minutes = int(mute.replace("h", ""))
                mute_time = datetime.timedelta(hours=minutes)
                await self.user.timeout(mute_time)
                await interaction.response.send_message(
                        f"{self.user} was timedout for {mute}")
            if mute.endswith("d"):
                minutes = int(mute.replace("d", ""))
                mute_time = datetime.timedelta(days=minutes)
                await self.user.timeout(mute_time)
                await interaction.response.send_message(
                        f"{self.user} was timedout for {mute}")
            else:
                await interaction.response.send_message("The mute must end with `m`, `h`, or `d`")
        except Exception as f:
            print(f)``` ![FunCool](https://cdn.discordapp.com/emojis/1376871513537646723.webp?size=128 "FunCool") Took way to long
woeful hill
#

so you timeout people 3 times 🤔

#

well it would raise exception but keep checking it after already timeout is kinda wasting computing power

narrow hazel
#

I've never had issues with it muting 3 times

woeful hill
#

mute = "3h"
first if, False
second if, True, timeout
third if, False, go to else block, send another response and get interaction already responded

#

but since you put it in try except block you wont see the traceback

#

perhaps you mean to replace the second and third if with elif

narrow hazel
#

Nope just once

woeful hill
#

you wont see the error because it only true in 1 of the if block, the last if block has an else but it is another reponse so it will raise interaction already reponded

narrow hazel
#

even if it doesnt produce an error by your logic it would trigger more than once for all 3 if statements but it doesnt

#

It works so I dont need to mess with it anymore

finite salmon
# narrow hazel ```py try: mute = self.b.value.lower() if mute.en...

I really don't understand why people do

try:
    ...
except Exception as e:
    print(e)

You're literally stripping out the most important part of the error message and only printing out a single line of the error message. It's almost as good as just suppressing the error entirely

narrow hazel
#

Thats how i saw it in the docs

#

and others code

finite salmon
narrow hazel
#

🤷

#

I looked it up like 3 months ago

finite salmon
narrow hazel
#

how is it supposed to be formatted?

finite salmon
#

Let your entire error message be thrown

narrow hazel
#

There is no error in cogs

#

I use try and except so I can see issues

finite salmon
#

It gives you complete detail on what went wrong on which line, which component, etc

narrow hazel
#

I know people said use the logging module but im lazy

finite salmon
finite salmon
narrow hazel
#

wdym

finite salmon
narrow hazel
#

im not sure how else to print out the errors since cogs wont show me the issue and the times it does tell me the issue its a syntax error not with discord.py but with python

#

try and except is the only way I can see what I did wrong

finite salmon
burnt quiver
#
from traceback import print_exception
finite salmon
narrow hazel
finite salmon
#

Bro fucked up his cogs big time

narrow hazel
#

im not sure how I would've done that

finite salmon
#

Me neither, but you somehow did

narrow hazel
#

this was the way I found

finite salmon
#

I suppose you must've been suppressing errors in some or the other place

#

Try doing raise ValueError() in one of your command at the top and see if you get traceback

narrow hazel
#

idk why im getting an unrelated error out of nowhere

finite salmon
#

Can u show

narrow hazel
finite salmon
#

You don't have the setup function in your commands/punishment.py

narrow hazel
#

I fixed it it was some weird issue with the formatter I had

#

I just reverted back

finite salmon
#

💀

#

Wild

narrow hazel
#

yeah idk

#

You just want me to do this?

finite salmon
#

No

#

Inside a command

#

Any command

narrow hazel
#

oh the setup

finite salmon
#

No not the setup

#

Like a user command which you can run

#

Unless you have a command called setup

narrow hazel
#

yeah I put it under the function, no?

finite salmon
narrow hazel
#

yeah

finite salmon
#

And not the setup function to load it into cogs

narrow hazel
finite salmon
#

Okay

#

Run your bot and use that command

narrow hazel
finite salmon
#

See if you get a traceback

#

Only god knows what you've done with your error handling 🙏🏿

finite salmon
narrow hazel
#

no

#

was I suppoed to?

finite salmon
#

Not really

#

I can't really tell unless I look at your entire source

#

Which I can't

narrow hazel
#

let me try a smaller command like my purge

#

nope

#
import discord
from discord.ext import commands
from discord import app_commands

class purge(commands.Cog):
  def __init__(self, bot):
    self.bot = bot
    
  @app_commands.command(name="purge", description="This will purge an amount of message from the current channel.")
  @app_commands.default_permissions(manage_messages = True)
  async def purge(self, interaction: discord.Interaction, amount: int, message_id: str = None):
    raise ValueError()
    await interaction.response.defer (ephemeral=True)
    
    try:
        if message_id:
          messages_to_delete = []
          async for msg in interaction.channel.history(limit=amount):
            messages_to_delete.append(msg.id)
            await msg.delete()
            if msg.id == int(message_id):
              await interaction.followup.send("Message ID found. Stopping Purge", ephemeral=True) 
              break
        else:
          d = await interaction.channel.purge(limit=amount)
          await interaction.followup.send(f"Purged {(len(d))} messages from {interaction.channel.name}", ephemeral=True) 
    except Exception as F:
        print("There was an error with the purge command: {F}")
async def setup(bot):
  await bot.add_cog(purge(bot))```
woeful hill
#

you used bot.start without setting up logging

#

so ofc there would be no error printed out

#

just use bot.run

narrow hazel
#

I dont have logging at all

woeful hill
#

yeah then you use bot.run

#

so the library will setup logging for you

finite salmon
gritty inlet
#

If you just print the exception, you might as well let it raise to begin with

#

But not so necessarily, for example I have a file set up where all of that stuff goes to

#

Some errors I even send to a Discord webhook

timber dragon
finite salmon
#

oh

narrow hazel
#

So I'll have to setup logging then

#

Makes sense

timber dragon
#

Not really

#

You should be loading your stuff in setup_hook and then using bot.run

timber dragon
woeful hill
#

The default permission decorator would just hide it from users who dont have the perms

timber dragon
#

Do you perhaps want lib side checks

gritty inlet
#

Then use bot.tree.error

#

Idk how it's done per cogs though

timber dragon
#

That's still per command when it can be done globally at once

gritty inlet
#

I don't think there's a version of this for any interaction, maybe I'm wrong

gritty inlet
#

Why'd you need for any interaction if we're talking about has_permissions xD

timber dragon
#

has_permissions is a lib side check

#

It raises an error

gritty inlet
timber dragon
#

See the message below that

gritty inlet
#

Ah i see

#

Something else you can do is make your own decorator

#

That doesn't raise

timber dragon
#

Don't

gritty inlet
#

Eh depends on usage

#

Here they don't gotta do that

timber dragon
#

Nah checks aren't supposed to send anything

gritty inlet
#

Fair

timber dragon
dry kelp
# timber dragon

I had this discussion a while back, i would recommend beginners to use disnake for a bot that's related to interaction commands.

#

The only - disnake has, it's that they're not really onto prefix commands, and there's no hybrid feature.

#

But still, you can just create your own hybrid, not recommended for beginners.

fast osprey
#

Arguably hybrids shouldn't exist in the first place since they completely screw with permissioning

dry kelp
#

That's not to use for beginners, perhaps, im not even using library permissions checks.

#

Since bot has a feature as in fake permissions, allowing users to use certain that are under a certain permission required, without actually having that permission in the guild.

#

Eitherway, im tired of commands, so im just making a bot that's fully components based (for setups).

#

eitherway, im still working on the actual container ui and design

#

I think it's a cool concept, but whole on help i want to just fully hide the components, and only make them appear onto command selection, and also working with dropdowns more

#

as in using user and role dropdowns labels.

#

Will work so much better than all these buttons

timber dragon
#

Very cool

dry kelp
#

more specifically, a mentionable select :D

dry kelp
dry kelp
#

Usually, exceptions are not handled like that, and they're handled globally, that way you can save a lot of lines of your code, and that's how supposed to be "best practice"

#

It's not that it "magically" doesn't work.

#

There is a reason, Since you say it "doesn't detect" anything could be due to the reason of not loading the cog where the error handled is mounted at.

#

error handler for interaction, should have something as on_interaction_command_error or similiar, im unfamiliar with discord.py

#

The cog requires a setup function, in order to be able to load that onto your bot.

#

Perhaps, instead of loading each file like that, try to create your main file, __main__.py being your main setup function of the bot, where you load a certain "extension/cogs" folder, and you can create your baseclass of the bot, (could be a __init__.py), having your own walk_module to load the path as you want.

#

How did you proceed your debug? into ensuring it loads?

#

Have you tried printing/logging inside of the main file verifying that it actually loads?

#

or wherever your setup cog function is being passed

#

You need to ensure that it actually loads, and not assume.

#

you're only logging an exception, check the extension_name that are being loaded.

#

and i doubt bot.load_extensions will fail (LOADING COGS), so it never tells you if that cog loads or not

#

Excuse you?

#

When you're able to build such a structure ask for help, unless then find your own information.

#

And you're wrong, You don't know if it loads or not, that log will only log if something is wrong with load_extension

#

append all the extensions that are being loaded, and put that log under load_extension

#

I don't need to use GPT in order to understand how to start some "cogs"

#

Well, then i guess you can remain with your magic way of thinking, thinking it "doesn't work for you"

#

clearly a library fault and not your code

#

Cause you're clearly not looking for help, and you're looking for arguments.

gritty inlet
#

I can just sum this up in one sentence

dry kelp
gritty inlet
#

Just do:

@tree.error
async def x(...):
  ...

And it will work for your commands, you don't need to manually refer them to your error handler

fast osprey
#

FWIW you don't need to loop over the file system. Python already has built in utilities for finding modules and packages, it's pkgutil

dry kelp
fast osprey
#

It's not a good reason I'm sure

#

This looping over .glob is rather rudimentary youtube tutorial level code when there are literally supported stdlib utilities made to do exactly this

gritty inlet
#

Idk what that reason could be

dry kelp
#

lol, filesystem to module normalization with safety rails. find_extensions accepts raw filesystem paths, converts them into importable dotted names, and rejects any path that attempts to escape the working directory before resolving the spec. It then raises tailored ExtensionError messages if the target can’t be found or isn’t a package, rather than propagating the lower level exceptions from importlib

#

Also, ignore handling tailored to our configuration surface. _walk_modules explicitly rejects the common “single string” mistake for ignores and converts iterable prefixes into a callable predicate so modules are skipped before pkgutil ever tries to load them, logic that isn’t present in the bare standard library iteration helpers.

fast osprey
#

await asyncio.gather([bot.load_extension(x) for x in pkgutil.iter_modules(['folder'], prefix='folder.')])

dry kelp
fast osprey
#

what are you even on about

#

literally none of that has anything to do with the youtube tutorial loop they posted

dry kelp
#

I don't rely on youtube tutorials.

fast osprey
#

I'm not talking about you

dry kelp
#

Oh

#

Eitherway, i just wanted to bring up some reasons of why we're doing this.

#

Based on a docstring appearing in a image you won't understand the baseclass of the bot, and it's purpose.

fast osprey
#

Or you could just not structure your project in an insane way and you don't need all that overhead, and the one liner I posted works fine

dry kelp
#

Where is the fun if we remain to simple stuff?

fast osprey
#

like yeah you could write a utility that covers every possible edge case, or if you're just writing something to import your own stuff you just don't do that insane shit

dry kelp
#

You do you, i do me, you can keep on and use it, i'll use my own ways.

dry kelp
#

e.g missing perms to interact with command, that is directly passed thru the perms callable

#

e.g max concurrency callable, all of these error messages are sent directly from library.

gritty inlet
#

You do not need both when the one I sent covers all

dry kelp
#

I just won't do that for each of my "trees" 😂

#

adding crazy lines of code for no reason that could be avoided

gritty inlet
#

Why would you need multiple trees anyway

dry kelp
gritty inlet
#

Tree is a single object per bot

dry kelp
#

I Assumed that meant the tree over an application command.

fast osprey
#

why would you need to check permissions yourself when discord already has a native permissioning system in the first place

dry kelp
#

Ah, so it's not a main group of a commandthinkCat

#

Well then yeah, that works and makes sense.

fast osprey
#

why are you always assuming I'm exclusively talking to you

gritty inlet
#

You didn't, said generally

dry kelp
#

Eitherway, my best recommandation for beginners, just use disnake library for a full intended interaction bot.

timber dragon
#

Why tho

#

There are a lot more Python libs out there

#

Even ones with the same features or http only

dry kelp
#

Because disnake, it's something i personally use, and it's absolutely friendly with new users.

#

The way on how interaction commands callables are named"

timber dragon
#

So you're biased

dry kelp
#

Also

quick gust
#

That's a personal bias
You can't say x is better if you have no experience with the 25 other libaries

dry kelp
#

discord.py, does it even register commands for you? as far as im aware, no

timber dragon
#

It doesn't have to

dry kelp
#

even some anime library i forgot name of

quick gust
#

Definitions?

dry kelp
quick gust
#

anime library is crazy 😭 I think you're talking about hikari

dry kelp
dry kelp
fast osprey
#

Libraries abstracting out meaningful decisions with side effects is not a good thing

timber dragon
#

How much money did they give you

dry kelp
#

Reasons why i've said it's beginner friendly.

dry kelp
timber dragon
#

Disnake isn't beginners friendly either

#

It's a lot more complex than other libraries imo

dry kelp
#

doing*

fast osprey
#

Not very beginner friendly when they get locked out of development and the library doesnt explain why

timber dragon
#

Also there other libs that sync app commands for you

#

It's not just Disnake

dry kelp
#

most beginners would only care about that making commands, and some validations for commands 😂

#

Nobody continues into making a deeper bot, most get bored.

#

So disnake it's definitely a good start into a beginners project.

timber dragon
dry kelp
fast osprey
#

If your library syncs for you under the hood without asking you, it can exhaust your rate limit of syncs

dry kelp
#

definitely, thinking they keep re-syncing all commands over and over, keep in mind, i said "all"

#

Just go try it out yourself.

timber dragon
quick gust
#

Could you explain what you meant by disnake being locked out of development? I use it but I may have missed this update

dry kelp
timber dragon
#

Locked as in ratelimited for syncing too often

dry kelp
#

I did guide multiple users into using disnake library, and most of them preffered it more than other libraries.

timber dragon
#

It's a personal preference yes

fast osprey
quick gust
#

Oh I see

fast osprey
#

Again, abstracting meaningful decisions with important side effects is not a good thing

dry kelp
quick gust
#

Totally misunderstood lol

timber dragon
#

Not "the most beginner's friendly library out there that everyone should be using"

dry kelp
#

It's giving them a chance and a opportunity to try something new.

#

That a lot of people use, and enjoy, it's just well made.

#

i've gave my personal review over disnake.

timber dragon
#

You're just shoving it in their face though

#

No you didn't

dry kelp
#

When did i say straight forward to a user, "go use disnake"?

#

If you find a message of me saying to a user within the last hour, telling or forcing to go to disnake library, feel free to send me your paypal, i'll send you 200$.

stark ingot
fast osprey
#

There isn't a library that can read your brain and know your ready for an api change

burnt quiver
#

Autosync in pycord with all the checks and everything sounds cool but I think it should default to false ngl

#

-# Also this is just an opinion

dry kelp
#

But yeah guys, thank you for this discussion, it was fun, i wasted too much time, i need to resume on my work, good luck into your projects.

stark ingot
timber dragon
fast osprey
#

It doesn't mean you will, it means you can and you won't know why because the library abstracted that decision from you

dry kelp
stark ingot
dry kelp
#

feel free to ping me for help.

dry kelp
dry kelp
timber dragon
#

True

stark ingot
fast osprey
#

I see people hit it all the time so don't know what to tell you

stark ingot
#

I have seen plenty of people hit the command create limit. Never seen anyone hit the upsert limit which is quite simple to implement in a extremely basic auto sync implementation

gritty inlet
#

Hitting it or not, dunno how it is good practice that your library makes you automatically update stuff that doesn't necessarily need updates

stark ingot
#

I still don't see why it is not good practice. I have never needed to not update my commands when I add a new command to the code. And if I did, I could turn off auto sync for that instance

gritty inlet
#

It wouldn't make sense that most of the changes to your code are adding commands

fast osprey
#

I'm vaguely remembering a discussion we had where you advocated that every command you ever commit should be made public immediately

stark ingot
#

Yes

fast osprey
#

Which I strongly disagree with given that it is industry best practice to not do this

stark ingot
#

If you don't want to use it don't use it. But you cannot say that there are not equally valid use cases. The majority of people are not running their discord bot based on industry best practices.

fast osprey
#

I won't use it, and I will continue advocating that other people should not

dry kelp
#

I do believe what he means, it's about confidence, e.g making a command, most developers have already a structure in head or written down once building a command.

#

After a certain level of experience, you don't even need that much "testing" to ensure a command is properly done.

#

Personally, i don't even test most commands, cause i already know they're built properly.

#

And most of the tests i do are not even "commands" related, are mostly about structural changes of the bot.

#

Whole bot API is on a different repo, Ensuring connection, that's stuff that do need checking.

#

So i can see ice point, and also your point, but shit... testing a ban command... i think everyone after some experience can think of proper validations, it's literally few checks, then you check what could raise while banning, which are normally handled thru a global command error handler

#

Even design of embeds, it's not even hard having some imagination over that.

fast osprey
#

There's a very important difference between master being deployable and everything on master being exposed to users immediately

dry kelp
#

I didn't see ice mentioning they're releasing everything directly on master.

fast osprey
#

I was referencing an earlier conversation

dry kelp
#

And i still can't see that, i thought he mentioned about relasing once command is done to main without testing it, which i don't see that being so bad.

fast osprey
#

It's very common practice to have unfinished code on master while master remains deployable. This is what feature flags are for

dry kelp
#

Welp, understood, i don't release on master, there is a branch that's used for production.

fast osprey
#

What you name the branch isn't important

#

The main point being that it is commonly accepted practice for a number of reasons to have a branch where every commit can be deployed while also having things in that branch which you don't want exposed to users the moment it gets committed there

dry kelp
#

I understand, once again, i'm not detailing everything, ofc my master branch is NOT production, and i hope you could've understood from the concept.

fast osprey
#

Sure, name branches whatever you want lol

dry kelp
#

But since i have to say this, it's a branch where once finalized code of a development branch (not main), goes to master, from master goes into production

fast osprey
#

You can deploy from shmorgle-dorgle as long as the principles are met

dry kelp
#

pfff, man u really don't get it from the names, do you?

#

I understand if i named them pickle peach and cookies, that wouldn't of had made sense

fast osprey
#

What is it you think I'm not understanding

dry kelp
#

no context, but if i tell u production means production

fast osprey
#

Okay...? I know what that word means and I don't know why you think I don't

dry kelp
fast osprey
#

What is it you think I don't understand

dry kelp
#

But you kept saying names are not importants, im using simple common names, which give you more context than what im currently typing.

#

Cause im not going to sit here and detail you each branch functionality.

fast osprey
#

I never asked for it

fast osprey
#

How is that me asking you to explain your branch names to me

dry kelp
#

Holy, bro you're slow, it was not an answer to that, i was ignoring it.

fast osprey
#

Don't appreciate you insulting me

dry kelp
#

You're not getting it from context, just let it fly.

fast osprey
#

You're refusing to explain the actual concept you think I'm misunderstanding

#

And talking in circles then insulting me because I don't get your circle

dry kelp
#

If you just can't understand common names, just take a walk, much appreciated.

fast osprey
#

Who said I can't understand common names

#

What common name do you think I don't understand

dry kelp
#

🤣 🤣 🤣 🤣

#

And if i call him slow, he says i insult him.

#

Whatever man, you're the best!