#discord-bots

1 messages · Page 424 of 1

elfin torrent
#

I'm having a problem adding a context menu command to apps of my bot

#

Can somebody help me

gritty inlet
elfin torrent
#

Its not appearing at all

#

User install command

gritty inlet
gritty inlet
elfin torrent
gritty inlet
elfin torrent
elfin torrent
fast osprey
#

or just send it here

elfin torrent
unkempt canyonBOT
elfin torrent
#

@fast osprey

fast osprey
#

are you sure this file is being loaded at all? And how are you syncing?

elfin torrent
fast osprey
#

yes but how are you verifying that it's being loaded

elfin torrent
fast osprey
#

what is the code that does that

elfin torrent
fast osprey
#

well that's already a bad idea for a number of reasons

elfin torrent
#

Yea I know, but I learn

fast osprey
#

no you don't

#

llm's just lie

#

anyways, your console saying something got loaded doesn't mean it did, especially without us seeing that code

elfin torrent
#

In my vacation I'll def learn

fast osprey
#

(hint: putting a print statement in the setup of that extension will tell you far, far more accurately if it got loaded or not)

elfin torrent
# fast osprey (hint: putting a print statement in the `setup` of that extension will tell you ...
@bot.event
async def on_ready():
    if not hasattr(bot, 'synced'):  # Prevent re-syncing
        bot.synced = True
        print(f'Logged in as {bot.user}')
        print('Prefix: m! or M!')
        await load_cogs(bot)
        print('Status: Online')
        try:
            synced = await bot.tree.sync()
            print(f"Synced {len(synced)} slash commands:")
            for cmd in synced:
                print(f"- {cmd.name}")
        except Exception as e:
            print(f"Failed to sync slash commands: {e}")
fast osprey
#

on_ready isn't a place to do any setup. It fires repeatedly and randomly

elfin torrent
#

Wdym

fast osprey
#

wdym wdym

#

on_ready fires over and over again and randomly. Don't do setup in it

#

The code from load_cogs will also be helpful, as well as the output of that print statement in there

gritty inlet
#

I already told you why it's not loading it

#

Ah wait

#

I was wrong, didn't see the bottom line xd

#

I'd say use setup_hook inside a bot subclass instead of on_ready

#

Not for necessarily fixing this but generally

elfin torrent
elfin torrent
elfin torrent
# gritty inlet Can you show load_cogs

async def load_cogs(bot): for root, _, files in os.walk('./commands'): for file in files: if file.endswith('.py'): cog_path = os.path.join(root, file).replace("\\", "/") cog_name = cog_path.replace("/", ".")[2:-3] try: await bot.load_extension(cog_name) print(f'Loaded: {cog_name}') except Exception as e: print(f'Failed to load command {cog_name}: {type(e).__name__} - {e}')

gritty inlet
#

When you start the bot, does it print "Loaded: that command youre trying to load" ?

fast osprey
#

*the file/module

gritty inlet
#

Yeah

elfin torrent
#

There's no isse in loading probably

gritty inlet
#

This. Does it load that cog?

fast osprey
#

if you're syncing and that context menu isn't in the tree, then the probable issue here is you aren't loading the extension you think you are

elfin torrent
#

And its being loaded yea

fast osprey
#

which you are confirming how

elfin torrent
fast osprey
#

confirm the file you think you're loading actually is being loaded in that file

fast osprey
#

the file you think you're loading

elfin torrent
#

Crypto.fantom bal2

elfin torrent
fast osprey
#

it's not

#

that is a screenshot of a console

fast osprey
#

which, as I have told you multiple times, is not accurate

#

that entire loop is fucked

elfin torrent
fast osprey
#

The long term correct answer would be to use pkgutil, which is a built in utility made for finding modules instead of this hacky ass looping over the file system and splicing file names

elfin torrent
#

In setup yea?

fast osprey
#

