#Basic Pycord Help

1 messages Β· Page 64 of 1

errant trout
#

you would have to tag everyone for every thread lol

#

idk if the everyone tag even works for threads, but direct mentions and role mentions (under 500 members) do

pulsar ferry
#

yeah the way i was thinking of setting it up was to tell people if they want notifications to just click this

#

so that way we could get around having to use roles for mentioning

#

but it doesnt seem to alrert the same way, like it doesnt have the red badge

errant trout
#

oh i didn't even know that existed

#

but yeah it only sends a notification without mentioning the user or making them join the thread

pulsar ferry
#

which is kinda what i want

#

because otherwise then their left hand sidebar would just get flooded

echo wraith
#

@tribal hornet

#

.tag slashnoshow

sly karmaBOT
#

Application Commands Not Showing Up?

  • Refresh Discord by restarting or pressing Ctrl+R (or Command ⌘ + R)
  • Uninstall libraries that conflict with the discord namespace (e.g. discord.py).
  • Invite your bot with the application.commands scope.
  • Load cogs before bot.run() (e.g. not in on_ready).
  • Do not override on_connect.
  • Update to the newest version of py-cord (see ?tag install).
  • Turn off User Settings > Accessibility > Chat Input > Use legacy chat input.
  • Share your code and errors.
tribal hornet
#

Ohhh okay, thanks

#

That's my full embed code pretty much

echo wraith
#

