#Basic Pycord Help

1 messages ยท Page 46 of 1

sage tendon
#

a db request per autocomplete call also isnt ideal

little cobalt
#

so store it at a local file ;3

vague plaza
#

Can I actually upload images passing a BytesIO object? It doesnt work on my end. it uploads an image with 0b. and this happens for every valid image I try it on.

await discord_channel.send(file=discord.File(photo_in_bytes))

sage tendon
#

buffer.seek(0)

#

or whatever you called your file thingy

vague plaza
sage tendon
#

we aren't in C lol, no need

#

actually show the code to open the file i forgor

#

as long as you use with you're fine

vague plaza
#

I dont actually open it, im developing a bot that forwards posts from a personal telegram channel to a discord channel. Idk if youre familiar with pyrogram library, but basically it fetches the latest 5 posts from a telegram channel, and for each one Im downloading the image in bytes:

@discord_bot.event
async def on_ready():
    print(f"{discord_bot.user} is ready and online!")
    async with Client('telegram_user1', session_string=session_string1) as app: #log into telegram account using pyrogram
        posts = app.get_chat_history(telegram_channel_id, limit=5)  #get latest 5 posts
        async for post in posts:
            if post.media.__str__() == "MessageMediaType.PHOTO":
                post_bytes = await post.download(in_memory=True) #download image to ram in bytes
                post_bytes.seek(0)
                discord_channel = discord_bot.get_channel(DISCORD_CHANNEL) #send to discord channel
                await discord_channel.send(file=discord.File(post_bytes))

So at least on my code theres no "with" statement apart from the one I need to use to log in, but that's permanent, as Im never logging off within the code

sage tendon
#

Yea no thats fine lol, itll be cleared by python

#

its just normal data in a variable, all variables get deleted from memory when they aren't in scope anymore

#

actually wait Thonk i may be stupid

vague plaza
#

so basically once the for loop iteration is done, python clears off the bytes? didnt know about that

sage tendon
#

see this is why i hate file stuff its always messy af

#

yea I'm actually not sure anymore, sorry im tired lol
i mean can't hurt to do post_bytes.close()

#

or maybe you can do async with await post.download... even

vague plaza
#

both could be valid solutions, let me try with the second one

#

File, line 35, in on_ready
async with await post.download(in_memory=True) as post_bytes:
TypeError: '_io.BytesIO' object does not support the asynchronous context manager protocol

sage tendon
#

f

vague plaza
#

might as well try the first one xD

sage tendon
#

thought it'd say that

vague plaza
#

no errors, so it should release the file bytes

#

hopefully

#

Thanks Toothy LovePycord

sage tendon
#

if you wanna make 100% sure put the send in a try except and put the close after that

#

close in the finally then

vague plaza
#

like this?

                try:
                    discord_channel = discord_bot.get_channel(DISCORD_CHANNEL)
                    await discord_channel.send(file=discord.File(post_bytes))
                except Exception as send_exc:
                    print(send_exc)
                post_bytes.close()

It wont do much tho, will it?

little cobalt
#

.get_x

sly karmaBOT
#

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.

sage tendon
vague plaza
# sage tendon put it in finally:
                try:
                    discord_channel = discord_bot.get_channel(DISCORD_CHANNEL)
                    await discord_channel.send(file=discord.File(post_bytes))
                except Exception as send_exc:
                    print(send_exc)
                finally:
                    post_bytes.close()
#

it throws no errors

sage tendon
#

yea that looks good

red mist
#

I have 1 braincell gonna read in quickly

little cobalt
sage tendon
#

lmao

vague plaza
# sage tendon yea that looks good

Great thanks again! I still dont get how this guarantees that the ram is freed after its been sent. Like wouldnt it be the same if I closed it right after the send, with to try/except/finally block?

            if post.media.__str__() == "MessageMediaType.PHOTO":
                post_bytes = await post.download(in_memory=True) #download image to ram in bytes
                post_bytes.seek(0)
                discord_channel = discord_bot.get_channel(DISCORD_CHANNEL) #send to discord channel
                await discord_channel.send(file=discord.File(post_bytes))
                post_bytes.close()
sage tendon
#

if the send throws an exception it will never close

vague plaza
#

Oooo I see what you mean

#

genius I didnt even think about that case scenario

red mist
#

Uh

sage tendon
#

yes voxy i am sorry lmao

red mist
# little cobalt no

You fucking ignore my question in dm and just show up here to tell me "no" ๐Ÿ’€๐Ÿ’€

little cobalt
#

xd

red mist
#

I'm confused

#

Still

#

What's this ab

#

Ok then the chat just dies

sage tendon
#

files in ram

red mist
vague plaza
sage tendon
red mist
#

Ohhhhhhhhhhhh

vague plaza
#

so tldr Toothy said, just do file.close()

red mist
#

... that

#

๐Ÿ’€

little cobalt
#

file.close?

red mist
#

I probably shouldn't question any further.

little cobalt
#

do you not use with open()?

sage tendon
#

not possible, we tried

vague plaza
red mist
#

^ with open file as f

sage tendon
sage tendon
vague plaza
#

read the chat its actually pretty short

sage tendon
#

its await download

#

and it says IOBytes dont support async context manager stuff

#

(you need async with for await in the expression right)

vague plaza
#

yeah now that im thinking about it probably I dont need async with, but just with await post.download()...

#

lemme try

sage tendon
#

yea i didnt think that would work

#

i love how it feels like we are all running on a combined 3 braincells here
everyone is confused

little cobalt
#

just use IOBytes

#

it should be fine

red mist
#

I- I want to say something but I'm A. Confused B. too afraid to pass false info

sage tendon
#

it literally is an IOBytes object thats returned

little cobalt
#

oh

sage tendon
little cobalt
#
with open("file", "wb") as f:
sage tendon
#

zervy

#

read up pleeeeease

little cobalt
red mist
#

Zervy

vague plaza
sage tendon
#

wtf

vague plaza
#

it sends the image perfectly and throws no errors

sage tendon
#

then what do you ever need async with for

#

ohhhh

vague plaza
#

cuz you told me to

sage tendon
#

i know

#

i know

sage tendon
red mist
#

To make something asynchroon in the first place

#

Fuc spelling

sage tendon
#

no its if you want async calls within the with

#

i just rembered

red mist
#

What the what

sage tendon
#

im gonna hop off

#

my brain is broken

red mist
#

You're explaining words with the words I apparently got wrong

little cobalt
#

Ich bin seit 3 Uhr wach...

sage tendon
#

SEIT*

little cobalt
#

mimimi

red mist
#

DANN GEH PENNEN DU DUMMER SACK BIST DU LEBENSMรœDE?!!!

#

๐Ÿ’€๐Ÿ’€

#

Ok ok anyway

vague plaza
#

lol

#

still big props to you I also learnt something new

red mist
#

Ok so async with is with context manager while normally when you await post.download it downloads it directly to your memory.

Use async with when you need to manage the setup and teardown of resources explicitly.
For simpler cases where such management is not necessary, using await is and should work perfectly fine.

#

I hope I got that right

#

๐Ÿ’€

sage tendon
#

but yea, if you have with you dont need to worry about file.close()

#

with handles everything

whole needle
#
import discord
from discord.ext import commands
from datetime import datetime
from data.checks import getWarnings, removeWarning, is_staff

async def get_warn_choices(ctx: discord.ApplicationContext):
    target_id = ctx.target_id
    warnings = getWarnings(target_id)
    return [
        discord.OptionChoice(name=f"{warn['id']}: {warn['reason']}", value=str(warn['id']))
        for warn in warnings
    ]

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

    @commands.slash_command(name='removewarn', description='Remove a warning by ID')
    @is_staff()
    async def removewarn(
        self,
        ctx: discord.ApplicationContext,
        target_id: int,
        warn_id: discord.Option(
            str,
            description="Select a warning ID to remove",
            required=True,
            autocomplete=get_warn_choices()
        )
    ):
        removeWarning(target_id, int(warn_id))
        embed = discord.Embed(
            title="๐Ÿ›ก๏ธ Warning Removed!",
            description=f"**User**: <@{target_id}>\n**Warn ID**: `{warn_id}`\n**Time Of Removal**: `{datetime.utcnow().isoformat()}`\n**Removed By**: {ctx.author.mention}",
            color=discord.Color.red(),
            timestamp=datetime.utcnow()
        )
        await ctx.respond(embed=embed)

def setup(bot):
    bot.add_cog(RemoveWarn(bot))

Why wont the warns load im not getting a error and on the option i have a Call expression not allowed in type expressionPylancereportInvalidTypeForm

