#discord-bots

1 messages · Page 418 of 1

woeful hill
#

anyways youre in the wrong channel for that

#

this channel is for discord bot development

runic valve
#

i know

#

can i use python for bots?

woeful hill
#

what is the server's name

finite salmon
#

As I said, you can use any language for anything

woeful hill
#

what is this channel name

runic valve
#

discord bots

woeful hill
#

connect the dots

runic valve
#

is there any tutorial

#

to make hacking bots

#

im joking, just normal ones

woeful hill
#

you seems to be obsessed with hacking

runic valve
#

yea hacking is interesting

finite salmon
#

But you need to know some fundamental python stuff

finite salmon
#

Like classes and stuff

finite salmon
woeful hill
#

a github pages link that host virus

#

sure

runic valve
#

idk about classes, what is it used for

finite salmon
#

At it's core it's meant to group data into a single namespace

woeful hill
#

classes are blueprints

finite salmon
#

But it can go deeper than that

woeful hill
#

!res

unkempt canyonBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

runic valve
#

alr i will learn it

stark ingot
# runic valve alr i will learn it

If you are truly interested in hacking you should check out cybersecurity capture the flags. They teach you the basic skills and allow you to practice them in a safe and legal manner.
Hack the box and PicoCTF are good starting points

idle current
#

SOMEONE HAVE A CODE BOT TREE FOR WHITELIST AND UNWHITELIST DISCORD BOT

fast osprey
#

CAPS LOCK AAAAA

tawny anchor
#

How can i put a title in a layoutview (components v2)

fast osprey
#

How do you mean title? Afaik you can use markdown in text displays

tawny anchor
#

What do you mean by markdown?

#

big text like this?

fast osprey
idle current
#

SOMEONE HAVE A CODE BOT TREE FOR WHITELIST AND UNWHITELIST DISCORD BOT

#

SOMEONE HAVE A CODE BOT TREE FOR WHITELIST AND UNWHITELIST DISCORD BOT

woeful hill
#

no need to shout thrice

#

unwhitelist 💀

#

what even is a "whitelist and blacklist discord bot" bot

fast osprey
#

CAPS LOCK CAPS LOCK GIVE ME FREE STUFF

#

Bro make it yourself

celest pelican
#

@idle current Please change your username, stop shouting and stop spamming.

idle current
#

Ok

#

Ok sorry

idle current
#

👍?

fast osprey
#

That's a very good question isn't it

gritty inlet
#

Regardless, some languages have a bold advantage in certain things over other languages

narrow hazel
#

Honestly I have yet to see a reason to code a bot in anything else except python

#

Python works with other stuff so If I need custom html or lua they do have modules that work eith them

timber dragon
#

So true

fast osprey
#

Hot takes in the python community server

terse niche
#

how to install python

grave sandal
# terse niche how to install python

If you're on Windows then go to the website, pick the version you want, download and run the install executable, check the little icon at the bottom left that says add interpreter to path then proceed with installation like any normal piece of software.

terse niche
timber dragon
#

Can also install it from the windows store

gritty inlet
#

The funniest thing to me is people who use Java for Discord bots

#

As if life isn't hard enough already

narrow hazel
stark ingot
timber dragon
#

Even with the new installer?

timber dragon
warm bramble
#

Do it yourself brada

wispy spade
gritty inlet
high kite
gritty inlet
narrow hazel
#

Anyone know of an easier way of writing buttons and their functions than just