you can use ``` for multiline codeblocks

#

You can define your embed outside of the command btw

#

since it dosen't change between comman inokations

tribal hornet
#

Idek what that means 🀣
Had this bot made for me, but now trying to add a single simple new /slash command that just gives the member updates on what's to come

#

@echo wraith Here u go πŸ‘†

echo wraith
#

thy

tribal hornet
#

And this is the thing I'm trying to get added pretty much

echo wraith
#

this code is not pycord code

tribal hornet
#

What then?

echo wraith
#
@bot.command(name="menu", description="Open the methods menu")
async def menu(interaction: discord.Interaction):
echo wraith
tribal hornet
#

I did pip show py-cord, says It's pycode

echo wraith
#

Also the code is messed up, it uses blocking code

#

I hope if you paid you didn't pay much for that...

tribal hornet
#

Paid $35

#

Is that bad?

echo wraith
#

yeah

tribal hornet
#

damn

echo wraith
#

you got kind of scammed there

tribal hornet
#

ah bruh

#

At least the bot works the way I wanted it to

echo wraith
#

yeah true

tribal hornet
#

So since the bot code is so messed up, I won't be able to add this new code / feature to it?

tribal hornet
#

How's it coming along @echo wraith

echo wraith
#

It should probably in theory, but I can't test it out and understand why it wouldn't work if the code is all over the place.

tribal hornet
#

Damn okayπŸ™
I think the issue I'm having is the /slash command not showing after i do CTRL+C and then doing Python main.py

echo wraith
tribal hornet
#

testing πŸ™

echo wraith
#

pip install typing_extensions too

#

what is your python version

tribal hornet
#

./

#

2.6.1 pycord

echo wraith
#

not pycord. python

#

python --version

tribal hornet
#

Python 3.11.9

echo wraith
#

yeah then you need to install typing_extensions

tribal hornet
#

Done πŸ™

#

or python .env?

echo wraith
tribal hornet
#

Some error

echo wraith
#

means your bot token is invalid

tribal hornet
#

Just double checked, it isn't

echo wraith
#

it must be

#

can you recreate one ?

tribal hornet
#

Yeah, let me do that

echo wraith
#

also make sure

#

.tag install

sly karmaBOT
#

1. Uninstall discord.py or any other forks of discord.py you might have with the namespace discord.
python -m pip uninstall discord.py discord -y

2a. Install py-cord
python -m pip install py-cord

2b. Update py-cord
python pip install -U py-cord

Installing other builds:
Note: You need to have git installed. Use ?tag git to find out how to install git.

Updating the module to master branch (unstable):
pip install -U git+https://github.com/Pycord-Development/pycord

echo wraith
#

just to be sure

tribal hornet
#

So first;

python -m pip uninstall discord.py discord -y

Then;
python -m pip install py-cord

And lastly;
python pip install -U py-cord

echo wraith
#

not the last one

#

just 1 and 2a

tribal hornet
#

Did that, I reset my token as well

#

And still shows same error

echo wraith
#

update the token in the .env file

#

and save that file too

#

you don't need the < >

#

also, please delete that picture

tribal hornet
#

It's online

echo wraith
#

neat

#

make sure to restart discord

tribal hornet
#

/menu is showing and works, but not /upcoming

echo wraith
#

for the commands to show

tribal hornet
#

Ohh wait

#

Yeah now it works

#

Thank you so so much @echo wraith

#

Really appriciate it

#

Oh wait

#

some of the /menu doesn't work

echo wraith
#

what specifically ?

#

on line 48, remove the await

#

that's mb

#

wait no

#

wait 1 sec

tribal hornet
#

πŸ™ alr alr

echo wraith
#

keep the await and all

tribal hornet
#

Works perfect now man, thank you so much πŸ™

echo wraith
#

happy to help !

pulsar ferry
#

Is it possible to have multiple default emojis for a thread, or disable them all together and have the bot add 2 every time a thread is created?

echo wraith
pulsar ferry
#

Yeah it seems like on the forum view it still only shows one at a time ☹️

pulsar ferry
# echo wraith the second option is possible afaik

trying to play with this... whats the proper way to react on a thread?

    thread = await channel.create_thread(name=thread_name, embed=embed, applied_tags=tags, auto_archive_duration=auto_archive_duration)
    # Add Verify and Invalid reactions to the thread
    await thread.add_reaction("βœ…")
echo wraith
#

I think you need to react to the original message

pulsar ferry
#

does the default emoji on the thread automatically sync to the first message?

#

ah nvm got it thanks! - looks to be so

    thread = await channel.create_thread(name=thread_name, embed=embed, applied_tags=tags, auto_archive_duration=auto_archive_duration)
    message = await thread.fetch_message(thread.id)  # Fetch the first message of the thread

    # Add Verify and Invalid reactions to the thread
    await message.add_reaction("βœ…")
pulsar ferry
# echo wraith I think you need to react to the original message

playing with this some more and seeing some pretty weird behavior, when i do this

    message = await thread.fetch_message(thread.id)  # Fetch the first message of the thread
    await message.add_reaction("❌")
    await message.add_reaction("βœ…")

On the discord desktop app it shows the last reaction (the green check) as the default, but on the mobile app it shows the first X as the default?

edgy nest
#

you might have a default emoji set, and the client is handling it wrong

torn barn
#

Also, instead of making an api call you can use get_partial_message

#

.rtfm Thread.get_partial

sly karmaBOT
maiden bloom
#

When I try to install py-cord 2.6.1, I get this error:

building 'aiohttp._websocket.mask' extension
  error: Microsoft Visual C++ 14.0 or greater is required.

I went and downloaded what I thought was needed from the MS build tools and restarted, but it's still showing this error. Is there something else I need to install?
Using Python 3.12.8
SOLVED: I installed the ARM version of Python and after switching to the regular Windows x64 release, the py-cord install worked fine and I didn't need anything additional from Visual Studio.

wise harness
#

Hi, this piece of code splits options into multiple select menus to adhere to the limit of 25 options per menu:

def create_select_menus(self, options):
                MAX_OPTIONS = 25
                option_chunks = [options[i:i + MAX_OPTIONS]
                                 for i in range(0, len(options), MAX_OPTIONS)]
                print(len(option_chunks))
                for i in option_chunks:
                    print(len(i))
                select_menus = []

                for idx, chunk in enumerate(option_chunks):
                    select_menus.append(discord.ui.Select(
                        placeholder=f"Menu {idx + 1}",
                        min_values=1,
                        max_values=1,
                        options=[discord.SelectOption(
                            label=option, value=option) for option in chunk]
                    ))

                return select_menus

From the output, there are a total of 5 select menus (which is the limit) for this interaction and total of 124 options:

5
25
25
25
25
24

yet i'm receiving DiscordServerError: 500 Internal Server Error (error code: 0): 500: Internal Server Error..?

sage tendon
#

typically if you get 500 its not your fault

wise harness
#

well, i did try this exact same command which had 50 or so options and that one doesn't throw this error, so i assume it had to do something with running too close to the limit or something

sage tendon
#

oh, i think you can only have 5 UI rows on one message, and you have 6

#

weird that that gives a 500 tho

wise harness
#

these are the number of options per select menu:

25
25
25
25
24
sage tendon
#

ah

#

yea then no clue

wise harness
#

i did some further testing by truncating the list of options, this works:

25
25
25
25
19

but this doesn't:

25
25
25
25
20
#

This is very likely some bug or it's a discord limit that i may not know of?

sage tendon
#

if anything its a discord bug

wise harness
#

is paginator.update() not too kind with ephemerality?

paginator = Paginator(
                pages=mypage, timeout=898, author_check=False)

            class MyModal(discord.ui.Modal):
                def __init__(self, *args, **kwargs) -> None:
                    super().__init__(*args, **kwargs)
                    self.add_item(discord.ui.InputText(
                        label="Enter Page number:"))

                async def callback(self, interaction: discord.Interaction):
                    page_num = int(self.children[0].value)
                    try:
                        await paginator.goto_page(page_num-1)
                    except IndexError:
                        await interaction.response.send_message("Invalid page number.", ephemeral=True)

            class MyView(discord.ui.View):
                @discord.ui.button(label="Switch page", row=1, style=discord.ButtonStyle.primary)
                async def button_callback(self, button, interaction):
                    await interaction.response.send_modal(MyModal(title="Travel to your desired page."))
            await paginator.update(custom_view=MyView())
            try:
                await paginator.respond(ctx.interaction, ephemeral=get_ephemeral_setting(ctx))

            except discord.Forbidden:
                return
            except discord.HTTPException:
                return

got this thing which throws AttributeError: 'NoneType' object has no attribute 'edit'

sage tendon
#

yea ephemeral messages are a bit weird so there's a change that function doesnt account for that

echo wraith
wise harness
# echo wraith I have a pr open but it is not for this issue afaik. I will open another, can yo...

The code I appended is pretty much that. Basically there's the default paginator instance and i am appending a button (for modal) in the second row using the paginator.update() method, and goto_page() to travel to the page number.

Also, something related:
I tried enclosing paginator.update() in a try-except block, but i just do nothing in the except block. This allows me to get the combination that I want even in ephemeral state (in the screenshot below), however when goto_page() is invoked in the callback, this error is thrown: discord.errors.NotFound: 404 Not Found (error code: 10008): Unknown Message

mossy star
#

is there a reason an InputText returns different values for self.children[0].value and self.children[0].to_component_dict()['value']

#

putting in an self.children[0].value = self.children[0].value seems to fix it but it's a little weird

sage tendon
#

like what two values do you get

mossy star
#

self.children[0].value returns the value after the modal is submitted but self.children[0].to_component_dict()['value'] returns the value it was initialized with

#

and if value wasn't set during creation, it doesn't exist in the dict

sage tendon
#

to_component_dict isnt even documented

#

unless its a built in i dont know

lapis dock
#

to_component_dict is used internally for sending the data to discord iirc

mossy star
#

it was just a command the IDE popped up with that seemed to fit what i wanted

#

i just assumed it was from a parent class

lapis dock
#

yeah, It probably should be private. It is working as intended, and it is not intended to be used externally from the lib

mossy star
#

it's literally one of the first things pycharm brings up lmao

#

but got it, not intended to be used

#

but back to the other part of it, why does self.children[0].value = self.children[0].value cause anything to happen at all?

wise harness
mossy star
lapis dock
#

It could be a weird quirk with how the setters work on value

sage tendon
#

because pycord uses properties so a function is called

#

yea

lapis dock
#

Yeah, I looked closer .value is never supposed to be assigned externally either

mossy star
#

so i suppose the intended method would be to delete and replace the InputText instead?

#

or i guess at that point there isn't much reason to reuse the modal

#

i just thought it was a handy feature that setting value to itself would keep its values between uses

#

when you click the little [source] button next to InputText in the docs, it does seem to have a setter. and to_component_dict() is there too

#

but yeah i can see where the weirdness comes from now that i've read through it all

#

but imo value shouldn't be being reused for two different things (_input_value and _underlying.value) depending on the context. it's a bit confusing

errant trout
#

it's probably a minor oversight, if you think the behaviour should be different then submit a PR.

halcyon totem
#

hi, i know nothing about coding and stuff, i need help on downloading pycord

sage tendon
#

pip install py-cord

#

and if you're brand new to programming I highly recommend doing some very basic stuff in python first and not to start with py-cord as your first thing ever

#

@halcyon totem

glad garnet
ebon swift
#

would someone be willing to help me with a small issue, I shortened my bot to the straight basics, it has a cog with a \ping command, I enter a discord_token_for_test_server the ping is available and works but when I just switch discord_token_for_real_server ping command isn't listed and doesn't work, does anyone have any idea why this would occur ? (if you think I should create a new space on the forum let me know)

ebon swift
#

I did not

#

let me try that

#

even after ctrl+r it doesn't appear..

errant trout
#

can you show the command code

ebon swift
#
import discord
from discord.ext import commands
from discord.ext.commands import Context
from loguru import logger

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

    @commands.slash_command(name="ping", description="Check if the bot is alive.")
    async def ping(self, ctx):
        await ctx.respond(f"Pong! thanks for checking on me {ctx.author.mention} !")


def setup(bot):
    bot.add_cog(Fun(bot))
errant trout
#

it's irrelevant to their issue

ebon swift
#

as for the import question I shortened the bot here and removed a ton of stuff so this is still here cause it as used before but not rn

errant trout
#

hmmm

#

are you sure you invited the bot? lol

ebon swift
#

stange isn't it

#

it is connected yes

#

should I re invite it ?

#

maybe ?

errant trout
#

does it show up in guild settings > integrations

#

see if it has any commands listed there

ebon swift
#

hooo

#

it does shows up

#

but one part is missing I think

errant trout
#

reinvite with the applications.commands scope

ebon swift
errant trout
#

though bot is meant to include that by default

ebon swift
#

see lara has slash command stuff

errant trout
#

reinvite it

ebon swift
#

ok

#

sorry if I sound dum which scope should I take appart from bot, I always forgot ?

#

is only bot enough ?

sage tendon
#

bot and application.commands

errant trout
#

it's included by default, but try add applications.commands

ebon swift
#

thank you

#

this didn't worked but that's definitely the issue

#

cause I have the slash command icon on my test server

#

maybe I'll jsut fully recreate it on dev portal

errant trout
#

eh... did you ever set guild_ids on any commands?

ebon swift
#

I didn't

errant trout
#

try changing the command name and restart the bot again

sage tendon
#

and restart discord if you havent yet

ebon swift
#

I did

#

I'll try to change command name

#

changing the command name indeed worked

#

could it be a conflict issue with an already existing bot ?

sage tendon
#

no

ebon swift
#

that what I thought, still the behavior is kinda strange

#

I'll dig into it and see if I can see where this comes from

errant trout
#

discord generally refers to commands by their name, so changing the name forces them to recognise it as a new command

sage tendon
#

discord's entire backend is strange

ebon swift
#

ok well thank you I'll keep that trick in mind if that ever happens again

errant trout
#

(though this is also somewhat the fault of our syncing method)

ebon swift
#

when I get my bot up and running as I want it I think I'll dig into pycord core

#

see how it's made

#

I'm sure I'll learn a lot of stuff

sage tendon
#

I'd say most of it is kind of just replicating Discord stuff like, well, guilds, channels, etc

#

i mean thats kind of the point of the library lol

ebon swift
#

yes I was more talking about the way to communicate with the discord api and such

sage tendon
#

http requests :]

errant trout
#

eh... maybe at the request level, but "replicating the library" is pretty broad

ebon swift
#

You know what I mean

errant trout
#

looking into any library to see how it works is worthwhile

ebon swift
#

thank u

sage tendon
#

yea

ebon swift
#

just need to solve some docker issues now , thanks again for the help see ya !

little cobalt
#

which permission should I use for bridge commands?

sage tendon
#

wdym?

little cobalt
#

discord.default_permissions or the basic one

sage tendon
#

ah, no idea

red mist
#

Default perms

#

As it's discord.permissions object no?

#

and that object just gives out bools

#

Sooooo theoretically if you know what the bools values are gonna be you can even input them manually \o/

little cobalt
#

its bridge.has_permissions

red mist
#

doesn't that just ... Wait hold on a min.

little cobalt
#

;3

red mist
little cobalt
#

xd

wise knoll
#

I have a list of users that the bot is intended to send DMs to and the basic function layout is like this

async def functionName(ctx):
    ctx.defer()
    for u in usersList:
        x = await get_or_fetch_user(u)
        x.send("hello")
        ctx.followup.send(f"sent message to {x.name}")
        asyncio.sleep(4)
    ctx.followup.send("sent messages to everyone")

My idea was if I wait 4 seconds between fetches + sends, I'd be able to make 30 requests to the discord api per minute to avoid being rate limited. The problem I'm facing now is that the bot stops are 45 DMs but there's no error messages in the console. How do I go about bettering this? Thank you for your time!

lofty parcel
#

Don't do that

wise knoll
#

Even with the users consent? They use a /join and that's how I get a list.
I'm not spamming them with ads or anything malicious. It's a secret santa bot so dms are somewhat necessary for secrecy reasons

fresh sierra
sage tendon
#

mee6 easily DMs 500 a minute

keen relic
#
Traceback (most recent call last):
  File "/home/container/.local/lib/python3.12/site-packages/discord/ui/modal.py", line 341, in dispatch
    await value.callback(interaction)
  File "/home/container/cogs/ticket.py", line 182, in callback
    await cog.create_ticket(interaction, self.name.value, self.problem.value)
  File "/home/container/cogs/ticket.py", line 293, in create_ticket
    await interaction.followup.send("You already have an open ticket!", ephemeral=True)
  File "/home/container/.local/lib/python3.12/site-packages/discord/webhook/async_.py", line 1794, in send
    data = await adapter.execute_webhook(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/container/.local/lib/python3.12/site-packages/discord/webhook/async_.py", line 222, in request
    raise NotFound(response, data)
discord.errors.NotFound: 404 Not Found (error code: 10015): Unknown Webhook```
fresh sierra
sage tendon
errant trout
sage tendon
#