The grab For The errors are

def getWarnings(userID):
    profile = getProfile(userID)
    if profile and "warnings" in profile:
        return profile["warnings"]
    return []

and the warns db be looking like

{
    "users": {
        "769389293658570752": {
            "warnings": [
                {
                    "id": "WARN-f0ed38123e23",
                    "reason": "test",
                    "warned_by": "osf0",
                    "date": "2024-07-07T06:27:06.174501"
                },
                {
                    "id": "WARN-d950b8a6d258",
                    "reason": "test2",
                    "warned_by": "osf0",
                    "date": "2024-07-07T06:27:34.439806"
                }
            ]
        }
    }
}
#

@errant trout

errant trout
#

uhhhh

#

what exactly isn't working

whole needle
#

the autocompletion

errant trout
#

remove the ()

#

in autocomplete=

whole needle
errant trout
#

ignore it

hallow copper
#

im prolly just being dumb but is there a way to add an option to a channel select? heres the code i wanna add it to

class view_class(discord.ui.View):
        def __init__(self):
            super().__init__(timeout=None)
        
        @discord.ui.channel_select(
            placeholder="Level Up Channel",
            channel_types=[discord.ChannelType.text]
        )
        async def channel_select_callback(self, select:discord.SelectOption, interaction):


errant trout
#

nope

hallow copper
#

really-

errant trout
#

yeah

hallow copper
#

thats annoying

errant trout
#

channel, role and user select are completely autofilled from your guild

hallow copper
#

that sucksss

#

i wanna add a "None" option

errant trout
#

best method is to just use string select with channel IDs as the value

whole needle
#
Task exception was never retrieved
future: <Task finished name='Task-18' coro=<ApplicationCommandMixin.on_application_command_auto_complete.<locals>.callback() done, defined at C:\Users\jarex\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\bot.py:869> exception=AttributeError("'AutocompleteContext' object has no attribute 'user'")>
Traceback (most recent call last):
  File "C:\Users\jarex\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\bot.py", line 872, in callback
    return await command.invoke_autocomplete_callback(ctx)
  File "C:\Users\jarex\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\commands\core.py", line 1036, in invoke_autocomplete_callback
    result = await result
  File "C:\Users\jarex\Downloads\Jarexs Tools\Heroic Productions\Main\commands\removewarn.py", line 7, in get_warn_choices
    target_id = ctx.user.id
AttributeError: 'AutocompleteContext' object has no attribute 'user'

i changed it a bit to @ the user and not make it a id and now i get the error

code :

import discord
from discord.ext import commands
from datetime import datetime
from data.checks import getWarnings, removeWarning, is_staff

async def get_warn_choices(ctx: discord.ApplicationContext):
    target_id = ctx.user.id
    warnings = getWarnings(target_id)
    return [
        discord.OptionChoice(name=f"{warn['id']}: {warn['reason']}", value=str(warn['id']))
        for warn in warnings
    ]

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

    @commands.slash_command(name='removewarn', description='Remove a warning by ID')
    @is_staff()
    async def removewarn(
        self,
        ctx: discord.ApplicationContext,
        user: discord.User,
        warn_id: discord.Option(
            str,
            description="Select a warning ID to remove",
            required=True,
            autocomplete=get_warn_choices
        ) # type: ignore
    ):
        removeWarning(user.id, int(warn_id))
        embed = discord.Embed(
            title="๐Ÿ›ก๏ธ Warning Removed!",
            description=f"**User**: <@{user.id}>\n**Warn ID**: `{warn_id}`\n**Time Of Removal**: `{datetime.utcnow().isoformat()}`\n**Removed By**: {ctx.author.mention}",
            color=discord.Color.red(),
            timestamp=datetime.utcnow()
        )
        await ctx.respond(embed=embed)

def setup(bot):
    bot.add_cog(RemoveWarn(bot))
hallow copper
errant trout
#

(maybe we should add some shortcuts there...)

whole needle
#

i just get this

errant trout
#

then warnings is empty

#

do you perhaps need to convert the ID back to string?

whole needle
errant trout
#

well, i'm just guessing

#

try using prints in getWarnings to see what results you're getting; my assumption is perhaps your getProfile function needs a string instead of an int

#

just gotta debug the process

lofty parcel
#

I mean, they're storing user IDs as strings

#

It's probably that

autumn narwhal
#

Is there a way to know how many people use User-Install?

errant trout
oak onyx
#

Should I use Member.status or Member.raw_status?
I tried boath, but they give me the same, and the docs don't rl say what the difference is

oak onyx
#

and another question: what is the status "Invisible" for?
there is no way it is in Member.status right?

oak onyx
#

yes, but can it be returned?

#

if yes, in what situation?

sage tendon
#

I doubt you can see it, that would defeat the entire point

errant trout
#

And invisible is considered equal to offline when checking another user, there's no differentiation

oak onyx
errant trout
#

i.e. bot.change_presence > printing ctx.me.status would work

cyan prism
#

I'm doing a spam filter thing for my bot uh

#

I have a list of messages

#

how do I get a message object by its id

lofty parcel
cyan prism
sage tendon
#

another question, why do you only have an ID?

cyan prism
sage tendon
#

why not store it in memory

cyan prism
sage tendon
#

holy same

cyan prism
#

why is this doing the shart and saying TypeError: 'Message' object is not subscriptable

#

or do I need to assign it to a variable

#

or

#

braim

#

not

#

work

sage tendon
#

show the full error

cyan prism
# sage tendon show the full error
    await coro(*args, **kwargs)     
  File "D:\Code\Python\VSGolem-Redux\VSGolem\main.py", line 26, in on_message
    await bot.get_cog("spamDetect").detectSpam(message, bot)
  File "D:\Code\Python\VSGolem-Redux\VSGolem\cogs\moderation\spamDetector\spamDetector.py", line 21, in detectSpam
    await bot.get_message(message["messageid"]).delete()