The other possibility is you are loading the file you think you are, but not the version of it you think you are (ex it's not actually being saved properly)

elfin torrent
#

"Loaded Portfolio " in setup

fast osprey
#

and that's what you put into the setup of that extension?

elfin torrent
#

Do you think the problem is with user installation? Its user installable

fast osprey
#

right before you sync, can you print(bot.tree.get_commands(type=discord.AppCommandType.user))

#

it's not, at least you didn't flag it that way

elfin torrent
#

I want the command to appear here

fast osprey
#

the line before you call sync, wherever that is

elfin torrent
#

Ok

fast osprey
#

the obvious suspects have been eliminated and that file is getting loaded so something odd is going on

elfin torrent
#
@bot.event
async def on_ready():
    if not hasattr(bot, 'synced'):  # Prevent re-syncing
        bot.synced = True
        print(f'Logged in as {bot.user}')
        print('Prefix: m! or M!')
        await load_cogs(bot)
        print('Status: Online')
        try:
            synced = await bot.tree.sync()
           print(bot.tree.get_commands(type=discord.AppCommandType.user))
            print(f"Synced {len(synced)} slash commands:")
            for cmd in synced:
                print(f"- {cmd.name}")
        except Exception as e:
            print(f"Failed to sync slash commands: {e}")
elfin torrent
fast osprey
#

ideally before the sync but yes

#

this should print out the metadata on your context menu, if it doesn't then there's some issue with how you're adding it

fast osprey
#

Isn't Crypto Portfolio your context menu?

elfin torrent
fast osprey
#

so it is syncing

elfin torrent
#

Yea I showed that lomg before too😭

fast osprey
#

then what's the issue

elfin torrent
#

Maybe in portal or user installation

#

Crypto Portfolio command should be displayed here

fast osprey
#

things aren't user installable unless you tell the library to make them

elfin torrent
#

Didn't I?

fast osprey
#

where?

elfin torrent
#

Idk

#

I did add the app, and restarted

fast osprey
#

the command/context menu needs to be specifically labeled in code to be user install

elfin torrent
fast osprey
#

!d discord.app_commands.allowed_installs

unkempt canyonBOT
#

@discord.app_commands.allowed_installs(guilds=..., users=...)```
A decorator that indicates this command should be installed in certain contexts. Valid contexts are guilds and users.

This is **not** implemented as a [`check()`](https://discordpy.readthedocs.io/en/stable/interactions/api.html#discord.app_commands.check), and is instead verified by Discord server side.

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

you made a context menu. Nothing in that says to make it user install

elfin torrent
#

So what do I do now

#

I want to be able to use that command in anybody's dm

fast osprey
#

also setting the install is separate from setting the contexts it can be run in. You'll also want

#

!d discord.app_commands.allowed_contexts

unkempt canyonBOT
#

@discord.app_commands.allowed_contexts(guilds=..., dms=..., private_channels=...)```
A decorator that indicates this command can only be used in certain contexts. Valid contexts are guilds, DMs and private channels.

This is **not** implemented as a [`check()`](https://discordpy.readthedocs.io/en/stable/interactions/api.html#discord.app_commands.check), and is instead verified by Discord server side.

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

There are 2 files
fantom bal and fantom bal2
the first file is command based 2nd one I wanted as an application

fast osprey
#

you use the two decorators I linked to modify the allowed installation and run contexts of individual commands

#

this is done on top of the command in question

elfin torrent
#

What else?

fast osprey
#

can you show where you put it?

elfin torrent
fast osprey
#

show that full code please

fast osprey
#

looks fine, save + reload + sync + refresh your discord client

elfin torrent
#

Did

fast osprey
#

and?

elfin torrent
fast osprey
#

how are you refreshing your discord client?

#

you will also need to install it now that you've made it user install

elfin torrent
fast osprey
#

how

fast osprey
#

...how are your other commands user install if you didn't know what the decorator was

elfin torrent
#

This isn't

fast osprey
#

That doesn't matter

#

at least in discord.py, nothing will be user installable unless you specifically flag it as such

elfin torrent
#

They only showed in that server application

#

Anyways what do i do now

fast osprey
#

Have you enabled user installs in the dev portal?

fast osprey
#

I just went through this exact flow and it works fine for me with a hard refresh

fast osprey
fast osprey
#

Essentially

elfin torrent
#

Can u try using it in my dms

fast osprey
#

I'd rather not

elfin torrent
#

Why?

fast osprey
#

I don't dm randos

elfin torrent
#

Dm any bot and send ss

fast osprey
#

I made a context menu, I set the allowed installs, I synced, I did a hard refresh on my discord, I installed my app with the user install link and the context menu showed up

elfin torrent
#

Nice, so what do i do now

#

Hard refresh but how

fast osprey
#

Mobile or desktop?

#

And also are you trying to run the context menu or just looking at the bot profile?

elfin torrent
#

I don't have pc/desktop :c

elfin torrent
fast osprey
#

I'd rather not

elfin torrent
#

Ah ok

elfin torrent
fast osprey
#

Have you tried running it on a user?

#

It works btw

elfin torrent
glass skiff
glass skiff
elfin torrent
glass skiff
elfin torrent
elfin torrent
glass skiff
#

Termux/vsvode

#

Mt manager?

elfin torrent
glass skiff
#

Ok

elfin torrent
elfin torrent
#

@gritty inlet

gritty inlet
#

?

elfin torrent
gritty inlet
#
bot = AutoShardedBot(
    command_prefix=[],
    intents=intents,
    allowed_contexts=discord.app_commands.AppCommandContext(dm_channel=True, guild=True, private_channel=True)
)

Just noting, you can do this to have all commands user installed by default

elfin torrent
gritty inlet
#

Also why'd you uncheck guild install

#

Unless that's really intentional

gritty inlet
elfin torrent
gritty inlet
#

Just make sure you're using the decorator right

elfin torrent
#

Yea

elfin torrent
gritty inlet
#
@app_commands.allowed_installs(guilds=True, users=True)
@app_commands.allowed_contexts(guilds=True, dms=True, private_channels=True)

allowed_installs is not needed if you have it checked on the dev portal I believe

elfin torrent
#

Does it matter

gritty inlet
# elfin torrent .

If you've done this, added the command (check your logs), synced properly (not for specific guild. check your logs on that too), then it should work

gritty inlet
#

Just the second one

elfin torrent
gritty inlet
#

Just letting you know, those will not appear on the command menu

#

That's why you don't see them there

elfin torrent
#

Damn 💀

elfin torrent
gritty inlet
#

Yeah you can do that there too

#

Go to a user's profile, click 3 dots -> Apps

elfin torrent
gritty inlet
#

You're welcome

young dagger
#

I thought this was never ideal

#

They’ve been doing this for a long time

#

I thought you should never do this kind of stuff during on ready

gritty inlet
#

Maybe cuz I was on mobile

fast osprey
#

at least some of this appears to be a misuse of on_ready, yes

dense swan
#

guys i got a roblox discrd server who is a discord bot dev so i can support them by using their bots?

#

dm me if its u

fast osprey
#

this place is for helping people build bots, not to advertise your server

dense swan
fast osprey
#

You aren't asking a question related to bot development in python

scarlet tiger
fast osprey
#

There are loads of good communities for sharing servers and engaging bot owners more broadly, or the popular bot list sites depending on what kind of bot you're looking for

gritty inlet
#

Today I learned dpy already has .waveform and .duration for Attachment
And for some reason they feel the need to convert waveform from b64 to bytes object so I followed that

#

But this is inside File

glass skiff
#

Guys can you help me to add ai to my discord bot when I'm in Termux on android

gritty inlet
#

But it's really easy to add voice message support

gritty inlet
gritty inlet
fast osprey
#

LLM and AI are not interchangeable terms

gritty inlet
#

Social media makes the term lose its meaning

fast osprey
#

Sadly so

elfin torrent
#

How Can i use these seperaters/dividers?

scarlet tiger
# elfin torrent How Can i use these seperaters/dividers?
GitHub

An API wrapper for Discord written in Python. Contribute to Rapptz/discord.py development by creating an account on GitHub.

GitHub

Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python - Pycord-Development/pycord

#

I don't see any examples in Nextcord's repository, I think.

fast osprey
#

in dpy, the component is discord.ui.Separator you'd add to your view/container

elfin torrent
#

Thanks

full mango
#

I think there's a problem with pypi.org, is it happening with everyone?

full mango
# finite salmon What problem?
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.HTTPSConnection object at 0x00000175BAD8DA90>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/disnake/
#

Everytime I try to install a package it just returns this

#

I've also tried to go to the website but it still fails

finite salmon
#

There's something wrong in your Network blocking pypi

#

Try reconnecting to your wifi or restart ur wifi

full mango
#

okay

finite salmon
#

Check your firewall too

full mango
#

Okay

finite salmon
elfin torrent
#

Hey I'm not able to complete ID verification for discord bot can someone help?

finite salmon
#

What id verification?

elfin torrent
#

I gave id front and back, it accepted and then redirected to dev portal page but still isn't verified

elfin torrent
finite salmon
#

This isn't discord support, you will have to mail them

#

This is a community channel to help with bot development

elfin torrent
finite salmon
#

We can't do much either

#

Bro nerd reacted me

elfin torrent
#

How can my bot get "uses automod" badge?

#

And Is it possible for my bot to have animated profile pic? Because I saw some bots have it

woeful hill
#

go to dev portal and upload a gif file as its pfp

timber dragon
#

Can only be done via the api

gritty inlet
hexed fiber
#

can someone tell me the system to make this type of discord bot's embed response but without the embed vertical color (i actually want that box thingy as response instead of embed)

timber dragon
#

Container (
TextDisplay,
Separator,
Section (
TextDisplay,
accessory=Thumbnail
),
TextDisplay,
Separator,
ActionRow (
Select
)
)

To be precise

hexed fiber
timber dragon
#

Not if your library supports it

timber dragon
hexed fiber
timber dragon
hexed fiber
timber dragon
#

Where did you get that from..

#

AI doesn't know about any of it

hexed fiber
timber dragon
#

Because that's not a thing

hexed fiber
hexed fiber
#

tysm for your help manh

#

@timber dragon

timber dragon
#

Nice

gritty inlet
green sorrel
#

Anyone can help me?

calm vector
green sorrel
#

How do i start making my own bot with ai?

calm vector
#

before trying to integrate AI into it, I would start by making a bot with a couple basic commands, just to confirm that you have things set up correctly. The commands do not need to be useful.

green sorrel
#

I want a bot thats helps my server. To set up my prices

#

For example in a server they have command when i write $ltc i get ltc exact price

calm vector
#

that's not AI, just so you know

fast osprey
#

is the question here that you want to make a bot which incorporates some kind of AI workflow, or you want to use a (shitty) LLM to make the bot in the first place

calm vector
viral sand
#

I'm thinking to host my discord bot in Glitch is it good?

fast osprey
#

It's shutting down?

viral sand
fast osprey
celest pelican
#

This is the second time Glitch shut down 😢

#

(different Glitch)

knotty ivy
#

@hexed fiber

hexed fiber
knotty ivy
hexed fiber
surreal rover
#

who else hates using classes

timber dragon
#

Great start of 2026

#

We hating on OOP now huh

glass skiff
#

2026 and next year is 2027 67

#

😭

sonic siren
fast osprey
#

Spoiler alert, it's all classes whether you think you're using them or not

velvet relic
fast osprey
#

You shouldn't be making both a client and bot

velvet relic
#

then how do I get the bot to read messages? all the guides I found online use client for that

fast osprey
#

Bot is a subclass of Client

#

You only need to pick one

velvet relic
#

ah so I can just do bot.event instead of client.event?

fast osprey
#

You should get rid of one of them entirely

velvet relic
#

if on_message will work for bot I can get rid of client

#

cool I think that'll do it, thanks

fast osprey
#

Yeah Bot is a subclass so it has everything Client does

#

Also dpy doesnt really work at all without the guilds intent

velvet relic
#

wdym?

fast osprey
#

wdym wdym

velvet relic
#

the ping command works fine

#

what do I need guilds intent for?

fast osprey
#

Well you won't have any guild metadata at all which most bots rely on, but if you don't you don't

velvet relic
#

oh yeah I don't need that in this case

vast comet
#

I have a question that might not be possible. I'm using discord.py . Is there any way to only show this bot message to the person who said that bad word?
I've seen online that the only way to do that would be to use a / command, but then it wouldn't be automatic. I thought I have seen other bots do this.

@bot.event
async def on_message(message):
if message.author == bot.user:
return

if "shit" in message.content.lower():
    print("message should be deleting")
    await message.delete()
    await message.channel.send(f"{message.author.mention}, Please don't use these kind of words.")

await bot.process_commands(message)
#

I know a DM is an option, but I would really prefer it to be in the channel

fast osprey
#

just use the built in automod. No bot needed

vast comet
fast osprey
#

bots can only send ephemeral messages when the user specifically interacts with that bot, so if they're seeing something when they just send a normal message yeah it's automod

#

and yeah just checked you can set custom messages when they trigger a rule

latent jay
#
@updatesnippets.error
async def updatesnippets_error(ctx, error):
    if isinstance(error, discord.ext.commands.errors.MissingRequiredArgument):

If the missing requried argument is a File shouldn't this isinstance get called because currently I just still get the error in console

fast osprey
#

have you tried debugging what error is?

#

the library often wraps exceptions in multiple layers, or it could be not calling this at all

latent jay
#

so it should be?

if isinstance(error, discord.ext.commands.errors.MissingRequiredAttachment):
woeful hill
#

Try it and see

fast osprey
#

sounds good to me

#

you may want to consider making this an app (slash) command which has a native file upload

latent jay
#

I coulda swore I tried that

#

Okay I guess I did not haha it seems to work

hexed fiber
fringe ginkgo
#

Hello! Is it possible to create a Discord event using a Discord bot and, if so, does anyone have a good example of how they executed that without a web dashboard?

fast osprey
#

Like a scheduled event? All of the popular libraries should have a method for that. Depends on which you're using

fringe ginkgo
fast osprey
#

!d discord.Guild.create_scheduled_event

unkempt canyonBOT
#

await create_scheduled_event(*, name, start_time, entity_type=..., privacy_level=..., channel=..., location=..., end_time=..., description=..., image=..., reason=None)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Creates a scheduled event for the guild.

You must have [`manage_events`](https://discordpy.readthedocs.io/en/stable/api.html#discord.Permissions.manage_events) to do this...
fringe ginkgo
crude dirge
#

Anyone willing to help me stress test my bot

fast osprey
#

It's pretty unlikely that the difference from 1 to 2 people is going to uncover some meaningful optimization

crude dirge
#

I meant more like trying to break it

fast osprey
#

what would someone else do that you can't?

crude dirge
#

I've already optimized from 700+ lines to 400

#

Without loosing functionality

fast osprey
#

line number is meaningless

#

Probably what you're looking for is for someone to help identify edge/test cases, then you can test those yourself

fast osprey
#

Well, what does your bot do? How do users interact with it?

crude dirge
#

It is a weather bot and the interact using /weather (location) /forecast (Daily/Hourly) (Location) and /warnings (location) with more commands to come in the future

fast osprey
#

that's a fairly small surface area. could pretty much hit all of it by just calling those commands with both valid and invalid inputs and see what happens

tight blaze
#

Are there people that can make me a discord bot?

fast osprey
#

What effort have you put into it?

stark ingot
#

Yes, most of them will charge you though. And this server does not allow soliciting work so you would have to find someone on a different server or a platform like fiver

misty leaf
flat breach
#

What's your matter?

dapper ocean
#

Is there something like a transformer but for non-application commands?

My goal is to have smth like

@commands.command()
async def foo(ctx: Context, card: Transformer[Card, CardTransformer]) -> None: ...
#

or do I have to transform the card value from str in the body of the command?

fast osprey
#

Converter

dapper ocean
#

great

#

ty

abstract hedge
#

!d help

spare cargo
#

Can someone help me?

stark ingot
#

Only if you state what you need help with

#
JKHub

Sometimes you have a question and want an answer but don't want to be direct. We get it. If you're new, it can be intimidating to ask for help. It's better to be direct and clear with your question right away, be clear about what you need as soon as possible. People are busy, attention spans are short, time is precious.

fast osprey
#

Oh haven't seen this one before it's good

gritty inlet
#

That and nohello

timber dragon
#

Huh interesting

safe onyx
#

hey where can i host my dc bot so its online 24/7

fast osprey
#

!hosting

unkempt canyonBOT
#
Discord Bot Hosting

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

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

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

static owl
#

Does anyone do bots here with anything else then python, I'm just wondering what to use rn. Ig python is prob the best

shrewd apex
#

there is discord.js

fast osprey
#

You're not going to get an unbiased opinion on the python community server 😂

young dagger
#

How can I make the embed transparent so it doesn’t break when the theme color changes?

#

The left bar in the embed is the same color as the background

woeful hill
#

those aint embeds tho

#

those are containers

young dagger
gritty inlet
#

Do embeds not change color when switching themes?

finite salmon
gritty inlet
finite salmon
gritty inlet
finite salmon
#

probably

woeful hill
#

yeah container default has no accent color

shrewd apex
spare pilot
#

Is already existing a bot to send a message to remind about an upcoming discord event? I know that you can welcome people when joining the server but I currently had to set a manual reminder to the event.

spare pilot
#

Exactly

gritty inlet
# spare pilot Exactly

First of all you can follow the channel in ddevs to have those messages forwarded to your server

#

As of a reminder, Idk

spare pilot
#

Sorry I meant an event like that, I usually create my own events

gritty inlet
#

When sending an event link, it has a button to remind you, no need for a bot

timber dragon
#

Yeah doesn't discord notify you about it when you're interested

spare pilot
#

yes, it could be a simple reminder if the events happen every time at the same time, but I need to check people's availability.

spare pilot
gritty inlet
fast osprey
#

Seems like a user notification setting issue

#

This would probably be pretty trivially easy to make on a bot but doesn't seem super needed

spare pilot
#

I'm also worried that using a bot could be an excessive solution. Currently it's just me creating a message with an everybody tag to remember to join the upcoming event

fast osprey
#

Sounds like it's just them not having their notifications set up properly, not something you have to do

gritty inlet
spare pilot
#

Yes, I know the notify button, but it came only at the same time as the event. I usually send the message a week earlier to present the event, and then about 30 minutes earlier, so people have some time to join

woeful hill
#

-# Well if they didn't care enough to have notifications turned on i wouldn't expect them to be there when the event comes

But if what you want is a bot that will send ping when you create an event so that you don't need to do it yourself, you can rely on auditlog

timber dragon
#

For?

#

You can just listen for the events

#

And then schedule your own thing for it

#

Scheduling an event for a scheduled event lol

woeful hill
#

Oh there is, i looked for on_ and didn't go down enough

spare pilot
#

sounds reasonable

#

thx

gritty inlet
#

I don't see the issue with people being notified on event start but hey do what you'd like

gritty inlet
#

Now I won't have to pass the type args PeepoGGERS2

shrewd apex
potent pelican
#

What are the best hosts for GB

#

<@&831776746206265384>

fast osprey
#

!hosting

unkempt canyonBOT
#
Discord Bot Hosting

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

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

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

potent pelican
#

need some for uk

fast osprey
#

why?

tender bobcat
#

In almost all cases it's fine to get hosting server at anywhere in the world
In some case you might want to put it in EU if possible due to gdpr

fast osprey
#

The location of the server isn't relevant for gdpr. It just matters if you're processing data of eu/uk citizens, then you're beholden to it

fast musk
#

I assume its best practice if you are having something that periodically sends info to a channel (from polling/scraping) its best to use a webhook?

#

The bot is pretty small, about 80 servers

#

the scraper itself is on the bot for now, so its fully authenticated. Just trying to understand if I even need to do a webhook or just channel.send them as they come in. Each guild would have to subscribe it to a channel

stark ingot
#

Webhooks are good for when you need to send unprompted information.

fast osprey
#

Are all servers getting the same updates?

fast musk
#

yes if subscribed

stark ingot
#

Then you could use an announcement channel and publish the messages. That is a built in discord feature

fast musk
#

oh. I guess thats new

#

heh. Its been a year or two 😄

#

oh wait I don't think I want that

#

they would have to come to a home discord server. I don't really have one

fast osprey
#

Takes about 5 minutes to make one

timber dragon
#

Users could even follow it via a command, don't need to be in the home server

potent pelican
#

I need a host thats good for the uk and does paypal

gritty inlet
#

Personally I'd look for a vps in the US if I'm doing only Discord bots

#

Just closer to the api servers lol

#

Rn I self host far far away from that and my ping is always around 150ms

fast osprey
#

again, why does it need to be uk

gritty inlet
#

Yeah no reason to be so specific

grave sandal
timber dragon
#

but chadgeyptie told me I need a UK one

vocal plover
#

top 10 uk based servers: the one in my staircase kek

potent pelican
#

Hostinger is way to hard note that

#

Don’t use it

fast osprey
#

Weird that you've dodged the question twice

fast musk
#

ok. I have deployed the feature. And yes, I did use an announcement channel 😄

#

I have yet to make a command to have it follow though heh. laziness

#

Thank you for the suggestion

#

also: dead chat daaang

naive trout
#

How should I start with discord bot development? I dont even know basic py so what courses/website should I use to learn.

unkempt canyonBOT
#
Resources

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

naive trout
#

Oh shoot! Ty lol, didnt see this was a thing

jolly geyser
#

hmm I discovered something interesting.
I was experimenting with discord user IDs and noticed that in one special calculation with my ID you will get 65536
I wondered if that works with other user IDs and didn't notice that same number.

((915693834829180989 >> 22)<<2) & 0x1f000

#

!e

print(((915693834829180989 >> 22)<<2) & 0x1f000)
unkempt canyonBOT
vocal plover
gritty inlet
jolly geyser
#

I know it's timestamp [internal worker id] [interal process id] [increment]

gritty inlet
#

I don't see the coincidence though, you just did a calculation that produces a number unique to your ID

jolly geyser
#

welp, I do see a coincidence because I personally like 2^16 (65536). it's a nice round number on base 2. and was surprised that I got that exact number from my own discord ID

hexed fiber
#

how can i make my discord bot works on everywhere everyone's dms?

vernal folio
#

In discord.py Even though i am using client.loop.create_task in order to run process separately, still says heart beat blocked...

data = await interaction.client.loop.create_task(async_function_name(**kwargs))

And i found this way on google, what do you guys think ?
-# I haven't tried this one yet.

async def run_blocking(blocking_func: typing.Callable, *args, **kwargs):
    """Runs a blocking function in a non-blocking way"""
    func = functools.partial(blocking_func, *args, **kwargs)
    return await client.loop.run_in_executor(None, func)
timber dragon
#

Well yeah making something async doesn't mean it won't block

#

You need to run it in a thread / executor
-# tbh I don't know a lot about async either

timber dragon
stark ingot
hexed fiber
stark ingot
#

Depends on the language and library you are using

#

I guess just library because you are probably using python

gritty inlet
#

Heartbeat will not be blocked if you run the async function with create_task (which is only for coroutines)

#

Heartbeat will be blocked if you run it on the same process, it being async is meaningless in this context

#

The benefit of awaiting is that it only blocks in its own "scope"

hexed fiber
gritty inlet
gritty inlet
#

Also go to the Developer Portal and toggle user install in your application's Installation page

vernal folio
gritty inlet
# hexed fiber ye ik that

And you can use @app_commands.allowed_contexts or .allowed_installs to implement command-specific behavior

gritty inlet
#

I mean not suitable for background tasks that should run forever

vernal folio
#

🤔

vernal folio
vernal folio
vernal folio
gritty inlet
#

The fact that to_thread returns something tells you it's not for infinite tasks

stark ingot
hexed fiber
vernal folio
gritty inlet
#

I'd like to see the context this is used in

#

If it's ok

vernal folio
# gritty inlet async_func_name? to_thread is for synchronous functions

well can you please tell me how to handle that...

  • I have a asynchronous function which is a scraper...
  • It takes time to do stuff and return value
  • And i wanted to run that along with my bot ( right now it blocks heartbeat )
  • What should i do T_T
  • -# It would be good if it resolves for now, left of the time my priority is learning all related stuff to asyncio
gritty inlet
vernal folio
#

considering there should not be any zombie process

vernal folio
#

well i can remove it though...

gritty inlet
#

It depends what you're doing in that func

#

Just call it normally (with await) since it's async..

#

If that blocks your heartbeat it means there's blocking code inside that function, that's a different problem

vernal folio
#

i have an async func for reporting error to me
as its await client.fetch_user that's all for await, i will redirect the error to error_logger and put the error handler like this maybe -

try:
  data = asyncio.to_thread(async_func_name, **kwargs)
except Exception as e:
  await report_error(...)
gritty inlet
#

If you could show me its code I might be able to tell what's the problem in there

gritty inlet
#
async def scraper():
  thing = await other_thing(...)
  blocking_thing = other_blocking_thing(...)

# different context:
_ = await scraper() # heartbeat *will* be blocked because of other_blocking_thing(...)
vernal folio
gritty inlet
gritty inlet
#

Yuh

vernal folio
#

-# thinking...

gritty inlet
#

Correct:

async def scraper():
  thing = await other_thing(...)
  blocking_thing = await asyncio.to_thread(other_blocking_thing, ...)

# different context:
_ = await scraper() # heartbeat will not be blocked (:
vernal folio
#

the blocking this is not asynchronous for sure...

gritty inlet
#

Wdym

woeful hill
gritty inlet
#

Generally if you're curious
asyncio.to_thread:

  • Takes: Sync function, args, kwargs
  • Runs a synchronous function asynchronously in a different thread
    asyncio.run:
  • Takes: Coroutine (an async function called without await but with ())
  • Runs an asynchronous function in a synchronous context
vernal folio
#
# Creating chrome options
chrome_options = Options()

# Enabling headless mode of chrome
chrome_options.add_argument("--headless=new")  # for Chrome >= 109

# Logging.
print(f'[ {process} ongoing ] Chrome Option Initialized.')
debug_logger.debug(f'[ {process} ongoing ] Chrome Option Initialized.')

try:
    driver = webdriver.Chrome(options=chrome_options)

    # Logging.
    print(f'[ {process} ongoing ] Connected to Chrome.')
    debug_logger.debug(f'[ {process} ongoing ] Connected to Chrome.')

    # Extracting page url associated with the name.
    page_url = client.info.get(name)

    # IF hero page url not found.
    if page_url is None:
        # Logging.
        print(f'[ {process} ongoing ] page_url is None for name : {name}.')
        debug_logger.debug(f'[ {process} ongoing ] page_url is None for name : {name}.')

        # Closing the browser.
        driver.quit()

        # Logging.
        print(f'[ {process} FAILED ] Chrome Connection Closed.')
        debug_logger.debug(f'[ {process} FAILED ] Chrome Connection Closed')

        # Sending error message.
        error_msg = f'Page Url Not Found For : {name}'
        await send_error(__file__, 'fetch_info(...)', error_msg, client)

        return None

    # IF hero page url found.
    else:
        # Logging.
        print(f'[ {process} ongoing ] Extracting info for {name}.')
        debug_logger.debug(f'[ {process} ongoing ] Extracting info for {name}.')

        # Fetching page through URL
        driver.get(page_url)
#

This is starting of the function, where it creates a connection to chrome driver for scraping

gritty inlet
#

driver.get(page_url) is sync, that'll block the heartbeat

#

Only that

vernal folio
#

and then it start scraping things ... like <div> <span>

gritty inlet
#

Fix:
Make the code above in an async function, then do

await asyncio.to_thread(driver.get, page_url)
#

And you'd probably need to do the same with page_url = client.info.get(name)

vernal folio
gritty inlet
#

Nah that's fine

#

find_element is fast

vernal folio
gritty inlet
vernal folio
#
client.info = {"yo": "bho!"}

that's it

gritty inlet
#

Yep

vernal folio
#

and why only that

#

what makes you think it blocks the heartbeat

#

u smart guy.. how how howw..!

gritty inlet
#

Because fetching a page typically takes long enough to block things

vernal folio
#

and if there is ... umm what we call

#

just a sec

gritty inlet
#

find_element only finds a string in a string so it's fast

vernal folio
#

what about this ?

# Wait for the `update time` div to be present.
WebDriverWait(driver, 10).until(
  EC.presence_of_element_located((By.CLASS_NAME, "time"))
)
gritty inlet
#

Why are you using that though

vernal folio
gritty inlet
#

Oh wait

#

Is it because you're waiting for the page to load?

vernal folio
gritty inlet
#

Ok. What does your function return when it returns anything?

#

The whole thing

#

Does it return at all?

vernal folio
#

a huge dictionary 🙂

#

and yeah it returns it

gritty inlet
#

Shall we switch to DMs? It's getting out of topic

vernal folio
#

yeah sure

glass mantle
#

does anyone have a good and not outdated website/free online book to learn how to make a client discord bot? (the ones with / commands)

vernal folio
glass mantle
stark ingot
#

Idk then, sorry

gritty inlet
#

Or is it only about slash commands

glass mantle
#

wdym framework

gritty inlet
#

Code*

glass mantle
#

well I know how to like create it in the discord developer portal and how to like put it online

gritty inlet
#

Again are you starting with discord.py from scratch now

fast osprey
#

the repo has examples

glass mantle
gritty inlet
broken fjord
#

can anyone help me with my discord auto mm bot theres alot of bugs idk how to fix

calm vector
broken fjord
finite salmon
unkempt canyonBOT
#

9. Do not offer or ask for paid work of any kind.

fast osprey
#

what even is auto mm Thonk

stark ingot
#

I believe auto middle man, most likely for crypto

fast osprey
#

ew

surreal rover
potent crown
#

need dev discord bot i buy ( Not much, 3 or 4 options (or more, we'll see).

woeful hill
potent crown
fast osprey
#

You can always learn and make it yourself :3

stark leaf
#

I am looking for devs dm me

fast osprey
#

Or you can ask your question here

weary bone
#

Would u say a bot token is faster at detecting changes or a user token

#

from what i heard bot token is the only way to automatically detect changes

#

But apparently user_tokens are much faster at detecting changes

fast osprey
#

Whether one is faster or not shouldn't really matter. It's not like you have a choice between the two

#

they are used for two completely disjoint purposes

#

If you are a human, you make a user account

#

if you are making automation, you make a bot

#

it's not a decision

weary bone
#

I see thanks

fast osprey
#

np prettythumbsup . You'll probably find that making a bot account will be perfectly fine for whatever your usecase is

gritty inlet
#

Now I see that the real name is there (chicle in this example) lol

#

Yet it still seems that the numbers representing the fonts do not go from 1 to 11

white lodge
#
intents = Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

@bot.event
async def on_ready():
    print("turned on")
    
bot.run(token, log_handler=handler, log_level=logging.DEBUG)

@bot.command()
async def test(ctx, arg):
    await ctx.send(arg)```
bot wont respond at all, no errors are coming up though
fast osprey
#

what do you mean by respond? what are you doing to try to get it to do something?

#

oh, your command is declared after the run

#

bot.run() is blocking, so anything after it won't be executed until you disconnect

young dagger
#

@fast osprey Do you know if the GDPR still applies when reviewing a recording of someone to determine moderation actions, even if the recording is deleted afterward?

#

(I know it's a bit off-topic, I just remembered we discussed this before)

fast osprey
#

GDPR always applies to processing of personal data, regardless of the intention

young dagger
young dagger
fast osprey
#

Define "recording"

young dagger
glass skiff
fast osprey
#

If the person being recorded is in a two party consent jurisdiction and they haven't consented, recording them is indeed illegal

young dagger
fast osprey
#

If someone sends you a file and you don't know what's in that file until you open it, that's a different story from "hey I recorded someone without their consent, wanna listen to it?"

young dagger
fast osprey
#

You should not suggest that people break the law, whether or not that itself is illegal

young dagger
fast osprey
#

I'm not in a position to give you legal advice but this is not something I would recommend flirting with on technicalities

young dagger
fast osprey
#

And it is possible that capturing that evidence would be illegal

#

so if this is something you care that strongly about, you should have a disclaimer that people have to consent to stating that they will be recorded

#

Otherwise their rights to privacy trump your desire to monitor

grave sandal
# fast osprey You should not suggest that people break the law, whether or not that itself is ...

I guess as a user that boils down to don't record people without their consent, and if you have to, which you don't, see: discord servers aren't authorities and they probably shouldn't be relying on your recordings. And as a discord server owner don't facilitate the transfer of content you shouldn't have. Bleh. I wouldn't want to deal with that though, 'this guy said the n word, here's proof in public chat' deletes evidence and pretends it never happened while it's spread round, or, oh I see, a lot of people here would agree you did the right thing but you're getting a temp ban because illegal, don't do it. Either way I want nothing to do with that situation 💀

young dagger
fast osprey
#

If you can reasonably prove that this person saw the disclaimer and consented, sure I guess. I don't know if it has to be in the call itself. But I personally am getting the hell out of a server that tells me they're going to record me, this is pretty invasive levels of control in the name of moderation

vocal plover
#

I run a server with 660k people, we have active voice channels that need frequent moderation. We do not record them.

#

It's not something you need to do for effective moderation, and I feel reasonably confident saying that if that works out at our scale it'll work out at the scale of the servers people here are discussing

vocal plover
#

this channel is unbelievable lol

#

I do need a discord bot, fortunately I am both a software engineer and the maintainer of a discord library, so I think I'm alright on my own lol

fast osprey
#

I think people can way overstate the importance of immediate, decisive moderation. Like one bad word needs to be punished with the fire of a thousand suns. It's really not a big deal, people can live with it, what actually needs to be addressed is repeated antisocial behavior which surfaces really clearly without the need for "evidence"

mighty pilot
#

Hey guys I am just getting back into dev stuff after moving a year ago. I have this bot that is giving me errors that it didnt used to give me.

I have it setup so that the user uses a drop down menu to select what they want to edit in the database, then the bot would wait for that user to send a message in the channel and it would use the message content.

This was accomplished by msg = await self.bot.wait_for('message', check=check)where check is making sure its the right user and channel

Now when this is used its telling me that my dropdown menu has no attribute 'bot'

Checking the documentation, this is correct, obviously, but it worked before. Is there a way to do this now or do I have to go back to the drawing board on this?

vocal plover
fast osprey
#

Eh I'm of the opinion that you can just boot people without needing to file form 836-B in triplicate and notorized. If you don't like em, kick em and if people don't like it they can leave

vocal plover
#

Me too, I wish it were so easy to convince others of it

fast osprey
#

Praying for you YotsubaPray

trim agate
mighty pilot
fast osprey
#

what object? What's the full traceback?

vocal plover
#

That's really not what this channel is for. Also, no, I add people who I know and who are my friends, not people who (incorrectly) think there's something about profile badges that makes me special.

mighty pilot
#

One sec I need to log back into discord on my laptop

vocal plover
#

being in the right place at the right time and doing some interesting things, but again, not what this channel is for

mighty pilot
trim agate
#

I want

fast osprey
# mighty pilot

What are you trying to accomplish, materially? IMO wait_for is just a really bad UX that can almost always be replaced with modals in 99% of cases

vocal plover
# trim agate I want

They're just meaningless pixels, except meaningless pixels where you get people harassing you to buy (read: scam you out of) your account. Discord badges are not a life goal, there's better stuff to aim for.

fast osprey
#

People who obsess about badges should really introspect and find better ways to accomplish things that are meaningful

trim agate
mighty pilot
fast osprey
#

Yeah in that case I'd really suggest responding to the dropdown with a modal so they can input what you want from them

#

much cleaner code wise and removes a reliance on message content

vocal plover
# trim agate How to get it can u tell me it's my dream

Find something else to want then, seriously dude they're not important, and I'm not important because of them. There's so many more worthwhile things to aim for in life. And besides, the two "special" badges I have are no longer obtainable anyway, so there's really no point wishing for them because they're not coming back

mighty pilot
#

i mean i could do that it was just a lot simpler at the time to wait for a message with one line of code vs a whole modal for one text box

fast osprey
# mighty pilot

the immediate problem is that your view doesn't have a bot attached to it. You can most likely replace that with interaction.client, which does attach the bot automatically to every interaction.

wait_for is much worse ux as it's not immediately clear to the user what you want them to do. You write the code for a modal once, and from that point forward it's just better for your users. It's really not that complicated

trim agate
mighty pilot
#

temporarily ill try the interaction.client but i will heed your advice and add a modal to it. not that much work but im just trying to get back to a functional code for now before i start improving it. making sure nothing else is broken

#

thanks

vocal plover
trim agate
fast osprey
#

"ban them from discord" wut

trim agate
#

And it can't be solved with a report him

fast osprey
#

You're not batman, just report them and move on with your life

timber dragon
#

I really doubt members of the trust and safety team can just willy nilly ban anyone they want lmfao

#

no such thing as a discord moderator fyi

mighty pilot
#

i cant find interaction_metadata in the docs

mighty pilot
#

wtf why didnt it come up with the search bar lol

finite salmon
#

yeah dpy docs search system really sucks

vocal plover
mighty pilot
#

it tells me to use interaction_metadata but theres no name attribute to the metadata

old flax
#

Hey guys! I'm 15 years old and I want to learn python on phone, suggest me some cool youtube courses from which I can learn

mighty pilot
#

and using pydroid

old flax
mighty pilot
#

try google

finite salmon
old flax
#

I have learned html
Css
Js
React

mighty pilot
#

I fear not the man who has practiced 10,000 kicks once, but I fear the man who has practiced one kick 10,000 times.

vocal plover
finite salmon
#

lol

old flax
mighty pilot
#

what about the elusive "jack of all trades, master of one"

old flax
#

I lose here

mighty pilot
#

lmao

#

it helped me get started in python. its a follow along style of book, i liked it

finite salmon
mighty pilot
#

theres more books after it. they cover everything from that to AI

finite salmon
unkempt canyonBOT
#
Resources

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

finite salmon
#

check this too for ton of resources

mighty pilot
#

oh yea i forgot about that

mighty pilot
old flax
mighty pilot
#

thats what i used

slate swan
finite salmon
#

You can still learn two languages side by side, but I'd discourage that if you're still new to programming though

slate swan
#

true that sounds right

timber dragon
#

discord doesn't want to expose that anymore

mighty pilot
# timber dragon indeed

so whats the new best method to accomplish this? its a simple bump reminder. it currently looks at the name of the interaction and if the name is bump it sets a timer for 2h and when the 2h is up it sends a message in the channel to remind people that they can bump again on disboard

fast osprey
#

You shouldn't be building your bot on top of unsupported, undocumented behavior of another bot

timber dragon
#

could check the response (author)

mighty pilot
mighty pilot
gritty inlet
#

Oh name of the command?

fast osprey
#

You are relying on them responding publicly and in a particular way

#

if this other bot wanted you to build on top of it, they would give you an actual stable api

gritty inlet
mighty pilot
#

you are not wrong. and they may change it in the future. just one step easier than sending a second command every time

gritty inlet
mighty pilot
fast osprey
#

You're more than welcome to do this but you should at the very minimum contact that bot and ask them if/how they want you interfacing with their bot

#

then respect their wishes

gritty inlet
#

Yeah I see, well one day you'll probably not have the deprecated one at all

mighty pilot
#

it doesnt interface with their bot at all. it watches interactions on discord and if someone uses any interaction called bump then it sets a timer and sends a message in a channel

gritty inlet
#

So yuh you should not do that if it means using a deprecated field thumbsup

mighty pilot
#

i agree. im starting up a bot that i made over a year ago and going through all the little things that have changed and fixing them

fast osprey
#

You listening for a bot doing something in particular in a particular way is interfacing with it

mighty pilot
#

i will check again but last i checked they dont prohibit timers only auto-bumpers

fast osprey
gritty inlet
#

I don't see the problem with doing this, it's just that the info is no longer meant to be used

mighty pilot
#

disboard bumping

#

server listing board that allows you to bump your server on their list every 2h to show activity

gritty inlet
#

It got approved hape hape

fast osprey
#

You lose absolutely nothing from sending a 5 minute email to them telling what you intend to do and asking if that behavior in their bot is stable or if there's something else you can use

#

but you do you

fast osprey
#

I never said this was against their guidelines

mighty pilot
#

so why would they care ? im confused as to what you are trying to say ig. i thought you were trying to say they would disapprove of what i was doing

mighty pilot
#

if it breaks it breaks its not a public use bot

fast osprey
#

I'm suggesting a 5 minute courtesy email to them and you're pushing back for some reason

mighty pilot
#

ok

stark ingot
#

See revised message below
I don't get why you would need to let them know. "Oh btw my bot can see the messages that your bot sends, as well as every other user in my server"

fast osprey
#

Reading what I said would be a good start, particularly the lack of ever saying they need to do this

stark ingot
fast osprey
#

I don't see how the repeated and consistent usage of "should" would remotely imply anything resembling a "need"

#

This isn't a compliance issue so much as building on top of a rocky foundation that can collapse under you which can be avoided with a 5 minute email

stark ingot
#

Fine let me reword my message then instead of arguing about stupid semantics

#

I don't get why you should let them know. "Oh btw my bot can see the messages that your bot sends, as well as every other user in my server"

fast osprey
stark ingot
#

Then what are you suggesting

fast osprey
#

sending a 5 minute email to them telling what you intend to do and asking if that behavior in their bot is stable or if there's something else you can use

#

If it's a one email exchange of "yeah that command will keep sending public responses and we don't intend on changing or introducing a proper api, go nuts" then that's pretty cut-and-dry. If they say "no that command isn't supported and likely to change, here's an API to use" that's a pretty relevant thing to know before investing your time to build something

mighty pilot
#

i invested all 5 lines into it. its not that big of a deal if they stop using it. however, they have had a supported command in discord to bump since 2017 with text commands

young dagger
fast osprey
#

You don't need truth. This isn't a court of law

#

just do whatever

young dagger
fast osprey
#

then don't punish them

young dagger
fast osprey
#

then you have someone join and if it's a repeated behavior you do something

#

again, it's not the end of the world if someone says a bad word once

stark ingot
#

Or beerhunter can develop a bot that fits the needs of their community and is inline with their moderation principles

fast osprey
#

what we were saying is that seeing this as a need is fundamentally misguided

#

objectively they can do whatever they'd like with the informed consent of their users (and proper storage protocols), subjectively a lot of people would be very put off by a chat community telling them it'll record their speech

mighty pilot
#

if im trying to play an mp3 file i would use discord.FFmpegPCMAudio('path/to/file.mp3') correct?

#
@app_commands.command()
async def play(interaction: discord.Interaction, channel: discord.VoiceChannel):
    speak = await channel.connect()
    await interaction.response.send_message(content= "connected")
    source = discord.FFmpegPCMAudio(mp3)
    speak.play(source)```
#

i dont know if its saying the ffmpeg program is not found? or its not finding the file at that destination? i feel like ive seen a dozen other examples showing basically the same thing but they worked for others

fast osprey
#

Yeah it's saying that it can't find your ffmpeg executable

vocal plover
mighty pilot
#

Got it figured out. specified the path to the exe in the arguments

stark ingot
fast osprey
mighty pilot
#

Idk, its in my path because when I type ffmpeg I get the help spam but the code wasnt triggering it. Luckily its an argument for the command though

trim agate
#

@vocal plover bro I want to ask you which type of perks you get in discord partner program and in discord moderation

stark ingot
# trim agate <@297045071457681409> bro I want to ask you which type of perks you get in disco...

Here are some links that might answer your questions. If they dont take a look and see if there are other articles in discords blog, or in the help center. There is no need to keep bugging people for things that are no longer relevant nor on topic for this channel.
https://support.discord.com/hc/en-us/articles/360035962891-Profile-Badges-101
https://discord.com/blog/announcing-the-discord-moderator-academy-exam

merry frost
#

Hi

#

I have to build discord bots

#

I know python till logics. Which tutorial will be good

fast osprey
#

Learn OOP/class design and async programming first if you haven't

stark ingot
merry frost
fast osprey
stark ingot
#

You really only need to know surface level about asyncio

gritty inlet
#

You wouldn't find yourself using much of the library

heavy peak
#

hi

#

how to make a py bot that works anywhere

stark ingot
#

Apps that work anywhere* are user installable apps. Do you have a library that you are using already?

#

*Some servers can force the responses to be ephemeral. And the bot can restrict the command to DMs group DMs or guilds if it wants

full lily
#

not sure about these slash commands

fast osprey
gritty inlet
fast osprey
#

Why does that matter if it affects you and knowledge is required?

gritty inlet
#

I don't see that being super necessary for making a Discord bot, ofc you'd need to know how async works in general but it doesn't have to be by using asyncio.something

fast osprey
#

You also interact with asyncio directly every time you call await

gritty inlet
#

By directly I mean using asyncio.thing

#

But alr

fast osprey
#

I'm not sure how one could consider await to be an indirect interaction when you're literally scheduling a task onto the event loop but that's pretty pointless semantics about what direct means I suppose

gritty inlet
#

From the point of view of the user I guess, whatever you'd wanna call it

sick birch
gritty inlet
#

Java

fast osprey
#

None of the dpy forks that's for sure. No idea what hikari does under the hood but I'd be surprised if it was thread based

#

Or yeah if you go to other languages that don't have good async support

gritty inlet
#

Would be kinda inconvenient to do that in Python

timber dragon
#

Are you 7 years out of date or did ai say that lol

gritty inlet
delicate flame
#

why are you rewriting discord.py? not questioning, just curious

#

um, ok? just asking from a curiosity standpoint, not a vindictive one

fast osprey
#

they aren't; there was a version of it that was called discord.py rewrite

open cobalt
#

If you have some time do make a little wrapper of your own. An easy one not too complicated.

delicate flame
#

heh, funny you say that. I have been! ScurryPy!

open cobalt
#

I have experimented and made a small one good practice

open cobalt
delicate flame
#

its a meme silly!

open cobalt
#

Ok I get it but this meme isnt funny at all

delicate flame
#

guess its not everyone's cup of tea?

open cobalt
delicate flame
#

also cat humor

gritty inlet
#

😭

grave sandal
#

This channel is really something

delicate flame
stark ingot
#

Also I am curious how about your design with the Cache AddOns. I see you use BotEmojisCacheAddon in this project, but I think there are a couple more

delicate flame
#

Before you ask, yes, I made classes I didn’t have a use for yet

vocal plover
delicate flame
#

I didnt know aiohttp has a ws_connect method

dusk pelican
#

No need for websocket aiohttp comes with it. All good we are here for learning !!

grave sandal
# delicate flame I didnt know aiohttp has a ws_connect method

Iirc I had an issue with aiohttp that resulted in me having to refactor certain code to use the websocket module directly. I think the issue might have been that once you place a timeout on one of the receive methods aiohttp will stop letting you read anything further. See the attached screenshot, basically if you ever want to set a timeout (and it happens to timeout) on your websocket and go back to it later in a loop, a cancellation error or timeout error will get raised (I forget), when that happens aiohttp freaks out and sets a close code, raises an exception, the generic exception handle is called, and that's when it sets it to closed and you can't read from the socket anymore. So if you ever want to use stuff like asyncio.timeout, or wait_for, etc, aiohttp is more limited. In addition to this, aiohttp doesn't conveniently document the exceptions the methods can raise so it's harder to integrate with, the websocket library makes it an explicit point to be better with that stuff. So I don't think using it is much of a mistake, but if you don't mind the slight inconvenience, and not being able to use timeouts, you can use aiohttp for consistency or something. I spent like 5 hours debugging as a result of this once wondering why my websocket kept getting "closed".

delicate flame
#

yeah, I might keep websockets. Playing around with aiohttp's connect_ws and its really weird to have to observe what the gateway is doing by codes rather than hacing exceptions to catch. I know the former is probably better practice, but my mental model relies on the exceptions and so does the code. Reconnection logic looks like its going to be a pain to handle because of the async with blocks. If someone submits a PR for using aiohttp over websockets, Ill consider it. But in terms of implementing it myself, I rather stick with what I have. Why fix what isnt broken? Plus, I like the separation of concerns where you use websockets for the gateway and http for rest. Creates a better division

#

huh? why here?

grave sandal
#

They're obviously bored and trolling. They're on mobile, they posted in the discord bots channel (which attracts people like this) and only in this one 😭

delicate flame
#

well that was swift lol

#

oh wait

grave sandal
#

<@&831776746206265384> (sorry if not supposed to ping, forget now this works/never bothered before)

grave sandal
# delicate flame yeah, I might keep websockets. Playing around with aiohttp's connect_ws and its ...

I think there's still architecturally a separation of concerns regardless but mentally and developer experience wise I do think it can be cleaner in this instance to use the one dedicated to websockets, which is also less quirky and easier to integrate with well (imo). I also personally prefer exceptions, if I'm not mistaken in python raising them is practically free compared to other languages. Even in the sense of "this isn't exceptional, so give a result instead" I avoided the same just the other day with some of my own code.

delicate flame
#

there really doesnt seem to be much of an argument against using websockets other than line count? aiohttp is ~40k to websocket's ~4k. aiohttp's websocket also appears to be more ws code driven than exceptions. But I dont know how true this is because it appears you still need exceptions as fallback anyway.
The theme I see is "use websockets if you just need websockets and use aiohttp if you need both websockets and HTTP." Perhaps it really is preference based and circumstantial?

delicate flame
grave sandal
# delicate flame there really doesnt seem to be much of an argument against using websockets othe...

Yea aside from some quirks it's down to preference I'd say unless you find yourself needing something different. For end to end testing I can't really use aiohttp personally because of its quirky handling of timeouts. And looking at it I don't think the recieve method raises exceptions but others like connect do iirc, or maybe even send. You can just use whichever you like more really and change it later if necessary probably, it's one very small part of your code if I'm not mistaken

celest pelican
#

!clban 1041270324932649000 byd ceo impersonator

unkempt canyonBOT
#

:incoming_envelope: :ok_hand: applied ban to @stable mantle permanently.

timber dragon
delicate flame
#

Ive never understood discordpy's setup. I get that it was designed pre-python3, but it basically does websockets anyway?
Like:

class WebSocketClosure(Exception):
    """An exception to make up for the fact that aiohttp doesn't signal closure."""

    pass

so why not use websockets?

gritty inlet
#

Does dpy preserve http sessions if that makes sense? 🤔

#

Instead of doing something like async with Session() as session every single time

woeful hill
#

you can certainly open a ClientSession and then start the bot so that you don't need to open more of them

gritty inlet
#

Alright so I'd assume preserving a single session is favored?

#

Globally

delicate flame
#

oh wait no, Im talking about the gateway, not http

gritty inlet
#

Websockets has nothing to do with http 🤔

delicate flame
#

I cant tell which one youre talking about

gritty inlet
#

Asked you something related to websockets (:

delicate flame
#

I use ClientSession for rest and websockets for the gateway. Im pretty sure discordpy uses ClientSession for both

gritty inlet
#

Is aiohttp's ClientSession not an http-only thing

#

I wouldn't know

delicate flame
#

it has websocket capabilities

gritty inlet
#

If so then I wonder how'd it do in terms of optimization when compared to, for example, httpx where it's not tied to WS at all

#

But if a lib that you use has something with both then I don't see why not use it

delicate flame
#

because you rely on the codes sent rather than thrown exceptions

#

and then fallback to exceptions anyway apparently

gritty inlet
#

Idk if that's really a big deal

delicate flame
#

maybe not for a bot dev, but maybe for maintainers

grave sandal
# delicate flame maybe not for a bot dev, but maybe for maintainers

I think it's fine for either but now how I'd choose to do it necessarily. It boils down to choosing result objects vs exceptions. You get a result object you have to check the type value of (more or less) iirc, it can usually be made a very minor part of the code I think. But I think exceptions with how websocket documents them makes for better documentation which is probably the issue. You can't see all the types that can be returned by the docstring of the receive message, in websocket, something important like close is documented, and so are places where exceptions are anyway like with connect. Websockets definitely tries to be more maintainer friendly though and adapting to your needs.

dusk pelican
#

I dont get it? So should aiohttp inbuilt websocket be used or the separate library websocket?

delicate flame
#

I guess it really is up to preference and what you've already built. If you're starting from a clean slate like I have, Id recommend websockets. If you're working with discordpy or the like where they're already using aiohttp's websocket, keep using that. It's probably not worth the swap. discordpy has bigger fish to fry that isnt because its using aiohttp

#

but my point is if the only difference between the two is that aiohttp uses socket codes to determine state while falling back on exceptions anyway and websockets uses exceptions, it seems like websockets is the obvious winner

gritty inlet
#

I'd assume aiohttp has some optimizations to it, with it being probably less direct

hollow rover
#

are llama-3.3-70b-versatile good for a discord bot's?

fast osprey
#

LLM's are trash

hollow rover
fast osprey
#

To what end?

hollow rover
#

it's a multipurpose bot so i think it'll be good if i implement AI features on it

fast osprey
#

what are those purposes, and how would they use AI

hollow rover
#

r u being fr rn

fast osprey
#

Why wouldn't I be

#

Not sure how you intend to build software without actually explicitly listing your goals and use cases

hollow rover
fast osprey
#

Because I don't believe in assuming things when specificity is important

hollow rover
#

understandable

fast osprey
#

If I had a nickel for every "multipurpose bot" I'd helped with which was just a random jumble of features they happened to like, I would be on a beach sipping cocktails rn and not on discord

shrewd apex
#

if u have such a powerful machine why let strangers burn electricity

hollow rover
fast osprey
#

And are you following discord's terms and data privacy data laws when doing so?

hollow rover
#

absolutely

fast osprey
#

And how are you doing that

grave sandal
#

@delicate flame I'm playing around with building a discord bot client myself (not as serious, just curious how well I can unit test it) and I've got a small gripe with scurrypy. I've got stuff in place to create discord users with all the optional information and I want to create the user model but all the optionals I have to go and fill in myself. It would be nice if the optionals were set to None by default or something so that I could just fill in the ones I want.

delicate flame
#

Oh! That's not what models are there for! They just model discord's payloads

#

what are you making a user for? Perhaps there's another way to accomplish this?

grave sandal
#

I'm making a custom client just for exploration sake to see how well I can unit test the logic. I've got a fake discord database in memory and part of it right now is to make a fake discord interface my bot will use to get the information. I figured since scurrypy already has the models I'd use that instead of making my own.

grave sandal
#

At least I think anyway. The discord API responses should be the same models as the gateway if I'm not mistaken

delicate flame
#

models are intended to be filled when you call an endpoint that returns data or for filling out event.
What you COULD do is pass in a dict instead like:

scurrypy.UserModel.from_dict({'name': 'my_user', 'id':1234567890, ...})

from_dict will nullify any fields not filled

#

from_dict will give you the UserModel class. convert it backto a dict if you need the dict version.

So:

scurrypy.UserModel.from_dict({'name': 'my_user', 'id':1234567890, ...}).to_dict()

will return a dictionary with all fields filled out and the fields you didnt touch will be none

#

OR if you really want to functionalize modeling without the hastle of dicts, you can try TypedDict with total=False and then pass that dict into from_dict

delicate flame
#

but yeah they're the same model with perhaps some fields none

grave sandal
#

I'm not really keen on putting everything from my classes into a dictionary, has less editor/ide support. For the actual thing it's fine but for testing I'd like to construct it like normal and skip over the data I don't want, but it's fine. This fake discord/database exists independently of this effort and doesn't use typed dict so I'm not sure I can do the second option. But I'll just fill them in with None manually then.

grave sandal
delicate flame
#

am I still missing the mark here?

grave sandal
#

I'm building my own client layer for io, but borrowing scurrypy models

#

The user is real, like its own database code thing, but translated to an API response when called through the interface

delicate flame
#

IM SORRY. Lemme get this straight, you want to pull a user from a database and turn it into a UserModel

#

omg Im ded if Im wrong again

dusk pelican
#

Discord api response with a bunch of data so in order to sort it therefore are models like user or message ….

delicate flame
#

the data is coming in as a dictionary right?

grave sandal
# delicate flame omg Im ded if Im wrong again

Yea basically. For my client I'm putting a simple discord API interface for the client to use, the real thing will actually hit the @me endpoint and so on and read the user there. But for my fake one for unit testing, It'll have an in memory database with fake discord stuff, like the real thing but isolated.

dusk pelican
#

Json data

grave sandal
gritty inlet
#

Just define a TypedDict and have a User class take it

grave sandal
# grave sandal

The interfaces use the scurrypy models, and the fake of those interfaces uses an in memory copy of everything or will.

grave sandal
gritty inlet
#

Depends on the context

grave sandal
#

I'm aware that it can get annoying with positionals and stuff or ordering, and I admit I might be wrong on even complaining about it. It's not critical, just like feels like it might be able to be better, idk.

gritty inlet
#

Ah I see

#

As of payloads, I just do this

gritty inlet
#

It's never included in the regular user payload

#

You could kinda blame the docs for this kind of things as they don't fully tell you that

delicate flame
# grave sandal I'm aware that it can get annoying with positionals and stuff or ordering, and ...

youd have to serialize it to a dict then. That would be the most sane option. But if its coming from a database, it should be a dictionary or at least be able to convert to a dictionary. But even then, you could do:

some_user = MyUser(...)

user_dict = {
    'id': some_user._id, # however you access the variables
    'username': some_user._username
}

scurrypy_user = scurrypy.UserModel.from_dict(user_data)

TypedDicts nor these models are position sensitive if you provide kwargs.
If you dont like the idea of using a dictionary directly, TypedDict gives you the class feel and still has IDE support.
You can do whatever you feel most comfortable with! But this example would be the most convenient for scurrypy's case.

delicate flame
#

scurrypy aims for correctness with discord's api

#

its not built with another library

gritty inlet
#

Just more memory overhead when this key will never be present in the payloads.....

#

It's not about libraries being inaccurate

#

Your choice though

fast osprey
grave sandal
# gritty inlet As of payloads, I just do this

My argument is this: The bot will function without all the non required stuff, so if I want to test the bot, I can make an emulator (simple word for it) that will have all that stuff and handle all the operations. When I do that and make an adapter, I have to translate my models or this information into the models being worked with, UserData in your case. While NotRequired and others are clear, in practice if anything is absent it's going to be None anyway, and it would be ideal if they had default values of None so that when you call the constructor you can just say, this is the username, this ist he id, and so on, so you can skim over what you don't care about and play around or use it and test it easier. But it's not critical because I can technically just fill all those in with None myself and deal with it.

gritty inlet
#

The TypedDict having "NotRequired" is purely for type checking

#

It's the User class that controls what happens with each thing

grave sandal
#

Maybe i misunderstand typed dicts ngl

gritty inlet
#

If you narrow down to keys that are always present, you just have a partial user object

#

Dunno why you'd want that

grave sandal
#

Maybe outside of testing there's no value in it. But I'd want it because the bot should function or be able to be tested with only that.

gritty inlet
#
  1. Autocomplete
  2. Have the variables typed without adding annotations again
  3. Tells you if you're getting that key in the wrong way