@discord.ui.button(blah blah)
Async def function_name()``` for each and every button?
#

I plan on making a ticket system with like 40+ buttons and it's gonna be a pain to write it all out manually

quick gust
#

What ticket system requires 40+ buttons...? Doesn't sound like a great design choice

#

If it's split across different commands/"pages" then that's fine, but you obviously need to define the callback function of the button

gritty inlet
#

40 different buttons sounds like bad UX

fast osprey
#

If the buttons do different things, how do you envision not writing it out? Python can't magically infer what you want them to do

timber dragon
#

You can subclass the Button for a callback

class MyButton(ui.Button):
    async def callback(self, interaction: Interaction) -> Any:
        print(f"{interaction.user} clicked button with label: {self.label} and custom_id: {self.custom_id}")
        ...


btn = MyButton(label=..., ...)
<view>.add_item(btn)
narrow hazel
#

I made it with a block programming language and im trying to move it to python

#

Got this much done but its still only like 20% of the system

narrow hazel
woeful hill
#

and more when I think of them
Then why would you wanna make 40 buttons

#

-# You cant btw

#

In a single message, 40 aint possible

narrow hazel
#

not in a single message

#

obviously it can only handle 25

#

its an advanced ticket system that can automate every need a user wants

woeful hill
#

Then why are you want to make 40 buttons inside a single view class

narrow hazel
#

im not

#

the system is gonna have a ton of buttons its not a single message

woeful hill
#

Then you just create 40 buttons decorators if they have different callbacks

#

Use a helper method if they share some logic

narrow hazel
narrow hazel
#

I was only asking if there was a simpler way cuz doing it takes a minute to write a button and its function

woeful hill
#

I want a quicker way to do this quickest way of doing different thing

#

It doesnt take a minute to write 2 bare bone lines of code

narrow hazel
#

if you're gonna keep insulting me for asking questions then im just gonna block you

#

im here to learn not be berated

finite salmon
#

Like soheab said, you can subclass discord.ui.Button and instantiate how many ever you want of them (and add it to the view) if those buttons share similar functionalities

narrow hazel
#

Sounds good I'll check it out thanks

timber dragon
gritty inlet
narrow hazel
#

Yeah I thought of changing a few for select menus

#

good suggestion i'll look into it

#

I gotta learn unix and task.loops first

#

so I can actually make an autoclosure

gritty inlet
narrow hazel
#

yeah I know how they work and the basic just gotta learn to effectively implement them with the command

gritty inlet
#

One problem with tasks is that you lose them on shutdown

#

Unless you don't experience unexpected shutdowns as much as I do

narrow hazel
#

hmm

#

not a big deal with a ticket system honestly, if need be it can be done manually

gritty inlet
narrow hazel
#

I should also learn how to save buttons but thats a task for another day

gritty inlet
quick gust
#

You don't have to manually loop over all the entries, that's what the WHERE clause is for

gritty inlet
gritty inlet
#

Then you might wanna start using those

narrow hazel
#

true I looked at how to do it but it was bit out of my zone since I didnt know JSONs at the time

leaden helm
#

how can i make dropdown inside an embed?

gritty inlet
#

discord.py:
Dynamic item is simple, you need to pass a template regex of how the custom id of that item should be structured

then you define from_custom_id which is a class method for making an instance from the custom id

and ofc, callback

narrow hazel
gritty inlet
#

Check the docs if you're interested

narrow hazel
gritty inlet
#

oh u use pycord?

gritty inlet
fast osprey
narrow hazel
fast osprey
#

That's not a good decision

gritty inlet
#

You should migrate definitely

#

Threads were made for this

narrow hazel
#

threads arent private unless you make a modmail system and i hate those

#

they're ugly

fast osprey
#

They're private if you tell them to be what

gritty inlet
#

Yeah.. just like text channels can be

narrow hazel
#

nah just shove them in their own category

#

they'll be fine

gritty inlet
#

Using normal channels is a mess, but go ahead

narrow hazel
#

I use threads for suggestions and bugs and automate those

#

I havent quite learned how to manage things from the bots DMs

gritty inlet
#

It doesn't have to be from the bot dm

narrow hazel
#

as far as I've seen it's not possible to change an individual threads overwrites

#

Unless im missing something

gritty inlet
#

Check your library's docs, because it is

gritty inlet
narrow hazel
#

I did it a bit with discord APIs with block programming and the only way to achieve private threads was through a modmail system

#

from my personal expierence

gritty inlet
#

Well I know for a fact it doesn't work that way lul

gritty inlet
narrow hazel
narrow hazel
gritty inlet
#

Fetch members fetches members..

#

I have nothing more to suggest than checking your library's docs

narrow hazel
#

yeah creating a completely private forum channel and using fetch members to grab and pull them into the thread

gritty inlet
#

Nah

#

it fetches members that are a part of the thread

#

Anyway that doesn't matter

narrow hazel
#

I did try using just a private forum with a button from another channel but the issue there was people could see past tickets

#

and couldnt have that so I scraped that idea

gritty inlet
#

There's all kinds of ways to go around problems like this, you just need to find one

narrow hazel
#

maybe but I know the text channel way rigjt now and have a system built around it so until I find something else I'll just stick withj it

#

im gonna look into persistant buttons and stuff

gritty inlet
#

readthedocs 🫡

narrow hazel
#

Fair

#

I should figure out if I'm using pycord cuz when I started I sorta just installed everything and haven't changed much

#

I don't think I am

quick gust
#

wait you've made a bot but you don't know what library you're using for it?

gritty inlet
#

He's most definitely using discord.py

But man just go to the module file and see

narrow hazel
#

Nah I learned by just looking up stackoverflow code and seeing if it worked if not moved on to a different article until I found one that worked and memorized that code

quick gust
#

you should never memorize code snippets

gritty inlet
#

import discord

click on discord

quick gust
#

that's a really bad way of "learning", if even

narrow hazel
#

I mean I learned some basics

#

but I did skip a lot

#

wish there was a roadmap to help

finite salmon
#

doesn't cover every single topic but it touches the main concepts of core python

narrow hazel
#

I'll check it out after I wake up thanks

finite salmon
#

if you wanna use it, save it in your system, that link will expire in a few days

narrow hazel
#

Oof

low harbor
#

How can i put a actionrow button to the right side in a components v2 layoutview?

gritty inlet
low harbor
tawny anchor
# burnt quiver code?

This is my code:

        buttons1 = PanaszkonyvButtonUBKERELEM(self)
        buttons2 = PanaszkonyvButtonSTAFFREP(self)
        buttons3 = PanaszkonyvButtonEGYEB(self)

        section1 = discord.ui.Section(ubreqtext, accessory=buttons1)
        section2 = discord.ui.Section(staffreptext, accessory=buttons2)
        section3 = discord.ui.Section(etcreptext, accessory=buttons3)

        container = discord.ui.Container(
            section1,
            discord.ui.Separator(),
            section2,
            discord.ui.Separator(),
            section3,
            accent_color=0x0E2F86
        )

        self.add_item(container)
burnt quiver
tawny anchor
burnt quiver
#

you're not supposed to add an action row

#

Add either a button only or Thumbnail

velvet compass
#

@mild kiln Your message was removed for violating server rules 6 and 9

mild kiln
#

Uhhh

vast gale
gritty inlet
#

What if discord.py had an unknown_interaction event to handle shit like this? It's not like nobody uses regular callbacks

burnt quiver
#

huh

gritty inlet
# burnt quiver huh

If you use discord.ui.Button(...).callback, and bot restarts, you will no longer be able to control that button's response, not even to tell the user properly that it expired. I just think that the "this interaction failed" default response is so ugly

burnt quiver
#

you can tho

#

just add the view on restart

#

Persistent views

gritty inlet
#

Welp you're right PensivePeach

#

Hmm but with persistent views, the bot will keep storing that view, which it wouldn't if such an event existed

#

I think it'd just be a little bit more optimized, maybe I'm wrong.

fast osprey
#

Sometimes it's worth spending a tiny bit of memory for a useful layer of abstraction

#

If you want to be "optimized" you shouldn't be using python in the first place

gritty inlet
timber dragon
gritty inlet
#

Knew I'd get hit with the dynamic item man

timber dragon
#

They're so good

gritty inlet
#

Well in that case I'd have to manage the cache myself, not that it's such a disaster, but still

timber dragon
#

What

#

OH

gritty inlet
#

Orrrr I can pass all info to the custom id

timber dragon
#

You don't want persistentsy

gritty inlet
timber dragon
#

Knowing whether a component was handled by a view would be nice yes

gritty inlet
#

😭 🙏🏻

#

They say right things but bruh atp remove regular callbacks as they're objectively bad for UX

timber dragon
#

If you really don't want to get in the way of views and not hardcode stuff, yes

#

Pycord is planning something like that 🙏

gritty inlet
#

Good for them

#

I don't get the idea of having a feature where there's a certain problem that's unfixable, with the only "fix" being using a different feature

timber dragon
#

It's easily fixable

#

Just people being stubborn and sticking to a certain design

gritty inlet
#

The advantage of the callback is that the library handles the interaction responses for me, inside a class, potentially - what I mean to say is that this is comfortable to use, quite more than dynamic items for some use cases

#

But then as I said it becomes useless if you don't make it persistent

timber dragon
#

Ya

gritty inlet
timber dragon
#

Probably but that's the simplest and it doesn't break any design choices

gritty inlet
#

I was thinking initially about making a Git issue but now you showed me they dont want this

timber dragon
#

You could still try lol

#

That was all a year ago

#

Just pretend like not knowing about the above :)

gritty inlet
#

And that binds this concept to components rather than to interaction in general

burnt quiver
#

views are confusing sometimes :blobpain:

timber dragon
#

Dpy doesn't store views per message though

gritty inlet
timber dragon
#

Wait

gritty inlet
#

Sorry for reply ping

burnt quiver
#

there's a message_id kwarg for add_view

gritty inlet
timber dragon
#

Is it always per message

gritty inlet
# gritty inlet

Very primitive since I have no real way of checking if it was created internally

burnt quiver
#

!d discord.Client.add_view

unkempt canyonBOT
#

add_view(view, *, message_id=None)```
Registers a [`View`](https://discordpy.readthedocs.io/en/stable/interactions/api.html#discord.ui.View) for persistent listening.

This method should be used for when a view is comprised of components that last longer than the lifecycle of the program.

New in version 2.0.
gritty inlet
#

By default they are attached to message ids

burnt quiver
#

time to look at the srouce code

timber dragon
#

Message.view would be bad and misleading

burnt quiver
#

hmmm

gritty inlet
# gritty inlet
class BaseView:
  ...

    def __init__(self, *, timeout: Optional[float] = 180.0, id: Optional[str] = None) -> None:
      ...
      self.id: str = id or os.urandom(16).hex()
      self.is_id_overridden: bool = id is not None```

One thing I thought of
#

Unless making this bound to view.id is not good

#

Then ig you could have a method that checks the view store to see if that view is there and whether it's managed by the library (condition: id is set)

timber dragon
#

but how would you get the view in the first place

gritty inlet
#

You mean how to find the view corresponding to the interaction?

#

view = bot._connection._view_store._synced_message_views.get(interaction.message.id)

timber dragon
#

like not using private methods

gritty inlet
#

Should the library not use its own internal things 🤔

#

I just think it can be "more accurate" if you do that, rather than checking if an error didn't occur

timber dragon
#

but

#

views and view id is a dpy thing

#

you don't get that from the interaction afaik

#

unless you mean the method should take a message_id > search for view > check if id is set > return True : else False

gritty inlet
timber dragon
#

what would the flow for the library be?

gritty inlet
#
class Interaction:
  ...
  @property
  def item_callback_available(self) -> bool:
    if not self.type == InteractionType.component:
      raise TypeError
    if not self.message:
      raise AttributeError
    view = self._state._connection._view_store._synced_message_views.get(self.message.id)
    return True if view and view.is_id_overriden else False

I'm not too familiar with the source code, but this is just a concept I had in mind

#

bot instance won't be used like that tho

#

Maybe you'd pass the instance

timber dragon
#

oh I was thinking something on the bot

#

so you could get it even without an interaction

gritty inlet
#

what about interaction.client

gritty inlet
burnt quiver
#

i thought

gritty inlet
#

The condition at the end was wrong, fixed it

burnt quiver
#

self._state directly can be used no?

gritty inlet
#

correct

fast osprey
timber dragon
gritty inlet
#

In order to get around using the private methods?

#

Or

timber dragon
#

no

timber dragon
fast osprey
#

X without Y

#

Why?

gritty inlet
#

The point is not making it persistent

fast osprey
#

Why not just edit the message to tell them that rather than making them interact

#

Just sounds annoying

gritty inlet
#

Unexpected restarts is the only thing that I thought of

#

For me that'd be great

#

Maybe I'm the only one who may find this useful at all idk

fast osprey
#

I mean if your bot goes down unexpectedly you have bigger issues

gritty inlet
#

Or not unexpectedly. Restarts can be a normal thing

fast osprey
#

And even then if you wanted to be paranoid there's dynamic items

fast osprey
#

Like yes when you rule out the mechanism made to do the thing for no reason, there is no alternative

gritty inlet
fast osprey
#

How are you proposing you avoid managing cache on a restart

gritty inlet
# fast osprey Why is this the a priori point

Maybe I'm wrong but to me it sounds like bad practice, both for whether it's a large bot (you will store many many view instances supposedly), and for the fact you only persist it for sending a basic message

fast osprey
#

What is the theoretical feature that magically intuits what data you need for you

#

Making persistent views isn't a bad practice

gritty inlet
#

Sorry, I meant that in a view class, with callbacks, you can easily access view attributes. You kinda lose that ability with dynamic items

fast osprey
#

Because dynamic items presumes the data is baked into the custom id

#

That's the whole point

#

This could even just be an id you query for everything else

gritty inlet
#

Indeed

#

I mean I actually know about someone who chose to use dicts because they didn't want certain things to be exposed in the custom id, but as I said that's probably considered an edge case

#

That's all I got to say

fast osprey
#

A lot of people assume everything is sensitive when most things aren't

#

I can give you id's all day and there's nothing you can do with them

gritty inlet
#

Trivia with the correct answer being in the custom id; I get message data; I cheat

#

But yeah I don't think that should be the reason for adding a new feature

#

So I agree that this matters less

fast osprey
#

That case is just poor design

#

Not a case against the paradigm

#

If those things needed to persist between restarts, the secret data by definition needs to be put into a db

gritty inlet
gritty inlet
fast osprey
#

But that isn't your best choice

#

Because you aren't supposed to use dynamic items to embed secret data

gritty inlet
#

Right that's where I'd want to use something non persistent, instead of implementing DB usage where it's not crucial at all if I use memory
And I'd want to be able to tell the user, that this non persistent thing, has expired
idk

#

And now we're back to whether using persistent views for that is bad practice or not

fast osprey
#

Why are you asking a user to interact with something you don't want them interacting with

#

Just remove it and tell them that rather than making them do an unnecessary step

gritty inlet
#

On restart you lose the ability to do that. Restarts are definitely not edge cases

fast osprey
#

If you care about restarts then make it persistent. That's what persistent means

#

You can't just say "I don't want to use the tool made to do the thing I want to do, so make another tool"

#

The library's assumed default is that most views are temporary, restarts are rare, and even if they do happen and one view goes bad it's not worth warping the library to accommodate it people can live

timber dragon
# timber dragon oh I was thinking something on the bot

something like

class Client:
    ...
    def get_view_from_message(self, message: Snowflake, /) -> Optional[BaseView]:
        """Retrieves a stored view sent with a message.

        .. warning::

            This is not the same as :meth:`discord.BaseView.from_message`. This method
            only retrieves views that have been sent in the current session or have been
            registered via :meth:`Client.add_view` using the ``message_id`` parameter.

        .. versionadded:: 2.7

        Parameters
        -----------
        message: :class:`~discord.Message`
            The message that the view is attached to.

        Returns
        --------
        Optional[Union[:class:`.View`, :class:`.LayoutView`]]
            The view if found, else ``None``.
        """
        return self._connection._view_store._synced_message_views.get(message.id)
gritty inlet
#

Still would need to implement the other checks

#

Like an internal method somewhere to check if that message's view is active

#

Or not internal idk

timber dragon
#

it shouldn't be in the dict if it isn't active?

gritty inlet
#

It populates when you send a message with a view

#

Ah wait I'm not sure that was a question xD

timber dragon
#

yes it is

gritty inlet
#

O yea

timber dragon
#

oh wait this is dumb then

gritty inlet
timber dragon
#

so we need something for the custom_id

gritty inlet
#

Wdym

timber dragon
gritty inlet
#

It does, that's its purpose

timber dragon
#

how so? _synced_message_views is empty after restart

gritty inlet
timber dragon
#

all discord sends with the event is the component type, id and custom_id

timber dragon
fast osprey
#

If you need data you are inherently on the hook for getting it

gritty inlet
#

I check using the message id of the interaction

timber dragon
#

oh god I need to wake up

#

I thought you were sending a message IF the view was stored

gritty inlet
#

Oh nah lol

timber dragon
#

that makes a lot of sense now

#

so

#

it would be

if (view := interaction.client.get_view_from_message(interaction.message)) and view.id in ...:
  return

...
fast osprey
#

You can accomplish this with persistent views, it just doesn't do this by default because the library maintainers aren't as paranoid and anal about restarts

timber dragon
#

true

#

but i'm a fan of options

fast osprey
#

IMO honestly just a generic error when there's an interaction without a corresponding component would be fine

#

Catch the error, send a response

timber dragon
#

yeah even that would be better than nothing

#

currently there is nothing

fast osprey
#

I imagine that PR wouldn't be controversial, an exception (or one you can optionally enable) isn't warping

timber dragon
#

raise_on_unknown_interaction=True

#

hm ig but then how would you handle that?

#

Client.on_error is not an event

gritty inlet
#

whats the point of raise if it doesnt let u respond

timber dragon
#

you can respond while handling the error?

fast osprey
#

Or rather than an error let you implement a fallback

gritty inlet
#

It should still be implemented as an event somehow

timber dragon
#

I doubt the maintainers would like to store a function like that

fast osprey
#

It doesn't need to be an event

gritty inlet
#

so a method that takes a fallback method? that can work

fast osprey
#

It could just be a method on client with a default empty implementation

timber dragon
#

hm

gritty inlet
#

So now back to how that's implemented xD

timber dragon
#

it's easy to implement

timber dragon
#

not easy to get it past the maintainers

#

well shit

burnt quiver
#

gotta get past teh hardest obstacle

timber dragon
#

sharding and multiple instances

burnt quiver
#

sinbad does make very good points

timber dragon
#

indeed

gritty inlet
#

I didn't exactly understand

#

Ah well in that case the interactions that are received and their responses may interfere with each other?

timber dragon
#

an interaction can only be handled once

#

yeah

gritty inlet
#

So how do respones in general not fail for multiple processes

#

whats the big difference

#

I guess because they're more dynamic

timber dragon
#

they're made per instance, the other instances doesn't know about the other ig

gritty inlet
timber dragon
#

<@&831776746206265384>

gritty inlet
#

Mods smite this guy

gritty inlet
#

Based on the guild so you know which shard covers that guild?

timber dragon
#

good question

#

I wish I knew how sharding works

gritty inlet
#

Since I don't know how it works, I just fail to understand how what he described is a real issue. But I have a reason to believe him Ig.

#

And still the interaction object is bound to a certain guild (or no guild at all), so you should still be able to choose the right process? Thonk

#

But no idea how it works

timber dragon
#

you could ask em

gritty inlet
#

Maybe it's about this.. Aiohttp uses that session for the request

#
    ...
    def __init__(self, *, timeout: Optional[float] = 180.0, id: Optional[str] = None) -> None:
        ...
        self.id: str = id or os.urandom(16).hex()
        self.is_id_overridden: bool = id is not None
    
class Client:
    ...
    def get_view_from_message(self, message: Snowflake, /) -> Optional[BaseView]:
        return self._connection._view_store._synced_message_views.get(message.id)

class Interaction:
    ...
    def component_callback_available(self) -> bool:
        if not self.type == InteractionType.component:
            raise TypeError
        if not self.message:
            raise AttributeError
        view = self.client.get_view_from_message(self.message)
        return True if view and view.is_id_overriden else False
    
async def the_holy_internal_check(interaction: Interaction):
    ...
    if not interaction.component_callback_available:
        await the_function_to_handle_this_situation(interaction)

Anyway this is what I was able to come up with.
But I can't get any forward with this for now, would probably have to first prove that it can work
But at the end of the day you get all sorts of data of that interaction, including guild data, so Idk where problems come from

timber dragon
#

i'm doing Client.on_unknown_interaction rn

#

it'll function similar to Client.on_error

gritty inlet
#

Thankfully I actually do have a sharded bot to test this on

#

Although its just a very few shards

gritty inlet
timber dragon
#

oh yeah

gritty inlet
#

But it doesnt really have to be view.id. It can also be a check whether all view's items have custom id, or even if just the item that sent the interaction has..

#

At the end of the day you'd be checking for the view by message id

#

I forgot why I brought up view.id for this to begin with 😭

timber dragon
#

i don't even know why view has an id

gritty inlet
#

yea it seems to not be used for mapping

#

lemme see where its found

#
{
  1426127885659410462: {
    (2,
    '012ea8912709d5077beb5d0c03e74df2'): <Buttonstyle=<ButtonStyle.primary: 1>url=Nonedisabled=Falselabel='Coqui Frog'emoji=Nonerow=Nonesku_id=Noneid=None>,
    (2,
    '406511a3b0bd23a85cb7ad334be75de2'): <Buttonstyle=<ButtonStyle.primary: 1>url=Nonedisabled=Falselabel='Red-Eyed Tree Frog'emoji=Nonerow=Nonesku_id=Noneid=None>,
    (2,
    'd4cd9ce7a1a092a7c480633b041c88b1'): <Buttonstyle=<ButtonStyle.primary: 1>url=Nonedisabled=Falselabel='Australian Green Tree Frog'emoji=Nonerow=Nonesku_id=Noneid=None>
  }
}
#

012ea8912709d5077beb5d0c03e74df2 is a view id for example

timber dragon
#

ah so it is used

gritty inlet
#
{
  message_id: {
    (component_type, 'view_id'): component object
  }
}```
#

yea

#
class Client:
    ...
    def get_view_from_message(self, message: Snowflake, /) -> Optional[BaseView]:
        return self._connection._view_store._synced_message_views.get(message.id)

class Interaction:
    ...
    def component_callback_available(self) -> bool:
        if not self.type == InteractionType.component:
            raise TypeError
        if not self.message:
            raise AttributeError
        view = self.client.get_view_from_message(self.message)
        return True if view else False
    
async def the_holy_internal_check(interaction: Interaction):
    ... # Make sure to handle dynamic items before the following, or find a way to make them not contradict.
    if not interaction.component_callback_available:
        await the_function_to_handle_this_situation(interaction)```

⬆️ Yea it can work without view.id (probably), Idk why I got it involved
#

Removed the baseview, its useless now

timber dragon
#

nice

#

ig it works https://images.soheab.com/euOoRIV9jLw.png

class MyClient(discord.Client):
    async def on_unknown_interaction(self, interaction: discord.Interaction):
        print(f'Unknown interaction received: {interaction.id} from {interaction.user} with data {interaction.data}')
        await interaction.response.send_message('Sorry, this interaction is not recognized.', ephemeral=True)


intents = discord.Intents.default()
client = MyClient(intents=intents)


@client.event
async def on_ready():
    view = discord.ui.View()
    btn = discord.ui.Button(label='Click Me', custom_id='my_button')
    async def callback(interaction: discord.Interaction):
        await interaction.response.send_message('Button clicked!', ephemeral=True)
    btn.callback = callback
    view.add_item(btn)

    view.stop() # added after first run
    await client.get_partial_messageable(679016927988940831).send(view=view)
gritty inlet
#

Bruh I forget to turn off mention

timber dragon
#

its fine

#

it's just <state>.dispatch('unknown_interaction', interaction) in bunch of places where it exists if not found

#

also for app commands

gritty inlet
#

Like if there was no dispatch, then dispatch the unknown interaction?

timber dragon
#

yes

gritty inlet
#

That works

#

Although it's more primitive

#

But it works..

unkempt canyonBOT
#

Please react with ✅ to upload your file(s) to our paste bin, which is more accessible for some users.

timber dragon
#

bruh

gritty inlet
#

😭

timber dragon
gritty inlet
#

I wonder if the maintainers would like the idea of having it as a fallback rather than a more specific condition

timber dragon
gritty inlet
#

Anyway you might see a similar response from them again, what do I know

timber dragon
#

most likely

gritty inlet
#

I'd find that very good but if there's no chance then there's no chance

timber dragon
#

Will see in a couple of hours

burnt quiver
#

:kekw:

mild kiln
#

Guys

#

Who wanna make a bot with me of discord

fast osprey
dry kelp
burnt quiver
#

it's just a test function

dry kelp
#

If you guys are trying to reactivate the buttons after bot's restart best version is creating a proper sync that works after bot is ready.

narrow hazel
#

Why is slash command information hard to come by. Everywhere I look for code information on python prefix are what everyone uses

#

Even tho slash ain't that hard

fast osprey
#

It depends where you're looking

#

if you're looking on google/youtube, that's just basement vibe coders that wait for someone else to copy

narrow hazel
#

It's crazy how easy it was to register slash commands compared to js as well as cogs

gilded nest
#

i need help with hikari

#

i have a command that return's a string from a list if the name of the link given in the command is in the list

#

so if i was to do /links_list name:test it would return the link named test if it is in the list

#

the problem is that i want to show what are the links available when typing the command but i have no idea how and i cant find anything on the internet

gilded nest
#

i guess

#

im still new to hikari

merry cliff
#

I mainly use d.py but looking at the docs there seems to be a way to specify that

merry cliff
# gilded nest im still new to hikari

if you pair lightbulb with Hikari I think this is the proper way to do it actuallyhttps://hikari-lightbulb.readthedocs.io/en/latest/by-examples/080_autocomplete.html

#

there's an example there

#

async def autocomplete_callback(ctx: lightbulb.AutocompleteContext[str]) -> None:
    current_value: str = ctx.focused.value or ""
    values_to_recommend = [
        i for i in list_of_links if i.lower().startswith(current_value.lower())
    ]
    await ctx.respond(values_to_recommend)```

I think the autocomplete for you might look like this
gilded nest
#

alr thank you i will try this

narrow hazel
#

Oh yeah I forgot about autofill

#

That's something I wanna mess with

serene pumice
#

Hi I need help

narrow hazel
#

You're gonna need to be specific

serene pumice
#

@narrow hazel where ?

gleaming inlet
twin pike
#

im creating my first discord bot

fast osprey
#

Best of luck!

mild kiln
mild kiln
#

Someone knows how to host a bot for free 24/7

young dagger
mild kiln
#

A vps?

#

How is that working

mild kiln
young dagger
#

😅

#

Get a paid one

#

5$/month

mild kiln
#

Oh I Heard that theres a way to host it for free

grave sandal
mild kiln
grave sandal
#

If you have a laptop you can host it at home 24/7 for free presumably

dry kelp
#

@mild kiln Sadly, in this world, your best option is buy a VPS, to be able to host your application 24/7.

#

I recommend hetzner, you can get it for cheap a month.

gilded nest
#

i am using crescent so it took some adjusting but it finally works

fast osprey
unkempt canyonBOT
#
Discord Bot Hosting

Using free hosting options like repl.it for continuous 24/7 bot hosting is strongly discouraged.
Instead, opt for a virtual private server (VPS) or use your own spare hardware if you'd rather not pay for hosting.

See our Discord Bot Hosting Guide on our website that compares many hosting providers, both free and paid.

You may also use #965291480992321536 to discuss different discord bot hosting options.

stark ingot
#

Oracle has a free tier, I have never used it to know if it is good

tawny anchor
#

Hello, how can i put a stringselect menu in a modal?

burnt quiver
#

!d discord.ui.Label

unkempt canyonBOT
#

class discord.ui.Label(*, text, component, description=None, id=None)```
Represents a UI label within a modal.

This is a top-level layout component that can only be used on [`Modal`](https://discordpy.readthedocs.io/en/stable/interactions/api.html#discord.ui.Modal).

New in version 2.6.
burnt quiver
#

the component being the string select

narrow hazel
#

Ooo new label

#

I gotta try that

narrow hazel
#

why has discord not made an easier way to get a threads content 😭 this is the first time I had to use an async for loop

merry cliff
#

I mean it's not something that a lot of bots will need to do

#

especially with slash commands

fast osprey
#

What about a loop isn't easy? That's one line with a built in keyword

narrow hazel
#

ive never done async for variable in variable

#

that was new to me

fast osprey
#

How does that translate to that being hard or that discord/the library should do something differently

timber dragon
#

[m.content async for m in thread.history(...)] works too

#

But it's still just one endpoint with pagination

serene osprey
#

can anyone make me a custom version of sapphire so I can change its pfp to my server logo. Pls.

gritty inlet
#

I really don't think you understand the huge scale of Sapphire, no, nobody can just make a copy of it

fast osprey
#

also random people aren't just going to give you things for free, especially if you put 0 effort into at least trying yourself

#

making some random bot have a hee hee anime girl profile picture is not worth all that work

grave sandal
#

What's sapphire?

high kite
#

Pay me and i make you 💀

#

not free

fast osprey
#

Advertising features that are now native and better on their front page lol

fast osprey
high kite
fast osprey
#

👍

molten bramble
#

I have 27 commands and only synced 10

fast osprey
#

Code?

young dagger
#

How can I use links without breaking them?

[*BoldName*#1234](https://www.op.gg/summoners/euw/BoldName-1234)```
[*BoldName*#1234](https://www.op.gg/summoners/euw/BoldName-1234)
fast osprey
#

could you elaborate on what you mean by breaking?

young dagger
#

Well I want to display BoldName#1234 with the asterisks

#

As part of the username

timber dragon
young dagger
#

Without the \

fast osprey
#

Doesn't seem like masked links respect escape characters

timber dragon
#

yeah no idk

#

mostly like that for safety reasons

gritty inlet
#

When it comes to markdown in hyperlinks, one thing I noticed is you cannot do a double slash after "http/s:"

#

Reasonable lol

lime meadow
#

I'm running into an issue in Discord.py where I need to access the Cog's self inside @app_commands.choices() for a slash command. The problem is that self isn't available outside of functions, and it's also not accessible when the class is being created along with the decorators

fast osprey
#

choices aren't meant to be dynamic

#

They're for a discrete small set of options that doesn't change

lime meadow
#

I don't want the options to change during execution, but I want to automate something that can vary from one run to another

fast osprey
#

I'd suggest just making it a constant, then

stark ingot
#

idk how it is setup in discord.py but you could manually set the choices in the cogs init.

class MyCog(Cog):
  def __init__(self):
    self.my_command.options[2].choices = self.whatever
  @app.command()
  async def my_command():

You can probably do something like that but the syntax is most likely different.

lime meadow
#

AttributeError: 'Command' object has no attribute 'options'

lime meadow
fast osprey
#

What's a shame about using a constant for...something constant what

gritty inlet
#

Perhaps you want to use autocomplete. readthedocs

#

Or a select menu. Dunno what your use case is.

gritty inlet
#

Question: If I create a ui.LayoutView instance that is not going to have any components, what should the timeout be? Should I just leave as default?

fast osprey
#

whatever is probably fine

stark ingot
narrow hazel
#

Whats the difference between a for loop and an async for loop?

#

I had an idea to update my project but I wasn't sure which method to use for it

stark ingot
#

async for is for when you want to iterate over an iterator that supports async iteration.

narrow hazel
#

ok so it's not used commonly when you need to loop stuff

stark ingot
#

yeah, not super common

narrow hazel
#

Another W

finite salmon
finite salmon
# narrow hazel Another W

Imo anything with more than 3 layers of nesting is goofy ahh code, only god knows how many more layers of nesting are there 🙏🏿

narrow hazel
#

so how would you do it to loop the message content and check if it equals the integer thats stored?

finite salmon
#

By not using jsons

narrow hazel
#

the json has nothing to do with the nesting

finite salmon
#

The with block does add up a layer of nesting

narrow hazel
#
  if message.channel.id == 1380373033516007597:
            try:
                with open("JSON_storage/counting.json", "r", encoding="utf8") as f:
                    count = json.load(f)
                    for m in message.content:
                        if count["Count"] == int(m):
                            count["Count"] += 1
                            with open(
                                "JSON_storage/counting.json", "w", encoding="utf8"
                            ) as f:
                                json.dump(
                                    count,
                                    f,
                                    sort_keys=True,
                                    indent=4,
                                    ensure_ascii=False,
                                )``` I could remove the JSON storage and it would still nest
finite salmon
#

I genuinely cannot read this on my phone

narrow hazel
#
count = 1
if message.channel.id == 1380373033516007597:
  for m in message.content:
    if count == int(m):
      count+= 1```
#

exactly the same just without the JSOn

finite salmon
#

Idk what exactly you're doing, could be just a design issue

narrow hazel
#

its a counting game

#

Im looping the message content to check if it contains the number for the count. I wanna allow people to talk in the counting game to add interaction

#

more fun than doing
1, 2, 3

finite salmon
#

Okay

timber dragon
#

Have you ever heard of regex

#

I have made a system that allows exactly that

#

Or even just "".join(n.strip() for n in message.content.strip() if n.isdigit()) if you want it really simple

gritty inlet
#

Also wouldn't int(m) fail if m isn't a digit?

#

But yeah Regex is good for this case, I guess re.match

burnt quiver
#

if n.isdigit()

#

oh

#

wait im dumb

#

yeah ig so

gritty inlet
#

Yeah Soheab's version is safe, the one in Zizzle's message isn't

rough island
# narrow hazel Another W

You are adding unnecessary file I/o operations, you can open a JSON file as write and read mode with the same statement

#

Also, may I ask why are you saving all the messages inside a JSON?

#

You could either just retrieve the whole channel message history (which is kind of inefficient) or just store the last valid number of the sequence in a global variable or cache

gritty inlet
#

Anyway yeah I really see no reason to save all messages. Is this for the counting game? You could save just last one in that case

rough island
gritty inlet
#

But it's conditional, he may not update the json

rough island
#

You dont necessarily need to write on the JSON file tho

gritty inlet
#

Ah you mean he could do it all in one if block, right

#

Or Idk

rough island
#

Yeah pretty much

#

When opening a file with r+ permissions, it allows you to read and also write without having to open the file twice

gritty inlet
#

For the counting game there's no reason to save more than the last message

rough island
#

I don't know if I'm explaining myself right

gritty inlet
#

I think you are

rough island
#

Yeah, I think the easiest way is to just store the last valid number in cache (if the bot is 24/7)

gritty inlet
#

I never depend on cache because I restart often xD

#

Better not use cache when self hosting

#

Actually it's less related to the environment u use

#

Better have persistency with a DB

rough island
#

Yeah true, even if you rely on persistent cache

#

If it's just a simple counting game you can just use Supabase

gritty inlet
#

Just noticed he saves on each iteration

#

Yeah that's not good

rough island
#

Yeah

gritty inlet
#

Recomparing to the newly saved data each iteration can't be good

#

Just stack them up and save at the end

rough island
#

I would suggest code, but cba cause I'm on mobile lol

gritty inlet
#

But wait, he opens the file before the iteration. Doesn't that mean that Count will stay the same?

rough island
#

Keep it simple, create a static class, with a counting variable and two static methods, increase and decrease counter, then every time someone passes a valid count increase

gritty inlet
#

A class is not that necessary xD

#

It's simple operations unless you use a DB

#

Which he should ig

rough island
#

It's for keeping it somewhat organized, that way you don't have to hit the database everytime counter increases

#

You can just update the DB entry every 30 mins or so with the latest counter number

#

Yeah I think we are just going to confuse him

#

@narrow hazel
I assume you are still learning so I won't suggest using a DB

I don't think it's necessary to store it in a JSON, a plain TXT file will be much simpler to use

narrow hazel
#

Json is used to store the count after restart

rough island
#

Yeah but you don't need a JSON, you can use a TXT file

#

As a JSON adds an unnecessary level of complexity for such an easy operation such as increasing count

gritty inlet
#

I just don't like losing data, and I don't think scheduling DB task is such a good thing

rough island
#

For small apps not much, but it's always better to avoid unnecessary transactions, because when you scale bigger, it affects performance

narrow hazel
#

I'm not sure the difference between a txt and json

rough island
rough island
#

In a JSON it would be:
{
"Count": 1
}

#

Un that case you have to load the JSON, the access the "Count" key and retrieve the value

#

With a plain TXT file you can just store the count itself, so 1 per se

lime meadow
gritty inlet
#

But alright

gritty inlet
lime meadow
gritty inlet
lime meadow
gritty inlet
lime meadow
gritty inlet
#

Nope

#

Use autocomplete or a select menu for automation

rough island
gritty inlet
#

For now as my app is small ill save each time

rough island
#

Yeah that's fine, you can also split into microservices any time

gritty inlet
#

ignore what i deleted if u saw it

rough island
#

Didn't haha

gritty inlet
#

Why assign choices like that instead of using app_commands.choices

narrow hazel
#

That's what I use

gritty inlet
#

Or u want to assign params like that, even more odd

verbal island
#

I was thinking if there is a way to make a "emergency backup" for my discord bot. If my discord bot get offline, a backup bot like dino, carl or Gaius Cicereius bot will activate (those bot are not by me)

#

Quite a stupid question ngl

#

Or is there anyway to keep my server cool if my home server gets shutdown (like a blackout)

#

(Please ping me if you have an answer, i'm going to be eating dinner soon)

fast osprey
stark ingot
#

This is a perfectly valid use case for choices. It's weird that discord.py does not support this (or at least without a lot of monkey patching)

timber dragon
#

It can supports it when using a transformer

fast osprey
#

It's really not

#

Choices are designed specifically for things that don't change, as you have to eat into your syncing rate limit every time you want to change them

gritty inlet
#

It's a max of 25 anyway, what's the worst that could happen if you just manually wrote them

#

It's simple if you ask me

stark ingot
#

Changing choices will not meaningfully eat into the syncing rate limit assuming you are updating

fast osprey
#

"Run to run" is pretty ambiguous

#

It might help to better understand the actual use case

gritty inlet
#

Changing choices is bad UX

slate swan
#

yo i havent coded in a minute

#

how do i make mmy dc bot sennd a cmd in like a format

quick gust
#

what?

fast osprey
#

bots don't send commands

slate swan
#

i mean msgs * 😭

fast osprey
#

what format do you mean?

slate swan
#

im tryna find a picture of what i mean wait

stark ingot
slate swan
#

look there see how the bot has that square box thing around its msg 😭

finite salmon
#

embed?

slate swan
#

EMBED yes ok thank u

quick gust
#

no...

slate swan
#

thats whats its called alr tysm

#

fully forgot

slate swan
#

ty

finite salmon
#

create an instance of it and pass it to the embed kwarg in whatever method you're using to send the message

stark ingot
#

Might want to look into components if you are just getting back into it

slate swan
#

can u send

stark ingot
#

Depending on your goals they have more flexibility

slate swan
#

alr cheers

gritty inlet
gritty inlet
#

And you can use sympy like this to support basic math expressions (:

rough island
#

@gritty inlet I like your solution, this is what i meant earlier this morning btw

class CounterManager:
    # Stores the count for each channel by its ID, shared variable across all instances.
    channels_count_storage: dict[int, int] = {}

    def __init__(self, channel_id: int) -> None:
        self.channel_id: int = channel_id

    def increment(self, sent_number: int) -> bool:
        current_count: int = CounterManager.channels_count_storage.get(self.channel_id, 0)
        expected_next: int = current_count + 1

        # Special case: Starting the game (nothing → 0)
        if self.channel_id not in CounterManager.channels_count_storage and sent_number == 0:
            CounterManager.channels_count_storage[self.channel_id] = 0
            return True

        # Validate sequence: sent number must be the next expected number
        if sent_number < 0 or sent_number != expected_next:
            return False

        CounterManager.channels_count_storage[self.channel_id] = sent_number
        return True

    def reset_current_channel(self) -> None:
        CounterManager.channels_count_storage.pop(self.channel_id, None)  # pyright: ignore[reportUnusedCallResult]

    @classmethod
    def reset_all(cls) -> None:
        cls.channels_count_storage.clear()

#

Then you can add checks to increment, so the logic lives inside the class and not inside the discord functionality layer

urban coyote
#

hello, everyone

rough island
# rough island <@487601133817298954> I like your solution, this is what i meant earlier this mo...

You can also add helper methods (advantage of OOP :D):

class CounterManager:
    # Stores the count for each channel by its ID, shared variable across all instances.
    channels_count_storage: dict[int, int] = {}

    def __init__(self, channel_id: int) -> None:
        self.channel_id: int = channel_id

    def increment(self, sent_number: int) -> bool:
        current_count: int = CounterManager.channels_count_storage.get(self.channel_id, 0)
        expected_next: int = current_count + 1

        # Special case: Starting the game (nothing → 0)
        if self.channel_id not in CounterManager.channels_count_storage and sent_number == 0:
            CounterManager.channels_count_storage[self.channel_id] = 0
            return True

        # Validate sequence: sent number must be the next expected number
        if sent_number < 0 or sent_number != expected_next:
            return False

        CounterManager.channels_count_storage[self.channel_id] = sent_number
        return True
    
    # Helper
    def get_current(self) -> int | None:
        return CounterManager.channels_count_storage.get(self.channel_id, None)
    
    # Helper
    def get_next_expected(self) -> int | None:
        return (self.get_current() or 0) + 1

    def reset_current_channel(self) -> None:
        CounterManager.channels_count_storage.pop(self.channel_id, None)  # pyright: ignore[reportUnusedCallResult]

    @classmethod
    def reset_all(cls) -> None:
        cls.channels_count_storage.clear()
rough island
fast osprey
#

Pretty clean implementation

rough island
#

Thanks 🫶

swift siren
#

out of curiosity , with the new components can you send the view aswell as an file that’s not part of the video together?

#

I’m too lazy but I know there’s some common sense here

fast osprey
#

What do you mean by "not part"?

#

You can send attachments with a component v2 message afaik

stark ingot
#

You have to put the attachments in a media gallery for them to render tho

lime meadow
#

I'm translating this here, so I don't understand it properly anymore, but I've already resolved it, I'm not going to use a class, I'm going to create the commands globally within startup, I don't see many advantages in using a class

fast osprey
#

what actually causes the options to change though?

#

they're not just changing randomly

#

You really might want to consider autocomplete here

elfin quarry
#

how do i get

fast osprey
#

get...?

swift siren
#

speaking about audio files, same way you can send a audio file with a embed , can you do the same way the new component since they can’t be added in the media gallery

stark ingot
#

There is no way to get audio files to have a preview or player with components currently.

swift siren
#

thanks

winged sequoia
#

What version does v2 component support

fast osprey
#

Depends on what library you're using

grand surge
timber dragon
#

You can't

#

That's a separate message

#

At least, I tried it a week go and it didn't allow anything

gritty inlet
#

Would be great if a file component could render if it's an audio file

swift siren
#

^^

#

wondering how it would look tho

gritty inlet
#

(Photoshopped ofc)

swift siren
gritty inlet
#

🥀

swift siren
#

wait

#

that doesn’t look half as bad

#

nevermind it looks terrible

gritty inlet
#

I just copied a real mp3 preview, no idea if Discord would make it that color and that size if they made them render

swift siren
#

still good concept

gritty inlet
#

Paint 3D is goated

#

Shame that it's deprecated

vocal kayak
dry kelp
#

Using the new components as v2 containers are definitely a improvement into style.

#

and labling of your messages

narrow hazel
#

is a list an array but just named differently? I was looking for the differences but they look exactly the same?

#

am I just being dumb?

stark ingot
#

Lists and arrays are the same thing for the context of python.

finite salmon
#

There's a separate module in python called array

narrow hazel
#

oo

#

does python have anyway to selfmake errors? Like in JS they have console.log for print and console.error for errors. Does python have anything similar?

finite salmon
narrow hazel
#

oh yeah the logging module, I messed with that once but couldnt figure it out. I might check it out again, thanks

finite salmon
narrow hazel
#

sounds good thanks

rough island
gritty inlet
#

logging.exception ☠️

#

Just raise (:

#

Or use .critical

gritty inlet
narrow hazel
#

What is this error from?

gritty inlet
narrow hazel
#

not that im aware of

gritty inlet
narrow hazel
#

I just got home and logged on PC and saw it

gritty inlet
#

Sure you didn't pip upgrade anything?

#

anything

narrow hazel
#

nope I just got home and I logged on and imported an event I worked on at work

#

I just copied the code from the server onto VSC

#

I got it

#

I upgraded discord.py and it stopped showing the error

gritty inlet
narrow hazel
#

so weird

fast osprey
#

These things don't have timers built in that randomly break things

#

You did something

gritty inlet
#

Are you using any feature audio-related

narrow hazel
#

Nope

#

I thought about that but it was too complicated

rough island
# gritty inlet logging.exception ☠️

What? It's the recommended way by ruff and many other linters, also re raising the exception will halt the execution of the program or send it to higher layers which is bad because it adds complexity

#

And also logging.exception automatically adds the traceback to the message, critical doesn't and it's best suited for more extreme cases where an error would cause the whole operation or application to malfunction

earnest cloud
#

nvm im blind

heavy peak
#

yooo

#

any ways for the bot to see tags?

fast osprey
#

Like the server tags on a user or the post tags on a forum?

#

Yes to both at least

dry kelp
gritty inlet
#

Audio file*

#

Voice messages will be the same in this context

dry kelp
gritty inlet
dry kelp
#

see! it's fun and easy :D

gritty inlet
#

I eventually had to terminate that command because it required presence intent 💔

#

And no I'm not going to implement Spotify's Oauth just for one command

narrow hazel
#

Does V2 have the same char limit as embeds?

timber dragon
#

not really?

#

huge block but it lists all the component limits

narrow hazel
#

Sheesh

narrow hazel
#

Is there a way to get an array of my events like I can with my commands?

#

Or do i have to go through each event manually and add a print statment

burnt quiver
#

what do u mean

narrow hazel
#

Like with commands you use the .synced to get an array of commands im wondering if events have something similar to find out which ones are working

burnt quiver
#

don't think so

narrow hazel
#

Ah well

fast osprey
#

What do you mean by events "working"?

narrow hazel
#

if they're properly formatted for event listener

gritty inlet
#

What does that mean? Whether you listen to them with a @bot.event statement?

#

Or you wanna know when an event is received?

#

There's an event for raw socket receive, Idk more than that

#

But I don't see how this kind of debugging is useful

narrow hazel
#

Thats it thanks

fast osprey
#

Not all listeners are in cogs

young dagger
timber dragon
#

Why not just defer and try-except the method like normal?

#

Oh you're sending a modal

#

Why the wait for in the wait for callback though

gritty inlet
#

Why limit the function's execution time like that

#

Plus the last try-except is unecessary

young dagger
#

Since we can't use defer when sending modals

gritty inlet
#

Limiting execution time does not equal ensuring errors are returned properly?

young dagger
#

It does if you only have 3 seconds to respond

gritty inlet
#

I think it's bad practice to enforce limits like this

young dagger
gritty inlet
#

Because it's too dynamic

#

"Sometimes it'll work sometimes not"

young dagger
gritty inlet
#

So you can avoid all kinds of errors

#

By not opening modal from command interaction

young dagger
gritty inlet
#

I can tell lol

young dagger
#

I dont see what is funny

#

The idea is to use the button for checking only. If that fails the user should receive an error embed

burnt quiver
#

Shouldn't this except Exception as e: be except asyncio.TimeoutError as e to be more specific or at least try to catch that error before catching all errors with Exception

gritty inlet
burnt quiver
#

that is a good point

gritty inlet
#

The function not running in the set time could indicate a different kind of failure, but time-limiting instead of catching the actual error isn't good

gritty inlet
#

Regardless, the very last try-except seems to be useless

gritty inlet
#

discord.py
What makes bot.user.avatar or banner populate and not be None?

fast osprey
#

Works normally for me

gritty inlet
#

Modify Current Member is new so that probably isn't implemented in the library yet, Idk

fast osprey
#

Not yet in dpy

gritty inlet
#

Hmmm

#

My banner gets auto cleared in the dev portal

fast osprey
#

I don't use banners shrug . But for normal users you have to fetch, the banner doesn't get cached

gritty inlet
gritty inlet
#

values is untyped.
should i just add # type: ignore or just access it from interaction.data...

ignore the variable name, its misleading

timber dragon
#

It's not untyped technically

#

Label.component is just typed as ui.Item

gritty inlet
#

Ye right right but my type checker doesnt care

timber dragon
#

So just tell the type checker what .component is

#

The typechecker is correct otherwise

gritty inlet
timber dragon
#

assert isinstance(self.avatar.component, discord.ui.FileUpload) is what all of dpy's examples do

#

Can also use typing.cast

gritty inlet
#

alrighty thanks

timber dragon
#

Or component: FileUpload = ...component # type: ignore

gritty inlet
#

ill use assert

timber dragon
#

Nice

gritty inlet
#

How can i pass conditional args to guild.me.edit?
For example "only pass" avatar if x

#

Because I'm pretty sure that if I pass avatar as None it'll clear it

finite salmon
gritty inlet
#

hmm i can pass utils.MISSING

gritty inlet
finite salmon
gritty inlet
gritty inlet
quick gust
#

Show code, I doubt using utils.MISSING would be better in any sense than passing in a dictionary of the keyword args

gritty inlet
#

wait nvm passing None should be ok because its per guild

#

🥀

fast osprey
#

Don't pass in missing, that's an internal implementation detail

gritty inlet
#

I'll pass None, didn't think about the fact that it clears just for that server which is fine

gritty inlet
finite salmon
#

thats cool

heavy peak
fast osprey
#

which?

heavy peak
#

user tag

fast osprey
#

!d discord.User.primary_guild

unkempt canyonBOT
gritty inlet
#

Funny that it's duplicated in the API response, it's there both as "clan" and "primary_guild"

gritty inlet
#

Is the exact rate limit of this known? Or even approximate

fast osprey
#

all rate limits except for the global one are dynamic

#

If you're hitting it then you're probably trying to do an improper use case

gritty inlet
#

What would be good UX wise for this 🤔

gritty inlet
young dagger
young dagger
#

I can't create a task and send the embed or modal without waiting?

fast osprey
#

you don't need to await it before sending stuff, but you do need to eventually await it

#

or at least store a reference to it

#

also wait, asyncio.create_task isn't a coroutine miku_what

young dagger
#

I want to create a task that removes the role and sends the modal without waiting for the task to finish

fast osprey
#

then what is going to store a reference to that task when your function returns?

cunning minnow
#

AttributeError: 'NoneType' object has no attribute 'id'

fast osprey
#

because python has a garbage collector?

#

you could also just await it in that method but after you've done your other stuff

young dagger
#

I just need that response within 3 seconds facepalm

stark ingot
narrow hazel
#

just a quick question, i've never actually used button IDs. Am I able to use the custom ID from discord.builders for a V2 button inside the @discord.ui.button(label="", style=, custom_id="") to control it's interaction?

narrow hazel
#

you're right

gritty inlet
#

!d discord.ui.Button

unkempt canyonBOT
#

class discord.ui.Button(*, style=<ButtonStyle.secondary: 2>, label=None, disabled=False, custom_id=None, url=None, emoji=None, row=None, sku_id=None, id=None)```
Represents a UI button.

New in version 2.0.
gritty inlet
#

Damn didn't know it had id as well

#

I doubt the usefulness of this for a button though

#

I haven't used id so far regardless, dunno what the use case is

finite salmon
#

So your views can work even after your bot restarts

gritty inlet
finite salmon
#

Internally as in?

gritty inlet
#

Not by me

#

I've had persistent views and none of them used this

finite salmon
#

You can pass in custom_id

#

Oh wait

gritty inlet
#

((((:

finite salmon
#

You're talking about id

gritty inlet
#

Indeed

finite salmon
#

Yea no clue

gritty inlet
#

All components have it and Idk how it's useful

finite salmon
#

Maybe the api returns a unique id for it idk

gritty inlet
gritty inlet
finite salmon
#

Oh

gritty inlet
#

Also find_item and remove_item take it

#

I never needed to do that but maybe some people do

timber dragon
#

find yes, remove no

#

But that's pretty much it

#

custom_id is still required, but id isn’t
Both must be unique, and id assigned a unique integer by discord when not passed

young dagger
#
  1. Run task to remove role
  2. Send embed
  3. Wait for the task to complete
#

Would that be any improvement over simply sending the embed first and removing the role afterwards?

gritty inlet
#

I wouldn't use tasks here

young dagger
gritty inlet
#

wait nvm

young dagger
gritty inlet
# young dagger Don’t get me wrong, I just want to see if I can learn something from the way you...
assert interaction.guild
assert isinstance(interaction.user, discord.Member)
if existing_account:

    role = interaction.guild.get_role(UNVERIFIED_ROLE_ID)
    if role and role in interaction.user.roles:
        asyncio.create_task(interaction.user.remove_roles(role, reason="Riot account linked"))

    embed = discord.Embed(
        description="You already have a Riot ID linked to your Discord account.",
        color=discord.Color.red()
    )
    await interaction.response.send_message(embed=embed, ephemeral=True)

else:
    await interaction.response.send_modal(RiotModal())```
#

My implementation

#

You do not need to await tasks

#

Also don't do these assert lines if you don't use a type checker. Moreover, make sure the user is a guild member

#

You need the else. Otherwise if existing_account is True, it will run that block and then will attempt to send modal

#

I also recommend wrapping the role removal in try-except but being more specific with the exception, not Exception (or at least add that as the last except)

fast osprey
#

This really doesn't seem to need a task. If sending the response doesn't require the results then just do that thing after sending the response

#

You're talking a difference on the order of less than a second

gritty inlet
fast osprey
#

Or just asyncio.gather if you want to run two coros together

gritty inlet
#

But you should've got NotFound

#

Unless you catch that exception

quick gust
#

if the lines they sent are relavant to the partial error they sent

gritty inlet
#

Ah well