TypeError: 'Message' object is not subscriptable```
sage tendon
#

i think you have the wrong variable there

#

message is your actual message object

#

wouldnt you just do message.delete() at that point

cyan prism
#

I did dum

sage tendon
#

uh

cyan prism
#

lmao

sage tendon
#

wouldnt that delete the older message

#

wouldnt you wanna delete the most recent duplicated message and not the oldest

lofty hedge
#

Is there a way to know if the command is ran through user installed app or as a regular command?

sage tendon
#

authorized_integration_owners

#

or something like that, definitely authorized_

#

in ctx

fresh sierra
#

Not that

rugged lodgeBOT
quartz umbra
#

quick question, say in my main.py file, I have an on_message listener, which has some logic. Say I were to attach a cog, which also listens to on_message with different logic. Would the two interfere with each other, or would it work? The desired behaviour is for both logic to be executed

errant trout
#

As long as you don't reuse the same function name in the same class or something

quartz umbra
sage tendon
#

function name of the listener i assume

rain dune
#

isnt there some way to get author of DeletedReferencedMessage

#

.rtfm DeletedReferencedMessage

rain dune
#

i dont see any way to get the author here

sage tendon
#

why do you need that specific class

rain dune
# sage tendon why do you need that specific class

actually i was doing something like this :

# If the message is a reply, add the reference to the response
        if message.reference is not None and message.reference.resolved is not None:
            resolved_message = message.reference.resolved

            if isinstance(resolved_message, discord.DeletedReferencedMessage):
                # Reference is a deleted message
                author = resolved_message.author.mention #THIS IS CREATING ISSUE
                reference_line = f"**In reply to:** {author}`{resolved_message.id}`(Deleted Message)\n"
                response = reference_line + response

            elif isinstance(resolved_message, discord.Message):
                jump_url = resolved_message.jump_url
                author = resolved_message.author.mention

                reference_line = (
                    f"**In reply to:** {author} [Jump to referenced message]({jump_url})\n"
                )
                response = reference_line + response

like if the message is a reply to some message, and the parent message also get deleted then ill have a context who was the author of the parent message

Hi (DeletedReferencedMessage) I want author of this message
-> How are you? (replied message)
errant trout
fresh sierra
#

how can i add a self. to a class of the bot ,

#
class Lumabot(bridge.AutoShardedBot):
    def __init__(self, *args, **kwargs):
        super().__init__(intents=discord.Intents.all(), *args, **kwargs)
        self.help_command = None
        self.owner_id = OWNER_BOT
        self.command_prefix = DEFAULT_PREFIX
        self.shard_count = 1 if is_custom_bot() else 4
        self.allowed_mentions = discord.AllowedMentions(
            users=True, roles=True, everyone=True, replied_user=True
        )
        self.multicog_metadata: Dict[str, str] = {}
sage tendon
#

what

fresh sierra
fresh sierra
#
    @Lumabot.group("antiraid")
    @Lumabot.command()
#

im just dumb that okay, i was using a classmethod and poassingf it inside the init

fresh sierra
#

Im facing an issue about the prefix group since 2.6, usually if i create a group bot, i can pass a funct that will be trigger if it doesnt find the subcommand, for example +bot test will trigger the funct of bot since test is not a subcommand

#

however since 2.6, im facing an issue that does not trigger the funct

#

any idea ?

#
  group = commands.Group(
      name=slash_group.name,
      description=slash_group.description,
      invoke_without_command=True,
      func=self.fake_coro,
      checks=slash_group.checks,
  )
errant trout
#

you need the full traceback, but also if you're hacking through library features to fit your own usage then it's pretty out of scope for us

#

(and from what i can tell we didn't make any particular changes to commands extension)

fresh sierra
fresh sierra
# errant trout you need the full traceback, but also if you're hacking through library features...
Traceback (most recent call last):
  File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 180, in wrapped
    ret = await coro(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/container/Utils/client.py", line 355, in fake_coro
    description = command.description_localizations.get(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: '_MissingSentinel' object has no attribute 'get'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/home/container/Utils/client.py", line 390, in invoke
    await ctx.command.invoke(ctx)
  File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 1555, in invoke
    await super().invoke(ctx)
  File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 959, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 189, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: '_MissingSentinel' object has no attribute 'get'
errant trout
#

ok, so i think you can solve it now

fresh sierra
#

so i suppose this mean command.description_localizations return a Missing, however when i print this one its not missing

#

but return a real thing

errant trout
#

well, at some point one of them is missing

fresh sierra
#

i will try to debug more

errant trout
#

fake_coro is your own function, just add some check and continue

vague plaza
#

how can I remove the link preview when sending a message with a bot?

errant trout
little cobalt
#

<link>

fresh sierra
errant trout
#

rip

fresh sierra
#

groups was causing the issue

tardy bluff
#

Does buttons have some sort of exit code? I have some views with a lot of buttons and they work but discord says Interaction failed

shell radish
tardy bluff
shell radish
#

you have to respond to the interaction using some type of interaction.response

tardy bluff
#

Ok thanks

vague plaza
vague plaza
sage tendon
#

I never did anything with the telegram API so no

vague plaza
#

gotcha, grateful anyway :)

shadow bear
#

how do you... use user-installed application commands

#

I've authorised the bot and checked permissions, but none of the commands show up, and they arent debug scoped or anything

shell radish
shadow bear
#

They're showing up as regular guild commands in my servers, and in my DMs

#

I can't find anything on the docs site though so im not entirely sure what im doing

shell radish
#

can you show me what one of your commands look like?

shadow bear
#

as in code or UI? or both

shell radish
#

code

shadow bear
#

sure two secs

#
@commands.user_command(name="User Info")
async def user_info(self, ctx: discord.ApplicationContext, user: discord.User | discord.Member):
    await ctx.defer(ephemeral=True)

    embeds = await self.get_info(user)
    await ctx.respond(embed=embeds["Overview"], view=GenericLabelledEmbedView(ctx, **embeds), ephemeral=True)

@commands.slash_command(name="user-info")
async def user_info_slash(self, ctx: discord.ApplicationContext, user: discord.User):
    """Fetches information on a user or member on discord."""
    if ctx.guild:
        try:
            user = await ctx.guild.fetch_member(user.id)
        except discord.NotFound:
            pass
    await self.user_info(ctx, user)

These are two of my commands

#

I haven't changed anything since 2.5 for what its worth, I merely bumped the pycord version lol

shell radish
shadow bear
#

ah cheers

vague plaza
#

Im already using a decorator from another lib, but I need to send a message from my discord bot to a discord channel while inside of this other lib's decorator block. How can I do that since I can only see a way of getting the bot working under its own discord_bot decorator? Is there a way to get the bot working without using its @discord_bot.event decorator?

lapis dock
#

You cannot use multiple discord bot libs at the same time. It will break things

#

if they have the same import name

#

there is also no reason to use multiple libs. Py-cord can do all you need

#

and i assume the other lib can do all you need as well

errant trout
#

hmm

errant trout
rough heron
#

@bot.slash_command(name="removenote", description="Remove a moderation note from a user")
@discord.default_permissions(manage_channels=True)
async def removenote(ctx, noteid: int):

Is this the correct way to hide commands for this permission? My role hasn't been able to see the command, and I'm not sure where I went wrong.

#

(I've gotten the @discord.default working for all other tiers of my moderation team but I've been unsuccessful to get this permission working. People with the Administrator permission can see the command.)

errant trout
rough heron
#

It doesn't look like it.

errant trout
#

click view

rough heron
#

Ah, I see

#

It does confirm that

errant trout
#

so what's the issue you're running into on your end

rough heron
#

The people with the manage channel permissions are unable to see the command.

#

It's linked to a role called "Senior Officer" which does have the permission, but they are unable to run it or anything like that.

errant trout
#

a little silly, but could you perhaps try renaming the command and restarting the bot?

rough heron
#

Wait actually, quick question. If the channel that they were trying to run the command in had the permission specifically disabled, so the role is yes but the channel blocks them, would that influence it?

errant trout
#

yes

#

the default permissions are exactly that, defaults - ANYTHING else will override them

rough heron
#

Gosh dang it

#

The server owners have terrible permissions setup lol

#

Thanks for the help

errant trout
#

allgood

tardy bluff
#

Is it possible to make the interaction.respond() message only visible to interaction.user?

tardy bluff
#

Thanks

deft kestrel
#

embed.set_image(url=image_url)

can i use this with an attachment in the command? photo=discord.Attachment

little cobalt
#

.rtfm discord.Attachment

broken igloo
#

is there a way to respond to ctx without sending a message, a modal.... etc.

sage tendon
#

like, how?

#

the only possible responses are a defer, a modal, or a message

broken igloo
#

i don't want the The application did not respond message

sage tendon
#

yea, you have to respond

broken igloo
#

hmm well then, my approach to this feature isn't correct

#

i want to make the bot's icon dynamic when responding

sage tendon
#

for what use case

broken igloo
#

depending on the message, my idea was to use webhooks

broken igloo
sage tendon
#

id consider a bot that constantly changes pfps to be more confusing than anything tbh

#

and i dont think thats possible without using webhooks

broken igloo
sage tendon
#

i mean the embed thumbnail is enough imo

broken igloo
#

yeh but the pfp tips me off not syncing for some reason

sage tendon
#

the only, limited way you could achieve this thats kinda ugly is by responding, then responding to that message with a webhook (no clue if thats even possible), and then deleting the original response
but thats limited and you cant do it ephemerally

broken igloo
#

yeh

#

il drop the idea ig

sage tendon
#

yea
as i said, imo, the embed thumbnail is enough

pulsar ferry
#

Is there a way to put a cooldown on a command based on the role of the user executing it?

broken igloo
#

ok third question

#

how should i add a delay for specific amount of time. And by that i want a convinient way for the user to put their delay

#

wish there was a datetime component for discord that would pop a UI to pick dates as well as delays and stuff

#

like yes i can add some format like weeks-days-hours-minutes-seconds but this feels inconvenient

broken igloo
#

hmmm

#

they kinda need to have a calculator open to calculate the seconds for their time

#

sounds simpler tho

broken igloo
#

well i want duration

#

for dates i can use something like <t:1721069524:F> <t:1721069524:F>

lapis dock
#

True. Here is a solution. I think with this it allows you to do 5H and not 5H0M0S which is a bit more user friendly

noble flax
#

Really silly question but is it here I saw an example being able to create an embed with x information and then be able to use reacts to add "additional pages"?

sage tendon
#

Pagination, there's a guide on it

noble flax
#

I thought there was, sound thank you.

noble flax
#

I wrote a bot in .NET for Discord sometime ago (years ago). You were able to log exceptions/info/debugs directly to a web hook so you could obviously post the messages to a channel instead of to log file (which i currently do) does pycord have any functionality to do this? (Or any other library for that matter)?

little cobalt
#

.rtfm webhook

frail basin
noble flax
#

That's along the lines I guess. It's a bit old but may work, sorry for bothering people.

fresh sierra
#

And thanks u for that

fresh sierra
#

.rtfm badge

sly karmaBOT
fresh sierra
#

can we get the list of the available badge of discord ?

#

and get the badge of a user

sage tendon
#

its in the flags

fresh sierra
#

thanks

carmine jackal
#

How do i create something like this?

deft kestrel
#

is there any solution when a bot does not connect? this happens sometimes idk why

shell radish
hoary cradle
#

is there no alternative to having my command defer, send ephemeral error, but non ephemeral for completed command?

#

i try using ctx.send for the final message but the bot is stuck thinking

errant trout
#

You coulddd try defer -> ctx.delete?

hoary cradle
errant trout
hoary cradle
#

oh i see, ok i will try it, thank you

broken igloo
#

also

#
        duration_secs = pytimeparse.parse(duration)
        if duration_secs is None and duration != "":
            await failure_embeds.generate_invalid_duration(ctx)
            return
        delta = None
        if duration != "":
            delta = datetime.now() + timedelta(seconds=duration_secs)
            if duration_secs > 604800:
                await failure_embeds.generate_higher_than_week_embed(ctx, delta)
                return
            await target.timeout(delta, reason="User Has Been Muted")
        await target.add_roles(mute_role, reason="Member Muted")
#

in await target.timeout(delta, reason="User Has Been Muted")

#

for some reason when i look on the remove timeout even tho i putted 1H which is 1 hour

#

and it was 3600 seconds which does equal to 1 hour

#

it showed 4 hours instead

#

and for 3H it made it 6 hours

#

realised my mistake

#

i didn't use UTC time

oak onyx
#

is there a util to covert an object like discord.Member into json?
Since it can not JSON serializable

TypeError: Object of type Member is not JSON serializable
little cobalt
oak onyx
little cobalt
#

but why do you want a member as a json?

fresh sierra
oak onyx
#

I want to save a backup of a member in that moment

fresh sierra
#

also you should take a look at that

#

.json

sly karmaBOT
#

JSON is a convenient and easy-to-read data storage protocol that's widely accepted by most programming languages. However, we caution against its use for storing and retrieving data in an asynchronous environment like a Discord bot. Donโ€™t use json!

  • It's a file-based data storage, which makes it vulnerable to race conditions
  • You'll need to implement your own synchronization primitives to avoid corrupting data
  • If you're not careful, you could accidentally wipe your entire JSON file.

Solution? Use a database. Recommended schema are SQLite, PostgreSQL, and MongoDB.

  • Async libraries exist on pypi for each of these
    sqlite -- aiosqlite (or Danny's wrapper: asqlite)
    postgresql -- asyncpg
    mongodb -- motor
  • Databases organize your data into tables, and are fast at inserting, retrieving, and removing records
  • You can impose uniqueness constraints to ensure against duplication
  • The Python libraries enforce synchronization for you
  • The query language is intuitive, you can get running with simple queries in just a few hours!
oak onyx
#

hm, ok I will think about it

vague plaza
vague plaza
# errant trout can you elaborate on what you're trying to accomplish here

yeah so Im trying to forward incoming telegram channel posts to a discord server. The telegram library Im using to get incoming posts is pyrogram, and I need the decorator they have for that. But since you cannot use two decorators at the same time without breaking anything, I asked how can I make my discord bot usable (able to send a message to a discord channel) without the need of a decorator.

sage tendon
#

await bot.get_channel(id).send()

errant trout
#

You don't need a decorator to send messages, so long as your bot object exists you can follow the example toothy provided above

lethal loom
#

Hi, can someone help me, I want the original message to be deleted when I press True, because the way I have done it now, it can't find the message

import discord
import json
import re
import datetime

from discord.ext import commands

from discord.commands import slash_command
from discord.ui import Button, View, Select, Modal

from datetime import datetime

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

    @slash_command()
    @commands.cooldown(1, 10, commands.BucketType.user)
    @commands.has_permissions(administrator=True)
    async def embed(self, ctx):
        view_before = View()
        view_before.add_item(Create())
        return await ctx.respond(view=view_before, ephemeral=True)

def setup(bot):
    bot.add_cog(Test(bot))

class Create(discord.ui.Button):
    def __init__(self):
        super().__init__(
            label="Create",
            style=discord.ButtonStyle.green,
            custom_id="interaction:create",
            emoji="โœ๏ธ"
        )

    async def callback(self, interaction: discord.Interaction):
        await interaction.response.defer()
        embed = discord.Embed(description="Test Embed")
        await interaction.edit(embed=embed, view=TemplateActionsView("Test Place"))


class TemplateActionsView(View):
    def __init__(self, placeholder):
        super().__init__()
        self.select_callback.placeholder = placeholder
        self.message = None  # Nachrichtenspeicher hinzufรผgen

    options = [
        discord.SelectOption(label="Delete Template", description="", emoji="โŒ", value="template_delete_rename"),
    ]

    @discord.ui.select(row=2, options=options, custom_id="template_action__select")
    async def select_callback(self, select, interaction: discord.Interaction):
        if "template_delete_rename" in interaction.data['values']:
            # Nachrichtenspeicherung hinzufรผgen
            self.message = interaction.message
            print(f"Stored message ID: {self.message.id}")  # Debug-Ausgabe der Nachricht-ID
            await interaction.response.send_message(
                f"Do you want to delete?", 
                view=TemplateDeleteView("True", "False", self.message), 
                ephemeral=True
            )

# HEre, when i click on the Button The main message must be delte

class TemplateDeleteView(View):
    def __init__(self, true_label, false_label, message):
        super().__init__()
        self.true_button.label = true_label
        #self.false_button.label = false_label
        self.message = message  # Nachrichtenspeicher hinzufรผgen
        print(f"TemplateDeleteView initialized with message ID: {self.message.id}")  # Debug-Ausgabe der Nachricht-ID
        
    @discord.ui.button(style=discord.ButtonStyle.green, custom_id="delete_template_view_true")
    async def true_button(self, button, interaction: discord.Interaction):
        # รœberprรผfen, ob die Nachricht existiert
        if self.message:
            print(f"Attempting to delete message ID: {self.message.id}")  # Debug-Ausgabe der Nachricht-ID
            try:
                await self.message.delete()
                print("Message deleted successfully")
            except discord.NotFound:
                print("Message not found or already deleted")
        else:
            print("Message reference is None")

        embed = discord.Embed()
        embed.description = f"The was deleted."
        await interaction.response.edit_message(content=None, embed=embed)
fresh sierra
#

shoud be

#
    @slash_command()
    @commands.cooldown(1, 10, commands.BucketType.user)
    @commands.has_permissions(administrator=True)
    async def embed(self, ctx):
        return await ctx.respond(view=Create(), ephemeral=True)
vague plaza
errant trout
#

If you load your telegram stuff as a cog then it should be pretty easy

fresh sierra
broken igloo
#

is there a way to make my mutes basically timed? Like after a certain duration the mute will be revoked

#

i think of hooking a async method with await asyncio.sleep and then triggering the unmute

#

but i don't think this is the best approach

sage tendon
broken igloo
#

ik that and i use that but i also want to make my bot keep track of time

fresh sierra
#

you can check the member.communication disable until

broken igloo
#

and yes i can see when the timeout gets removed

sage tendon
#

just let discord handle it

broken igloo
#

meh, i also want this time concept for stuff like bans

fresh sierra
#

o

sage tendon
#

for bans you need a db, else you will run into problems

fresh sierra
#

so no not the best idea

#

yeah db is a must

broken igloo
#

got it set up already

sage tendon
#

but you really should let discord handle the timeouts

#

there is zero reason to make it more complicated

#

and i mean you have to pass a timeout duration or datetime anyway

broken igloo
#

mhm

#

i don't want staff members to simply remove it tho

#

like yeh they can execute a command to remove it

sage tendon
#

then dont give them permissions

broken igloo
#

ok

#

also for the ban system? How would i go about approaching it

sage tendon
#

task that checks whether a ban is overdue every 5m or so

broken igloo
#

well i kinda care about the individual seconds

sage tendon
#

then make it run every 10s

#

but it will come at increased load of course

broken igloo
#

yeh... I have an idea tho

#

is there a way to manually create a task? And tell pycord to execute it after this time

#

without needing to do this

@tasks.loop(seconds=5)
async def very_useful_task():
    print('doing very useful stuff.')
sage tendon
#

you shouldn't do that

sage tendon
sage tendon
broken igloo
#

also how much would it cost if i put seconds=1?

sage tendon
#

try it and find out

#

and you will have to use an async db connector else your bot will be blocked constantly

#

but there's no point in running it every second
when do you ban someone for any amount of seconds

broken igloo
#

mhm

broken igloo
sage tendon
#

if you execute a sync db query your bot will be blocked

#

and if you run the task every 5s itll be blocked constantly

#

the connection will of course also stop existing when your bot stops running lol

broken igloo
#

my brain ain't working after 12 hours

#

but got what u mean

#

tbh my idea was to use tasks to delay the task for a certain amount of time and then execute stuff after

sage tendon
#

yea, thats a no no

broken igloo
#

hm i could use a mix of asyncio sleep and tasks

#

and predict if the timing hits a later iteration or not

sage tendon
#

No

broken igloo
#

if not then sleep the remaining seconds and then unmute

sage tendon
#

You do not handle bans purely in-memory

#

period

broken igloo
#

task is not running

#
    def __init__(self, bot):
        self.bot: discord.Bot = bot
        self.guild = self.bot.get_guild(id)
        self.mute_task.start()

    @tasks.loop(seconds=10)
    async def mute_task(self):
         # ...
sage tendon
#

how do you know its not running

broken igloo
#

i try to print but doesn't print stuff

#

(ik i shouldn't print stuff, but was testing out of curiousity)

sage tendon
#

no problem with printing

broken igloo
#

oh

#

hold on

vague plaza
sage tendon
#

is the bot actually in that server & channel?

#

also you dont have to pass the content as kwarg, its positional

vague plaza
sage tendon
sly karmaBOT
#

Tag not found.

Did you mean...
get_x

fresh sierra
#

.get_x

sly karmaBOT
#

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.

lethal loom
#

I have a strange problem, namely in the navview the first print self.old_interaction does not work but the second and the second one gives me none and with the first one I get this fehelr

Traceback (most recent call last):
  File "C:\Users\jurek\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\discord\ui\view.py", line 426, in _scheduled_task
    await item.callback(interaction)
  File "c:\Users\jurek\Documents\Development\Python\DC Bots\Xenority\Xenority-Main-Pycord-V2-PY\cogs\dev\embed_builder_v3.py", line 45, in callback
    await interaction.edit(embed=embed, view=NavigateEmbedsView(embeds=embeds))
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\jurek\Documents\Development\Python\DC Bots\Xenority\Xenority-Main-Pycord-V2-PY\cogs\dev\embed_builder_v3.py", line 940, in __init__
    self.add_action_view()
  File "c:\Users\jurek\Documents\Development\Python\DC Bots\Xenority\Xenority-Main-Pycord-V2-PY\cogs\dev\embed_builder_v3.py", line 955, in add_action_view
    print(self.old_interaction)
          ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NavigateEmbedsView' object has no attribute 'old_interaction'
    def __init__(self, embeds, start_index=0, template_name=None, interaction: discord.Interaction = None):
        super().__init__()
        self.embeds = embeds
        self.current_index = start_index if 0 <= start_index < len(embeds) else 0
        self.template_name = template_name
        self.current_site = self.current_index + 1
        self.add_editor_view()
        self.update_buttons()
        self.add_action_view()
        self.old_interaction = interaction
        self.add_template_view()

    def add_editor_view(self):
        self.editor_view = EditorView(self.template_name)
        for item in self.editor_view.children:
            self.add_item(item)

    def update_buttons(self):
        self.add_item(PreviousButton(self))
        self.add_item(EmbedInfoButton(self))
        self.add_item(NextButton(self))

    def add_action_view(self):
        #print(self.old_interaction)
        if self.template_name is None:
            self.action_view = ActionEmbedsView("Send", "Save Template", "Share", "Template Name", "Choose a Template name", "Title")
        else:
            self.action_view = ActionEmbedsView("Send", "Update Template", "Share", "Template Name", "Choose a Template name", "Title", self.template_name)
        for item in self.action_view.children:
            self.add_item(item)

    def add_template_view(self):
        print(self.old_interaction)
        if not self.template_name is None:
            self.template_view = TemplateActionsView(f"Current Template: {self.template_name}", self.template_name,
                                                     self.old_interaction)
            for item in self.template_view.children:
                self.add_item(item)```