This is my code, but it keeps typing for a few seconds or so after the respond

lofty parcel
#

Why are you using typing in a slash command

#

Defer already shows a thinking state

sage tendon
#

yea im also a bit unsure how to handle this rn because my command is kinda weird

#

lol

#

probably a dumb thought anyway
so ig typing only goes away with a .send?

#

What I really wanna do isn't really possible.. I kind of have just an LLM chatbot in my bot
currently i do it with a slash command and the result looks like this

#

which is kind of annoying to decouple in the code, the user-part and the bot-response part

lofty parcel
#

It should technically stop typing after the with block ends

sage tendon
#

i thought of doing it with pings, but idk, i kinda like doing it with a slash command

sage tendon
#

which i thought it only does with trigger_typing

#

either way im really unsure whether a slash command or an @bot hello would be best
tho my users are used to the slash command now

errant trout
#

(strictly speaking discord handles that)

sage tendon
#

weird

errant trout
#

how long on average does your typing block take

sage tendon
#

2-3 seconds at most

errant trout
#

hmmm this is kinda silly but you could attempt to manually cancel the task py async with typing() as t: ... await t.task.cancel()but this shouldn't be necessary because your code takes under 5s and the respond should have it naturally end anyway

#

you could change it to trigger_typing and not bother with the typing block; that's only necessary if the code takes more than 10s

sly ember
#

can somebody send me the docs for peristent views? trynna make a button work after bot restart

rugged lodgeBOT
#

Here's the persistent example.

sly ember
#

thanks!

cosmic swift
#

can somebody tell me how i can set optional options for commands cause i couldnt find anything about it

shell radish
#

required = False

cosmic swift
gray flame
#

Hey everyone. I'm a lil dumb. Basically I'm trying to make a command that creates a new post in a forum channel. So, the command is executed in a forum post, which gets that post's parent (the forum), and creates a thread. I know usually it needs a starting message. I tried using the ...create_thread(name="test", message="test")but its not valid, neither is type. Pls help.

async def test(ctx):

    print(ctx.channel.id)
    main_channel = ctx.channel.parent
    print (main_channel.id)

    await main_channel.create_thread(name="test", auto_archive_duration=60)```
deft kestrel
#

I made a bot to give a role to online members and sync on message in a channel. It worked for my test server but didn't work for main server which is bigger. There is no perms or intents issue.

#

This is the code.

#

Does the server size have a impact on this ?

#

The target role in main server is a moderator role which has only 17 members

sage tendon
# deft kestrel This is the code.

"didn't work" means what?
did you make sure to change the role IDs when changing servers first of all? hardcoded IDs are a nightmare

deft kestrel
#

I also put a print message for on message to check if it gets triggered

sage tendon
#

does your bot have all the permissions

#

and is its role above the to be assigned role

deft kestrel
#

In both servers

#

Also intents is set to all and all intents are enabled

#

I believe this is related to server size

#

The main server has 215k+ members and test server had just 7 (my accounts and some bots)

sage tendon
#

do you get any error or anything at all?

deft kestrel
#

Nope

sage tendon
#

and no roles are ever assigned or removed

deft kestrel
#

Nope. All logs are clean

sage tendon
#

are you triple sure you got all the IDs right

deft kestrel
#

100%

#

I changed all one by one

#

All 4

#

Even added a print function to print that it actually recd the message event and it prints that it did

sage tendon
#

and do the prints inside the ifs print too?

deft kestrel
#

I will make it print all members in mod role with their status

sage tendon
#

no, you have prints for "assigned role to name" and "removed role from name"
do those work

deft kestrel
#

Yes those work

#

Those were printed for test server

#

It correctly assigned and removed everytime

sage tendon
#

can you print your assigned_role

deft kestrel
#

Okay. I will add that and try

sage tendon
#

but you are testing it with other people and not yourself (if you are the owner) right?

deft kestrel
#

It's for moderator role. So it would assign online moderator role to PPL in moderator role who are online in main server

#

That's what I want to achieve

sage tendon
#

yea i know, i just wanna make sure you test it with a member that isnt you if you own the server

#

bots cant do a lot of stuff on server owners

deft kestrel
#

I am not owner in any. Although bot has second highest in main but it's above both roles and even actual online mods were not assigned

#

Also no error in console confirms no perms issue

sage tendon
#

unless you have a global error handler that eats the errors silently somehow lol

deft kestrel
#

I'll get more logging

#

Like log everyone in mod role and print the status. To see what's actually the problem

gray flame
sage tendon
#

show the error

#

code looks fine as long as it's executed in a forum thread (or well, it works in a normal channel too I think)

deft kestrel
#

oh wow. I changed nothing. went home and just ran it again. it works now πŸ˜‚

sage tendon
#

lol

gray flame
# sage tendon show the error
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\commands\core.py", line 138, in wrapped
    ret = await coro(arg)
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\commands\core.py", line 1082, in _invoke
    await self.callback(ctx, **kwargs)
  File "c:\Users\Usuario\Desktop\Bot Dev\vote2.py", line 16, in test
    await main_channel.create_thread(name="test", auto_archive_duration=60)
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\channel.py", line 1319, in create_thread
    data = await state.http.start_forum_thread(
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\http.py", line 374, in request    
    raise HTTPException(response, data)
discord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In message: This field is required

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\bot.py", line 1137, in invoke_application_command
    await ctx.command.invoke(ctx)
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\commands\core.py", line 435, in invoke
    await injected(ctx)
  File "C:\Users\Usuario\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\commands\core.py", line 146, in wrapped
    raise ApplicationCommandInvokeError(exc) from exc
discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In message: This field is required```
lapis dock
proven valley
#

has anyone used testcord with pycord?

echo wraith
proven valley
#

unfortunate

sage tendon
#

imo unit testing is just too much for a discord bot

#

unless its like dyno

proven valley
#

yeah but I would like to have it to make sure things are going into the data base correctly and I don't make an error when I change something, retesting everything by hand is a pain in the butt.

sage tendon
#

then verify the data in your db connector

meager mantle
#

Kind, does anyone know of any known issues related to the fact that discord.ui.Select().add_option(). It just stops the thread execution and the bot just doesn't respond to the command.

Now it is just in async def ApplicationCommand, maybe this is the reason, because in another command it works calmly from class foo(discord.ui.View).

meager mantle
meager mantle
sage tendon
#

because snowflake ID ints are too long for the type of integer discord uses

#

thats why they have to be passed as strings

#

@meager mantle

lethal loom
#

Hi, How can i translate commands?

sage tendon
#

like what

#

localisation?

lethal loom
#

when i do /rank in a english server and /rang in a german server

sage tendon
#

same for command options

lethal loom
#

ah nice thx

echo wraith
#

If I want for some reason to make requests to the api in a raw manner, as long as I do it trough httpclient they are rate limited correctly ?

silk spire
#

Through pycord's HTTPClient.request method? Yes

steady crater
#

anybody have experience using environment variable to enable/disable commands? something like this:

# .env
ENABLED_COMMANDS=slash_command_1,slash_command_2

# config.py
import os
from typing import List

def get_enabled_commands() -> List[str]:
    commands_str = os.getenv('ENABLED_COMMANDS', '')
    return [cmd for cmd in commands_str.split(',')]

# bot.py
from config import get_enabled_commands

def setup(bot):
    enabled_commands = get_enabled_commands()
    bot.add_cog(AdminCog(bot, enabled_commands))

# main.py
from dotenv import load_dotenv

load_dotenv()
sage tendon
#

if cmd.strip() what

#

and no clue if thats easily doable with slash commands

steady crater
sage tendon
#

also you dont need to import List from typing since like, 3.10 or something

steady crater
#

i didn't write this code, 4o did

#

i'm just asking about being able to use environment variables to toggle enabled commands

sage tendon
#

i mean sure you can

steady crater
#

are there code examples?

sage tendon
#

no, this isnt really something common to do lol

steady crater
#

is there a better way to easily enable/disable commands in production without rebuilding the image?

sage tendon
#

wdym rebuild the image

#

you'll most likely need this and this, and you probably need to sync commands after doing that as well

steady crater
#

i have it hosted in AWS ECS

sage tendon
steady crater
#

yeah that would be easier but i'd rather have the command not show up at all if possible

lethal loom
#

