#Basic Pycord Help
1 messages · Page 63 of 1
Yea i know, but it seemed odd for .1 to break when .0 worked
and i just wanted to throw it in because maybe whoever handles 3.13-proofing rn isnt aware of this
the current PR is https://github.com/Pycord-Development/pycord/pull/2666
what is the fastest way for me to get anyones username?
fetch user?
i need to get like 10 usernames in one command
Quick question.
discord.on_application_command_error(context, exception) triggers for both prefix commands and slash commands?
definite "anyone"
No, only for slash commands and views etc
I'm not sure I get what you mean. What do you have ? A user id ? And what username do you want ? Display name ?...
Dosen't trigger for views afaik
ohwell
So on_command_error just for commands
for views you have the view's own handler
And the other for slash, interactions, etc
anyone that could interact with the bot
yea
ok
i have user id
What's the use case
leaderboard, i store user ids in mongo
You should try to get the user from the cache first.
the docs are great, use em
i did
"Returns a user with the given ID."
this is all
yea, and that's exactly what you want lol
you'd think so for a function called get_user
anything that is called get_x uses the cache
get_ methods get stuff from cache
ah ok
what if it is not in cache?
fetch_
but you should avoid that wherever possible
And if the user isn't in cache for some reason (e.g. left all mutual servers) get will return none
Bots: Attributes activity, allowed_mentions, application_flags, application_id, auto_sync_commands, cached_messages, cogs, debug_guilds, default_command_contexts, default_command_integration_types,...
typically every user who shares a server with your bot should be in cache unless your bot has thousands of users
i would expect docs to mention that, idk i might have missed that
what
read.
also, reading the source code is also possible when the docs don't mention something you find important
This explains it in pycord
Any function that starts with get_ in Py-cord is retrieving the related object from your bots cache. If the object is not in the bots cache the get_ method will return None. Because of this behavior you should check if the get_x method is None and if it is use the fetch_x method.
Why Is Using fetch_ Without Using get_ First Bad?
The fetch_ method makes a call to the discord API. This API call is unneeded if you already have the information. It will also make your command take longer because it will have to send and than wait for a response from the discord API. It will also contribute to the discord APIs global rate limit of 50 requests per second.
What Is Cache?
The cache is a temporary storage inside your bot. It holds many objects from members to messages. When you restart your bot the cache will be empty. When the cache is full it will delete older objects to make space for the new objects.
AttributeError: 'ForumChannel' object has no attribute 'fetch_message'
What? Since when
Is it possible to set an interaction deferral as ephemeral while not having the first follow up response be ephemeral? I'd like to have the possibility of using ephemeral responses after the deferral but don't want it for every message. When I enable it for the deferral, the first follow up message is ephemeral even if I explicitly set it to not be.
await ctx.interaction.response.defer(ephemeral=True)
await ctx.send_followup(embed=self.string_to_embed(embed_msg_str), ephemeral=False)
This code results in the follow up message being ephemeral^
and if I don't use ephemeral in the deferral there's no possibility of using it in the follow up messages
no
So the first follow up will have to be ephemeral?
Yes
also, just use ctx.defer and ctx.respond
shortcuts & make your code less error prone
I thought you could only respond once and only when an interaction hasn't been deferred?
respond will handle all cases
Ah, must be new then. Thanks
meh, i know it since forever
2 naked, 4 per embed.description, 6 in all embeds total
https://discord.com/developers/docs/resources/message#embed-object-embed-limits
past as in 2.0.0a7
whats the thing called where its autocomplete but the names shown in the list are different from the ones that are actually sent in the command
And use value
oh thats so much easier than i thought tysm
does anyone know, how i can get the url of the invite link a user used?
you can't directly
You have to track all existing invites, and just check which one has more uses after a user joins
ok. thx.
Is there a way to get Discord to defer automod to a bot? I'm setting up a community server for my university and I'm interested in being able to filter some content, and it'd be ideal to be able to prevent it being sent in the first place (like the profanity or mention filters do), but I can't remember if this is actually a thing or if I just made it up one day and tricked myself into believing it
Yeah thats not a thing
Your bot can create automod rules
But you can't prevent the user from sending the message by yourself
Just not custom ones? only the ones already available?
like can I only use these, even with a bot?
You can make custom rules using a bot
will also give your bot a badge
But honestly if it's a small server, and only one server in general, it's easier to just do it yourself in discord
That happens after 100 rules lol
oh yea true
I don't understand why bots would set up automod rules. Is it just so less technical people don't have to do it themselves or is there something extra bots can do?
Ig some bots offer an easier command to setup a rule
Uhh Carl bot switched to automod rules i think?
Or some big bot like that
its just so bots that already have block rules anyway can do it right inside discord & prevent messages from being sent in the first place
Nah, I need some functionality that discord doesn't have. One of the lecturers doesn't want to join the discord server unless we can guarantee we can filter content, so ideally being able to prevent the messages being sent in the first place
but its fine, deleting the message will be fast enough
just opens a different can of worms
like what functionality
The main 2 things that I still see on servers that use automod are spam across channels and advertisements. It seems to be able to cover everything else pretty well
i mostly use it to quickly mute trolls spamming 1000000 variations of slurs, all handled via regex
insta 1d mute, so they're taken care of even with mods offline
this is handled by discord, but additionally there are events that will fire whenever discord filters a message https://docs.pycord.dev/en/master/api/events.html#discord.on_auto_moderation_action_execution
basically everything you're asking for is already possible in guild settings, im not sure what else you'd want
Targeted harassment and malicious images
mainly
It's fine though, I can just do it via the bot and delete messages
it'd just be easier to win over this lecturer if we could prevent the abusive messages being sent in the first place, but as the saying goes, better late than never :^)
i dont see what a bot can do here that automod cant
Well regex doesn't work, it doesn't know what context is. An algorithmic approach would
so you want AI automod, oh boy
trust me, i've tried, it's really not a 100% approach
Just have mods like every other server and block the most common shit with automod
We can't just throw mods at the server for T&S, and we're all based in the same country, so if someone decides to spam when the committee are asleep, there's nothing we can do really
if I'm honest it's excessive, but I've been asked to implement it 
well good luck, all i'll say is that AI automod is hard to get right
It really sounds like whoever tasked you with this isn't the brightest ngl
I'm dealing with people who don't write bots 😔
I've got to bridge the gap between 50yo+ lecturers concerns and the ideas of 18 year olds
No, conceptually
No server ever has AI automod, they have mods and automod
Oh yeah
And, i tried
No matter which model, most are defeated relatively easily if you want to
oh well
can't win them all eh
I'll just lie to the lecturer and say that the automod does what he asked :^)
and hope it never needs to ACTUALLY do what he asked
For View timeouts, is that based on the message send, or the last interaction?
Docs do say last interaction, but I don't see anything in pycord source that updates it
mm, I see it. When a callback is dispatched, _timeout_expiry is advanced.
Indeed they're based on the last interaction
this error occured after a few hours: Event loop stopped before Future completed.
future: <Task finished name='Task-4' coro=<Client.run.<locals>.runner() done, defined at /home/container/.local/lib/python3.9/site-packages/discord/client.py:790> exception=RuntimeError('Concurrent call to receive() is not allowed')>
Traceback (most recent call last):
File "/home/container/.local/lib/python3.9/site-packages/discord/client.py", line 792, in runner
await self.start(*args, **kwargs)
File "/home/container/.local/lib/python3.9/site-packages/discord/client.py", line 756, in start
await self.connect(reconnect=reconnect)
File "/home/container/.local/lib/python3.9/site-packages/discord/shard.py", line 477, in connect
raise item.error
File "/home/container/.local/lib/python3.9/site-packages/discord/shard.py", line 180, in worker
await self.ws.poll_event()
File "/home/container/.local/lib/python3.9/site-packages/discord/gateway.py", line 612, in poll_event
msg = await self.socket.receive(timeout=self._max_heartbeat_timeout)
File "/home/container/.local/lib/python3.9/site-packages/aiohttp/client_ws.py", line 315, in receive
raise RuntimeError("Concurrent call to receive() is not allowed")
RuntimeError: Concurrent call to receive() is not allowed```
I'm trying to have an upload function where I can upload multiple files. Currently I have async def upload(self, ctx, attachments: list): as the function however it cannot take a list as a parameter. I was able to get one to upload when changing it to upload(self, ctx, attachments: discord.Attachment)
huh, I have no idea how that's happening specifically, the lock should prevent it from running more than once at the same time
There is no input type that accepts multiple attachments.
You can only receive one per option.
You can only do that with prefix command I think
Is there a way to get the user install counter with pycord?
on master/2.7, you can get it from await bot.application_info() -> accessing approximate_user_install_count
but 2.7 isn't out yet; if you're using a 2.6 release or lower you can instead run await bot.http.application_info() directly and parse the dict for approximate_user_install_count
Ok ty
🤷♂️
The bot is find without shards but I can’t do that anymore since it’s in more than 2.5k servers where it requires shards.
This is annoying as fuck
This bug
Goes offline every hour or so
Can someone please fix this, I’m sure people in my situation just switched to discord.py since it’s a breaking bug
^ error
I have tried to reproduce it but I don’t seem to be able to
Try reinstalling aiohttp and py-cord
Use debug logging. An help
Is there a set character limit for discord.Embed.description or is it to do with screen size?
Some classes are just there to be data containers, this lists them. Unlike models you are allowed to create most of these yourself, even if they can also be used to hold attributes. Nearly all clas...
read the docs
I always read the Docs and do a couple Google searches before coming here, am I blind?
I am indeed blind. Thank you :D
does the shard keep an info about since when it was connected ?
am probably dum but how can i send voice_messages as a bot (user installable app)
Still not implemented in py-cord but I think there is a PR you can work with
Installing this PR will give you access, however I still have test code on it, I can try to finish it up this week and get it to master.
Thanks just did.
Am still confused why another user installable app can send voice messages everywhere but mine can't...
Ye but can't figure out how ahah am not smart enough
and whatever other bot you use might use another library, or pycords master branch, or they did it themselves
The other bit runs on a slightly modified discord.js
I don't get why people want voice messages so bad tho, instead of mp3s
Am now trying to figure out what it does different
Tbh I just want it to work cuz it just annoyed me that I couldn't get it working everywhere.
Personally never used voice messages.
I think it's cause of mobile
You don't get a player on mobile if it's a mp3 file
oh yea
complete idiocy by discord
mp3 is deprecated
no it isnt
mp3 is probably the dominating audio format for sending sound files if not in the form of proprietary stuff like voice messages
I think wav is now used
proprietary tho
it being dominaiting dosen't mean it's not deprecated
who said its deprecated?
mp3 encodes and stores music. An mp3 file takes up just 10 percent of the storage space of the original file, meaning music can be quickly transferred over the Internet and stored on mp3 players. As a result, music fans’ entire collections fit onto a device no bigger than a matchbox.
It's not supported anymore
There are always more superior file formats, which are just not used cuz it's new
Like webp vs jpeg
I somehow use ogg opus for most audio files
I did
Anyone knows the limits for message commands (A UI-based command that shows up when you right click or tap on a message), i know its 5 per bot, however is there a global limit for this, lets say if 3 bot has 5, i havent exactly found this in the documentation
you mean across all bots?
yea, in 1 server
i don't think it's specific to commands, but servers are limited to 50 integrations
the developer should only worry about their own bot's command limit
(you just get a stupidly long command list)
anyone have a repo/link to a repo that has a public user application, i want a user app to look at for an example
Here's the slash users example.
it's just a matter of setting the install and integration types
so how do i make it so commands can only be used by users that installed the application and not in a guild
the example above includes some comments on the usage ```py
@bot.slash_command(
# Can only be used in private messages
contexts={discord.InteractionContextType.private_channel},
# Can only be used if the bot is installed to your user account,
# if left blank it can only be used when added to guilds
integration_types={discord.IntegrationType.user_install},
)
...
@bot.slash_command(
# This command can be used by guild members, but also by users anywhere if they install it
integration_types={
discord.IntegrationType.guild_install,
discord.IntegrationType.user_install,
},
)
okay so in theory if i remove the guild_install integration_type, it wont work in guilds right?
do you not want users to use it in guilds at all, only DMs?
setting user_install means users can only add it to their account, not adding a bot to a guild, but they can still use it anywhere
ah no i mean as in, i dont want ppl to utilize it as an actual bot (like they add it to a server as an integration), just want it to only be on their acc
okay perfect
appreciate the help
yep 
do i need to setup intents like a regular bot as well?
ehhh
apart from the priveliged intents, intents are related to the events the app recieves
if you don't plan on your bot being anywhere, then for the most part they have no effect
just note that user apps are relatively limited; they will ONLY work with specific data recieved in the interaction
if you're used to being able to access guild attributes and methods with regular bots, you have to throw all that out the window
but does the user app have access to say all the guilds the user is in, and can it access messages inside a guild the user is in?
ooh that kinda sucks
it's not in the guild, unless someone already installed it to that specific guild
makes sense
is the app still able to dm other users (using maybe bot.fetch_user or something) just fine
gotcha
basically you have to treat user app commands as if the bot isn't in the server at all
and user apps can still do all the view stuff right, has the same core functionality as a bot
if it's through interaction responses then yeah
perfect thank you
(note: maximum 5 followup responses per interaction)
whattt is that a user app only thing
swear ive never seen that with my regular bots
yes
is there an issue with 2.6?
no i just didnt even know there was a 2.6 😭
well we're on 2.6.1
#library-updates
Anyone know what happened here?
Can be a response you sent too late without a defer
I might not be understanding what you are saying, but giving a different input to the parameter with the command works perfectly fine
You have 3 seconds to respond to a slash command by default
That error usually means you fail to respond in that time window
i mean first of all make sure every code path leads to a response in your command
and if you really have heavy code that needs 3 seconds, you can use await ctx.defer() at the start of the command
Perfect! That worked :33
defer is often used when you have to make a API or database call. Also any image/file manipulations stuff. Those are all considered slow operations.
Can some1 tell me whats wong?
aiohttp.client_exceptions.ClientPayloadError: Response payload is not completed
what are you doing that causes that
I never saw that error
@ltc.command(name='me', description='Allows you to display your LTC address for others to send to.', integration_types={discord.IntegrationType.user_install})
async def me(self, ctx: discord.ApplicationContext):
await ctx.respond("hai")
am i doing something wrong? the applications authed to my account but this command doesnt show and the cog gets loaded fine too
anyone?
It’s weird
you have to set integration_types on the entire group
doesn't work for subcommands
🤔 Are there ways to get arguments into autocomplete= references? functools.partial or lambda or something?
like how
As in.. Say you have an autocomplete=search_records, but maybe there's a flag to search only records that are 'active' (or some other arbitrary flag)
autocomplete=functools.partial(search_records, active=True)
hm no idea
I'd just make a second function for that and call the first function while passing the appropriate parameter
You'd have to make two separate autocomplete methods. That's what I'm trying to avoid is all
not really
the other method would have 1 line
but there is probably some smart way to do this but idk it, id do it like i said
...what? You'd have to have search_records and search_active_records. That's two methods. Sure they could call different parameters of a centralized method they both reference, but that doesn't negate what I said.
actually
hm
ChatGPT says
autocomplete = lambda: funcname(flag=True)
which honestly does make sense but i never really use lambda in python
The problem with that specifically is you need the autocompletecontext, which we don't have yet
ah yea
Anyway, functools.partial() appears to suffer from the same issue (which I actually don't fully understand, the whole idea is to bind the parameters but still be able to inject the rest of the method args)
example = lambda **kwargs: funcname(flag=True, **kwargs)
either kwarg or arg, not sure what autocomplecontext is passed like
but that looks like it should work
autocomplete context has a .options attr
It contains the previously selected options
what they mean is they basically wanna prefill that flag per function
ah
Mm, nothing to do with options themselves.
My autocomplete, when it populates items, may need to initially care about certain records from the data source
So it's something you set in your code?
Right. Say I have a big dict/list/whatever of animals
But a particular command may be specific to dogs, so I only want to provide autocomplete results for items that are in my list of dogs.
ohhh
Granted, I can just make an autocomplete method called autocomplete_dogs that filters them, but it would be helpful if I could have a single autocomplete method that would allow for the autocomplete= definition to set some context.
did you try this? should work (try both *args and **kwargs cuz idk how pycord passes it)
This just gives unresolved reference my_autocomplete
It's a local function, homie
s h o w
It just doesn't like it being in a lambda
Open your own IDE, find a method with an autocomplete, and put your autocomplete method in a lambda. unresolved reference is pretty self-explanatory.
or just make a screenshot so there are no misunderstandings
mmkay
weird
I've never seen lambda *args anyway (but it is A Thing)
i mean its just how you catch a list of all args, works in a lambda too ig
So yeah, anyway; I cannot bare-reference my method, and of course self. doesn't work either.
but it works without the lambda:?
Yes, autocomplete=clm_vault_autocomplete is fine, as well as every autocomplete within a class. Which I admittedly always thought was weird.
Which part
does the code run
vault_id: Option(str, "Target Vault", autocomplete=clm_active_autocomplete, required=True),
runs just fine and has for year(s) at this point
Can some1 tell me whats wong?
aiohttp.client_exceptions.ClientPayloadError: Response payload is not completed
i'm wondering if it has to do with the lambda being inside of the function header as opposed to a decorator (or anywhere else)
you ignored me previously so I'll ask again
what are you doing that causes that error
So one should be able to lambda *args: autocomplete_method(*args, mykwarg=True) to pass arguments to the autocomplete?
Oh I didnt saw. Its a flag quiz code which does a api request to an api
yeah
Do you get a line number for the method that is the direct link to the error?
lambda is just an inline function
let me hek
just to rule a weird issue out, can you try make that specific option with a decorator and try the lambda syntax in there?
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/discord/client.py", line 400, in _run_event
await coro(*args, **kwargs)
File "/data/cogs/flagquiz.py", line 250, in on_message
country = random.choice(await request.json())
File "/usr/local/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 1161, in json
await self.read()
File "/usr/local/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 1101, in read
self._body = await self.content.read()
File "/usr/local/lib/python3.10/site-packages/aiohttp/streams.py", line 373, in read
block = await self.readany()
File "/usr/local/lib/python3.10/site-packages/aiohttp/streams.py", line 395, in readany
await self._wait("readany")
File "/usr/local/lib/python3.10/site-packages/aiohttp/streams.py", line 302, in _wait
await waiter
aiohttp.client_exceptions.ClientPayloadError: Response payload is not completed```
so i guess the data you got from the API isn't "completed" whatever that means
Any Idea how to fix?
wheres the line you made the request on
Hm, no user code in that traceback?
second traceback block
There are cases where an API returns data across multiple responses
Idk
I can show you how i do the request
yea but it would wait for the response to be done
connector = aiohttp.TCPConnector(verify_ssl=False)
async with aiohttp.ClientSession(connector=connector) as client_session:
async with client_session.get(url=flag_api) as request:
country = random.choice(await request.json())
country_name = country['name']['common']
country_name_de = country['translations']['deu']['common']
country_flag_url = country['flags']['png']
difficulty = country['idd']['root']```
print response.status
I can try on pc. Give me a moment
also, why the whole connector= bit?
To turn SSL verification off
What do you mean
It is?
i mean you put it there
and it does say verify_ssl=False
so i assumed you know why you put that there
.. . that's literally what you're doing in the first line. lol. You create your own Connector with the verify flag off, then load that into ClientSession
Is that a problem?
Eh. It does slightly speed up operation, and you're not really doing anything here where a domain hijack would cause issues. But it's not a good habit to get into
Verifying SSL is a pretty important security concern.
Is it wrong? Afaik it didnt work without that
so thats ChatGPT code then?
I asked bc ssl didnt work
"wrong" is subjective. I don't think it's the source of your issue, though.
Im not sure if i asked here or chatgpt
U mean how the api is build?
Anyway, putting it in the lambda does indeed seem to change the context. It can no longer find my method within the class ('name <method> is not defined), but if I make a method outside of the class, it captures that reference just fine. But that's dirty.
The url
can't you just do lambda: file.Classname.func
Are you making the request everytime?
Why not just make one and store the result
-# not related to the issue but
Bc itts too much
On pc it works
too much what
Data
its like 2mb max
Interesting
autocomplete=lambda self, *args: self.clm_vault_autocomplete(*args, active=True) actually works
However, it cannot be a coroutine (which makes it not a longterm solution), otherwise it says it wasn't awaited, which I guess is because the lambda fails the coro test in utils.basic_autocomplete
You really should be respecting external websites. If you're consuming data from them, caching is important.
(offtopic: How dare you abuse your mod powers lol)
And how?
it makes your bot faster tho
Means?
is subtext automodded? lol
it doesnt work. the API is broken.
It does
self.flags = []
if not self.flags:
...
async with client_session.get(url=flag_api as request:
self.flags = request.json()
random.choice(self.flags)
yeah, Lala believes it's just for bot use.
it does not work.
For me it worked 2 mins agon
What?
my api req worked
Chrome is getting a 200, but no response data.
Try firefox
ltc = SlashCommandGroup(name='ltc', integration_types={discord.IntegrationType.user_install})
@ltc.command(name='me', description='Allows you to display your LTC address for others to send to.')
async def me(self, ctx: discord.ApplicationContext):
await ctx.respond("hai")```
still doesnt show my commands
Anyway, you should also have some error handling for whether the API doesn't return valid json.
and was the json correct?
I didnt fetched the whole json. I run my code and it worked
Yeah, that's interesting. How the hell did it push 167K of ... nothing (I don't think it did, it's just the content-length header)
yea then its randomly wrong
Do you have access to a linux-like shell? If I wget https://restcountries.com/v3.1/all, the connection fucks up. 🤷♂️
my bud still waiting for a response
https://dark.hates-this.place/i/PGbBIj.png
So I'm willing to bet the aiohttp erorr you're getting is related to that.
What happens if i run?
Then wget will try to access and download the content at the URL
or a curl
I dont want to download xD
so either its sending like hundreds of megabytes of data, or its broken

You really should. Asking them to serve that data to you repeatedly (especially without caching) is rude.
download json once, always have it accessible within fractions of a second
vs downloading it for seemingly minutes every time
seems like an easy issue for me
If i run that i have the json?
only one way to find out
enjoy the json
So, the server is closing the connection after 65326 bytes, which is why you have the 'unterminated string'. I noticed after my wget that I actually did have some data, it's just truncated.
And I can import that like the code I have?
Thankss ❤️
surprised you dont know how to open json files
see? 2mb
I do
just as i predicted
I mean... I don't, always. I hate that I have to open a file descriptor.
Need a get_file_contents() method like PHP 😉
meh
ChatGPT my friend and helper 😄
To rewrite the json get
oh
lol
@echo wraith the speed demon
heyyy
I saw your comment in the issue, the problem with the factory there, is that you can't call it in the function definition because it needs an instance
Sweet, this does work. Admittedly I like the option in ##2668, but I think using partials is also intuitive
Use whichever you prefer, functools.partial is more concise, but admittedly can be less explicit, and doesn't allow for doing more complicated stuff.
It's really a matter of preference
I'm using a "dev" version of my bot so the real bot is not offline while doing testing, but i am now using app emojis but the issue is that my dev app don't have all the emojis i have on my real app. Is there anyway to fix that without uploading all the emojis in the two apps ?
I don't really think so
It’s stored on the app account (you can see this by going to your Discord applications page). If they’re two separate apps, then that’s two separate emoji pools
You can use the API to upload them I believe. So you could copy them all over. How to do this and if it is implemented in Pycord, I don't know
not sure if it's an issyou or issme but bridge commands wont work properly when i make them in a cog, prefix works but not slash. The bot can make commands because i have smth in main.py which works properly
IIRC discord bots still have free nitro so just put them in the same server and add emojis there
its not really that they have nitro they just have many of the perks of nitro
Can I ask here smth about py?`not pycord
what bot class are you using
what is it
Python
I just want to try haha
discord.ext.bridge.Bot
async def on_ready(self):
print(f'Logged in as {self.user}')
for cog in os.listdir("cogs"):
if cog.endswith(".py"):
try:
if cog == "cogs.commondata.py":
continue
self.load_extension(f"cogs.{cog[:-3]}")
print(f"Loaded cog: {cog[:-3]}")
except Exception as e:
print(f"Failed to load cog {cog}: {e}")
raise e
print("All cogs loaded!")```
aight will try
what would be optimal
well you cant use the way i use i think because you have a non-cog file in your cogs folder
but
this is what i do
but you could even pass recursive=True to the top one, that way it also loads cogs in any subfolders
aight
not sure if it ignores non-cog files, but in any way its way simpler than what you, and seemingly most others, do
i think its in the guide as well and IMO its just overcomplicated and prone to errors
But yea slash commands need to be registered before the bot starts to be automatically synced by pycord thus you need to load cogs with any slash commands before starting the bot
got it
works thank you very much :D
Also how do i make the help command also bridge, and also remove these duplicates from the help menu
no clue, the help command is kinda weird ngl
never had it work right
i just make my own, its really just an embed after all
on_ready + listdir was standard before slash commands
so it's basically just legacy practice that people still try to use
I wish the guide would be updated in many regards
and would put bridge and prefix under a "legacy" section
what's your help command logic
i think thats just the default help command built into the library
hmmm i guess, but i wanted to check if they did their own logic anyway
discord froze up while uploading 💀
rip
While docs are the worst and I can't blame anyone for not doing something I wouldn't do myself, I do wish the Guide got more love.
anyways
ahhh i see
i mean the duplicates are because you take all commands and bridge commands really are just two commands in a trench coat
filter_commands logic ignores application commands
but it was never updated for BridgeCommand
if not isinstance(command, discord.commands.ApplicationCommand)```
oh
it's a little silly, but add your own filter_commands override and adjust the logic as you see fit https://github.com/Pycord-Development/pycord/blob/master/discord/ext/commands/help.py#L553
aight
f
(also tip: isinstance can take a tuple of types for the second arg)
truuuuue
debuggers are for wannabes OR complex issues
no in-between
[<discord.ext.bridge.core.BridgeExtCommand object at 0x749c5c205e20>, <discord.commands.BridgeSlashCommand name=player_info>, <discord.ext.bridge.core.BridgeCommand object at 0x749c5c25b2c0>, <discord.ext.bridge.core.BridgeExtCommand object at 0x749c5c206000>, <discord.commands.BridgeSlashCommand name=java_status>, <discord.ext.bridge.core.BridgeCommand object at 0x749c5c25b2f0>, <discord.ext.bridge.core.BridgeExtCommand object at 0x749c5c206270>, <discord.commands.BridgeSlashCommand name=bedrock_status>, <discord.ext.bridge.core.BridgeCommand object at 0x749c5c1d1f70>]
debugger is like loading a 50 cal bullet into a glock
imma just submit a pull request tbh
yeah fair lol
maybe it should just reverse the check to isinstance(command, Command)
xd
now im scared of getting rejected by CI
it'll tell you what the issue is anyway
CI's so agressive can't even mark stuff as archived
lol
got it working
prefix_commands = [
command
for command in commands
if not isinstance(command, (discord.commands.ApplicationCommand, bridge.core.BridgeCommand))
]```
nvm i cant send a pr because 2656
Oh that's me
@violet star
i think they are aware of that PR given they were the ones to bring it up..
Btw that's not enough, that breaks it always, I made the same mistake, you have to filter them only when doing cog help
ye probably trying to be helpful by providing a direct link
well im using it rn and no issues on my end
It is very subtle
They're saying that other instances using the filter will break i think
No but nvm it's not important
If it works don't touch it
Do I have to use discord.Cog or commands.Cog for a bridge cog?
commands.Cog I think
if i use # in a json file for the number of something multiple times how can i use it in a f string without it greying out the rest of the line
like if i just do {#} it would grey out the rest or would i have to change # to another symbol
For what do you need that?
im trying to parse in # from a json file as a variable into a embed
json doesn't support comments
or do you mean python dicts
no like its a json file im getting it from and if i try to use the # variable from json in my embed thats written in python
it makes it a comment
instead of looking at it as a variable
...can you show an example
yes 1sec
async def embed(Name, pokemonid, ):
discord.Embed(
title = f"Infos about {Name}:"
ID of {Name}: {#}
)
then no
like no as in it doesnt work
anything after a # in python is plaintext
isn't the ID of {Name} line meant to be a string?
ngl i just wrote it for the example
idk if its correct eitherway
this is my first time working with embeds and like my third day with pycord 
are you trying to access a json key named # inside an fstring
yeah
yea its 5am in my time dont mind it
is there any event that is triggered when the bot disconnects from discord?
on shard disconnect since u are using shard
user.display_avatar.url_as(format='jpg')
How does this work with never versions?
Lemme get the changes, 1 sec
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
Days without Fabio reading the docs: 460
I searched in the docs but i didnt know I need a asset
You don't need it, it is what it's returned
i searrched for avatar, as, format
discord.User -> Avatar -> Asset -> with_format method
didnt searched user
thats on you
Ye
Didnt codet for ages
has nothing to do with that
i always go to the base class i use if i need anything below it unless i am 100% certain of the type of said thing
or check the type of what you need by hovering over it
and i mean your IDE should autosuggest the methods for display_avatar, which arent many
yea i was referencing something useless nvm
is it even possible to use cogs with discord.Bot? My first time trying pycord rn, and I thought it would be better to start with discord.Bot and not the "old" command.Bot, but I keep running into issues and I cant find anything about Cogs with discord.Bot on the docs
sure you can
just dont load them in on_ready (that will make slash commands not show up)
@pseudo lichen what's the issue you're having exactly
discord.Bot with discord.Cog
commands.Cog works too
that is right
commands.Cog just has slightly modified functions to support prefix commands, otherwise it's identical to discord.Cog
How can I prevent the heartbeat from stopping while an AI is processing (with torch and transformers)
Create a task for it instead of directly blocking the main thread
There is one problem
But ill try that
The hell are you doing in that poor cpu
When the AI starts processing that starts to happen
Since the server does not have a GPU
and yes field names is a list
whats the best practice to delete a ctx.respond after x seconds?
delete_after only exists for ctx.send, right?
p sure respond has it too, try it out
yeah my bad it does, works now.
But just ran into another issue 😅 Trying to create a purge command rn, and I want it to read the permissions of the channel and re apply them to the new creatd channel. But I somehow cant access the overwrites.. I i try to print the ctx.channel.overwrites but I cant get anything
Task was destroyed but it is pending! it appears in my terminal randomly
Hey guys - is it possible to spin up a web server to run in parallel with pycord?
Trying to do something like this but cant seem to get the discord bot to play nicely
# Function to run FastAPI server
async def run_fastapi():
config = uvicorn.Config("main:app", host="0.0.0.0", port=3333)
server = uvicorn.Server(config)
await server.serve()
# Run the bot in its own event loop in a background task
def run_bot():
loop = asyncio.get_event_loop()
loop.create_task(bot.start(SWEEPY_TOKEN))
# Main function to run bot and FastAPI server concurrently
async def main():
# Run the bot in the background
run_bot()
# Run FastAPI server concurrently
await run_fastapi()
if __name__ == "__main__":
# Run the event loop and handle both bot and server
asyncio.run(main())
Task exception was never retrieved
future: <Task finished name='Task-11' coro=<ConnectionState._delay_ready() done, defined at /Users/ethan/Python Projects/SweepsElite/.venv/lib/python3.11/site-packages/discord/state.py:589> exception=ValueError('The future belongs to a different loop than the one specified as the loop argument')>
Start your server as a task of the bot's thread
you mean make the bot a task of the server or the server a task of the bot?
.rtfm create_task
Target not found, try again and make sure to check your spelling.
The server a task of the bot
I do it like this
https://github.com/BruhDark/sally/blob/main/src%2Fcogs%2Fapp.py#L31-L42
hmm does this automatically run it in the background? couldnnt i just do something like
@tasks.loop(count=1)
async def run_fastapi():
config = uvicorn.Config(app, host="0.0.0.0", port=8000)
server = uvicorn.Server(config)
await server.serve()
ah yep got it working thanks!
one other quick question..
guild = bot.get_guild(GUILD_ID) # Replace GUILD_ID with your actual server ID
owner = guild.owner
embed.set_author(name=owner.name, icon_url=owner.avatar.url)
Cant seem to pull owner info - i have the intents set and admin pems
is this the right way to pull it?
What returns None? The guild or the owner?
i think the guild
Debug it and tell me what it is
yep guild returning None
also have
intents = discord.Intents.default()
intents.members = True # Enable member-related intents
intents.guilds = True
# Initialize bot with intents
bot = discord.Bot(intents=intents)
yes on command but being called without ctx from fasatpi endpoint
async def add_thread(ctx, casino_name, link: str, description: str, tag: str):
channel = bot.get_channel(CASINO_CHANNELS[casino_name])
thread_name = f"{link}"
existing_thread = await find_existing_thread(channel, thread_name, link)
if existing_thread:
if ctx is None:
return {"message": f"Thread already exists: [Go to Thread]({existing_thread.jump_url})"}
else:
return await ctx.respond(f"Thread already exists: [Go to Thread]({existing_thread.jump_url})", ephemeral=True)
embed = discord.Embed(
title=f"{link}",
description=description,
color=discord.Color.blue(),
)
if ctx is None:
guild = bot.get_guild(GUILD_ID) # Replace GUILD_ID with your actual server ID
print(guild)
owner = guild.owner
embed.set_author(name=owner.name, icon_url=owner.avatar.url)
else:
embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar.url)
target_tag = discord.utils.get(channel.available_tags, name=tag)
thread = await channel.create_thread(
name=thread_name,
content=description,
embed=embed,
applied_tags=[target_tag] if target_tag else [],
)
if ctx is None:
return {"message": f"[{tag.capitalize()} Posted]({thread.jump_url})"}
else:
await ctx.respond(f"[{tag.capitalize()} Posted]({thread.jump_url})", ephemeral=True)
ahh wait - fetch_guild seems to be getting the guild now... owner still not workign though
Add a check before fetching the guild
get it, if none, then fetch it
Fetching it is an api call
Do the same for the user
.rtfm get_or_fetch
discord.utils.get_or_fetch
discord.ext.bridge.AutoShardedBot.get_or_fetch_user
discord.Client.get_or_fetch_user
discord.ext.commands.Bot.get_or_fetch_user
discord.Bot.get_or_fetch_user
discord.ext.commands.AutoShardedBot.get_or_fetch_user
discord.AutoShardedBot.get_or_fetch_user
discord.AutoShardedClient.get_or_fetch_user
discord.ext.bridge.Bot.get_or_fetch_user
the fetch worked but for some reason the owner property returns None even though i can get the owner_id
...so doing this works although doesnt seem optimal
guild = await bot.fetch_guild(GUILD_ID) # Replace GUILD_ID with your actual server ID
owner = await bot.fetch_user(guild.owner_id)
embed.set_author(name=owner.name, icon_url=owner.avatar.url)
Yeah get or fetch it through the owner_id
That's why I'm telling you to get first and then fetch
ah the get_or_fetch
guild = bot.get_guild
if not guild:
guild = await bot.fetch_guild
owner = await bot.get_or_fetch_user(guild.owner_id)
why not just
guild = await get_or_fetch(bot, "guild", GUILD_ID)
owner = await get_or_fetch(bot, "user", guild.owner_id)
embed.set_author(name=owner.name, icon_url=owner.avatar.url)
Whatever you prefer
Or even better, and properly typed:
even though you could overload get_or_fetch, that would become one large function
guild = await bot.getch.guild(...)
owner = await bot.getch.user(guild.owner_id)
...
https://gist.github.com/Soheab/02f127459407ec18377fd94374a9e375
getch? Wtf
yea, thats just worse straight up
Does anyone have any tricks for getting around the 25 option limitation in slash commands?
autocomplete
hmm okay let me look into this thanks
got it thanks!
Is there a way to create / delete tags from a forum channel?
.rtfm ForumChannel.edit
You pass available_tags
well before i go this route of creating a ton of channels... is there any tips to get around the 20 tag limit?
im writing a bot for a server that shares giveaway links and the idea was to have 1 channel with a tag for each site the giveaway is from, but there are several dozen... so the idea now is to create a seperate forum channel for each site and then have a giveaway / freebie / promo type tag but its going to be a lot of channels :/
Just make a thread for each site
how would i control the tags within a thread though
why do you need tags?
Just have one thread for each giveaway site, and then post the giveaway in the correct thread
when you say thread, youre saying 1 forum channel, and then within 1 different post for each site?
Forumchannel
- Giveaway site 1
- Giveaway site 2
etc
with each site being its own thread / post
yes
well the only problem with that is i dont want all the history
then delete the old giveaway messages
if i do a seperate post for each giveaway, they can auto archive
plus its much easier for someone to come in and see the lsit view of all the links (titles of each one)
scrolling through a single thread isnt great because you cant filter / sort, etc.
whats the proper way to create the channel?
async def create_channels():
channel_names = ["channel1", "channel2", "channel3"]
tags = [discord.ForumTag(name=tag, emoji=emoji) for tag, emoji in zip(["freebies", "promos", "giveaways"], ["🎰", "💰", "🏆"])]
guild = await get_or_fetch(bot, "guild", GUILD_ID)
for name in channel_names:
# Check if the channel already exists
if not await find_channel_by_name(name):
# Create the forum channel
forum_channel = await guild.create_text_channel(
name=name,
topic="Discuss topics here!",
type=discord.ChannelType.forum,
# default_thread_auto_archive_duration=1, # 1 day
# default_sort_order=0, # Sort by creation time
)
# Update tags after the channel is created
await forum_channel.edit(available_tags=tags)
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
i have no idea where you got that type= kwarg from lol
ah yeah that did it
I have a stupid, basic question. Files that are uploaded through discord.Attachment are binary. Say that's a CSV; what's the best way to read that as text? I thought I could just throw it at csv.DictReader, but it also doesn't like that it's binary
Seems one way I can do this is through codecs.StreamReader
if you have a string, io.StringIO works
the general point is you can upload anything as long as you have a valid method of converting it to bytes
Well discord.Attachment.to_file is always BytesIO? Or are you saying I can directly convert it to StringIO? (A brief search didn't immediately come up with ways to do that)
ohh wait, i thought you meant to upload a csv
no no, accessing an uploaded csv
if it's from an attachment to work as csv hmmmm
if you want to be lazy you could just save the file
otherwise your library will probably have a way to load a csv from bytes?
typically open methods also allow you to pass bytes you got from read
This worked for me. With attachment as discord.Attachment:
file = await attachment.to_file()
stream_reader = codecs.getreader('utf-8')
wrapper = stream_reader(file.fp)
csv_reader = csv.reader(wrapper)
header = next(csv_reader)
for row in csv_reader:
...
(I know I can use DictReader, but I want to ensure the headers are correct)
Sadly the built-in csv library does not
why are you using to_file > file.fp
What else would I be using? discord.Attachment has a to_file which returns a discord.File object. Within that is fp, which is the BytesIO instance
I don't want BytesIO, I want StringIO.
read() just turns it into a flat text file, I can't iterate through that with the csv lib
then pipe the text back into stringio?
S..ure, but then it becomes no different than what I'm doing lol. 🙂
well.. bytesio and stringio handle different things
I know. What I'm doing is taking the BytesIO and using the StreamReader to convert it to StringIO. You're taking the text and stuffing it into StringIO. Is there a specific performance implication I'm missing?
i'm probably just missing the point, ignore me if your flow works
The point is simply to be able to use the csv module, which requires a file pointer or a buffer. We're both migrating the buffers, just taking different paths. .read() converts the BytesIO into a string where you suggested to stuff it back into StringIO; codecs seems to simply convert it.
hex or gtfo
I am trying to change an member nickname by doign the code:
async def replace_username(self, member: discord.Member, to_replace_regex: str, replace_str: str) -> bool:
nickname = member.nick
if nickname is not None:
nickname = re.sub(to_replace_regex, replace_str, nickname.strip())
if nickname != member.nick:
await member.edit(nick=nickname)
return True
return False
When running I am getting an embed error:
I check the permissions, the bot have Permissions.manage_nicknames. Just to be sure I also tried with the bot with admin permissions
also tried with bypass_verification=True, tried also with await ctx.defer(ephemeral=True) and ephemeral=False
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
Anybody know what could be the cause ?
oh never mind, there is some custom global error handler I did long ago
just found it 😄
can i use something like https://discohook.org/ to make a format in which i want to give information out with instead of the add_field thingy
but still, I get forbidden even tho the bot have admin permissions:
Application Command raised an exception: Forbidden: 403 Forbidden (error code: 50013): Missing Permissions
Can anyone point me to the proper way to parse an embeds fields?
getting None when trying to print out the fields
async def find_existing_thread(channel, link):
for thread in channel.threads:
first_message = await thread.fetch_message(thread.id)
if first_message.embeds:
embed = first_message.embeds[0]
embed_dict = embed.to_dict()
claim_field = next((field for field in embed_dict.get("fields", []) if field["name"].lower() == "claim"), None)
print(claim_field)
if claim_field and claim_field["value"].lower() == f"[click here]({link})".lower():
logger.info(f"Found existing thread with matching claim link: {claim_field['value']}")
return thread
return None
What?
can i use discohook to make good looking messages to be given out on command
Is there any reason you're making the embed a dict?
instead of using add_field
I don't get the relation between discohook and add_field
They're quite literally two different things
whats the difference
just got it working - not sure how else to get the fields?
can u show me what u got
or how u fixed it *
was referring to my post above not yours sorry
Just iterate over embed.fields (without it being a dict)
i know
discohook is to create messages and send them through webhooks...
add_field is a method to a field to an Embed object...
Not sure what you're even trying to do
got it thanks
```Python
async def find_existing_thread(channel, link):
for thread in channel.threads:
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(f"Found existing thread with matching claim link.")
return thread
return None
trying to make my output look better than the {} i previously been putting out
Huh? What {}?
i got a json file in which i got information and i just parse it from there and print it out
OK and
God now I'm even more confused why you wanted to use discohook and the relation with add_field
thought that theres maybe a way that lets me use discohook
idek if i can copy the message from the website i just remembered it existed
cause im unsure about how add_field works and it wouldve made it easier prob
yea
It literally just takes two arguments
Did you even read the docs
.rtfm Embed.add_field
i didnt read the docs ive been watching yt videos
most of them are old so idrk if i can rely on them tbh
So you've been blindly copying code
yeah no
its different bots they were making
mb og
i tried making a embed once
i dont think i did it correctly
look at it 1sec
async def embed(Name, id, HP, Type_1, Type_2, Total, Attack, Defense):
discord.Embed(
title = f"{Name}:",
description = f"Information about {Name}:",
color= discord.Color.red
)
embed.add_field(name=f"ID of {Name}", value={id}, inline = False)
embed.add_field(name="Type 1:", value={Type_1}, inline = False)
embed.add_field(name="Type 2:", value={Type_2}, inline = True)
embed.add_field(name="The Total Stats:", value={Total}, inline = False)
embed.add_field(name=f"Healthpoints:", value={HP}, inline = True)
embed.add_field(name=f"Attackpoints:", value={Attack}, inline = True)
embed.add_field(name=f"Defencepoints:", value={Defense}, inline = True)
You're overriding your own method with the variable
That's gonna give you some issues
And you're not assigning your discord.Embed to any variable?...
can u explain what u meant before
You're literally plain slapping a discord.Embed but not in any variable
Rename your function.
yeah i didnt know how i got it running ngl
i should read docs
💔
async def create_embed(...):
embed = discord.Embed(...)
....
Yes OK congrats
🥳
Now you need to return the embed...
how can i use the embed in a context though
Do you know python?
You don't know how to use your own function?..
im not here for getting bashed fr
my_awesome_embed = await create_embed(...)
Girl you're expected to have python knowledge.
This is basic python, not nasa calculus.
I don't know what else you want me to explain.
async def create_embed(...):
embed = discord.Embed(...)
....
return embed
In whatever context you use it like that
If you say so
In slash commands for arguments can you have more than 25 choices from the dropdown menu?
only with autocomplete
do i just pass autocomplete = True?
no, read the docs
could someone please help me out with the proper way to have the bot do something on reaction?
This section outlines the different types of events listened by Client. There are 3 ways to register an event, the first way is through the use of Client.event(). The second way is through subclass...
I'm trying to watch for reaction on thread specifically and change tag accordingly
is this the proper way?
@bot.event
async def on_reaction_add(reaction: discord.Reaction, user: discord.User):
print(reaction)
not seeing anything
if thats in a cog, you need to use a listener
well, what are your intents first of all
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
guilds is part of default intents
ok but i have all of them i believe?
well looks fine to me
did you restart your bot, and did you make sure it has access to whatever you are reacting to
yes because the post is from the bot itself
This section outlines the different types of events listened by Client. There are 3 ways to register an event, the first way is through the use of Client.event(). The second way is through subclass...
oh does it matter if its the default emoji on threads?
Some classes are just there to be data containers, this lists them. Unlike models you are allowed to create most of these yourself, even if they can also be used to hold attributes. Nearly all clas...
yep this one worked
yea then your bot somehow doesnt have that message cached
part of default intents
It might be that message intent is required but its not documented but not sure
so should i be using the raw reaction add though?
I mean you can use either but if the normal one doesnt work (because your bot doesnt have that message cached, somehow) then you gotta use the raw one
or try to see if adding message intents fixes it, that'd be my only guess rn
hmm adding the intent didnt solve it
i fixed, (but it took me extra 10 min to realise that i placed the function outside class
How can i edit the tags directly on a thread post?
is this not possible?! https://guide.pycord.dev/popular-topics/threads#editing-threads
Threads with Pycord
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
Is there a way to get a list of messages in a channel that have been edited since a given time?
get all messages and check https://docs.pycord.dev/en/stable/api/models.html#discord.Message.edited_at
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
Still a little stuck on this... for some reason its not letting me grab the available_tags?
@bot.event
async def on_raw_reaction_add(payload: discord.RawReactionActionEvent):
if isinstance(await bot.fetch_channel(payload.channel_id), discord.Thread) and str(payload.emoji) == "✅":
thread = await bot.fetch_channel(payload.channel_id)
message = await thread.fetch_message(payload.message_id)
total_checks = sum(r.count for r in message.reactions if str(r.emoji) == "✅")
# Proceed if there are enough checks
if total_checks > 0:
channel = bot.get_channel(payload.channel_id)
applied_tags = thread.applied_tags # Applied tags on the thread
verified_tag = discord.utils.get(channel.available_tags, name="Verified")
not_verified_tag = discord.utils.get(channel.available_tags, name="Not Verified")
# If "Not Verified" tag exists, remove it, and add "Verified" tag
if not_verified_tag:
applied_tags.remove(not_verified_tag) # Remove the "Not Verified" tag
if not verified_tag:
applied_tags.append(verified_tag) # Add the "Verified" tag
# Update the thread with the new tags
await thread.edit(applied_tags=applied_tags)
Traceback (most recent call last):
File "/Users/ethan/Python Projects/EliteSweeps/.venv/lib/python3.12/site-packages/discord/client.py", line 412, in _run_event
await coro(*args, **kwargs)
File "/Users/ethan/Python Projects/EliteSweeps/main.py", line 171, in on_raw_reaction_add
verified_tag = discord.utils.get(channel.available_tags, name="Verified")
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Thread' object has no attribute 'available_tags'
does the post have any tags
yes because when i print applied tags i see them
i dont know why i cant get the available tags fromt his
verified_tag = discord.utils.get(channel.available_tags, name="Verified")
oh, yea, i misread
Thread.available_tags isnt a thing
the forum channel has it
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
oh?
docs help
yeah sorry i struggle with the docs on where i need to look 😅
oh wait i guess because the channel in this scenario is actaully the forum?
i was confusing the actual thread with the channel
i.e. this channel = bot.fetch_channel(payload.channel_id) is returning the thread, not the forum
yea, and the error tells you that too
yeah kinda confusing that its still called channel
also, you shouldn't fetch 3 things every single time a reaction is added
use the cache and only fetch when needed
yeah that was my next question, how i could do this in a much better way hahah
Models are classes that are received from Discord and are not meant to be created by the user of the library. Attributes key, url. Methods def is_animated, async read, def replace, async save, def ...
Retrieving thousands of messages and looking for changes in when they were edited seems awfully heavyweight. Is that truly the most efficient way?
This section outlines the different types of events listened by Client. There are 3 ways to register an event, the first way is through the use of Client.event(). The second way is through subclass...
Yeah, that I'm already doing. Just want to pick up any changes that might have happened while the bot was offline. Guess there's not a good way to handle that.
Isn't there also on_raw_message_edit for messages that may not be cached by the bot any longer?
then no shot beside going through all messages you missed
That's a heavy requirement.
Long story, but the short form is that I support a music streamer that uses a discord channel for keeping notes about various songs he's learned live on his streams, and I have a bot that goes back and does a bunch of indexing on them and a few other things... but sometimes we discover that something we did in the past has, for example, a non-normalized name for a song, which we eventually go back and correct. That kind of thing.
(you could argue that using discord as a storage for this kind of thing is broken, but I have no control over that)
The reality is the bot will almost always be online and really shouldn't miss edit events, but I am a paranoid bitch that likes to do things correctly rather than "it'll usually work [until something unexpected happens]"
i mean how many messages are in that channel
i doubt itll be thousands
for the rare case that the bot goes off you can just slowly iterate through all messages to "catch up" if you missed anything, on startup
well if you have a loop task that writes uptime to a db or whatever, then the bot goes online, it checks the last time it was online, and rechecks the messages in that timeframe only
that shouldn't be too heavy of an api load
especially if it's only down for short times.
why would it not ?
since any message from whenever could be updated in the downtime
yeah but you can have a reasonable buffer ig
my solution is the only possible one that doesnt miss any edits 100%
yeah makes sense
and if you do it slowly so you dont exhaust any ratelimit you can get it done in a few mins depending on how many messages there are
Currently about 11,000

Fortunately we don't really go back and update things often so it shouldn't be a huge ideal to just cope with the bot missing things when the stars align perfectly for allowing it to happen.
should I go python for discord bots, or a different lang
You use whatever language you're most comfortable with
People have a weird thing of calling languages better than other ones.
Again, you use whatever you prefer
well im comfortable with jetbrain IDEs and one of them is pycharm
any recommended plugins if you use it?
I don't use pycharm
I have no idea what you're asking
im trying to use the code in the guide, but it won't run
Excited to create your first bot? Once you install Pycord, you can start right
God what's with people and being vague these days. We can't read minds.
import os # default module
from dotenv import load_dotenv
load_dotenv() # load all the variables from the env file
bot = discord.Bot()
@bot.event
async def on_ready():
print(f"{bot.user} is ready and online!")
@bot.slash_command(name="hello", description="Say hello to the bot")
async def hello(ctx: discord.ApplicationContext):
await ctx.respond("Hey!")
bot.run(os.getenv('TOKEN')) # run the bot with the token```
@safe quarry
Traceback (most recent call last):
File "c:\Development\PyCharm\Python Projects\Eterneon\eterneon.py", line 1, in <module>
import discord
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\__init__.py", line 27, in <module>
from . import abc, opus, sinks, ui, utils
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\abc.py", line 58, in <module>
from .voice_client import VoiceClient, VoiceProtocol
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\voice_client.py", line 55, in <module>
from .player import AudioPlayer, AudioSource
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\player.py", line 29, in <module>
import audioop
ModuleNotFoundError: No module named 'audioop'
PS C:\Development\PyCharm\Python Projects> & C:/Users/EternalHell/AppData/Local/Programs/Python/Python313/python.exe "c:/Development/PyCharm/Python Projects/Eterneon/eterneon.py"
Traceback (most recent call last):
ckages\discord\__init__.py", line 27, in <module>
from . import abc, opus, sinks, ui, utils
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\abc.py", line 58, in <module>
from .voice_client import VoiceClient, VoiceProtocol
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\voice_client.py", line 55, in <module>
from .player import AudioPlayer, AudioSource
File "C:\Users\EternalHell\AppData\Local\Programs\Python\Python313\Lib\site-packages\discord\player.py", line 29, in <module>
import audioop
ModuleNotFoundError: No module named 'audioop'```
You're using python 3.13, audioop was removed as a standard library.
Downgrade or install audioop-lts
okay
@bot.event``` now im confused here? why is it saying theres an issue here when its the exact same on the guide
What's the error
TypeError: Client.event() missing 1 required positional argument: 'coro'
missed that part
note we don't officially support 3.13 yet, i'd recommend 3.12 or below for now
on changing the code of a discord view, the views that were before the code change no longer work right
highly depends on what exactly you changed
it was a very minute change, i didnt expect it to break the old views
is it possible to make the old views work again? be it through changing the code back to original
on clicking a button, earlier it used to send an embed into another channel as a response, now instead of an embed it sends plaintext
views in general stop working if you restart the bot unless you make them persistent
,tag persistent
damn i forgor
yeah they're persistent
this
oh
yea that shouldn't break it
does it keep working on bot restart if you dont change anything?
Guessing views that have values passed onto their headers wont ever be persistent?
Feeling like thats the problem I have with the current view
what
think someone deleted a question on threads, the Guild.active_threads fetch function returns them in descending ID order but we cannot guarantee the same for cache (e.g. guild.threads, channel.threads)
i had posted the question then deleted it because i think i answered it myself... just called for thread in reversed(channel.threads): to get it newest to oldest
fair
but it sounds like youre saying its not always going to give me latest in doing this?
we do not sort cached threads at all
(i think?)
but if you fetch guild.active_threads, or synced threads when the bot starts up, discord should return them as newest to oldest
it could just be coincidence that i got the latest then, but to be safe what would be the proper way to fetch?
async def find_existing_thread(channel, link):
for thread in reversed(channel.threads):
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(f"Found existing thread with matching claim link.")
return thread
return None
i mean you can always use sorted with a lambda function
what is the attribute to sort it on?
id is easy enough
oh lower id are older im assuming?
so something like this?
async def find_existing_thread(channel, link):
for thread in sorted(channel.threads, key=lambda t: t.id, reverse=True): # Sort by ID descending
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
cool will test it out thanks!
i guess one pitfall, it's possible that the first message was deleted
but if you're working in a controlled environment where that doesn't happen then no need to worry i guess
the first message in each thread is a message posted by the bot - so it shoudlnt be
yeah this is custom bot for 1 server
seems to be working thanks again
allgood
One other question - i thought doing something like this would have the thread disappear after 24 hours? its seems like they are all still showing... What does "archive" mean on discord forums?
thread = await channel.create_thread(name=thread_name, embed=embed, applied_tags=tags, auto_archive_duration=1440)
it disappears in the sidebar
this option in thread/post settings
you mean like how this is showing?
mhm
well if you have it open it'll show regardless
but outside of that thread, it won't after the duration
yeah i gues i dont really get what that does because if i have a bot thats creating the threads anyway, it doesnt show there until someone "joins" it or types in the thread
what i was looking for was more just always only showing the last 24 hours of posts when they go to the forum
it only applies to threads you have joined yes