sage tendon
#

well, pass "interaction" then lol

lethal loom
#

ok

sage tendon
#

yea because you print it before interaction is assigned

tepid coyote
#

bot on start up is always coming up with this but using a different bot token its fine, the bots have admin and have access to everything in the servers

Ignoring exception in on_connect
Traceback (most recent call last):
  File "/Users/ollie/Github/104Systems/.venv/lib/python3.11/site-packages/discord/client.py", line 400, in _run_event
    await coro(*args, **kwargs)
  File "/Users/ollie/Github/104Systems/.venv/lib/python3.11/site-packages/discord/bot.py", line 1178, in on_connect
    await self.sync_commands()
  File "/Users/ollie/Github/104Systems/.venv/lib/python3.11/site-packages/discord/bot.py", line 754, in sync_commands
    app_cmds = await self.register_commands(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ollie/Github/104Systems/.venv/lib/python3.11/site-packages/discord/bot.py", line 531, in register_commands
    prefetched_commands = await self._bot.http.get_guild_commands(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ollie/Github/104Systems/.venv/lib/python3.11/site-packages/discord/http.py", line 367, in request
    raise Forbidden(response, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50001): Missing Access
#

any ideas as to why this happens, it doesnt appear to affect the bot when its running, just annoying to see in the terminal

fresh sierra
#

it can be because u have a debug guild set

tepid coyote
tiny sable
#

my workaround is testing on prod xd

#

BUT a friend told me this is most likely a discord API bug

sage tendon
#

and every permission individually in the roles

vague plaza
# sage tendon https://docs.pycord.dev/en/stable/api/clients.html#discord.Bot.fetch_channel if ...

If I replace get with fetch channel, I get an error

Traceback (most recent call last):
File "e:...\mainv5.py", line 37, in echo
ds_channel = await discord_bot.fetch_channel(DISCORD_CHANNEL)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:...\venv\Lib\site-packages\discord\client.py", line 1805, in fetch_channel
data = await self.http.get_channel(channel_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:....\venv\Lib\site-packages\discord\http.py", line 285, in request
async with self.__session.request(
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: '_MissingSentinel' object has no attribute 'request'

sage tendon
#

can you show your bot definition

sage tendon
sage tendon
tepid coyote
vague plaza
#

not sure if this is what youre looking for, lemme know if it isnt

sage tendon
#

and you actually run the bot?

errant trout
#

Just show your main file

vague plaza
vague plaza
# errant trout Just show your main file

import discord, os, traceback
from dotenv import load_dotenv
from pyrogram import Client, filters

print('Starting...')

OWNER = -1111111111 
TELEGRAM_CHANNEL_SOURCE = - -222222222
DISCORD_CHANNEL_RECIPIENT = 3333333333

session_strings = {
"userbot1":"abc",
}

load_dotenv()
discord_bot = discord.Bot() #discord bot login

app = Client('ubot1', session_string=session_strings['userbot1']) #telegram userbot login

@app.on_message(filters.channel)
async def echo(client, post):
    print(post)
    try:
        print(f"{discord_bot.user} is ready and online!")
        ds_channel = await discord_bot.fetch_channel(DISCORD_CHANNEL_RECIPIENT)
        try:
            if post.media.__str__() == "MessageMediaType.VIDEO" or post.media.__str__() == "MessageMediaType.PHOTO" or post.media.__str__() == "MessageMediaType.DOCUMENT":
                
                post_caption_da_mandare = post.caption.markdown
                with await post.download(in_memory=True) as post_bytes:
                    post_bytes.seek(0)
                    await ds_channel.send(content = post_caption_da_mandare, file=discord.File(post_bytes))

            elif post.media.__str__() == "MessageMediaType.WEB_PAGE":
                await app.send_message(OWNER, f'Webpage not sent')
                await app.forward_messages(OWNER, TELEGRAM_CHANNEL_SOURCE, post.id)
                print(post)

            elif post.text:
                post_text_da_mandare = post.text.markdown
                await ds_channel.send(content = post_text_da_mandare)
                print(f'text post sent')

            else:
                print(post)
                
        except Exception as post_exc:
            print(f'{traceback.format_exc()}\nCause:')
            print(post)
    except Exception as e:
        print(traceback.format_exc())

app.run()
print('logging in discord') # never gets printed, most likelblocked by app.run()
discord_bot.start(os.getenv('DISCORD_BOT_TOKEN'))
print('logged in discord')

errant trout
#

pyrogram's run is actually very similar to pycord's run, using the same technique

#

i would say, do the following:

  1. override discord_bot.start to prefill your token:
async def start():
    await discord_bot.login(token)
    await discord_bot.connect()
discord_bot.start = start```
2. after doing so, try to use `compose` as demonstrated in the pyrogram docs <https://docs.pyrogram.org/api/methods/compose#pyrogram.compose>

i can't guarantee any of that works, you'll need a fair bit of debugging to pull it off
echo wraith
#

What is the command that sends the comparison of discord.client bot bridge bot etc...

sly karmaBOT
#
discord.Client # just for events
discord.Bot # events + slash/user/msg commands
commands.Bot # above + prefixed commands
bridge.Bot # above + bridge commands (application commands and text commands in one)
echo wraith
#

Thanks

vague plaza
granite pier
#

does anyone have any idea why this command is the only (guild) one that pops up in dm?

#

I thought I forgot to sync it after some changes, but it looks like that's not the problem, especially since some of the others have the same structure kekwlaugh

little cobalt
#

Is it possible to set a role as default in a role select?

sage tendon
little cobalt
sage tendon
#

what

granite pier
granite pier
granite pier
#

so no depre for this

#

as it sets contexts

#

only for

@commands.slash_command(guild_only=...)
granite pier
#

hmm let me check something

little cobalt
#

guild_ids=[]

#

@granite pier

#

not guild_only=

granite pier
#

we are talking about this

granite pier
#

this is the ony case when its false lmao

#

nvm im blind

#

it should be discord.guild_only

#

hahahah

#

I don't know why, I totally didn't notice it and in the conversation above I was checking the right decorator

#

thanks toothy I think that if I hadn't started digging deeper I wouldn't have even noticed it at the current moment

sage tendon
#

wait what was the solution now

granite pier
granite pier
#

haha

errant trout
broken igloo
#

can you edit files when editing a message?

#

i wanna sync back the components when the bot goes inactive and active again

#

and well my message is an embed

#

which has a thumbnail as a local file

#

previously i was using discord CDNs but better migrated towards local files instead

little cobalt
#

.local

#

.tags local

#

.local-file

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

._.

#

not send edit

sage tendon
#

check message.edit in the docs

#

it's all right there

broken igloo
#

oh wait nvm,

heavy vortex
#

Hello! How do I properly allow a certain role to view a voice channel? I used view_channel=True, but the position is set to neutral (/)...

sage tendon
#

show your code

shadow bear
#

Is there a way to know if you're running in a user install context or a guild install context outside of checking if ctx.guild.me is None?

#

ah, ctx.interaction.context

#

No, that's not the one

lofty parcel
#

.rtfm app_context

sly karmaBOT
#

Target not found, try again and make sure to check your spelling.

lofty parcel
shadow bear
#

that tells me what location context its in (i.e. DM/Guild/whatever else). I need to know whether im running in a context where the bot is in the server or not, because half of the Guild data is just None in that case

#

This is incredibly poorly named lmao

lofty parcel
#

Ah

#

You have to check if ctx.guild is None

#

That's the way to check if you're in a guild or not

tardy linden
#

how do i make it so that a discord.Option can have a discord attachment

sage tendon
#

set discord.Attachment as the input type

tardy linden
#

i did, didn't work

#
discord.Option(name="file", description="Upload your .replay file", required=True, type=discord.Attachment)```
shadow bear
#

nothing wrong with that, it just feels inefficient lol

lofty parcel
#

If you're outside a guild, aka DMs, guild will be None

lofty parcel
shadow bear
lofty parcel
#

required is True by default, you can remove that

shadow bear
#

these things

#

user install is where commands are available everywhere without the bot being in the guild

lofty parcel
#

Then we go back to the first thing

shadow bear
#

So is it guild regardless of whether the bot is installed in the guild?

#

I swear, app commands get more ambigious with each api update

#

nothing was wrong with regular text commands

lofty parcel
#

If you get a user_id, then you can assume the command is ran in a user installed context

#

I haven't played around with installable apps yet

shadow bear
sage tendon
shadow bear
# sage tendon ambiguous how?

well on topic, there's ambiguity around "contexts" - install contexts and "command invocation" contexts (e.g. DM/Guild/Private)? and then there's the library specific ApplicationContext, BridgeContext and commands.Context. There's also "command contexts" in the sense of slash command, message command, and user command. "user context" could either refer to the install context, or the right-click context

shadow bear
#

you got a message, in a channel, sometimes in a guild, from member, or user otherwise

#

I might just prefer the platform from a time long ago, but I really do think that app commands have just added more hurdles to the process

#

credit where its due, they have added some really nice things, I just think they're more of a hassle

sage tendon
shadow bear
#

that's what I mean by non-installation user context

sage tendon
sage tendon
shadow bear
#

I swear they're referred to as user context commands

#

huh, no?

sage tendon
#

no

shadow bear
#

man ive been convinced since their initial release they were "user context" ๐Ÿ˜ญ

sage tendon
#

context menu commands as a whole, for both message and user commands

shadow bear
#

ah that'll be why I though that

fresh sierra
shadow bear
fresh sierra
#

I was thinking he was meaning message command like user command

#

I tend to prefer prefix as slash command, but I implemented both creating my ยซbridgeยป thing because itโ€™s easier for the new user of the bot

broken igloo
#

any tips on optimising my bot for modlogging and stuff?

#

it takes ~3 seconds to do either unmuting or muting

sage tendon
#

well, ever measured what takes so long?

#

because a normal discord timeout call sure doesnt take 3 seconds

broken igloo
#

this isn't the only thing im doing

sage tendon
#

yea then measure what takes so long

errant trout
#

indeed, logging is typically <1s

#

you receive events within a couple ms (latency dependent), anything beyond that is your own overhead

echo wraith
#

You can gather multiple asynchronous tasks too run them concurrently of that can help you

broken igloo
#

im interacting a lot with the discord API

#

i add a role, create a DM channel, send a embed in the DM channel, send an embed in the current channel

#

man i wish you could group these actions into 1 HTTP request (that depends on discord themselves)

#

like you could do

await discord.execute_multi_action(
    ctx.followup.send(embed=embed, file=thumbnail, ephemeral=True),
    target.timeout(delta, reason=reason),
    target.add_roles(mute_role, reason=reason),
    target.create_dm()
    # ....
)
sage tendon
#

why followup.send, just use .respond

broken igloo
#

i defered the response

sage tendon
#

and no, you cant make multiple API requests in one, that makes no sense

sage tendon
broken igloo
#

whats the difference using .respond and not followup

sage tendon
#

its a shortcut really
respond is how you should do it
it handles it appropriately, regardless of whether its been deferred or not, or even if you already responded

broken igloo
#

oh ok

sage tendon
#

oh wait, no, i get it
but why lol

#

there's no reason to wrap it in a function

broken igloo
#

well this was just an example

sage tendon
#

ah

broken igloo
#

but the problem rn is first it takes more time for discord to handle like 5 different requests than it is for 1

sage tendon
#

i mean yea, but, you cant combine API requests

#

it makes no sense, thats not how APIs work

#

and i doubt thats why it takes so long, did you measure the time?

broken igloo
#

yeh i did

#

all the other tasks did milliseconds

sage tendon
#

yea so what takes long

broken igloo
#

the requests, sending messages.... etc.

sage tendon
#

shrug welp

#

can also be amplified by being far away from discord's servers

broken igloo
#

mhm

#

so ig i can't do anything about it

sage tendon
#

also, don't do member.create_dm

broken igloo
#

yeh...... I saw it in the docs

#

but dunno how to check if i can DM the user

sage tendon
#

can_send

#

but it had some drawbacks i dont remember rn

broken igloo
#

like this?

target.can_send()
sage tendon
#

but really, just put it in a try except

sage tendon
broken igloo
#

ok

sage tendon
broken igloo
#

i have the feeling it improved the performance and shaved off a second

#

like this?

#
embed, thumbnail, view = await other_embeds.generate_dm_mute_embed(msg, bot, target, reason, duration_secs)
can_send_to_target = target.can_send(embed=embed, file=thumbnail, view=view)
if not can_send_to_target:
  return
dm_msg = await target.send(embed=embed, file=thumbnail, view=view)
sage tendon
#

yea
try it with an account you disable DMs on

broken igloo
#

mhm

#

i get

discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: Forbidden: 403 Forbidden (error code: 50007): Cannot send messages to this user
#

but

#
    can_send_to_target = False
    try:
        can_send_to_target = target.can_send()
    except discord.errors.Forbidden:
        return
    if not can_send_to_target:
        return
sage tendon
#

no lol

#

put the actual sending part in the try, and get rid of the can_send then

broken igloo
#

oh

#

xD oh sorry

#

it actually did improve performance

#

removing the create dm channel

heavy vortex
# sage tendon show your code

Yeah, srry for late reply

clan_role = discord.utils.get(clan_guild.roles, name=clan_name)
new_text_channel = await clan_guild.create_text_channel(name=text_name, category=clans_category, position=2)
new_voice_channel = await clan_guild.create_voice_channel(name=voice_name, category=clans_category, position=1)
await new_text_channel.set_permissions(clan_role, view_channel=True)
await new_text_channel.set_permissions(clan_guild.default_role, view_channel=False)
await new_voice_channel.set_permissions(clan_role, view_channel=True)
await new_voice_channel.set_permissions(clan_role, connect=True)
await new_voice_channel.set_permissions(clan_guild.default_role, view_channel=False)
sage tendon
#

id do it with permissionoverwrite
yes you can do kwarg permissions but meh

#

also remember that the bot has enough permissions

sage tendon
#

how does role comparison work?
I'm creating a discord.Object(role_id)
can i == this to the actual role itself and get true?
basically
discord.Object(role.id) == role

deft kestrel
#

ctx.defer() can it be ephemeral?

errant trout
errant trout
deft kestrel
sage tendon
fresh sierra
#

How can I access all the loop of the bot ?

#

(Tasks.loopโ‚ฌ

errant trout
fresh sierra
errant trout
#

(it makes slightly more sense if you print it and see what you're dealing with)

errant trout
fresh sierra
#

Like a discord error connection that cancel an essential loop

#

And restart them in case

broken igloo
#

is it possible to make the context menu options have a value on autocomplete?

#

so visually it is A B C but when i get the value its abc

sage tendon
#

yes

#

use OptionChoice as autocomplete option

broken igloo
#

i got this

#
            tag: discord.Option(
                str,
                description="The faq tag to choose from",
                autocomplete=discord.utils.basic_autocomplete(get_tags)
            )
#

oh wait

#

i did this

#
def get_tags():
    faq_document_path = Path("./assets/documents/faq")
    faq_documents = faq_document_path.glob("**/*.json")
    l = []
    for doc in faq_documents:
        with open(doc, "r") as f:
            data = json.load(f)
            l.append(discord.OptionChoice(name=data["tag"], value=str(doc)))
    return l


tag_choices = []


class FaqCog(commands.Cog):
    def __init__(self, bot):
        self.bot: discord.Bot = bot

    @commands.slash_command()
    async def faq(
            self,
            ctx: discord.ApplicationContext,
            tag: discord.Option(
                str,
                description="The faq tag to choose from",
                choices=tag_choices
            )
    ):
      # ...


def setup(bot):
    global tag_choices
    tag_choices = get_tags()
    bot.add_cog(FaqCog(bot))
#

i could put them manually ik but i prefer automating that

sage tendon
#

yea that works

#

but just do choices=get_tags()

little cobalt
#

Isnt opening a json blocking?

deft kestrel
#

https://github.com/Akatsuki2555/Akabot/blob/b622168a7866c36931fc0b3ebf7942d196e7628b/features/per_user_settings.py#L31

Ignoring exception in on_connect
Traceback (most recent call last):
  File "F:ยฅProjectsยฅAkabotยฅ.venvยฅLibยฅsite-packagesยฅdiscordยฅclient.py", line 400, in _run_event
    await coro(*args, **kwargs)
  File "F:ยฅProjectsยฅAkabotยฅ.venvยฅLibยฅsite-packagesยฅdiscordยฅbot.py", line 1178, in on_connect
    await self.sync_commands()
  File "F:ยฅProjectsยฅAkabotยฅ.venvยฅLibยฅsite-packagesยฅdiscordยฅbot.py", line 735, in sync_commands
    registered_commands = await self.register_commands(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "F:ยฅProjectsยฅAkabotยฅ.venvยฅLibยฅsite-packagesยฅdiscordยฅbot.py", line 599, in register_commands
    registered = await register("bulk", data, _log=False)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "F:ยฅProjectsยฅAkabotยฅ.venvยฅLibยฅsite-packagesยฅdiscordยฅhttp.py", line 373, in request
    raise HTTPException(response, data)
discord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In 32.options.0.choices.0.value: Could not interpret "['ฤŒeลกtina - 98%', 'English', 'Franรงais - 97%', 'ๆ—ฅๆœฌ่ชž - 95%']" as string.
#

I need help, this error wasn't happening yesterday

sage tendon
sage tendon
sage tendon
#

that's not the issue

deft kestrel
broken igloo
sage tendon
#

yes, it does

#

because that's exactly what you're doing, just with extra steps

broken igloo
#

like i tried it before doing this

sage tendon
#

it's literally what you're doing with extra steps.

broken igloo
#

oh

sage tendon
#

call function that returns list > save to variable > pass variable with list in it to choices kwarg
or
call function directly and pass the list directly into the choices kwarg

broken igloo
#

also the thumbnail

if data.get("thumbnail") is not None:
  f = discord.File(fp=Path("./assets/images/" + data["thumbnail"]), filename="faq_thumbnail")
  embed.set_thumbnail(url="attachment://faq_thumbnail")
#

doesn't work

#

for some reason

#

even tho i send the file

sage tendon
#

do you actually attach it to the message?

broken igloo
#

yes

#
thumbnail = None
with open(tag, "r") as f:
  data = json.load(f)
  embed = discord.Embed(
    title=data["title"],
    description=data["description"],
    color=discord.Color.blurple()
  )
  if data.get("thumbnail") is not None:
    thumbnail = discord.File(fp=Path("./assets/images/" + data["thumbnail"]), filename="faq_thumbnail")
    embed.set_thumbnail(url="attachment://faq_thumbnail")
await ctx.response.send_message(embed=embed, file=thumbnail)
deft kestrel
#

Does the choices list support Asian languages? Because ๆ—ฅๆœฌ่ชž is Japanese

sage tendon
#

supports any string for all I know

sage tendon
broken igloo
#

oh yeh srry

sage tendon
broken igloo
#

there is no thumbnail

#

and no errors

sage tendon
#

the entire message

broken igloo
deft kestrel
#

this list is valid for choices=?

sage tendon
#

should be
tried the same but without the Japanese (?) characters?

broken igloo
#

found out why

#

i forgot the .png extension to put

sage tendon
# broken igloo

hm
can you try just attaching the image to the message to see if the image works in the first place

sage tendon
broken igloo
#

local files are a lil clunky to work with, should be abstracted away

deft kestrel
#

tried this

#

same thing

#

why is it interpreting as a string

#

I put in something into the list

#

but still

sage tendon
#

can you show how you define the option

deft kestrel
#

I didn't change this line of code

#

I've changed the get_language_names method

#

to return a hardcoded list

#

even this doesn't work

#

putting it in a list and using * to unpack list

#

which in python console returned the exact same thing as calling it directly

#

ok so now I'm confused, this doesn't work either

sage tendon
#

and if you just put choices=["string"]

#

ah

#

this shouldn't work but can you add str as positional argument to the option

deft kestrel
sage tendon
#

no, just put str, at the beginning of your option decorator

deft kestrel
#

like this?

sage tendon
#

yea

deft kestrel
sage tendon
#

ah damn I'm dumb

#

yea nvm

deft kestrel
#

I've tried type=str too

sage tendon
#

I really don't know why it does that then

deft kestrel
#

that didn't work either

sage tendon
#

input_type I think

little cobalt
#

name is fine but just remove the str at the option()

sage tendon
deft kestrel
#

out of all of this it's the only one that doesn't work

little cobalt
#

option(name="")

deft kestrel
#

it's the one at per_user_settings:31

sage tendon
#

zervy

#

that isn't the issue

#

read up

deft kestrel
#

all of these are defined, name=<name>, description=<description>, choices=[<choices>]

#

this one doesn't have issue and it includes East Asian characters

sage tendon
#

legit no idea

#

seems like a really weird bug

#

maybe remove the choices entirely, restart, and then add them back

deft kestrel
#

somehow it throws the error even if I remove the entire cog

#

including the import

sage tendon
#

lol what

deft kestrel
#

and even if I remove the file completely it throws the error

sage tendon
#

show

deft kestrel
#

idk what's happening

little cobalt
#

OH

limpid marten
#
@bot.command()
async def create_role(ctx, name:str, colour):
    guild = ctx.guild
    member = ctx.author
    role = await guild.create_role(name=name, colour=colour)
    await member.add_roles(role)
    await ctx.send(f'Role "{name}" created successfully.')

why sadbean

little cobalt
limpid marten
sage tendon
limpid marten
#

what in the world is that

sage tendon
#

the way you're supposed to respond

#

ctx.send is wrong for application commands

limpid marten
#

i dont use application commands

sage tendon
#

prefix??

limpid marten
#

pls steamhappy

sage tendon
#

ok cursed

limpid marten
#

staying classic

sage tendon
#

nvm then

limpid marten
#

i always loved the "pls " prefix

sage tendon
deft kestrel
sage tendon
#

don't terminate it before the {}

#

wait I'm dumb

limpid marten
#

only reason id use application commands is to use them everywhere

sage tendon
#

:>

#

I for one refuse to use prefix commands :>> anyway

shell radish
#

how do you know its app commands

deft kestrel
#

I'm going to check usages of the get_language_names method

limpid marten
sage tendon
deft kestrel
#

man I'm dumb

#

sorry for wasting time

sage tendon
sage tendon
limpid marten
#

you know its a bad problem when even the server's helper doesnt know what the fuck is wrong with your code

sage tendon
#

im just some guy

limpid marten
#

youre cool in my eyes

sage tendon
#

oh wait, i see now

#

the color is the problem

#

cast it as int

limpid marten
#

so like colour:int

sage tendon
#

i think

#

yea

limpid marten
#

tried that

#

lemme try again

sage tendon
#

its read as string currently

#

im not quite sure how you'd take a hex color and convert it into a proper format rn

#

but it should work if you cast it as int

limpid marten
#

oh my lord

sage tendon
#

and then put like 0x34213 or whatever

limpid marten
#

messed up

sage tendon
#

show what you put in chat

limpid marten
#

same thing i put previously

sage tendon
#

idk what kind of character that is, but it has to be an x

#

that looks like some mathematical x lol

limpid marten
#

time to try that out

limpid marten
sage tendon
#

can you remove the typehint and try int(color) instead

#

it should work

limpid marten
#

whats a typehint if you dont mind me asking

sage tendon
#

: str

limpid marten
#

wait does it matter if its color or colour

#

theres no difference right

sage tendon
#

as long as you type it the same

limpid marten
#

now theres this

sage tendon
#

no, not there

#

in the function

limpid marten
#

this is even worse

#

im not sure i did it right

#

quick check

#
@bot.command()
async def create_role(ctx, name:str, colour):
    guild = ctx.guild
    member = ctx.author
    role = await guild.create_role(name=name, colour=int(colour))
    await member.add_roles(role)
    await ctx.send(f'Role "{name}" created successfully.')
sage tendon
#

im just taking this from the python docs rn lol

#

try int(colour, 0)

#

if that doesnt work then i dont know

limpid marten
#

EUREKAAAAAAA

#

IT WORRRRRRKS

#

THANK YOU MR TOOTHLESS

sage tendon
#

np

#

is it the right color tho

limpid marten
#

YES

sage tendon
#

nice

deft kestrel
#

embed.set_image()

can i set a video with that?

little cobalt
fresh sierra
#

is it normal that discord.Member allow user ?

sage tendon
#

like how?

errant trout
#

if you mean slash options, yes

fresh sierra
#

in the slash

fresh sierra
errant trout
#

yes, because there is no member type

#

it's just user

fresh sierra
#

why is there no member ?

#

like that's so strange

errant trout
#

GuraShrug but validating it isn't particularly hard

pulsar ferry
#

Hey all is this the right way to have an optional arg? its still saying its required when i try to test it

@discord.option("pair", type=str)
@discord.option("start_date", type=str)
@discord.option("end_date", type=str)
@discord.option("fees", default=0.001, required=False, type=float, min_value=0)
@bot.slash_command(description="Optimize a strategy")
async def optimize(ctx, pair, start_date, end_date, fees):
fresh sierra
sage tendon
pulsar ferry
pulsar ferry
sage tendon
#

just remove type=

#

and move the input type to the second position for your last option

#

the order of the positional args is name, type so there's no need to pass it as kwarg

pulsar ferry
#

so this?

@bot.slash_command(description="Optimize a strategy")
@discord.option("pair", type=str)
@discord.option("start_date", type=str)
@discord.option("end_date", type=str)
@discord.option("fees", type=float, default=0.001, required=False, min_value=0)

async def optimize(ctx, pair, start_date, end_date, fees):
sage tendon
#

remove type=

pulsar ferry
#

ahh ok

sage tendon
#

and technically you dont even need it for str, because options are strings by default

#

also id highly recommend typehinting the parameters in your function definition, especially ctx
helps a lot during development

pulsar ferry
#

i need to type hint as well as define the type in the option? i thought doing type= was equivalent

sage tendon
#

you dont have to

#

but its just nicer, especially if you do it for ctx (imo)

pulsar ferry
#

what would the ctx type hint be?

sage tendon
#

because else your IDE wont suggest anything if you do parameter.<anything>

sage tendon
lean garnet
#

Hello, is it possible to create a private user bot (that only the owner can add) ?

errant trout
#

this toggle also takes effect on user installations

lean garnet
#

fixed now

deft kestrel
#

What if I want my slash commands available only in guilds and not in private chat

shell radish
limpid marten
#

Another one

#

Command.call() missing 1 required positional argument: 'context'

#
@bot.hybrid_command()
async def purge(ctx:commands.Context, limit):
    await purge(limit=limit, bulk=True)
    await ctx.send(f'Successfully purged {limit} messages.')
sage tendon
#

wtf is hybrid_command

#

that isnt a pycord thing

limpid marten
#

it is

#

both prefix and slash command

sage tendon
#

no, thats called bridge

limpid marten
sage tendon
limpid marten
#

so do i use that instead

sage tendon
#

there is something very wrong

sage tendon
limpid marten
sage tendon
#

then you aren't using pycord

limpid marten
sage tendon
#

show your pip list

#

because i think they call it hybrid command

limpid marten
sage tendon
#

yea, then you are wrong here lol

limpid marten
#

oh

#

wait so pycord and discordpy IS NOT THE SAME THING

sage tendon
#

no

limpid marten
#

oh fuck me i used the discordpy doc for my whole code

sage tendon
#

lol

limpid marten
#

๐Ÿ˜ญ

#

also how can i use the slash commands everywhere thingie

sage tendon
#

thats a user app

#

if you wanna keep using discord.py you'll have to ask them how to do it

sage tendon
#

?

limpid marten
#

alright whats the discordpy server

sage tendon
#

shrug google it
or its on their website

limpid marten
#

oh yup found it

outer trout
#

I have a very weird problem:

If a channel is moved to another category, the new channel is not part of the .channels list of the category object (but in discord I can see it is). I have to restart the bot, then its there. The weird thing is, the same code worked without any problems like a year long and since a few days I have this problem. Some change in the API?

category = discord.utils.get(bot.guilds[0].categories, id=id_int)
all_channels = category.channels
limpid marten
sage tendon
#

you are calling the function of the command again

#

that makes no sense

clear lark
#

Is it possible to check if the current message is being sent as ephemeral? while I do know ctx.response.defer(ephemeral=True), in my case its user app slash command, which it automatically sets the message ephemeral if it detects Use External Apps server permission is denied. The command has ctx.send commands which it will cause MissingAccess error if it tries to send message if the command is user-installed

sage tendon
#

that will tell you if its installed as user app or on the guild (or even both)

#

or lock the entire command to only being used when the bot is guild installed

clear lark
#

eh

'ApplicationContext' object has no attribute 'authorizing_integration_owners'
#

but this is exactly what i need

sage tendon
#

mb its in interaction

#

ctx.interaction.authorizing...

limpid marten
#

i have an issue where the embed in my discord bot just wont load

sage tendon
#

show your code

#

also aren't you using discord.py now? then you should ask there

limpid marten
fresh sierra
sage tendon
#

no, thats not how that works

limpid marten
#

honestly i have no idea where discordpy and pycord is used in my code ๐Ÿ˜ญ

sage tendon
#

then decide for one and make it equal across your bot

limpid marten
fresh sierra
#

Then if itโ€™s working itโ€™s pycord

sage tendon
limpid marten
#

but the question is: which one is better

sage tendon
#

for anything but prefix commands pycord

#

hands down

#

and in prefix commands they're largely the same under the hood

limpid marten
#

ok then ill use pycord

fresh sierra
#

Why prefix command is under the hood ?

limpid marten
#

ill just delete discordpy i guess

sage tendon
#

pycord forked from discord.py when application commands were just announced

#

thus the code for all the prefix stuff is still the same for a lot of it

#

unlike for application commands where discord.py is completely shit

#

and pycord has its own implementation

limpid marten
#

discord.ext is discordpy right

sage tendon
#

pycord has that path too

limpid marten
#

uhhhh.........

sage tendon
#

just uninstall anything called discord (and pycord if you have it), and then ONLY do pip install py-cord

limpid marten
limpid marten
#

okay

#

done

#

pretty sure

sage tendon
#

show your pip list
and also restart your IDE

limpid marten