HI;

    async def update_rate(self, ctx: discord.ApplicationContext):
        xp_rate = await level_db.fetch_rate(ctx.guild.id)
        
        timestamp = ctx.message.created_at
        print(timestamp)```

Ignoring exception in on_application_command_error
Traceback (most recent call last):
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 138, in wrapped
ret = await coro(arg)
^^^^^^^^^^^^^^^
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 1078, in _invoke
await self.callback(self.cog, ctx, **kwargs)
File "g:\Development\Python\Xenority\extensions\level\main.py", line 455, in update_rate
timestamp = ctx.message.created_at
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'created_at'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\client.py", line 412, in _run_event
await coro(*args, **kwargs)
File "g:\Development\Python\Xenority\extensions\error_handler\main.py", line 121, in on_application_command_error
raise error
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\bot.py", line 1137, in invoke_application_command
await ctx.command.invoke(ctx)
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 435, in invoke
await injected(ctx)
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 138, in wrapped
ret = await coro(arg)
^^^^^^^^^^^^^^^
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 1486, in _invoke
await command.invoke(ctx)
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 435, in invoke
await injected(ctx)
File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\commands\core.py", line 146, in wrapped
raise ApplicationCommandInvokeError(exc) from exc
discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: AttributeError: 'NoneType' object has no attribute 'created_at'

edgy nest
#

applocation command has no associated message

sage tendon
#

it does, but only in some cases

edgy nest
#

you can find when an interaction was sent with discord.Object(ctx.interaction.id).created_at

edgy nest
sage tendon
#

what about a defer?

edgy nest
#

that is not a component interaction

sage tendon
#

yea but isnt the defer counted as message?

little cobalt
#

does it?

sage tendon
#

im 99% sure its included in channel.history (i know cuz of a command i have)

edgy nest
#

that has nothing to do with the context's message attr

sage tendon
#

hm ok weird

lethal loom
#

Why its not ehp?

    # Leaderboard Befehl mit Paginator
    @level_cmd.command(name="leaderboard", description="Zeige die Rangliste an.")
    async def leaderboard(self, ctx):
        await ctx.defer()
        guild_id = ctx.guild.id
        all_levels = await level_db.fetch_all_levels(guild_id)
        all_levels = [level for level in all_levels]
        
        if len(all_levels) == 0:
            await ctx.respond("Es gibt noch keine Benutzer in der Datenbank.", ephemeral=True)
            return

        # Sortiere nach Level und XP
        all_levels.sort(key=lambda x: (x["level"], x["xp"]), reverse=True)

        # Bereite Seiten vor
        pages = []
        for i in range(0, len(all_levels), 10):  # 10 Benutzer pro Seite
            
            description = "### Rangliste der Top-Benutzer \n\n"
            for j, level in enumerate(all_levels[i:i + 10], start=i + 1):
                user = ctx.guild.get_member(level["user_id"])
                if user:
                    ##description += f"`{j}.` {user.mention} Level **{level['level']}** XP **{level['xp']}**\n"
                    description += f"{j}. {user.mention} - Level: {level['level']} | XP: {level['xp']}\n"
            
            embed = await self.create_embed(
                ctx,
                title="XP Rate",
                description=description
            )   
            pages.append(Page(embeds=[embed]))

        # Paginator starten
        paginator = Paginator(pages=pages)
        await paginator.respond(ctx.interaction, ephemeral=True)```
sage tendon
#

because you deferred without ephemeral=True

lethal loom
lofty parcel
#

The response won't be ephemeral if your defer wasn't

lethal loom
#

ohhh

rugged lodgeBOT
#

Here's the persistent example.

lapis dock
#

@hardy abyss you need to use persistent views. See the example above

lethal loom
#

select = Select(placeholder="test", options=role_options)

#

is it possible to say i can select all values in teh dropdown

sage tendon
#

please read the docs

runic sparrow
#

hi

#

i have a question

#

how make this select menu?

#

i got it

maiden bloom
#

When a guild isn't chunked and I try to create a role in it, the attempt fails with a forbidden error even though the bot has the required permissions. Is there a way to create the role even if the guild isn't chunked?

sage tendon
#

you shouldn't get forbidden as long as you have proper permissions

maiden bloom
#

The code is pretty much just what's below, but users sometimes have to wait an hour or so for the guild to be chunked before the role is created. They send screenshots that the bot has the manage roles permission enabled and after not changing any permissions it works after waiting for the guild to be chunked.

try:
    await guild.create_role()
except discord.errors.Forbidden:
    # Send the user a message it didn't work.
sage tendon
#

and guild there is ctx.guild?

maiden bloom
sage tendon
#

what if you fetch the guild?

maiden bloom
#

Yeah good point, I just thought of that lol. I'll have to try it and see if it helps

lethal loom
#
Traceback (most recent call last):
  File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\ui\view.py", line 426, in _scheduled_task
    await item.callback(interaction)
  File "g:\Development\Python\Xenority\extensions\level\main.py", line 650, in add_channel_select
    embed = await Levelsys.LevelSetupEmbed(Levelsys, interaction)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "g:\Development\Python\Xenority\extensions\level\main.py", line 607, in LevelSetupEmbed
    embed = await self.create_embed(
                  ^^^^^^^^^^^^^^^^^^
TypeError: Levelsys.create_embed() missing 1 required positional argument: 'ctx'
#

can where help me im confuse how can i fix this

lapis dock
#

You did not include the create embed function. My guess is you forgot to include self as the first parameter of that function

stoic hazel
#

is on_ready() but in a cog a thing? or would on_ready() just work in a cog

#

i have a self.something variable i'm setting in __init__ of the cog but it's not being filled properly because it runs too early (i think)

errant trout
#

__init__ is run the moment you load_extension/load the cog; assuming you load cogs before the bot starts, this is always before on_ready

stoic hazel
#

tbh i just moved the line from the command code to __init__ and tacked on a self. so it wouldn't repeat the line across all commands
idk if this is the right way to do this but it workedβ„’ before and doesn't now

errant trout
#

so this'll result in logchannel being None

stoic hazel
#

yeah that's exactly what i'm getting

errant trout
#

because get_channel doesn't work before the bot's started

stoic hazel
#

(if it isn't the right way please enlighten me)

errant trout
#

if you want, you can have an individual on_ready listener in your cog using the @commands.Cog.listener() decorator

#

(but you should make sure to define in both init and on_ready since reloading the cog won't run on_ready again)

#

though, what i personally like to do is set @property for objects i frequently access across the cog ```py
@property
def guild(self):
return self.bot.get_guild(SOME_ID)

stoic hazel
#

(reloading the cog?)

errant trout
#

do you ever reload_extension

stoic hazel
#

no

#

what's that for

errant trout
#

it reloads a cog and the code for the listeners and commands inside it

#

so you don't have to restart for purely code changes, though sometimes it's finnicky with slash commands and if you want to update command metadata like names/options you still need to restart

sage tendon
#

if so what's the point of making a property instead of just self.get_guild()

glad garnet
errant trout
#

guild was probably a poor example because most of the time you're using ctx.guild anyway

#

but if there's a common cached resource i'm accessing in a cog then setting properties is nice

sage tendon
#

yea but I'm wondering what the proper benefit is because get_thing() and thing() isn't really that much different
or what do you use it for

errant trout
#

90% of coding decisions is just preference

sage tendon
#

properties are 100% builtin right?

errant trout
#

yeah

echo wraith
#

Yes

sage tendon
#

Is this good for automatically creating commans or is there a better approach?

#

i tried just defining it with the decorator inside of the create_social_command function but it didn't do the trick

sage tendon
#

and im struggling to pass the cog correctly, no matter how i try it, ctx.command.cog is None

#

setting command.cog = self causes some weird error, and setting command._cog directly causes an error upon command invocation

#

overall i just cant find the intended way to do this apart from decorators which i (seemingly) cant use lolw

#

Okay i managed this now.. is this an IDE error? type(command_function) is SlashCommand, so its correct

#

ok apparently setting the cog can be achieved like this

little cobalt
#

I kinda do the same with name and description adding, I dont have to add it to every command anymore

sage tendon
#

also with decorators in a function?

little cobalt
#

I use bot._pending_application_commands for it

sage tendon
#

what

#

this is my entire code (for one part of the commands)

fresh sierra
#

what is ur issue ?

#

does everything work ?

sage tendon
#

yea, but im wondering if this is the way to do it

#

because it seems a bit weird

fresh sierra
#

create custom slash commands is the weird thing for me

errant trout
#

your method is correct

fresh sierra
#

like it doesnt make a lot of sens since it will be block pretty easily if its a public bot and if its not create prefix seems more logical since you will not have any limite and user will not have to restart their discord

#

but else if it works it works

sage tendon
#

The only reason I'm doing this because before, i had about 30 commands that were all the exact same save for a few strings

fresh sierra
#

o i see so its not to create it after the bot is running

#

mb then

sage tendon
#

im not creating them during runtime

fresh sierra
#

why not making a command like /action with an autocomplete after ?

sage tendon
#

yea i thought about that too but that would've required me to have the same mapping of a bunch of strings i already have like this, so i thought might as well do it the fancy way and keep the commands seperate

fresh sierra
#

ok i see

#

any idea how should i format my tree ?

#

because rn i feel like its messy

errant trout
#

eh, seems fine? unless you want to subdivide into even more folders

sage tendon
#

i'd say merge some of them

#

seems like a huge number

fresh sierra
#

each folder inside the slash has like

#

some of my issue are for exemple i have a folder name event where i put some config but not all of them are event

#

like there is some cog to check if there is some blocking code, some other to just wrap all the istener to check if there is an error and get it etc

sour hedge
#

I forgot to respond earlier

#

but yes, that's how you should do it

sage tendon
#

that's not really how cogs are intended lol

fresh sierra
#

and i have a file for each command because i find it more clear

sage tendon
#

yea, IMO you divided everything much, much too far

#

at the very least you can put all subcommands into a single cog

#

also makes them easier to manage and you dont need multicog

fresh sierra
sage tendon
#

unless its >300 lines its fine imo

fresh sierra
#

i have a custom thing that make everything os i dont really have to do anything with multicog or bridge

fresh sierra
#

also some of my other issue is my yaml file that is 10k line...

sage tendon
#

wtf

#

for what

fresh sierra
#

10k for french, then 10k line for english etc

#

this is like all the answer of the bot

#

7k sorry

#

like this is hell to maintain

#

maybe i can do for each folder of subcommand something like that :
one folder for all translation for this group
one folder for all view
one file for each utils functions
and other like normal thing

#

but even this seems big asf

little cobalt
fresh sierra
#

my bot has a lot of command

echo wraith
#

Localization

frail basin
#

If an ephemeral view has it's timeout set to None, await view.wait() is called, and the user presses the Dismiss message button, what happens to the function that called .wait()? Will it hang forever?

Example code:

@discord.slash_command(name="test")
   async def test(self, ctx: CustomApplicationContext):
       view= TrueFalseSelectView("Yes", "No")
       await ctx.respond("Test", view=view, ephemeral= True)
       await view.wait()
       print(view.final)
class TrueFalseSelectView(discord.ui.View):
    def __init__(self, true_button_label: str, false_button_label: str):
        super().__init__(timeout=None)        
        self.final: bool | None = None

        false_button = discord.ui.Button(style=discord.ButtonStyle.red, label=false_button_label)
        false_button.callback = self.false_callback
        self.add_item(false_button)
        
        true_button = discord.ui.Button(style=discord.ButtonStyle.green, label=true_button_label)
        true_button.callback = self.true_callback
        self.add_item(true_button)

    async def false_callback(self, interaction: discord.Interaction):
        await interaction.response.defer(ephemeral=True)
        await interaction.delete_original_response()
        self.final = False
        self.stop()

    async def true_callback(self, interaction: discord.Interaction):
        await interaction.response.defer(ephemeral=True)
        await interaction.delete_original_response()
        self.final = True
        self.stop()
#

Based on my testing, it never returns, however I'd like some additional confirmation on this.

#

And if this is indeed the case, is there some sort of workaround to check whether the message has been Dismissed?

little cobalt
frail basin
#

It would be a universal "Confirm" / "Cancel" view for warnings.

#

Take the following as an example use case

sage tendon
#

btw you can use ctx.respond as a shortcut

lapis dock
#

You can check if the message still exists. By getting the interactions original response. Ideally you would have a timeout instead though. Ephemeral messages are supposed to be temporary so you should not treat them as persistent. I don't think you can check if the message exists after 15 minutes as this is when the interaction token expires (which is used to get the message)

frail basin
#

Timeout it is then. Purely out of curiousity, would my code in its current state leak little bits of memory with each Dismissed view?

lapis dock
#

Not 100% sure but I think so. Unless the message gets marked as unavailable some other way later on

frail basin
sage tendon
#

how lol

frail basin
#

Β―_(ツ)_/Β―

sage tendon
#

man vsc really is incapable of even the most basic IDE task

sage tendon
#

same

#

ephemereal usually

lapis dock
#

Ephermial I add an I for some reason.

frail basin
sage tendon
#

not even sure why it is

#

like its a function why is it a property lol

#

oh nvm makes sense

fresh sierra
#

is there an error for a subcommand that doesnt exist being invoke ?

#

like command not found but subcommand not found

pulsar ferry
#

I am getting this when issuing a command but then it seems like the command still runs its just taking a bit? is there a default time pycord uses when issuing a command that can be modified?

little cobalt
pulsar ferry
#

yes the command does work in some scenarios, but when there is more processing in backend that has to happen it seems to timeout

little cobalt
pulsar ferry
#

ah sorry thought you were asking if using either. yes using ctx.respond @little cobalt

lapis dock
#

Discord gives you 3 seconds from the moment the user runs the command until they expect to recive the response.
For longer running commands you can use ctx.defer(). This tells discord that you need extra time and then allows you to have 15 minutes to respond. You should defer at or near the top of your command callback as the defer needs to be received by discord in 3 seconds as well.

lapis dock
pulsar ferry
# lapis dock Discord gives you 3 seconds from the moment the user runs the command until they...

Exactly what i needed, thank you... follow up though as to the question now in trying to establish why the command is taking so long

The command I have looks into previous threads to see if a specific link was already included in the embeds posted in each thread. I only want it to look at threads that have not been archived, and the default archive time I have the threads is 24 hours. IT seems like even with this code though it may be searching through every thread, including the archived ones... is there something im missing here?

async def find_existing_thread(channel, link):
    for thread in sorted(channel.threads, key=lambda t: t.id, reverse=True):  # Sort by ID descending
        if not thread.archived:
            first_message = await thread.fetch_message(thread.id)
            embed = first_message.embeds[0] if first_message.embeds else None
            if embed and any(f.name.lower() == "claim" and f.value.lower() == f"[click here]({link})".lower() for f in embed.fields):
                logger.info("Found existing thread with matching claim link.")
                return thread
    return None

sage tendon
pulsar ferry
sage tendon
#

well if the message isnt in cache you need to fetch it

pulsar ferry
#

arent i then hitting the api again though?

sage tendon
#

yea but you should default to using cache

pulsar ferry
#

so something like this?

first_message = await get_or_fetch(bot, "message", thread.id)
sage tendon
#

so just do first_message = thread.starting_message or thread.fetch_...

pulsar ferry
#

Neither of above worked, this seemed to do it though

first_message = thread.starting_message or await thread.fetch_message(thread.id)

That being said though, still taking very long to run and i think its still going through the archived messages

sage tendon
#

oh yea you need to await

sage tendon
lapis dock
sage tendon
#

i mean their code should work no?

fresh sierra
pulsar ferry
#

because this didnt print anything...

        elif thread.archived:
            print(thread.id)
lapis dock
#

oop wrong reply

sage tendon
#

print the thread names and check if it prints any unarchived ones

pulsar ferry
#

Nothing printed

#

Is there a way in the discord UI to determine if a thread is archived? …perhaps nothing is actually getting auto archived?

#

Because I’m still seeing everything even that’s older than like 2 days and I have it set to 24 hrs

lapis dock
#

In forum channels: It shows under the "Older Posts" header

sage tendon
lapis dock
#

Also I dont know how reliable the auto archive is.

sage tendon
#

maybe it doesnt even apply to forum posts

lapis dock
#

It does, we have it here

pulsar ferry
# lapis dock

yeah i dont have that. - should "close post" be already selected on archived posts?

#

ah shit - baby just woke up gotta run, will be back in a bit to keep tinkering thanks so far

lapis dock
#

πŸ‘ Yeah, "archived" is the API name "closed" is the public name

#

If it is archived it will say "open post"

pulsar ferry
lapis dock
sage tendon
#

threads and posts should have been 2 seperate classes

#

not sure if discord themselves differentiate it

lapis dock
#

Discord treats them the same.

sage tendon
#

archived for forum posts might mean forcibly closed

lapis dock
sage tendon
#

it is closed though

lapis dock
#

It is closed but I dont think anyone closed it I think it was automatic

#

Unless someone closed threads not using the /close command

sage tendon
#

i do that rarely

shell radish
#

oh i remember manually closing that rhread because the bot was down

lapis dock
#

... well that was a big coincident.
Do you do that a lot? There are a bunch of other threads that follow the same pattern

shell radish
#

not recently

edgy nest
#

archive is set to 3 days

lapis dock
#

yeah, but why are posts that are more than 3 days old not auto archived. I just closed a bunch but they were inactive for 20+ days

edgy nest
#

im not sure why some threads are still open

#

discord stroke ig

lapis dock
#

It happens a lot

sage tendon
#

remember

#

its a feature added past discord's prime

#

so it HAS to have some bugs in its core functionality

#

its the law

lapis dock
pulsar ferry
#

Hey checking back in here - seems like this is an actual issue with discord itself not py-cord?

#

Could it have anything to do with the β€œauto_archive_threshold” arg?

#

and if not, does the api call to manually archive the thread still work? Maybe we just need a background job every hour to check total age of the thread and archive accordingly

lapis dock
#

Yeah, it seems that there is something strange with how discord closes threads. A manual API call to archive would work.

pulsar ferry
#

Alright I’ll try writing something up when back at pc later tn

#

Perhaps it’s something that should be built into pycord though? Since all the args for setting thresholds prob aren’t working for everyone using them

echo wraith
#

Is there a possibility to have an attachment as a parameter to an ext.command just like slash or should I iterate over ctx.message.attachments ?

fresh sierra
echo wraith
#

that didn't work :/ I think I might have messed up smth

#

oh well

#

in the end I am just iterating over the attachments so I can have my own logic

fresh sierra
#

maybe it does not work with more than 1 arg

sage tendon
#
  1. why prefix
echo wraith
# sage tendon 1. why prefix

Idk. But users want it so I don't really care, I give both options with, most of the time, more options for slash, and they do whatever they want

pulsar ferry
#

Alright not entirely sure what i did, was just playing with archiving manually and it seems like ive now entirely hidden a few channels πŸ˜…

#

I can still get to them by doing like #rules and clicking it but its hidden from the sidebar... how do i get it back?

sage tendon
#

did you enable onboarding

#

or just disable "show all channels"

pulsar ferry
#

i do have onboarding enabled but where is that show all channels setting?

#

because now its not even showing in the 'browse all channels'

sage tendon
lapis dock
#

Did you somehow enable server guide?

pulsar ferry
# sage tendon

ah okay that did it - but how do i force those channels to always show like how you guys have the #rules in info

#

my rules channel has this in the settings...

#

and theres no 'dont hide' option

sage tendon
#

enable them as default in onboarding

sage tendon
lapis dock
#

Is your rules channel a forum channel? nvm

pulsar ferry
pulsar ferry
sage tendon
#

yea you enabled it as rules channels in server guide

#

it wont show as channel then

pulsar ferry
#

the same issue is happening for FAQ though

sage tendon
#

also part of server guide

#

disable server guide

lapis dock
#

(or remove those channels)

sage tendon
#

not sure you can remove the rules

pulsar ferry
#

ahhh you guys have server guide and SEPERATE channel for rules

#

thats really confusing... discord has like 3 seperate places for 'rules' and none of them are linked

lapis dock
sage tendon
#

you need to make a speerate channel

pulsar ferry
#

onboarding, rules channel, and then a seperate server guide rules

sage tendon
pulsar ferry
#

its not possible to make the server guide not hide the channels?

sage tendon
#

no

#

unless you duplicate them

#

well thats only true for the rules channel

#

i think

pulsar ferry
#

ah alright think i got it set up how i want... how do you remove the events and other crap up there?

sage tendon
#

cant

#

and thats not really pycord related now lol

pulsar ferry
#

yep fair - i saw it wasnt in your guys thing at the top so figured id ask

#

1 last pycord question... is this the most efficient way to get a channel by its name?

async def find_channel_by_name(channel_name: str):
    guild = await get_or_fetch(bot, "guild", GUILD_ID)
    # Look for a text channel with the provided name
    channel = discord.utils.get(guild.channels, name=channel_name)
    return bot.get_channel(channel.id) if channel else None
sage tendon
#

the first question is why do you need to do that

pulsar ferry
#

trying to go through all my code now and optimize where i dont need to be fetching every time

#

its a helper function.. i have multiple commands that can be invoked that then should write to specific channels... i could hardcode the channel IDs i guess but wanted it to be somewhat dynamic in case i change channels later

sage tendon
#

im pretty sure you can just remove the bot.get_channel line since discord.utils.get should already return the channel object

sage tendon
#

same for the if channel else None

pulsar ferry
#
async def find_channel_by_name(channel_name: str):
    guild = await get_or_fetch(bot, "guild", GUILD_ID)
    # Look for a text channel with the provided name
    return discord.utils.get(guild.channels, name=channel_name)

works thanks!

sage tendon
#

but keep in mind getting channels by name is really not ideal

pulsar ferry
#

Yeah i know - this is a custom bot just for my 1 server though so cutting a few corners

errant trout
#

(a small bot like yours will always have the guild cached, so you rarely need to fetch anything really)

pulsar ferry
errant trout
pulsar ferry
#

Yah I guess my style is more β€œhave and not need” than β€œneed and not have”

#

There’s no harm in having as it’ll use cache and if it doesn’t need to fetch

hardy abyss
#

How to make slash_command only visible in a certain guild

errant trout
errant trout
round heart
errant trout
#

no

round heart
#

Is that a Discord limitation, or a pycord one?

errant trout
#

well for starters, discord has no concept of "disabling" a command

#

it either exists or it doesn't

#

when we set guild_ids, it creates a new individual command on every guild through their individual endpoint

round heart
#

So when you refresh commands with Discord, you have to send them all? There's no way to say 'this specific command is no longer available'?

errant trout
#

there's a few different sync methods

#

pycord by default does a bulk sync and overwrite

#

the important part is if for some reason a command is "deleted" or not included in an overwrite sync, you'll also lose any user customizations such as permissions

#

which obviously isn't ideal for a public bot

round heart
#

I'm not saying it's not complex, but is it theoretically possible - given available methods from Discord - to manage available commands per server on-the-fly? Whether via a bulk sync or with some of the other type of sync you hinted at

errant trout
#

oh it absolutely is

#

just a pain lol

#

ideally pycord v3 will also make it easier, the current sync system sucks for anyone trying to even remotely do their own thing

round heart
errant trout
#

well it wasssss

#

but when permissions v2 came, it was moved to user control

#

thus if you want to programatically set permissions you need oauth instead (which is why large scale dashboard bots can do it)

round heart
#

mm, that makes sense (but is overly complex for smaller bots, especially bespoke ones.)

I can just imagine there's been a non-zero number of times privileged commands were accessed by commonfolk because the integrator forgot, or didn't get to it in time

errant trout
#

at least we do have default perms which is a decent enough compromise, but yeah at the time it was a pretty big deal

maiden bloom
#

Are there any downsides to using py-cord[speed]?

little cobalt
#

for what is speed even?

maiden bloom
#

I found it on the pypi page

echo wraith
#

I think it's uvloop, or what is it ?

edgy nest
#

that are intended to make the library run marginally faster

maiden bloom
#

Sounds worth it to me

pulsar ferry
errant trout
#

That was my original point

pulsar ferry
#

Ah

#

Okay maybe I need to update that one then

drowsy grove
#

I made my own help command and added it to my bot’s help_command setting. However, it isn’t responding with it. Does it take a while to load the command like how slash commands do?

sage tendon
#

did you restart discord and the bot

#

also i think help_command is kind of a remnant of prefix times, not sure how well it works with slash

drowsy grove
#

I don’t have it set up as a slash, I was just wondering if it had the same load bearing as slash does when it comes to being a global command. I restarted the bot, but not discord. Everything else didn’t need a discord restart so tbh I didn’t think about that.

#

I’ve tried even getting just the Minimal Help Command to appear, but it just won’t register the command

lapis dock
#

Prefix commands are not registered to discord so you only need to restart your bot. If it is not working immediately after restarting your bot you have something wrong in your code.

It is recommended to use slash commands at this point in time though.

#

Ah, i see you talked about it in #general

drowsy grove
#

Yeah, I'm just going to bail on prefix commands. It's good to know now that they're useless. It's getting easier as I translate my commands. Finished file 1/7 so far, and was able to cut out a lot of commands since a lot of it was 'help adjacent'. Makes it so much easier since discord will handle that.

sage tendon
#

everything is easier with slash commands

#

absolutely everything

drowsy grove
#

Yeah, I'm very quickly learning that lol

#

Each feature is reducing in code by a large margin

#

So much error handling is automatically taken care of if I do typing

sage tendon
#

you don't even have to do typing lolw

#

but you should

drowsy grove
#

I'm def going to do typing for my own sanity

pulsar ferry
errant trout
stray cape
#

Hey guys I made a bot that uses views (with the bot ui kit), but it seems like that if I run my project on my local computer, it runs on time, it doesn't have any delay or anything. But when I run it on my vps, it has slightly delay with timeout, it timeout's a minute later what might be the cause?

lapis dock
#

How are you setting your timeout?
I sounds like you mean that the timeout is actually 1 min 15 seconds on your VPS or similar?

sage tendon
#

VPS system time might be wrong would be my first guess

stray cape
#

This is how I create my views and set my timeout:


class AnnounceView(discord.ui.View):
  def __init__(self, someone: discord.Member, *args, **kwargs):
      super().__init__(timeout=600, *args, **kwargs)
      self.someone = someone

view = AnnounceView(...)
#

its like a minute delay

sage tendon
#

check if the time of your vps is correct

stray cape
#

its more a shared hosting but does this have to do something with the timezone difference?

sage tendon
#

doesnt matter if its shared or not, check the time of the server lol

#

and no, timezones are 30m minimum

stray cape
#

what specifically do you want me to check about the time of my vps?

sage tendon
#

whether its correct or off by a minute lol

stray cape
#

1 hour delay thats it

#
luxkatana@nest:~/cautious-computing-machine$ date
Mon Dec 30 10:06:24 PM UTC 2024
sage tendon
#

so the minute is correct? hm

stray cape
#

the timeout is dynamic by the way, but it has some pattern

lapis dock
#

That is strange. If the VPS time was off it should not effect something that happens X seconds in the future as that is a duration not a specific time.

sage tendon
#

it might have taken the time from which the message is sent as a timestamp, thats how i imagined it

lapis dock
#

The timeout resets every time you interact with the view. Are you aware of this?

stray cape
#

I sent the view already, at that point the timeout time should go off, right?

#

This is what I mean (the time currently is 23:17 or 11:17 PM for you dumb americans)

#

This is how the timeout is decided:

Current time + 10 minutes
current time seconds will be zero so that'll timeout when it is exactly after 10 minutes

stray cape
lapis dock
#

Yes the timeout is how long the view needs to be inactive before it does its timout things

stray cape
#

Oh?

#

I want to make this behaviour that it should last for n amount of seconds how can I do that then?

sage tendon
#

run view.stop() after that amount of time

#

and before that, view.disable_all_items() i think

#

so the buttons become inactive

stray cape
#

manually

sage tendon
#

no lol

#

hm actually not quite sure how id do it tho rn

#

probably running a function in a new asyncio runner that then waits 10m exactly and then disables all items and stops the views

stray cape
sage tendon
#

tasks can have dynamic timings

echo wraith
#

Yeah

#

Wait I sent an example some time ago

stray cape
#

@tasks.loop

echo wraith
#

An asyncio task

#

#1132206148309749830 message

sage tendon
#

oh i also thought you were talking about pycord tasks lmao

#

so yea we mean the same thing

stray cape
#

cant I just wait using asyncio.sleep for the amount of time directly? And disable the items of the views after the sleep?

echo wraith
stray cape
lofty parcel
#

It doesn't block the thread

stray cape
#

thats impossible right because its asynchronous.. right?

#

if you use time.sleep then it will block?

lofty parcel
#

asyncio.sleep doesn't block the bot

lofty parcel
stray cape
#

so it shouldnt be a problem to use asyncio.sleep ig

sage tendon
#

It does

lapis dock
#

On my stuff like that I just check the time when someone interacts and if it is passed the end time I say "sorry to late" then disable/stop the view. This works well for longer timeouts

sage tendon
#

because it still pauses code execution on that branch

#

so, unless im wrong, the view will never respond to events or your command code wont resume (assuming something happens in the command used to send that view)

stray cape
#

after 10 minutes, it'll do another stuff (creating channels, handling other views and stuff)

sage tendon
#

might be wrong tho

stray cape
#

i should be trying stuff out ig, but thanks guys!

#

i read my role wrong thought it said transistor

lofty parcel
#

I remember using it somehwrre

errant trout
#

asyncio.sleep will only block the code after it, nothing else

#

(that's the entire point)

sage tendon
#

yea but i worried about the init never finishing and thus that branch of code never returning the command until after those 10m but since there's apparently no command is fine

toxic echo
#

quick question, what feature is this bot using to generate profiles programmatically?

torn barn
#

Webhooks

pulsar ferry
#

Hey guys qq - I am using autocomplete for an arg on one of my commands, but the command is still able to be executed with a value taht is not in the list... is there a way to force the user to only be able to execute by using a value from the autocomplete?

@bot.slash_command(guild_ids=[GUILD_ID], description="Share a promo the community!")
async def promo(
    ctx,
    name: discord.Option(str, "specify the name", autocomplete=discord.utils.basic_autocomplete(name_autocomplete)),
):
sage tendon
#

use options

pulsar ferry
#

I cant because there are more than 25 or whatever the limit was

lofty parcel
#

Then you will need to check against the autocomplete options and return an error message

#

Or use multiple select menus

pulsar ferry
#

yep okay thats fine i can write a manual check just didnt know if there was a quick arg that could be set

drowsy grove
#

New day, new question. I have a global error handler to handle (obviously) errors. I also have command specific errors. My global handler is interfering and dealing with errors that only my command specific error handlers should touch. Is there a way to prevent this?

sage tendon
#

are you actually setting handlers or do you just do the handling right in the command code

#

if you set handlers, you can add this to the top of your global handler and it should work

if ctx.command.has_error_handler():
    return
pulsar ferry
#

Hey guys another quick one - is it possible to respond as ephemeral when returning the function?

I am trying to do something like this but it seems like the bot response is still showing public to everyone

    msg = f"[{category.capitalize()} Posted]({thread.jump_url})"
    logger.info(msg)
    return await ctx.respond(msg, ephemeral=True) 

If not, is there a way to hide the args that were passed to the command when clicking on used <command> ?

sage tendon
#

you need to defer ephemerally if you wanna respond ephemerally

pulsar ferry
#

oh so every function essentially then that has a response should have the first line be the ctx.defer?

sage tendon
#

no

#

but you are deferring there, no?

pulsar ferry
#

ohh wait you mean pass the ephemeral arg as True to the defer?

sage tendon
#

yes

pulsar ferry
#

got it thanks!

drowsy grove
drowsy grove
#

Thanks!

#

I had something similar that worked with prefixes, it was a hasattr(command, β€˜error’)

#

It broke once I swapped to slash commands

pulsar ferry
#

is my server subscription tier bugging out, or does discord upcharge the fee on ios devices?!

echo wraith
#

They do

#

I'm pretty sure

sage tendon
#

yep

#

ios purchases are more expensive

pulsar ferry
#

wow okay thought i was going crazy with messing up a tier

pulsar ferry
#

Anyone know if this actually works either or do I need to write a custom greet message in pycord? Have people signing up and no message :/

#

I wonder if its because there is a week free trial, so maybe after the trial ends it procs?

sage tendon
#

yea i guess so

#

since it does say "purchases"

pulsar ferry
#

but they do put in the credit card and everything when they click 'subscribe'

sage tendon
#

not charged tho

pulsar ferry
#

hmm yah i guess

#

have an actual py-cord question now... are there any examples of how to determine when someone joins, what invite they used and then subsequently who created that invite (i.e. who invited them?) ..Thinking of doing a referral type system

sage tendon
#

only indirectly

#

you need to actively track the number of uses of each invite and recheck after a join

#

but joining is just on_member_join

pulsar ferry
#

Yeah so i worked up something like this with that thinking, was hoping there was a better way though

@bot.event
async def on_member_join(member):
    guild = member.guild
    # Fetch the current invites from the server
    invites = await guild.invites()

    # Find the invite with increased uses
    for invite in invites:
        if invite.uses > 0:
            inviter = invite.inviter
            if inviter:
                print(f"{member.name} joined using invite by {inviter.name}.")
                # Store inviter-invitee relationship
                inviter_tracker[member.id] = inviter.id
            break

sage tendon
#

yea thats how you need to do

pulsar ferry
#

but this would obv need some tweaking to check against a cache

stray cape
#

hey guys I'd like to know when I could use persistent views

#

and when not

sage tendon
#

when you need them past a bot restart

drowsy grove
#

Ok I’m losing my mind here. How do I get the SKU id for a premium shop item??? I want to verify that a user has the correct SKU, but have no idea how to do so because discord does NOT explain how to do so in their documentation. I’ve been staring at it for literal hours.

#

Am I just missing something??

fresh sierra
#

And user_id for the other v

lapis dock
fresh sierra
#

You need to compare the old invite count to the new one, here it will just always show the same person who has an invite greater than 0

drowsy grove
# fresh sierra Isn’t it entitlement.id ?

That’s what I thought, but I don’t know where to get that from. Is it from the ApplicationContext being passed through? Via obtaining the bot/client from the context for the bot’s SKU and obtaining the user for the user’s SKU? In that case, how do I know which SKU belongs to the subscription I am trying to reference? From what I can tell there are no names within an entitlement object, just id’s. I haven’t looked at a SKU object, so maybe it’s there, but I find it weird that I can’t find the SKU id before having to grab it via the application command. That would mean I’d have to call the method to read all entitlements available and then pick and choose until the right entitlement is selected

rugged lodgeBOT
edgy nest
drowsy grove
drowsy grove
# rugged lodge

Does this grab the entitlements that are in the guild? Or the one that the invoking user has within the guild?

edgy nest
#

that would grab entitlements attached to guild subscriptions

drowsy grove
#

Ah ok. I think I have mine set up to user subscriptions instead. Would I instead just grab the user from context and do user.entitlements, giving the same result?

edgy nest
#

yes

drowsy grove
#

Thanks 🫑

edgy nest
drowsy grove
#

Cool. So if I did Client.entitlements it would pull all entitlements, regardless of guild/user?

edgy nest
#

yes

drowsy grove
#

Perfect

#

Thanks a lot!

edgy nest
#

additionally if you're using interactions, Interaction.entitlements should return everything that applies to that interaction

#

(both user & guild)

drowsy grove
#

I am indeed using interactions. I have application commands returning ApplicationContext, which give me access to the user and the interaction within it

#

So either way I can grab the entitlements

#

I just had no clue where to grab the SKU I need for comparison

edgy nest
#

Inter.entitlements is preferred because it's not an extra API call :3

drowsy grove
#

Even ChatGPT told me it was displayed on the discord applications page 😭

drowsy grove
drowsy grove
#

Yeah. It displays it, just not next to the SKU (which is what it said lmao)

edgy nest
#

it does in analytics but you can't copy it :p

drowsy grove
#

Weird

edgy nest
#

i guess they expected people to just fetch it over the api

drowsy grove
#

Is there a way in discord to pin that response? I won’t be able to get around to the fix until day after tomorrow

drowsy grove
#

I just don’t want to open another API connection

#

I’m lazy

#

So lazy that I already started making my own database for entitlements instead of fetching from the API

edgy nest
#

yeah

#

you can cache them in memory, you just have to fetch them on startup

#

then listen to events

drowsy grove
#

I have event listeners up for entitlements, just didn’t wire them to the DB yet. Going to do this solution instead

pulsar ferry
fresh sierra
#

Then when a member join check which invite is greater than the one you save

#

And then you will now which one invite the member

ionic wasp
#

whats the interval at which a bots latency refreshes?

#

as per bot.latency

sage tendon
#

logically it would be every API call or even every heartbeat ig

stray cape
#

hey guys got a discord.File object how can I get the link of it to use it for example as an image for an embed or as thumbmail?

sage tendon
#

you need to upload it as attachment to the message then make the image link a certain thingy

#

wait, there's a tag for it

sly karmaBOT
#
f = discord.File("some_file_path", filename="image.png")
e = discord.Embed()
e.set_image(url="attachment://image.png")
await messagable.send(file=f, embed=e)```
sage tendon
#

yes that

stray cape
#

oh okay

#

thanks!

#

do I have to close the file tho?

sage tendon
#

show your code, depends on what you do

stray cape
#

Currently I am taking a file from a slash command

sage tendon
#

yea show your code

stray cape
#
async def apply_as_helper(ctx: discord.Interaction, image: discord.File) -> None:
    if SEARCHING_FOR_HELPERS is False:
        await ctx.response.send_message("Helper applications are closed.", ephemeral=True)
    else:
        STAFF_CHAT = await ctx.guild.fetch_channel(1323056105835991050)
        embed = discord.Embed(title=f"{ctx.user.name} is applying for helper", description=f"{ctx.user.mention} is applying for helper")
        await ctx.response.send_message("Cool, thanks for applying as a helper, we're gonna make our decision later!", ephemeral=True)

sage tendon
#

ctx is not discord.Interaction

#

and I'm pretty sure files uploaded to slash commands are discord.Attachment

#

and you can use ctx.respond() as a shortcut
and :3 you shouldn't fetch the channel but rely on cache (get_channel)

stray cape
#

ctx is discord.ApplicationContext?

sage tendon
#

yes

stray cape
#

and that it returns None?

sage tendon
#

and no if you get an attachment from a slash command like that you don't have to close anything

sage tendon
stray cape
#

ohh alright

sage tendon
#

also idk what ctx.user exactly points to but usually you use ctx.author

#

sorry for being annoying I love to nitpick

edgy nest
sage tendon
#

ok

stray cape
#

is there a way to remove webhook messages of a channel?

sage tendon
#

delete them like normal messages

pulsar ferry
# fresh sierra Check the invite create to save all of the invite with there use

For anyone else who may be interested... this seems to be working

server_invites = []

@bot.event
async def on_ready():
    # Cache Server invites
    global server_invites
    guild = bot.get_guild(GUILD_ID)
    server_invites = await guild.invites()

@bot.event
async def on_member_join(member):
    global server_invites
    new_invites = await member.guild.invites()
    for old, new in zip(server_invites, new_invites):
        if old.code == new.code and old.uses < new.uses:
            update_referral(member.id, new.inviter.id) # Custom function to do something with the data
            break
    server_invites = new_invites  # Update cached invites
sage tendon
#

why do you declare the global twice lol

#

or rather why make it global at all

#

oh bc its not in a cog

fresh sierra
#

So you will have to update the invite also during invite create

pulsar ferry
# fresh sierra You lack one thing, if a invite was not saved it will not work

yeah i actually just just realized that after posting... trying something like this now

@bot.event
async def on_member_join(member):
    global server_invites
    new_invites = await member.guild.invites()
    old_invites = {invite.code: invite.uses for invite in server_invites}
    for invite in new_invites:
        if invite.code in old_invites and invite.uses > old_invites[invite.code]:
            update_referral(member.id, invite.inviter.id)
            break
    server_invites = new_invites
#

and i think the assumption i still need to add is that IF there is a new code, that is the one to use... not sure how to account for if more than 1 code is created though before someone new joins

fresh sierra
pulsar ferry
#

oh wait great idea... just use the event create to update the server_invites

fresh sierra
#

And consider saving the invite inside ur on_ready too

pulsar ferry
#

something like this?


async def refresh_invite_cache():
    global server_invites
    guild = bot.get_guild(GUILD_ID)
    server_invites = await guild.invites()

@bot.event
async def on_ready():
    logger.info(f"Caching server invites...")
    await refresh_invite_cache()

@bot.event
async def on_invite_create(invite: discord.Invite):
    await refresh_invite_cache()

@bot.event
async def on_invite_delete(invite: discord.Invite):
    await refresh_invite_cache()

@bot.event
async def on_member_join(member):
    global server_invites
    new_invites = await member.guild.invites()
    old_invites = {invite.code: invite.uses for invite in server_invites}
    for invite in new_invites:
        if invite.code in old_invites and invite.uses > old_invites[invite.code]:
            update_referral(member.id, invite.inviter.id)
            break
    server_invites = new_invites
edgy nest
#

invite create & delete you can just manually update the cache instead of refetching all of them

#

since only one invite changed

pulsar ferry
#

but i wouldnt get the uses if i manually added the code...would I? ah wait nvm i could add the object

#

but feels safer to just pull a refresh?

edgy nest
#

safer technically but unnecessary

echo wraith
sage tendon
#

f

pulsar ferry
echo wraith
echo wraith
#

For the guild invites...

fresh sierra
#

And he used the on_ready to sync again between restart

#

For a single guild bot this seems to be good

echo wraith
fresh sierra
#

Because I don’t really see any scenario where it will not works

#

Or it will not work for 1 member if discord has an issue

echo wraith
#

Still needs error handling imo, e.g. server is a bit unresponsive and multiple users join at similar times

#

Race condition basically

fresh sierra
#

Yeah, for a single bot it should be good but ofc it can be better

echo wraith
#

The race condition issue doesn't depend on the number of guilds. But yeah I get the fact that it's for a single guild. Although imo that tracking method is still hacky and duct taped

echo wraith
#

At least

#

Then have some kind of lock on server_invites and run the appropriate logic with that lock

pulsar ferry
#

Sorry stepped away for a bit thanks for the tips here - yes single server use only but lock is a good idea for race condition even if it’s an edge case

ionic wasp
#

can i asign custom values to slash commands directly from
@discord.slash_command(name="", description="")

so that these custom values show up in bot.application_commands

echo wraith
ionic wasp
sage tendon
#

for what purpose

echo wraith
#

uh

ionic wasp
sage tendon
#

I mean you should be able to do command_function.attr = " "

#

right under the definition of the function

ionic wasp
#

i dont think that works

echo wraith
#

But I'm unsure why you would want to do that

sage tendon
#

to say it doesn't work without even trying is wild

echo wraith
#

@ionic wasp Do you mind sharing a bit more about your exact use case so we can find maybe a better implementation ?

sage tendon
ionic wasp
#

thanks

serene mauve
#

how to get user's bio (about me)?

sage tendon
#

not possible

echo wraith
#
class MySlashCommand(discord.SlashCommand):
    def __init__(self, *args, **kwargs):
        self.owner_only = kwargs.pop("owner_only", False)
        super().__init__(*args, **kwargs)

def slash_command(**kwargs):
    return discord.application_command(cls=MySlashCommand, **kwargs)


@slash_command(yada yada)
async def cmd(ctx:...):
    ...
ionic wasp
#

πŸ‘ cheers

pulsar ferry
# echo wraith I would make it so that server_invites = new_invites is in a finally block or el...

Thanks for the tip, how do you think this looks?


server_invites = []
server_invites_lock = asyncio.Lock()

async def refresh_invite_cache():
    global server_invites
    async with server_invites_lock:
        guild = bot.get_guild(GUILD_ID)
        invites = await guild.invites()
        server_invites = invites

@bot.event
async def on_invite_create(invite: discord.Invite):
    await refresh_invite_cache()

@bot.event
async def on_invite_delete(invite: discord.Invite):
    await refresh_invite_cache()

@bot.event
async def on_member_join(member):
    global server_invites
    async with server_invites_lock:
        new_invites = await member.guild.invites()
        try:
            old_invites = {invite.code: invite.uses for invite in server_invites}
            for invite in new_invites:
                if invite.code in old_invites and invite.uses > old_invites[invite.code]:
                    update_referral(member.id, invite.inviter.id)
                    break
        finally:
            server_invites = new_invites
echo wraith
stray cape
#

hey guys what's the default timeout of a View

pulsar ferry
#

I was thinking of doing cogs but it seemed to add a lot of other challenges as i have a few other things happening in this file as well that would cause some circular import references. As it stands the whole file right now is only like 500 lines of code so was trying to just keep it simple

sage tendon
sage tendon
#

the only real challenge with cogs is spreading a single command group across multiple cogs

#

everything else can easily be put either in helper files or synced via the bot object

pulsar ferry
# sage tendon cogs make everything easier

Well so for example the issue i was having is that in my main.py right now, i also have the bot spinning up a fastapi webserver. so in a theoretical webserver.py where i define the fast api app and all its endpoints, i couldnt figure out how to call commands that require the bot because in the main.py where i have the bot, it also needs to import the app so it can spin up the server

@tasks.loop(count=1)
async def run_fastapi():
    logger.info("Starting FastAPI server")
    config = uvicorn.Config(app, host="0.0.0.0", port=8080)
    server = uvicorn.Server(config)
    await server.serve()
#

so i just kept it all in main.py πŸ˜…

stray cape
sage tendon
#

you do not ever import bot from your main file

#

ever

pulsar ferry
#

how do i run it then?

if __name__ == "__main__":
    bot.run(SWEEPY_TOKEN)

sage tendon
#

check the cog guide please

pulsar ferry
#

I was on this page and thought i understood how to essentially define all the cogs as modules, then add them in main.py with something like bot.add_cog(Greetings(bot)) .... but i though you still would have to actually start it after adding all the cogs call bot.run() It doesnt say on this page how to start the bot a different way unless its documented somewhere else?

https://docs.pycord.dev/en/master/ext/commands/cogs.html

sage tendon
#

check the guide

#

there's a guide specifically for cogs

pulsar ferry
#

oh is this not the right page?

sage tendon
#

that's the docs

echo wraith
#

That should be it

pulsar ferry