#discord-bots

1 messages · Page 200 of 1

tired pollen
#

Don't use this method to load cog this is too old
Just load your cogs in setup_hook() event

tired pollen
#

Its just an event

#

Instead of creating new func (load) just change it to setup_hook() event

#
@bot.event
async def setup_hook():
    ...
slate swan
#

aight tysm

smoky sinew
#

make a message command to sync

tired pollen
#

To load cogs

slate swan
#

i dont even know what im using xd

#

i did it with a tut

tired pollen
#

Bot = commands.bot()

unkempt canyonBOT
#

Hey @slate swan! I noticed you posted a seemingly valid Discord API token in your message and have removed your message. This means that your token has been compromised. Please change your token immediately at: https://discord.com/developers/applications

Feel free to re-post it with the token removed. If you believe this was a mistake, please let us know!

tired pollen
#

Also from discord.ext import commands

slate swan
#
import asyncio

import discord
import os

from discord import Intents
from discord.app_commands import commands
from dotenv import load_dotenv
import discord.ext.commands

intents = Intents.default()

bot = discord.Client(
    intents=intents,
    debug_guilds=[1069881952460603462]  # hier server id einfügen
)


@bot.event
async def on_ready():
    print(f"{bot.user} ist online")

@bot.event
async def setup_hook():
    for filename in os.listdir("cogs"):
        if filename.endswith(".py"):
            await bot.load_extension(f"cogs.{filename[:-3]}")


bot.run("cant send tokens here")




``` is the code i have atm
tired pollen
#

Yea that's ok but client don't have load_extension() method

#

i mean discord.Client

slate swan
#

can i just remove it?

smoky sinew
#

replace it with commands.Bot

tired pollen
#

Bro

slate swan
#

aight sry

tired pollen
smoky sinew
slate swan
#

sure ty

tired pollen
#

Also you forget command_prefix kwarg

slate swan
# smoky sinew replace it with commands.Bot

File "main.py", line 28, in setup_hook
await commands.Bot.load_extension(f"cogs.{filename[:-3]}")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: BotBase.load_extension() missing 1 required positional argument: 'name'

smoky sinew
#

it's not a kwarg though @tired pollen

smoky sinew
slate swan
slate swan
tired pollen
shy abyss
#

damn

tired pollen
shy abyss
#

are you in the western hemisphere?

#

2am

#

jeez

smoky sinew
#

eastern probably

shy abyss
#

yeah

smoky sinew
shy abyss
#

most likely

slate swan
smoky sinew
#

!e ```py
class Dog:
def init(self, name):
self.name = name

def say_name(self):
    print(self.name)

my_dog = Dog("insert name here")
my_dog.say_name()

print("now dog.say_name:")
Dog.say_name()

unkempt canyonBOT
#

@smoky sinew :x: Your 3.11 eval job has completed with return code 1.

001 | insert name here
002 | now dog.say_name:
003 | Traceback (most recent call last):
004 |   File "<string>", line 12, in <module>
005 | TypeError: Dog.say_name() missing 1 required positional argument: 'self'
vocal snow
#

although i would learn basic python first if you haven't done that

tired pollen
slate swan
slate swan
#

guys, how do i count the number of characters from an expression?

tired pollen
slate swan
#

i'm planning to use it to count how many brackets there is in a contect of my list

smoky sinew
#

otherwise you will struggle

warped mirage
#

Guys sorry for this question, but what's the max commands / sub commands a discord bot can have?

slate swan
smoky sinew
slate swan
slate swan
#

!e def name(name, age)
print(f"hi, i am {name}, and i am {age} years old")

name("averages name", 15)

#

!e def name(name, age):
print(f"hi, i am {name}, and i am {age} years old")

name("averages name", 15)

unkempt canyonBOT
#

@slate swan :x: Your 3.11 eval job has completed with return code 1.

001 |   File "<string>", line 2
002 |     print(f"hi, i am {name}, and i am {age} years old")
003 |     ^
004 | IndentationError: expected an indented block after function definition on line 1
slate swan
#

!e
def name(name, age):
print(f"hi, i am {name}, and i am {age} years old")

name("averages name", 15)

unkempt canyonBOT
#

@slate swan :white_check_mark: Your 3.11 eval job has completed with return code 0.

hi, i am averages name, and i am 15 years old
humble verge
#

does anyone have an understanding of how discord bots work? Past using a pre-made api. I think it's http requests using your bot key and stuff right? Where can I find which exact calls are being made?

smoky sinew
humble verge
#

Thanks

smoky sinew
#

websocket is only for voice i think

slate swan
#

okay, i discovered that discord.py only accepts 16 characters

#

how do i expand it?

smoky sinew
#

what do you mean

#

i don't think it does

#

@slate swan you have a space in your input right?

slate swan
#

this is the expression that my bot is gathering:

smoky sinew
#

you need to use quotes around an argument with spaces

slate swan
#

this is my input:
2d6+[[5*1d4]/1d3 *4d8]/2d5

smoky sinew
#

!command "your input"

slate swan
#

oh now i see

graceful ermine
#

how do I fix this

Ignoring exception in on_connect
Traceback (most recent call last):
  File "C:\Python310\lib\site-packages\nextcord\client.py", line 512, in _run_event
    await coro(*args, **kwargs)
  File "C:\Python310\lib\site-packages\nextcord\client.py", line 2482, in on_connect
    await self.sync_application_commands(
  File "C:\Python310\lib\site-packages\nextcord\client.py", line 2296, in sync_application_commands
    await self._connection.sync_application_commands(
  File "C:\Python310\lib\site-packages\nextcord\state.py", line 829, in sync_application_commands
    await self.register_new_application_commands(data=data, guild_id=guild_id)
  File "C:\Python310\lib\site-packages\nextcord\state.py", line 1036, in register_new_application_commands
    await self.register_application_command(app_cmd, guild_id)
  File "C:\Python310\lib\site-packages\nextcord\state.py", line 1071, in register_application_command
    raise e
  File "C:\Python310\lib\site-packages\nextcord\state.py", line 1067, in register_application_command
    raw_response = await self.http.upsert_global_command(self.application_id, payload)
  File "C:\Python310\lib\site-packages\nextcord\http.py", line 393, in request
    raise HTTPException(response, data)
nextcord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In name: String value did not match validation regex.```
#
import nextcord, os
from datetime import datetime

from nextcord.ext import commands
from nextcord import ui
import random

intents = nextcord.Intents.all()


bot = commands.Bot(command_prefix='*', intents=intents)



@bot.slash_command(name="Ban", description="Bans a user")
async def ban(interacton: nextcord.Interaction, member: nextcord.Member, Reason):
    
    
    
    member.ban(Reason=Reason)
    
    interacton.send(f"I have banned {member.mention} for {Reason}")
    
    
    
    
    
    
@bot.slash_command(name="Avatar", description="Shows a avatar of a user")
async def Avatar(interacton: nextcord.Interaction, member: nextcord.Member): 
    

    
    Embed = nextcord.Embed(title=f"{member.mention} pfp!")
    Embed.set_thumbnail(url=member.avatar)
    
    interacton.send(Embed=Embed)```
slate swan
graceful ermine
#

@slate swan

slate swan
#

wdym

#

use lowercase names for your slash commands

ionic garden
#

can i put autocomplete in a modal

naive briar
#

No

spice carbon
#

how can i create a "empty" button (a button without label)?

#

or with a invisible label

unkempt canyonBOT
#

examples/views/tic_tac_toe.py lines 12 to 16

# A label is required, but we don't need one so a zero-width space is used
# The row parameter tells the View which row to place the button under.
# A View can only contain up to 5 rows -- each row can only have 5 buttons.
# Since a Tic Tac Toe grid is 3x3 that means we have 3 rows and 3 columns.
super().__init__(style=discord.ButtonStyle.secondary, label='\u200b', row=y)```
spice carbon
#

thanks

robust fulcrum
#

Hi all
Ca anyone help me understand this code , i asked chatgpt for a views manager it gave me this code

class View:
    def __init__(self, state=None):
        self.state = state

class ViewsManager:
    def __init__(self, initial_state):
        self._views = {}
        self._state = initial_state

    def register_view(self, view_id, view):
        self._views[view_id] = view

    def update_state(self, new_state):
        self._state = new_state

    def get_state(self):
        return self._state

    async def handle_view(self, interaction):
        view_id = interaction.data['custom_id']
        if view_id in self._views:
            view = self._views[view_id]
            new_state = view.handle_interaction(self._state, interaction)
            if new_state != self._state:
                self._state = new_state
                # Broadcast new state to all registered views
                for v in self._views.values():
                    await v.update_state(self._state)
naive briar
#

Don't ask ChatGPT about dpy 2 stuff

#

It doesn't understand

#

And that certainly is not dpy view things

robust fulcrum
grim beacon
#

I'm building a text RPG system for a future discord bot

graceful ermine
#

I fixed it

#

how do I make a permission handler for slash commands?

#
   
@bot.slash_command(name="kick", description="kicks a member")
@application_checks.has_permissions(administrator=True)
async def kick(interaction: nextcord.Interaction, member: nextcord.Member, reason=None):
    if (not interaction.user.guild_permissions.administrator):
            await interaction.send("System faliure, you do not have the system to do this code red :red:")
            return

    embed = nextcord.Embed(title=f"I have kicked",
                        description=f"{member.mention} for {reason}",
                        colour=nextcord.Color.green())
    
    await member.kick(reason=reason)
    
    await interaction.send(embed=embed)
    
    ```
#

Please help!

smoky sinew
graceful ermine
#

@smoky sinew

smoky sinew
#

i was responding to your old message

#

check your help channel

polar ice
smoky sinew
#

message.guild.id is different than message.guild_id

naive briar
#

Why not just use that then

#

And use aiohttp instead of requests

polar ice
#

@smoky sinew didnt even notice that, i need a break from the computer 😄 thanks!

smoky sinew
#

sometimes we overlook the simplest mistakes

polar ice
#

exactly that!

ionic garden
#

does self.add_item() only work in __init__?

naive briar
#

What is self

ionic garden
#

a view

smoky sinew
ionic garden
#

oh just before you send it

ionic garden
#

that's a bruh

#

btw i'm setting button.disable = True, but it doesn't seem to affect anything

#
    @ui.button(label="Start fishing!", style=discord.ButtonStyle.blurple)
    async def bait(self, i: discord.Interaction, button: ui.Button):
        coins = dm.get_user_coin(self.user.id)
        if coins < BAIT_COST:
            await i.response.send_message(
                f"You need at least {BAIT_COST} to buy bait!",
                ephemeral=True
            )
            return

        button.disabled = True
```it doesn't seem to do anything
sick birch
#

You need to either send it again or edit the original message with the newly modified local state

ionic garden
#

so you can't disable a button when you click on it or smth?

sick birch
#

Just need to update discord with the new state (with the disabled button)

ionic garden
#

and how would i do that?

smoky sinew
naive briar
#

The old view but with edited items 🧋

smoky sinew
#

it's the updated view

sick birch
#

You pass in self to the view kwarg

#

view=self

sick birch
#

JSON keys have to be strings, while ctx.guild.id is an integer

#

So it never matches

polar ice
sick birch
#

No, when you do a lookup in server_settings

#

You're searching for an integer key but JSON doesn't support integer keys

sick birch
#

Looks like you either took too long to respond or already responded

ionic garden
#
    @ui.button(label="Start fishing!", style=discord.ButtonStyle.blurple)
    async def bait(self, i: discord.Interaction, button: ui.Button):
        coins = dm.get_user_coin(self.user.id)
        if coins < BAIT_COST:
            await i.response.send_message(
                f"You need at least {BAIT_COST} to buy bait!",
                ephemeral=True
            )
            return

        button.disabled = True
        await i.edit_original_response(view=self)
```idts?
naive briar
#

Respond to the interaction

#

!d discord.InteractionResponse.edit_message

unkempt canyonBOT
#

await edit_message(*, content=..., embed=..., embeds=..., attachments=..., view=..., allowed_mentions=..., delete_after=None)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Responds to this interaction by editing the original message of a component or modal interaction.
ionic garden
#

oh there's an i.response at the bottom

#

should've probably sent the full code, sorry

unkempt canyonBOT
#

Hey @strong plover!

You either uploaded a .txt file or entered a message that was too long. Please use our paste bin instead.

strong plover
#

I boost in league of legends. I figured why not make a bot that makes the process easier for a client to figure out a quote and get a payment form through stripe.

Simple enough, I was gonna start the task, I haven't been programming for years so I feel super rusty. I thought, why not ask chatGPT to make this for me, obviously their stuff is going to be out of date but I figured I would give it a shot.

This is what they came up with, since I haven't been coding for so long, I have little to no idea how to update it to the current state of discords api. Although I could probably figure it out.

Anyways, here's the generated code from chatgpt.

https://paste.pythondiscord.com/udijupaxup

vale wing
#

That view is aids

strong plover
#

Lol i figured as much, was just having fun with it.

vale wing
#

That components nesting

strong plover
#

Yeah I figured the functions should've been called under the view, not the cog, but I'm new to programming again so idk

slate swan
#

chatgpt knows nothing about discord.py views 🔪 views werent even released in 2020

strong plover
#

interesting, I wonder why it attempted to use them

brisk shard
#

Not well anyway

slate swan
#

it will still be highly inaccurate

brisk shard
#

Ive had it give totally accurate results when doing what i just said… but yeah i wouldnt count on it

dull terrace
naive briar
#

🧐

dull terrace
#
response = f"Hello {user.mention}! Would you be so kind as to vote for me? I would be ever so grateful! And as a token of my appreciation, I will reward you with a lemon! :lemon: \n\nYou can vote for me by clicking the link here: [voting link]"```
naive briar
#

That's funny

slate swan
#

is it alr downloaded or something?\

vocal snow
#

can you link the docs?

ocean dragon
#

How can I create a global error handler within a cog?

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

    @commands.Cog.listener()
    async def on_ready(self) -> None:
        print(f"Logged in as {self.bot.user} (ID: {self.bot.user.id})")

    ...

async def setup(bot: commands.Bot) -> None:
    await bot.add_cog(BotListeners(bot))
naive briar
#

!d discord.on_error

unkempt canyonBOT
#

discord.on_error(event, *args, **kwargs)```
Usually when an event raises an uncaught exception, a traceback is logged to stderr and the exception is ignored. If you want to change this behaviour and handle the exception for whatever reason yourself, this event can be overridden. Which, when done, will suppress the default action of printing the traceback.

The information of the exception raised and the exception itself can be retrieved with a standard call to [`sys.exc_info()`](https://docs.python.org/3/library/sys.html#sys.exc_info "(in Python v3.11)").

Note

`on_error` will only be dispatched to [`Client.event()`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Client.event "discord.Client.event").

It will not be received by [`Client.wait_for()`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Client.wait_for "discord.Client.wait_for"), or, if used, [Bots](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#ext-commands-api-bot) listeners such as [`listen()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.listen "discord.ext.commands.Bot.listen") or [`listener()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog.listener "discord.ext.commands.Cog.listener").

Changed in version 2.0: The traceback is now logged rather than printed.
naive briar
#

Register a listener of this event

ocean dragon
#

is it just this then?

    @commands.Cog.listener()
    async def on_error(event, *args, **kwargs) -> None:
vale wing
#

Event? It should be a method of Bot or @bot.event

vale wing
#

The event for command errors is different

#

!d discord.app_commands.CommandTree.on_error idk dpy actually but this is all I could find

unkempt canyonBOT
#

await on_error(interaction, error, /)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

A callback that is called when any command raises an [`AppCommandError`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.AppCommandError "discord.app_commands.AppCommandError").

The default implementation logs the exception using the library logger if the command does not have any error handlers attached to it.

To get the command that failed, [`discord.Interaction.command`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.Interaction.command "discord.Interaction.command") should be used.
vale wing
#

If you use slash commands

ocean dragon
#

ah that's probably what I want

#

that probably wont work with cogs though

vale wing
#

!d disnake.disnake.ext.commands.on_slash_command_error disnake is so good

unkempt canyonBOT
#

disnake.ext.commands.on_slash_command_error(inter, error)```
An error handler that is called when an error is raised inside a slash command either through user input error, check failure, or an error in your own code.

A default one is provided ([`Bot.on_slash_command_error()`](https://docs.disnake.dev/en/latest/ext/commands/api.html#disnake.ext.commands.Bot.on_slash_command_error "disnake.ext.commands.Bot.on_slash_command_error")).
vale wing
#

Weird bug

vale wing
ocean dragon
#

nvm there is also a cog_app_command_error

#

am I not using it right, or why is nothing getting printed on error?

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

    async def cog_app_command_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError) -> None:
        print("App command error")
        return await super().cog_app_command_error(interaction, error)
        
    async def cog_command_error(self, ctx: commands.Context, error: commands.CommandError) -> None:
        print("Command error")
        return await super().cog_command_error(ctx, error)

    @commands.Cog.listener()
    async def on_ready(self) -> None:
        print(f"Logged in as {self.bot.user} (ID: {self.bot.user.id})")

async def setup(bot: commands.Bot) -> None:
    await bot.add_cog(BotListeners(bot))
vague wasp
#

How to deploy python flask web app

naive briar
golden portal
ionic garden
ocean dragon
# golden portal that is only called for errors that are happening within that cog, i dont see an...
    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload:discord.RawReactionActionEvent) -> None:
        if payload.member.bot:
            return

        if payload.channel_id == config.channel.roles:
            if payload.emoji.id in config.role_reactions:
                await payload.member.remove_roles(config.role_reactions[payload.emoji.id])
            if payload.emoji.name in config.role_reactions:
                await payload.member.remove_roles(config.role_reactions[payload.emoji.name])

2023-02-20 17:45:53 ERROR discord.client Ignoring exception in on_raw_reaction_remove
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 409, in _run_event
await coro(*args, **kwargs)
File "D:\projects\python\mybot\commands\stats\listeners\stats_listeners.py", line 42, in on_raw_reaction_remove
if payload.member.bot:
AttributeError: 'NoneType' object has no attribute 'bot'

#

there are role reaction listeners, but the error gets printed instead

bright wedge
ionic garden
#

yeah i guess?

bright wedge
naive briar
unkempt canyonBOT
#

Whether guild member related events are enabled.

This corresponds to the following events...

ocean dragon
#

read up guys 😅 I'm just trying to get my global error handling working

naive briar
#

It's clearly saying that payload.member is returning None

ocean dragon
#

yes but that was just to test if my error handling function works

bright wedge
#

?

golden portal
ocean dragon
golden portal
#

oh i see, well, thats an event, cog_command_error captures command errors within the cog, cog_app_command_error captures app command errors within the cog

#

not events

ocean dragon
#

wouldn't the error be a command error within the cog?

golden portal
#

no, thats an event

#

event error gets sent to bot.on_error

ocean dragon
#

which event can I listen to so that I have access the interaction?

golden portal
#

for?

ocean dragon
#

no specific reason, other than that interaction contains more information than context so I'd rather use that instead

golden portal
#

no i mean, in what context, for app command interaction, for view item interaction? what is it

ocean dragon
#

oh

#

app command interaction

#

slash command

golden portal
#

you want global app error handler?

ocean dragon
#

yeah

golden portal
#

its just bot.tree.on_error

#

it doesnt have an event, it gets sent to there

naive briar
#

!d discord.app_commands.CommandTree.error

unkempt canyonBOT
#

@error(coro)```
A decorator that registers a coroutine as a local error handler.

This must match the signature of the [`on_error()`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.CommandTree.on_error "discord.app_commands.CommandTree.on_error") callback.

The error passed will be derived from [`AppCommandError`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.AppCommandError "discord.app_commands.AppCommandError").
hushed galleon
#

what interaction would you want when you're handling an error for some random event?

#

or was that listener stuff not relevant anymore?

ocean dragon
hushed galleon
#

ah ok

ionic garden
sick birch
#

Interactions can only be responded to once

smoky sinew
#

anyone want to give feedback on my gist

ionic garden
#

turns out you have to respond before using edit_original_response

smoky sinew
slate swan
unkempt canyonBOT
#

pagination.py line 4

from typing import (List,)```
smoky sinew
#

they are disabled

slate swan
#

oh wait you are, nvm that

#

yes

smoky sinew
#

and wdym?? why would i use typehints?

vocal snow
#

?? you are using typehints

slate swan
#

why would you import it that way?

#

(List,)

smoky sinew
#

so it's easier to import more later i guess

slate swan
#

um ok

smoky sinew
#

i can change it

#

there

slate swan
unkempt canyonBOT
#

pagination.py line 52

message = await interaction.client.wait_for(```
smoky sinew
#

true

unkempt canyonBOT
#

pagination.py line 46

and message.channel == interaction.message.channel```
smoky sinew
#

!d discord.ext.commands.Bot.wait_for

unkempt canyonBOT
#

wait_for(event, /, *, check=None, timeout=None)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Waits for a WebSocket event to be dispatched.

This could be used to wait for a user to reply to a message, or to react to a message, or to edit a message in a self-contained way.

The `timeout` parameter is passed onto [`asyncio.wait_for()`](https://docs.python.org/3/library/asyncio-task.html#asyncio.wait_for "(in Python v3.11)"). By default, it does not timeout. Note that this does propagate the [`asyncio.TimeoutError`](https://docs.python.org/3/library/asyncio-exceptions.html#asyncio.TimeoutError "(in Python v3.11)") for you in case of timeout and is provided for ease of use.

In case the event returns multiple arguments, a [`tuple`](https://docs.python.org/3/library/stdtypes.html#tuple "(in Python v3.11)") containing those arguments is returned instead. Please check the [documentation](https://discordpy.readthedocs.io/en/latest/api.html#discord-api-events) for a list of events and their parameters.

This function returns the **first event that meets the requirements**...
vocal snow
#

interaction.message can be None

smoky sinew
#

why would it be none

#

when the message is deleted?

slate swan
#

nope

#

you will always get the message object in a component interaction

#

it's missing in slash command interactions

#

the evil side of discord.py's single interaction class

smoky sinew
#

i just realized i can do interaction.channel anyway

vocal snow
smoky sinew
#

i don't know how to ignore them though

slate swan
#

if you want to ignore the error in a particular line

#

or you can turn off optional error type from your type checker options

smoky sinew
#

i don't get why context implements messageable but interaction doesn't

vocal snow
#

or maybe just typing.cast them

slate swan
#

i prefer something like ```py
assert (message:=interaction.message) is not None

now the type of message is Message

message.channel

#

using isinstance is also an option

broken flame
#

Why isn’t this working?

#

import discord
from discord.ext import commands
bot - commands. Bot (command_prefix-'!")
@bot.event
async def on_ready():
print('Bot is online.')
@bot.command
async def vote(ctx):
user - ctx.author
response - f"Hello (user mention)! Would you be so kind as to vote for me? I wd await ct.send (response)
@bot.command()
async def lemon (ctx):
user = ctx.author
response - f"Here you go, {user.mention)! Thanks for voting for me! : lemon:" await ctx.send(response)
bot. run('TOKEN")

smoky sinew
#

command_prefix-'!"

#

ct.send, no closed quotes in the vote command and no indentation

#

also no paranthesis on @bot.command, bot - ... and user - ... instead of bot = ... and user = ...

#

@broken flame

broken flame
#

Thanks! I’m still quite new to this! 😉

ocean dragon
#
class MyBot(commands.Bot):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    @bot.tree.on_error
    async def on_app_command_error(interaction: discord.Interaction, error: discord.app_commands.AppCommandError) -> None:
        ...

any way to do this? or do I have to have the instance ready for the decorator

sick birch
sick birch
smoky sinew
#

is it possible to have a slash command help command?

sick birch
#

You can also subclass CommandTree

ocean dragon
sick birch
ocean dragon
#

can you show how I'd subclass CommandTree

sick birch
ionic garden
#

so i have a view that can hold multiple values
like at the end of a game you've win, lose, or draw
should this be a string or enum

smoky sinew
sick birch
# ocean dragon can you show how I'd subclass CommandTree
class MyCustomTree(CommandTree):
  async def on_error(interaction: Interaction, error: AppCommandError) -> None:
    # handle error here

async def MyCustomBot(Bot):
  def __init__(self, *args, **kwargs) -> None:
    super().__init__(*args, **kwargs)
    self.tree = MyCustomTree(...)
#

You can also customize other behaviour of CommandTree this way

hushed galleon
# smoky sinew i don't get why context implements messageable but interaction doesn't

hmm in theory it should be possible for Interaction to implement a TextChannel-like interface required by most of the methods, maybe they just havent gotten around to doing so?

though polymorphism would get messy with the send() method because the set of parameters is different, e.g. ephemeral is only available for interaction, and reference isnt allowed, so what do you do? change the ABC so every Messageable "supports" both parameters?

ocean dragon
sick birch
#

You could probably write your own, though, if discord.py doesn't natively support it

ocean dragon
#

can I get the full stacktrace from AppCommandError into a string variable?

#

(probably can, but how)

hushed galleon
#

!d traceback.format_exception is probably what you'd want to use

unkempt canyonBOT
#

traceback.format_exception(exc, /, [value, tb, ]limit=None, chain=True)```
Format a stack trace and the exception information. The arguments have the same meaning as the corresponding arguments to [`print_exception()`](https://docs.python.org/3/library/traceback.html#traceback.print_exception "traceback.print_exception"). The return value is a list of strings, each ending in a newline and some containing internal newlines. When these lines are concatenated and printed, exactly the same text is printed as does [`print_exception()`](https://docs.python.org/3/library/traceback.html#traceback.print_exception "traceback.print_exception").

Changed in version 3.5: The *etype* argument is ignored and inferred from the type of *value*.

Changed in version 3.10: This function’s behavior and signature were modified to match [`print_exception()`](https://docs.python.org/3/library/traceback.html#traceback.print_exception "traceback.print_exception").
ocean dragon
#

ty

ocean dragon
eager portal
#

I have a button to close tickets on my discord bot and I keep getting this error after trying to add message trasscript: object async_generator can't be used in 'await' expression

smoky sinew
#

why don't you print the traceback in your error handler

#

anyways, you can't do await channel.history, you have to loop over it

#
async for message in channel.history(...):
#

@eager portal

clear ivy
#

Where do I get this 6 digit code?

#

I didn't get a text or an email

sick birch
#

Like Google Authenticator

clear ivy
#

or an auth app

sick birch
#

Well, discord wouldn't be asking you for it then 🙂

clear ivy
sick birch
#

Looks like this fyi

clear ivy
#

Yeah, I never had that

clear ivy
sick birch
#

Ok well, enable it and follow the steps

clear ivy
#

Alright, I can try\

#

Wait

#

I don't have my phone rn

#

so I can't

smoky sinew
sick birch
#

eh, it resets in a few seconds

ocean dragon
#

there is a tree_cls parameter in commands.Bot constructor but I'm not sure if that's the same

#

can't get that working either

graceful ermine
#

Hey how would I add a error handler in my interaction?

#

@bot.slash_command(name="ask", description="Give you a response with the prompt")

async def ask(interaction: nextcord.Interaction, prompt: str):

    await interaction.response.defer()

    openai.api_key = ""
    
    
    
    await interaction.send("if it takes too long to load your prompt then that means the bot went through an error or the prompt was too long!")
        
    response = openai.Completion.create(
        model="text-davinci-003",
        prompt=prompt,
        temperature=0,
        max_tokens=4000,
        top_p=1,
        frequency_penalty=1,
        presence_penalty=1,
        stop=["Human:", "AI:"]
    )

    AI_Message = response['choices'][0]['text']

    embed = nextcord.Embed(
        title="Here you go!",
        description=f"{AI_Message}",
        timestamp=datetime.datetime.now(),
    )
    embed.set_footer(text=f"By {interaction.user.name}#{interaction.user.discriminator}", icon_url=interaction.user.avatar.url)


        
    
    await interaction.followup.send(embed=embed)
    ```

sometimes when someone writes a long prompt the bot fails
smoky sinew
eager portal
smoky sinew
eager portal
#

no

#

i dont think so anyhwayt

graceful ermine
#

I have multiple bots lmao

#

I just want to experience from both forks

vale sierra
#

hello, can someone help resolve a small issue : my bot doesn't answer/respond at any commands in a server (permissions is right) but only answer in private. It's been a while that my bot hasn't being turn on. This is my intents code : python bot = commands.Bot(command_prefix="+", description="...", help_command=None, intents=Intents.all()) bot.ticket_configs = {} intents = discord.Intents.default() intents.members = True bot.multiplier = 1 bot.db = aiosqlite.connect("expData.db") bot.db2 = aiosqlite.connect("warnData.db") bot.run('TOKEN')

smoky sinew
#

also, you are using all intents, not just members

vale sierra
vale sierra
smoky sinew
wheat yoke
#

can i get the category id from the message ?

vale sierra
slate swan
#

How do I access the url and change it in the forloop?

smoky sinew
slate swan
#

urllib

#

Oh

smoky sinew
#

and you're parsing message commands manually

eager portal
#

can someone help me i can find the dir in another test python program but not in my ticket one idk why its the same code i know it works on another program

#

can anyone help me?

slate swan
#

so does this show the users local time?
or is there a way to manipulate it to show AEST, UTC, etc...
<t:1676938269:F>

eager portal
#
datetime.datetime.now().strftime("%m/%d/%Y at %H:%M:%S")```
chilly dove
slate swan
#

I'm asking because I wanted to use this method for timestamps. I know there's datetime, but I was curious how this unix worked and if it worked with embeds

slate swan
#

ty

smoky sinew
#

yes, that would work

graceful ermine
#

Hey

#

@bot.slash_command(name="ask", description="Give you a response with the prompt")

async def ask(interaction: nextcord.Interaction, prompt: str):

    await interaction.response.defer()

    openai.api_key = "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"
    
    
    
    await interaction.send("if it takes too long to load your prompt then that means the bot went through an error or the prompt was too long!")
        
    response = openai.Completion.create(
        model="text-davinci-003",
        prompt=prompt,
        temperature=0,
        max_tokens=4000,
        top_p=1,
        frequency_penalty=1,
        presence_penalty=1,
        stop=["Human:", "AI:"]
    )

    AI_Message = response['choices'][0]['text']

    embed = nextcord.Embed(
        title="Here you go!",
        description=f"{AI_Message}",
        timestamp=datetime.datetime.now(),
    )
    embed.set_footer(text=f"By {interaction.user.name}#{interaction.user.discriminator}", icon_url=interaction.user.avatar.url)
    
    
    
    

    await interaction.send(embed=embed)
    
    if isinstance(error, nextcord.errors.ApplicationInvokeError):
        await interaction.send("Something went wrong!")```
graceful ermine
#

???

polar ice
#

Any idea which is the best way to return the role id for an administrator. cant find anything on google for pycoord?

polar ice
#

of a guild

upbeat otter
unkempt canyonBOT
upbeat otter
#

Use this

#

Wait

#

Role Id....the topmost role?

#

Sorry 💀

polar ice
#

guild owner would be better thinking about it

upbeat otter
#

Hm

hushed galleon
#

if you mean the administrator permission, you'd probably want to iterate through all the roles for one that has it

smoky sinew
#

slash commands should have been designed like this

#

would have been so much better

polar ice
#

@upbeat otter Just printed this

                server_settings[message.guild.id] = {
                    'battlemetrics_id': message.content,
                    'admin_id': discord.Guild.owner_id
                }```

11640919
<member 'owner_id' of 'Guild' objects>```

Still isnt returning the admin_id as the guild owner id. any ideas?

smoky sinew
#

what do you mean admin_id

polar ice
smoky sinew
#

what is it returning then?

polar ice
#

i also tried py discord.utils.get(message.guild.roles, name="Administrator") but that just returns the name?

smoky sinew
#

you're saying you want to get the ID of the "Administrator" role

#

or you are saying that you want to get the id of the person who created the server

#

also, discord.utils.get will return the Role object

#

not the name

polar ice
#

Ah sorry my bad, both would work.

#

So i was just testing, ideally the administrator role id. but if thats to complicated then the owners id would also work

smoky sinew
#

you are doing discord.Guild.owner_id, you need message.guild.owner_id

#

it doesn't know which guild you are referring to when you say discord.Guild.owner_id

polar ice
#

🤦‍♂️ ofcourse

#

@smoky sinew awesome, thanks for the help. apologies for the noob questions 😄

smoky sinew
#

np

polar ice
# smoky sinew np

It prints properly now, but now its erroring on updating the SQL DB 😪

  File "C:\Users\Jorda\PycharmProjects\SCUMBot v1 - 2023(NEW)\main.py", line 241, in button_continue
    f"VALUES ('{interaction.guild.id}','{server_settings[interaction.guild.id]['admin_id']}','{server_settings[interaction.guild.id]['battlemetrics_id']}','{server_settings[interaction.guild.id]['name']}','{server_settings[interaction.guild.id]['description']}','{server_settings[interaction.guild.id]['location']}')")
KeyError: 'admin_id'```
slate swan
#

!sql-fstrings

unkempt canyonBOT
#

SQL & f-strings
Don't use f-strings (f"") or other forms of "string interpolation" (%, +, .format) to inject data into a SQL query. It is an endless source of bugs and syntax errors. Additionally, in user-facing applications, it presents a major security risk via SQL injection.

Your database library should support "query parameters". A query parameter is a placeholder that you put in the SQL query. When the query is executed, you provide data to the database library, and the library inserts the data into the query for you, safely.

For example, the sqlite3 package supports using ? as a placeholder:

query = "SELECT * FROM stocks WHERE symbol = ?;"
params = ("RHAT",)
db.execute(query, params)

Note: Different database libraries support different placeholder styles, e.g. %s and $1. Consult your library's documentation for details.

See Also
Python sqlite3 docs - How to use placeholders to bind values in SQL queries
PEP-249 - A specification of how database libraries in Python should work

smoky sinew
#

but anyway as sarth mentioned your bot is vulnerable to SQL injection

fringe matrix
#

Anything better than nextcord?

#

And whose learning curve is lower

slate swan
#

disnake

slate swan
#

dpy with a low learning curve?

smoky sinew
#

yes

#

there is a lot of documentation for it compared to a fork or an entirely new library

slate swan
#

you can't even learn how to make choices properly without using ?tag slashchoices in the official server lol, talk about documentation they added the docs now nvm, the cmd tree is confusing as well bored

#

dpy is under documented when it comes to app commands

#

but yeah disnake still got better docs and impl

hushed galleon
#

^ waiting for the day Rapptz/discord.py#7654 gets finished

lament depotBOT
polar ice
#
                    server_settings[message.guild.id] = {
                        "ip": f'{server_ip}:{server_port}',
                        'admin_id': server_settings[message.guild.id]['admin_id'],
                        'battlemetrics_id': server_settings[message.guild.id]['battlemetrics_id'],
                        "name": title,```

Any ideas when i go to insert the ip onto my SQL DB it doesnt work?

ive printed server_settings and it all prints as it should?
glass tangle
#

what are the legal/contractual restrictions on discord bots?

slate swan
#

the general TOS still apply

mild token
#

i am using discord.py wants to group my commands i want to add parent command too

#

i want something like this /top_command this should also work then /top_command sub_command

slate swan
#

not possible

#

use an option with fixed choices as subcommand

ocean dragon
#

can I set the embed description to be below a field in an embed?

#
async def on_error(interaction: Interaction, error: app_commands.AppCommandError) -> None:
    exception = "\n".join(traceback.format_exception(error))
    logs_channel = interaction.client.get_channel(config.channels.logs)
    
    if logs_channel is not None:
        embed = discord.Embed(color=config.colors.red)
        embed.add_field(name=f"Exception [{interaction.client.user}]", value=error)
        embed.description = exception
        await logs_channel.send(embed=embed)
#

the field is going under the description and doesn't look very nice

#

I guess it's not possible

#

any alternative ways I could do this?

#

I tried sending the full exception as a file and a shorter version as embed, but for whatever reason the file goes above the embed

sullen roost
#

How do I notify users ?
Like whenever there is new updates
It notifies the users and sends details abt it

unkempt canyonBOT
#
await send(content=None, *, tts=False, embed=None, embeds=None, file=None, files=None, stickers=None, delete_after=None, nonce=None, allowed_mentions=None, reference=None, ...)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Sends a message to the destination with the content given.

The content must be a type that can convert to a string through `str(content)`. If the content is set to `None` (the default), then the `embed` parameter must be provided.

To upload a single file, the `file` parameter should be used with a single [`File`](https://discordpy.readthedocs.io/en/latest/api.html#discord.File "discord.File") object. To upload multiple files, the `files` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.11)") of [`File`](https://discordpy.readthedocs.io/en/latest/api.html#discord.File "discord.File") objects. **Specifying both parameters will lead to an exception**.

To upload a single embed, the `embed` parameter should be used with a single [`Embed`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed "discord.Embed") object. To upload multiple embeds, the `embeds` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.11)") of [`Embed`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed "discord.Embed") objects. **Specifying both parameters will lead to an exception**.
shrewd fjord
#

Send the message to their DM

#

Make sure to do it inside
try-except block

#

It may raise HTTPException, if user not found or their dm is off

tender prawn
#

pls help i am learning to make a bot and this happened File "c:\Users\Gabriel\Bot\bot.py", line 10, in <module>
bot.run("Mytoken")
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\discord\client.py", line 828, in run
asyncio.run(runner())
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\discord\client.py", line 817, in runner
await self.start(token, reconnect=reconnect)
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\discord\client.py", line 746, in start
await self.connect(reconnect=reconnect)
File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python311\discord\client.py", line 672, in connect
raise PrivilegedIntentsRequired(exc.shard_id) from None
discord.errors.PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal. It is recommended to go to https://discord.com/developers/applications/ and explicitly enable the privileged intents within your application's page. If this is not possible, then consider disabling the privileged intents instead.

Discord Developer Portal

Integrate your service with Discord — whether it's a bot or a game or whatever your wildest imagination can come up with.

short silo
# tender prawn pls help i am learning to make a bot and this happened ...

It is recommended to go to https://discord.com/developers/applications/ and explicitly enable the privileged intents within your application's page. If this is not possible, then consider disabling the privileged intents instead.

As it says, go to the site and enable the intents

Discord Developer Portal

Integrate your service with Discord — whether it's a bot or a game or whatever your wildest imagination can come up with.

slate swan
#

!intents enable the intents from the dashboard

tender prawn
#

still dont work

#

i tried again same error

tender prawn
slate swan
tender prawn
slate swan
#

yep

#

make sure you enabled it for the same bot you're tying to run

#

you need to click on save changes after doing this too

tender prawn
#

yeah i have only one bot

#

and yeah saved changes

#

i even reset token to see if that is problem

#

k i tried it 3 times and on the third it worked so i guess its ok lol

short silo
#

So, if i keep loading cogs for testing, i will hit the rate limit it seems. Is there any way to prevent that ?

naive briar
#

Loading cogs don't have rate limits, it's just reimporting the file that the cog comes from

#

Unless you're using something that needs to fetch something in the cog setup

short silo
# naive briar Loading cogs don't have rate limits, it's just reimporting the file that the cog...
@bot.slash_command(name="load_all",guild_ids=GUILD)
async def load_all(ctx: discord.Interaction):
    try:
        bot._pending_application_commands = []
        if(ctx.author.id in ADMINS):
            try:
                await ctx.response.send_message("Starting Process...",ephemeral=True)
                for filename in os.listdir('./Commands'):
                    if filename.endswith(".py"):
                        bot.load_extension(f'Commands.{filename[:-3]}')
            except Exception as E:
                await ctx.followup.send(E,ephemeral=True)
                raise E
                return
            try:
                for filename in os.listdir('./Misc_Commands'):
                    if filename.endswith(".py"):
                        bot.load_extension(f'Misc_Commands.{filename[:-3]}')
            except Exception as E:
                await ctx.followup.send(E,ephemeral=True)
                return
            finally:
                await bot.sync_commands()
                await ctx.followup.send("Bot loaded.",ephemeral=True)
                 

this is what i was using

short silo
fringe matrix
#

Can someone please tell me how to delete n last messages from a channel using a bot command? Like how to write code of it?

unkempt canyonBOT
#

await purge(*, limit=100, check=..., before=None, after=None, around=None, oldest_first=None, bulk=True, reason=None)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Purges a list of messages that meet the criteria given by the predicate `check`. If a `check` is not provided then all messages are deleted without discrimination.

You must have [`manage_messages`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Permissions.manage_messages "discord.Permissions.manage_messages") to delete messages even if they are your own. Having [`read_message_history`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Permissions.read_message_history "discord.Permissions.read_message_history") is also needed to retrieve message history.

Changed in version 2.0: The `reason` keyword-only parameter was added.

Examples

Deleting bot’s messages...
slate swan
#

dm me if u can help me

fringe matrix
slate swan
fringe matrix
#

Put a for or while inside of it

unkempt canyonBOT
#

Hey @fringe matrix!

It looks like you tried to attach file type(s) that we do not allow (.jpg_1). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a, .csv, .json.

Feel free to ask in #community-meta if you think this is a mistake.

fringe matrix
vale wing
#

What are you trying to achieve

#

Basically asynchronously?

#

What kind of loop do you have and how do you expect it to run faster

naive briar
#

🫠

vale wing
#

Yeah that's asynchronous

#

You basically split it up into several tasks to be executed with separate threads or asyncio if they are not blocking

#

But like what does your loop do

#

Sometimes it is just pointless

#

😳

#

!d threading.Thread probably for that, I still don't get the context

unkempt canyonBOT
#

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)```
This constructor should always be called with keyword arguments. Arguments are:

*group* should be `None`; reserved for future extension when a `ThreadGroup` class is implemented.

*target* is the callable object to be invoked by the [`run()`](https://docs.python.org/3/library/threading.html#threading.Thread.run "threading.Thread.run") method. Defaults to `None`, meaning nothing is called.

*name* is the thread name. By default, a unique name is constructed of the form “Thread-*N*” where *N* is a small decimal number, or “Thread-*N* (target)” where “target” is `target.__name__` if the *target* argument is specified.

*args* is a list or tuple of arguments for the target invocation. Defaults to `()`.

*kwargs* is a dictionary of keyword arguments for the target invocation. Defaults to `{}`.
naive briar
#

lmao

vale wing
#

But like you can't print to stdout asynchronously I think? You will get synchronization issues

naive briar
#

Too much overhead for something like that

vale wing
#

I still don't get why would you need to print stuff in separate processes and why are you asking about it in discord bots channel

#

Same thing but on OS level

naive umbra
#

@slate swan your only option is to spawn two separate os processes using the multiprocessing library

vital condor
#

Hello guys!! wassup

slate swan
#
    channel = channel_id[0]
TypeError: 'NoneType' object is not subscriptable```


```py
@bot.listen("on_message")
async def suggestions(message):
    async with aiosqlite.connect("main.db") as db:
        async with db.cursor() as cursor:   
            await cursor.execute('SELECT channel_id FROM sug WHERE guild = ?', (message.guild.id,))
            channel_id = await cursor.fetchone()
            channel = channel_id[0]
            final = bot.get_channel(channel)
        if message.author.bot:
            return
        embed = nextcord.Embed(title=f"New suggestion!", description=f"__**User:**__ \n {message.author.mention} \n \n __**Suggestion:**__ \n{message.content}", timestamp=datetime.now() , color=0x4e80cf)
        embed.set_thumbnail(url=message.author.display_avatar.url)
        embed.set_footer(text=f" {message.author} - {message.author.guild.name}")
        if message.channel is not final:
            return
        moji=await final.send(embed=embed)
        await moji.add_reaction('✅')
        await moji.add_reaction('❌')```
#

hey guys i am trying to use pypresence to make a rpc for my app but when i provide the large_image url it shows this image which is nothing, the code is below:

from pypresence import Presence
import time

client_id = '1077017214198235238'  # Fake ID, put your real one here
RPC = Presence(client_id)  # Initialize the client class
RPC.connect() # Start the handshake loop

print(RPC.update(state="Lookie Lookie", details="A test of qwertyquerty's Python Discord RPC wrapper, pypresence!", large_image="https://media.discordapp.net/attachments/1073265473661194311/1076871839374119022/real_nexus_logo_b43778ba-acb0-46a1-837f-921cf9402582.png?width=468&height=468"))

while True:  # The presence will stay on as long as the program is running
    time.sleep(50) # Can only update rich presence every 15 seconds
slate swan
slate swan
slate swan
#

it looks like this rn, after reloading its looks like that with no assets

unkempt canyonBOT
#

@shrewd fjord :x: Your 3.11 eval job has completed with return code 1.

001 | <string>:1: SyntaxWarning: 'NoneType' object is not subscriptable; perhaps you missed a comma?
002 | Traceback (most recent call last):
003 |   File "<string>", line 1, in <module>
004 | TypeError: 'NoneType' object is not subscriptable
shrewd fjord
#

This is why and how the error occurs

#

The channel_id isnt thing to iterate over

slate swan
#

i did it in another event and it worked

granite sleet
#

I am thinking of doing a discord bot that would create custom profiles for server is that possible to make?

#

you would write a command and it would show embed ui or something as your profile

naive umbra
naive umbra
slate swan
desert sparrow
granite sleet
naive umbra
granite sleet
#

and then you would do command to show it in some embed I think like that meep bot does

slate swan
#

Oh okay

#

checking

granite sleet
#

maybe it is not that interesting

#

I need to do something for school and I always wanted to do discord bot but I am not sure what it should do

desert sparrow
granite sleet
#

maybe I should make quiz or game bot

desert sparrow
naive umbra
desert sparrow
#

showed off end result = is just showed off end result seen to user.
matters interface you provide to users and how it works behind
and how you are going to maintain... discord bot, like any web infra needs monitoring/logging systems preferably

slate swan
desert sparrow
desert sparrow
granite sleet
#

I am just doing it as a school project so I can just host it from my PC when testing

desert sparrow
naive umbra
naive umbra
granite sleet
#

python is best language for discord bots right

naive umbra
#

any general purpose language works equally well

#

python and js are easy, so they tend to be the go-to for beginners

granite sleet
#

is C# good for making bots too?

desert sparrow
granite sleet
#

I tried to make bot before in GO language

naive umbra
slate swan
#

it doesn't really matter what language you make the bot in

granite sleet
#

yes it is the one I mainly used so far

slate swan
#

well if they have the SDK maintained, sure it is

desert sparrow
# granite sleet python is best language for discord bots right

i would not say so.
python/js make crappy fast results, which are kind of hard to make of good quality. Possible to make big products even in them, but it will be... very specific effort to fight language limits if wishing to achieve good quality.
Discord.py is especially pain due to bad code architecture design, forcing very bad architectural pattern, not easy to unit test

Java/C#/Golang make reliable results of higher code quality, where your application works in a stable well, with all covered static typed and handled errors in a code instead of runtime. End result is usually way nicer to extend and maintain

naive umbra
granite sleet
#

and I have python course this year but I havent used python before

naive umbra
slate swan
granite sleet
#

I think I will just use C# then

naive umbra
slate swan
#

i did that right

@bot.listen("on_message")
async def suggestions(message):
    async with aiosqlite.connect("main.db") as db:
        async with db.cursor() as cursor:   
            cursor = await db.execute('SELECT channel_id FROM sug WHERE guild = ?', (message.guild.id,))
            channel_id = await cursor.fetchone()
            channel = channel_id[0]
            final = bot.get_channel(channel)
        if message.author.bot:
            return
        embed = nextcord.Embed(title=f"New suggestion!", description=f"__**User:**__ \n {message.author.mention} \n \n __**Suggestion:**__ \n{message.content}", timestamp=datetime.now() , color=0x4e80cf)
        embed.set_thumbnail(url=message.author.display_avatar.url)
        embed.set_footer(text=f" {message.author} - {message.author.guild.name}")
        if message.channel is not final:
            return
        moji=await final.send(embed=embed)
        await moji.add_reaction('✅')
        await moji.add_reaction('❌')```
naive umbra
slate swan
#

okay

naive umbra
#

and try adding a print before you use the id, like this:

cursor = await db.execute('SELECT channel_id FROM sug WHERE guild = ?', (message.guild.id,))
channel_id = await cursor.fetchone()
print(channel_id)
channel = channel_id[0]
naive umbra
naive umbra
#

even so, python and js are fully capable of scaling that big

desert sparrow
# slate swan type checking in python and ts for js exist and support for these 2 language is...

three (four) main problems of making python bots

  1. Static typing (can be compensated by Mypy) (gradual typing has its limits though)
  2. Worst code architecture design brought by Discord.py which is hard to unit test (i was able to solve it by redirecting input/output to CLI library argparse
  3. Python handles errors only at runtime (impossible to compensate for)
  4. Discord.py requires using async only solutions, which kind of makes additional headache to 2nd point. Python async ecosystem is not very mature. Already possible to use, but still kind of not always possible to apply async solutions. compensating with stuff like asyncio.to_thread solves problems though (again solvable, but still kind of additional headache brought by Discord.py)
slate swan
#

None Ignoring exception in on_message Traceback (most recent call last): File "C:\Users\PC\AppData\Roaming\Python\Python39\site-packages\nextcord\client.py", line 512, in _run_event await coro(*args, **kwargs) File "c:\Users\PC\Desktop\HelpMe Bot\main.py", line 286, in suggestions channel = channel_id[0] TypeError: 'NoneType' object is not subscriptable (1036256958094770218,)

naive umbra
# desert sparrow three (four) main problems of making python bots 1) Static typing (can be compen...
  1. Static typing is not a part of python, and shouldn't.
  2. You simply don't unit test discord bots because it's all dependant on discords gateway connection triggering events, not yours, anything else that requires unit tests will be irrelevant to discordpy.
  3. That's because it's interpreted, that comes with a pro and a con.
  4. Discord bots should be written concurrently, otherwise you end up with a poorly written way of handling event driven connections like discord gateway, that will grow much more complexity and also add a ton of overhead.
#

let me add one more, 5) it's a discord bot, these semantics doesn't matter and being pedantic wont help any better

slate swan
# desert sparrow three (four) main problems of making python bots 1) Static typing (can be compen...
  1. static typing is for sure an issue in python but I don't see why would that be an problem for applications like a discord bot, most parts of bot dev is just interacting with the webserver and the api, which i don't think python has any significant issue with ...
  2. https://pypi.org/project/hikari 🙂 fully typed + low level API + extendable with support for REST apps etc..
  3. ik that sucks, makes me cry lmao
  4. well python for sure has a async ecosystem different from other programming languages, but it's not an issue when you once get hold to it... and yeah the issue with blocking libraries exist but most of the time there's either an alternative or to_thread or run_in_executor exists, just 2-3 lines of extra code
desert sparrow
# naive umbra 1) Static typing is not a part of python, and shouldn't. 2) You simply don't uni...
  1. very very wrong. Testing should be considered at code architecture level of application. Read Clean Architecture by Robert martin to see impact of frameworks upon it and how to mitigate the damage
  2. nevertheless it is a minus that can't be compensated
    4)...i have no problems of writing discord bot in Golang. Very nice end result. I use go routines to keep in one of them constant listening to input from Discord. and having simple abstraction Discord API, which allows me to send to it actions i need without making my main code dirty by Discord. Coode unit testing in result.
  3. any product can be made with quality and growing in requirements. Bots can be pretty complex backend systems too.
slate swan
#
@bot.listen("on_message")
async def suggestions(message):
    async with aiosqlite.connect("main.db") as db:
            cursor = await db.execute('SELECT channel_id FROM sug WHERE guild = ?', (message.guild.id,))
            channel_id = await cursor.fetchone()
            print(channel_id)
            channel = channel_id[0]
            final = bot.get_channel(channel)
    if message.author.bot:
            return
    embed = nextcord.Embed(title=f"New suggestion!", description=f"__**User:**__ \n {message.author.mention} \n \n __**Suggestion:**__ \n{message.content}", timestamp=datetime.now() , color=0x4e80cf)
    embed.set_thumbnail(url=message.author.display_avatar.url)
    embed.set_footer(text=f" {message.author} - {message.author.guild.name}")
    if message.channel is not final:
            return
    moji=await final.send(embed=embed)
    await moji.add_reaction('✅')
    await moji.add_reaction('❌')```
#

i mean if you know python or whatever language just use it, no need to learn a new language 🤾

desert sparrow
slate swan
#

i personally use that for my projects, its a bit different for other python discord libs but is awesome

desert sparrow
#

one of problems with python... errors handled at runtime. Discord.py is not handling them all too 😁
your bot can fall down due to error that Discord.py forgot to handle and wrap into library defined error

naive umbra
slate swan
desert sparrow
#

anyway, i just don't fight python for this. i already implemented new version in Golang and really liking end result.
with _ "embed" constructions of golang, even all templating files are embedded into fast compiled end binary result.
whole bot is a single binary file, that is just nice.

#

and i don't need any stuff like redis/celery for it. Golang go routines are very smooth working to be having nice multi threading in application without problems
and data corruption is not a problem once again due to easy to use mutexes there

#

all 4 parallel processes threads necessary to run for my application work pretty fine in Golang and experience no GILL issues 😁 sharing memory of variables, making very easily written app.

naive briar
#

We're in a Python server ducky_sus

slate swan
#

mfw when go spawns threads like crazy on start-up

#

!pep 9001 solves everything

unkempt canyonBOT
#
PEP not found

PEP 9001 does not exist.

slate swan
#

💀 i can swear this existed

naive umbra
desert sparrow
slate swan
#

i have autosave

naive umbra
slate swan
#

ohh okay

naive umbra
#

before the async with aiosqlite.connect(...

#

put this also at the top

if message.channel is not final:
    return
slate swan
#

please don't use is not here, != should be the deal

#

omg tysm!

sacred oyster
#

hello

#

so my code gives a error that before it didn't

#

this is the error

naive umbra
#

!intents

unkempt canyonBOT
#

Using intents in discord.py

Intents are a feature of Discord that tells the gateway exactly which events to send your bot. Various features of discord.py rely on having particular intents enabled, further detailed in its documentation. Since discord.py v2.0.0, it has become mandatory for developers to explicitly define the values of these intents in their code.

There are standard and privileged intents. To use privileged intents like Presences, Server Members, and Message Content, you have to first enable them in the Discord Developer Portal. In there, go to the Bot page of your application, scroll down to the Privileged Gateway Intents section, and enable the privileged intents that you need. Standard intents can be used without any changes in the developer portal.

Afterwards in your code, you need to set the intents you want to connect with in the bot's constructor using the intents keyword argument, like this:

from discord import Intents
from discord.ext import commands

# Enable all standard intents and message content
# (prefix commands generally require message content)
intents = Intents.default()
intents.message_content = True

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

For more info about using intents, see discord.py's related guide, and for general information about them, see the Discord developer documentation on intents.

slate swan
#

!intents

naive briar
#

Read the error

sacred oyster
young dagger
#

What's the most common way to make moderation commands only work for certain roles?

slate swan
#

!d discord.ext.commands.has_any_role

unkempt canyonBOT
#

@discord.ext.commands.has_any_role(*items)```
A [`check()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.check "discord.ext.commands.check") that is added that checks if the member invoking the command has **any** of the roles specified. This means that if they have one out of the three roles specified, then this check will return `True`.

Similar to [`has_role()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.has_role "discord.ext.commands.has_role"), the names or IDs passed in must be exact.

This check raises one of two special exceptions, [`MissingAnyRole`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MissingAnyRole "discord.ext.commands.MissingAnyRole") if the user is missing all roles, or [`NoPrivateMessage`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.NoPrivateMessage "discord.ext.commands.NoPrivateMessage") if it is used in a private message. Both inherit from [`CheckFailure`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CheckFailure "discord.ext.commands.CheckFailure").

Changed in version 1.1: Raise [`MissingAnyRole`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MissingAnyRole "discord.ext.commands.MissingAnyRole") or [`NoPrivateMessage`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.NoPrivateMessage "discord.ext.commands.NoPrivateMessage") instead of generic [`CheckFailure`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CheckFailure "discord.ext.commands.CheckFailure")
young dagger
#

What if you only want to make the commands work in a certain channel?

naive briar
#

Make your own check

#

!d discord.ext.commands.check

unkempt canyonBOT
#

@discord.ext.commands.check(predicate)```
A decorator that adds a check to the [`Command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command "discord.ext.commands.Command") or its subclasses. These checks could be accessed via [`Command.checks`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command.checks "discord.ext.commands.Command.checks").

These checks should be predicates that take in a single parameter taking a [`Context`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context "discord.ext.commands.Context"). If the check returns a `False`-like value then during invocation a [`CheckFailure`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CheckFailure "discord.ext.commands.CheckFailure") exception is raised and sent to the [`on_command_error()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.discord.ext.commands.on_command_error "discord.discord.ext.commands.on_command_error") event.

If an exception should be thrown in the predicate then it should be a subclass of [`CommandError`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CommandError "discord.ext.commands.CommandError"). Any exception not subclassed from it will be propagated while those subclassed will be sent to [`on_command_error()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.discord.ext.commands.on_command_error "discord.discord.ext.commands.on_command_error").
young dagger
#

Thanks

slate swan
#

hi

#

can someone help me ?

slate swan
#

datetime is imported but timedelta isnt defined

#

its fixed lol

#

just wrong import

#

from datetime import timedelta

#

raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'discord.utils._MissingSentinel'> for field name is not allowed: use default_factory

#

can anyone help with this?

slate swan
unkempt canyonBOT
#

Custom Command Checks in discord.py

Often you may find the need to use checks that don't exist by default in discord.py. Fortunately, discord.py provides discord.ext.commands.check which allows you to create you own checks like this:

from discord.ext.commands import check, Context

def in_any_channel(*channels):
  async def predicate(ctx: Context):
    return ctx.channel.id in channels
  return check(predicate)

This check is to check whether the invoked command is in a given set of channels. The inner function, named predicate here, is used to perform the actual check on the command, and check logic should go in this function. It must be an async function, and always provides a single commands.Context argument which you can use to create check logic. This check function should return a boolean value indicating whether the check passed (return True) or failed (return False).

The check can now be used like any other commands check as a decorator of a command, such as this:

@bot.command(name="ping")
@in_any_channel(728343273562701984)
async def ping(ctx: Context):
  ...

This would lock the ping command to only be used in the channel 728343273562701984. If this check function fails it will raise a CheckFailure exception, which can be handled in your error handler.

slate swan
#

raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'discord.utils._MissingSentinel'> for field name is not allowed: use default_factory
can anyone help with this?

golden portal
slate swan
unkempt mauve
slate swan
#

read what i wrote again

unkempt mauve
#

so the defer need to be above?

slate swan
#

yes

#

you need to enable message_content intents

#

!intents pretty much like tjis

unkempt canyonBOT
#

Using intents in discord.py

Intents are a feature of Discord that tells the gateway exactly which events to send your bot. Various features of discord.py rely on having particular intents enabled, further detailed in its documentation. Since discord.py v2.0.0, it has become mandatory for developers to explicitly define the values of these intents in their code.

There are standard and privileged intents. To use privileged intents like Presences, Server Members, and Message Content, you have to first enable them in the Discord Developer Portal. In there, go to the Bot page of your application, scroll down to the Privileged Gateway Intents section, and enable the privileged intents that you need. Standard intents can be used without any changes in the developer portal.

Afterwards in your code, you need to set the intents you want to connect with in the bot's constructor using the intents keyword argument, like this:

from discord import Intents
from discord.ext import commands

# Enable all standard intents and message content
# (prefix commands generally require message content)
intents = Intents.default()
intents.message_content = True

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

For more info about using intents, see discord.py's related guide, and for general information about them, see the Discord developer documentation on intents.

slate swan
#

both in the developer portal and the code

unkempt mauve
#

thanks, it worked

#

defer above solved it

ocean dragon
#

not really a bot question, but do I need a bot if I want to fetch a list of members that have a specific role on a server?

#

I just need to save the member ids for a database, I rather have a single HTTP request than use a bot to do it

sick birch
#

Otherwise http works

ocean dragon
#

not sure how to use it though, I assume it still needs to be a bot to authenticate

unkempt mauve
#
try:
    anime = animec.Anime(query)
except animec.errors.NoResultFound:
    await interaction.response.send_message(f"No anime found with the name **{query}**", ephemeral=True)
    return```
It doesn't sends the error message, rather it sends it in console.
quick gust
#

what anime are u trying this with?

#

perhaps it does not have a teaser

#

because it works fine for me

unkempt mauve
# quick gust perhaps it does not have a teaser

How do I say 'N/A' if it doesnt have teaser. I tried this code below but it doesnt works:

    if anime.teaser is None:
        emb.add_field(name='Teaser', value='N/A')
    else:
        emb.add_field(name='Teaser', value=str(anime.teaser))```
quick gust
#

explain 'doesnt work'

unkempt mauve
#

it doesnt works and puts error in the console...

quick gust
unkempt mauve
#

and the embed is not getting sent

quick gust
#

I believe the lib hasnt handled that error

#

youll have to add a try except statement

unkempt mauve
#

then should I remove the teaser field?

unkempt mauve
vocal snow
#

What is nbr_favo?

quick gust
unkempt mauve
quick gust
#

great

vocal snow
#

And you're sure it's an int?

ionic garden
#
    @ui.button(label="Toggle Map", row=1, style=discord.ButtonStyle.blurple)
    async def toggle_map(self, i: discord.Interaction, button: ui.Button):
        msg = i.message
        await i.response.defer()
        print("before:", i.message.attachments)
        if i.message.attachments:
            await i.message.remove_attachments(*msg.attachments)
        else:
            self.loc_img.fp.seek(0)
            await i.message.edit(attachments=[self.loc_img])
        print("after:", i.message.attachments)
```why does before and after print the same thing?
unkempt mauve
#

how do u make a parent command in slash commands?

hushed galleon
hushed galleon
hushed galleon
unkempt mauve
#

oh so a class!

sick birch
#

smh

sick birch
unkempt canyonBOT
#
Sure.

Your reminder will arrive on <t:1677018942:F>!

stark geyser
#

i am working on a music bot which i am trying to add playlist url support
what i currently have:
@classmethod
async def create_source(cls, ctx: commands.Context, search: str, *, loop: asyncio.BaseEventLoop = None):
loop = loop or asyncio.get_event_loop()

    if "playlist?list" in search:
        playlist_id = search.split("playlist?list=")[-1].split("&")[0]

        partial = functools.partial(cls.ytdl.extract_info, f"https://www.youtube.com/playlist?list={playlist_id}", download=False)
        playlist_info = await loop.run_in_executor(None, partial)
        if playlist_info is None:
            raise YTDLError(f"Couldnt fetch playlist '{search}'")
        
        if 'entries' not in playlist_info:
            raise YTDLError(f"No videos found in playlist '{search}'")
        
        video_info = playlist_info['entries'][0]


        return cls(ctx, discord.FFmpegPCMAudio(video_info['url'], **cls.FFMPEG_OPTIONS), data=video_info)

currently it only takes the first video from the playlist
what would i have to change to get it to get all the videos in the playlist

desert badger
#

@client.event
async def on_message(message):
    print(message.content)
```this literally doesnt do anything at all
#

why tho i can print message

slate swan
#

!d discord.Intents.message_content enable message content intents

unkempt canyonBOT
#

Whether message content, attachments, embeds and components will be available in messages which do not meet the following criteria:

• The message was sent by the client

• The message was sent in direct messages

• The message mentions the client

This applies to the following events...

unkempt canyonBOT
#

Per Python Discord's Rule 5, we are unable to assist with questions related to youtube-dl, pytube, or other YouTube video downloaders, as their usage violates YouTube's Terms of Service.

For reference, this usage is covered by the following clauses in YouTube's TOS, as of 2021-03-17:

The following restrictions apply to your use of the Service. You are not allowed to:

1. access, reproduce, download, distribute, transmit, broadcast, display, sell, license, alter, modify or otherwise use any part of the Service or any Content except: (a) as specifically permitted by the Service;  (b) with prior written permission from YouTube and, if applicable, the respective rights holders; or (c) as permitted by applicable law;

3. access the Service using any automated means (such as robots, botnets or scrapers) except: (a) in the case of public search engines, in accordance with YouTube’s robots.txt file; (b) with YouTube’s prior written permission; or (c) as permitted by applicable law;

9. use the Service to view or listen to Content other than for personal, non-commercial use (for example, you may not publicly screen videos or stream music from the Service)
ionic garden
#

i also wanna access the .attachments field outside of it as well, after view.wait()

hushed galleon
#

point still stands, and from what i found in the source code the message objects associated with interactions arent part of the cache

ionic garden
#
            view = Decision(...)
            attach = [file] if show_map else []
            await adventure_msg.edit(embed=embed, attachments=attach, view=view)
            await view.wait()
```how would i get the message changes from the view here?
hushed galleon
#

the edit methods return a new Message object, store it

ionic garden
#

the view changes adventure_msg

hushed galleon
#

e.g. py message = await message.edit(...)

ionic garden
#

that's not the part that matters tho

hushed galleon
#

but again my point still stands, in-place updates of message objects do not happen if they are not stored in the client's message cache

#

if adventure_msg is not in the cache, you wont see its attributes update

ionic garden
#

so how would i fix this?

#

rn i have a hacky fix that involves storing relevant info in the attribute of the view

hushed galleon
#

either forcefully push the message into cache with internal methods, or use the newly created message object that the edit() method returns

ionic garden
#

again, the edit() here isn't what i'm after

hushed galleon
#

then where else are you getting the updated message from?

ionic garden
#

the view here has a method

ionic garden
hushed galleon
#

so why wont you store the resulting message object from the remove_attachments()/edit() methods that has the updated information?

ionic garden
#

fail to see how that would propogate back to adventure_msg

hushed galleon
#

the only way to propagate it is to share that message object back

#

store it on your view instance and access it there, then you can replace it whenever and your other method will be able to use it

ionic garden
#

oh, that's basically the same as my current method

#

just stored the relevant attribute in a self.field

hushed galleon
#

ye

hasty rain
#

guys teach me how to make bots please

#

😢

ionic garden
#

read the docs? look up an online tutorial?

hasty rain
#

No. I need something like Juniper

ionic garden
#

you want to make your own juniper?

hasty rain
hasty rain
hasty rain
#

I need a bot for my clan from the game zombix online

ionic garden
sick birch
# ionic garden wb the docs?

The docs are usually always up to date and a reliable and great resource (if you know how to use them efficiently)

hasty rain
#

youtube?

sick birch
cloud dawn
#

I'll upload a vid

hasty rain
sick birch
cloud dawn
cloud dawn
sick birch
#

Most experienced folk are usually too busy to do mentoring or 1:1 lessons

cloud dawn
#
  • this server doesn't provide coding sessions/steaming.
#

I wish they did

hasty rain
#

=(

#

ok then i'll just watch the coding

#

on the other hand you are right

velvet compass
hasty rain
#

the problem is that I am Russian. and I don’t know English well, so I use a translator

#

=(

vale wing
#

Privet mate

sick birch
#

Pair coding sounds like a great idea

#

Match up people of similar skill with common interests

cloud dawn
# velvet compass Do you have some ideas or thoughts on how that would work?

Well I did throw it in the #community-meta a couple of times, but they always ended with not being able to monitor any misbehavior. I've said something like giving it out to certain members, to earn it so to speak. But that has already been done once and proved to still cause problems.

You could do privately but I'm not such a fan of that since I don't want people to send me messages if I'm working or taking some time off. I'd really enjoy if something like pair programming/ relaxed sessions with multiple people can occur. The company were I work at and I are experimenting with pair programming and demo's and find them to be quite effective and intriguing. Plus the added benefit if pointing out mistakes and learning from each other.

velvet compass
#

We do have an idea for having some events team members to do some workshops, but it is a decent amount of setup and work to layout what you are going to cover and how to show it best. Maybe a more informal "event" with someone having temporary stream permissions in the voice channels could work

sick birch
hasty rain
#

Ничего не понятно=/

velvet compass
#

But with a start time, and a topic

#

So a step above spontaneous, but still informal

cloud dawn
#

I'd certainly like to apply for that, especially the informal part. I'm not 100% mistake free and I'd appreciate it if someone would point out a mistake or has a better method of doing it.

vale wing
maiden fable
#

Wait I just realized that mina became the Director and Seb got a new role 👀

vale wing
#

Necessary is more correct term

maiden fable
#

Wrong timing, oops

maiden fable
#

Nice
I have been offline lately, exams sigh

distant burrow
#

elo, does anyone know if I can just smack my new bot in a community server? or does it get restricted in some way then

cloud dawn
#

If you meant by just joining a server then no, depending on the permissions given of course.

ocean dragon
#
    async def fetch_rates(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
        if interaction.extras.get("rates") is None:
            async with aiohttp.ClientSession() as session:
                async with session.get("https://api.exchangerate.host/latest") as response:
                    data = await response.json()
                    interaction.extras["rates"] = data["rates"]

        symbols = interaction.extras["rates"].keys()
        closest_symbols = difflib.get_close_matches(current.upper(), symbols, n=5, cutoff=0.0)
        return [app_commands.Choice(name=str(symbol), value=str(symbol)) for symbol in closest_symbols]

    @app_commands.command(name="convert", description="Convert from a currency to another")
    @app_commands.describe(amount="The amount to convert")
    @app_commands.describe(from_symbol="The currency to convert from")
    @app_commands.autocomplete(from_symbol=fetch_rates)
    @app_commands.describe(to_symbol="The currency to convert to")
    @app_commands.autocomplete(to_symbol=fetch_rates)
    async def convert(self, interaction: discord.Interaction, amount: float, from_symbol: str, to_symbol: str) -> None:
        rates = interaction.extras.get("rates")
        ...
#

I'm trying to cache the rates into the interaction in fetch_rates autocompletion function, but whenever I access it in convert, it is None

maiden fable
ocean dragon
#

yes

vale wing
#

Does dpy really use such method of describing parameters

cloud dawn
#

Best way to check is to print the current and then the symbols on the the fetch_rates function. Since I think when you autocomplete the input string is empty thus overriding the symbols variable.

cloud dawn
vale wing
#

Good they have docstring

cloud dawn
#

Also pretty sure the decorator takes inf kwargs.

#

You don't need to call it 3 times for 3 separate args.

maiden fable
#

I wish they at least had **kwargs so that we can describe multiple args in a single deco

#

(saying this based on his code)

ocean dragon
cloud dawn
#

!d discord.app_commands.describe

unkempt canyonBOT
#

@discord.app_commands.describe(**parameters)```
Describes the given parameters by their name using the key of the keyword argument as the name.

Example:

```py
@app_commands.command(description='Bans a member')
@app_commands.describe(member='the member to ban')
async def ban(interaction: discord.Interaction, member: discord.Member):
    await interaction.response.send_message(f'Banned {member}')
```  Alternatively, you can describe parameters using Google, Sphinx, or Numpy style docstrings...
ocean dragon
#

I have a command with like 7 args and autocomplete

maiden fable
#

Then please, for the love of god and sanity, use that xSurf

cloud dawn
#

lol

maiden fable
#

Thanks for the support........ Lancebot

ocean dragon
#

I have bugs I have to kill first

cloud dawn
#

Then you can oneline it.

cloud dawn
#

This is the same as opening a file then closing it just for fun.

#

Sessions are meant if you are adding cookies to it and want to do something with that afterwards.

#

Imagine keeping your browser open and it will delete once you close the browser.

ocean dragon
#
    async def fetch_rates(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
        print(f"Extras: {interaction.extras}")
        print(f"Current: {current}")
        if interaction.extras.get("rates") is None:
            async with aiohttp.ClientSession() as session:
                async with session.get("https://api.exchangerate.host/latest") as response:
                    data = await response.json()
                    interaction.extras["rates"] = data["rates"]

        symbols = interaction.extras["rates"].keys()
        closest_symbols = difflib.get_close_matches(current.upper(), symbols, n=5, cutoff=0.0)

        print(f"Extras: {interaction.extras}\n")
        return [app_commands.Choice(name=str(symbol), value=str(symbol)) for symbol in closest_symbols]

    @app_commands.command(name="convert", description="Convert from a currency to another")
    @app_commands.describe(amount="The amount to convert", from_symbol="The currency to convert from", to_symbol="The currency to convert to")
    @app_commands.autocomplete(from_symbol=fetch_rates, to_symbol=fetch_rates)
    async def convert(self, interaction: discord.Interaction, amount: float, from_symbol: str, to_symbol: str) -> None:
        print(f"Interaction.extras: {interaction.extras}")
        rates = interaction.extras.get("rates")
        ...
cloud dawn
#

Most likely the interaction from the autocomplete isn't the same interaction but separate.

ocean dragon
cloud dawn
#

You are working in a class so you could make a temp cache and then delete it afterwards when the command is finished.

ocean dragon
#

I'm already using interactions.extras as cache for another command so I don't understand why this one isn't working

cloud dawn
#

I got an idea but why is the other one working?

ocean dragon
#

idk that's why im confused

ocean dragon
hushed galleon
hushed galleon
#

oops double ping

cloud dawn
cloud dawn
ocean dragon
#
    async def test_fetch(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
        interaction.extras["rates"] = ["test"]
        return [app_commands.Choice(name="USD", value="USD")]

    @app_commands.command(name="test", description="test")
    @app_commands.describe(param="param")
    @app_commands.autocomplete(param=test_fetch)
    async def test(self, interaction: discord.Interaction, param: str) -> None:
        print(f"Interaction.extras: {interaction.extras}")

this prints Interaction.extras: {} too

#

hold up

cloud dawn
#

I mean yeah it's empty by default.

#

!d discord.app_commands.Command.extras

unkempt canyonBOT
hushed galleon
#

instead of storing the rates in an interaction, cache it somewhere else like on your cog and then get from that cache when its available - multiple autocomplete + command interactions can then reference the same result and not spam the API

cloud dawn
#

Redis timeee

#

🎉

#

🎊 🎊 🎊 🎊 🎊 🎊 🎊 🎊 🎊 🎊 🎊 🎊

#

Almost hit emoji limit lol

ocean dragon
#

nvm I wasn't using it in the command itself

ocean dragon
#

not sure why it's just not stored in the same interaction

hushed galleon
# cloud dawn Yes but in this case it's just thrown away.

eh, for infrequent queries you wont see much benefit, though its also not that difficult to properly store and cleanup a session: py async def main(): async with bot, aiohttp.ClientSession() as session: bot.session = session await bot.start(...)

cloud dawn
ocean dragon
#

the rates

#

well, in this case it wouldn't matter would it

cloud dawn
ocean dragon
#

I dont know, but I'm not speaking about this, but if you used it for something else

#

to fetch user information for example

cloud dawn
ocean dragon
#

probably

#

can u create a task within a cog?

cloud dawn
#

I mean it most likely won't change every minute and the keys are always the same so you don't need to actively refresh those imo.

#

Thinking about it you won't even need a task then.

ocean dragon
ocean dragon
cloud dawn
#

But why? Just have a static list of the currency and fetch the value once you are converting it in the command.

hushed galleon
# ocean dragon not sure why it's just not stored in the same interaction

an autocomplete interaction is its own interaction, isolated from the eventual app_command interaction your bot receives, the only way you're sharing data between the two is either embedding it in the value= of your choices or storing it externally in said cache

for the message above that, yeah it could turn into a race condition resulting in two concurrent requests

ocean dragon
cloud dawn
# ocean dragon if I'm already fetching the values, I might as well update the symbols too

I don't think you understand what I'm saying. Here. So having a static list with all the currencies.. ```
['AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTC', 'BTN', 'BWP', 'BYN', 'BZD', 'CAD', 'CDF', 'CHF', 'CLF', 'CLP', 'CNH', 'CNY', 'COP', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GGP', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'IMP', 'INR', 'IQD', 'IRR', 'ISK', 'JEP', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRU', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLL', 'SOS', 'SRD', 'SSP', 'STD', 'STN', 'SVC', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TWD', 'TZS', 'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VES', 'VND', 'VUV', 'WST', 'XAF', 'XAG', 'XAU', 'XCD', 'XDR', 'XOF', 'XPD', 'XPF', 'XPT', 'YER', 'ZAR', 'ZMW', 'ZWL']


Use this for the autocomplete... from... to...
So like `/convert SYP LYD` then the from/ to values are defined. Commands get ran..
Inside the command fetch the json and get the from/to value and do math -> respond.
ocean dragon
#

yeah but it's still 1 request to the website even if I update the symbols

distant burrow
cloud dawn
ocean dragon
cloud dawn
ocean dragon
#

but I store the value in the cog so I wont have to get it in the command

cloud dawn
ocean dragon
#

they are if the interaction is different each time

#
    async def fetch_rates(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
        if not self.rates:
            async with aiohttp.ClientSession() as session:
                async with session.get("https://api.exchangerate.host/latest") as response:
                    data = await response.json()
                    self.rates = data["rates"]

        symbols = self.rates.keys()
        closest_symbols = difflib.get_close_matches(current.upper(), symbols, n=5, cutoff=0.0)

        return [app_commands.Choice(name=str(symbol), value=str(symbol)) for symbol in closest_symbols]
cloud dawn
#

But then you'd still do 1 request per command thus doing the same but way more complicated.

ocean dragon
#

its not more complicated

#

this way I wont have to have ugly static block in the code 😅

cloud dawn
hushed galleon
#

if you get the symbols alongside the values, you might as well keep em

#

invalidating the response after some time is a separate thing to work on

hushed galleon
cloud dawn
#

I mean depends on how often the api updates it's values.

#

I'd most likely just refresh it every 10 seconds. Or use my method to get the values inside the command.

ocean dragon
#

anyway moving to next problem
bot_base.py```py
async def on_error(interaction: Interaction, error: app_commands.AppCommandError) -> None:
print(f"{error} ({type(error)}) class: {error.class.name}")
if isinstance(error, exceptions.UserNotFoundException):
embed = ...
return await interaction.response.send_message(embed=embed, ephemeral=True)

# unhandled exception
embed = ...
return await interaction.response.send_message(embed=embed)

class MyBot(commands.Bot):
def init(self, *args, **kwargs):
super().init(*args, **kwargs)
self.tree.on_error = on_error

commands_member.py```py
class CommandsMember(commands.Cog):
    def __init__(self, bot:MyBot) -> None:
        self.bot = bot
    
    @app_commands.command(name="dummyfunc", description="Lorem ipsum")
    async def ping(self, interaction: discord.Interaction) -> None:
        raise exceptions.UserNotFoundException()

Output: Command 'ping' raised an exception: UserNotFoundException: (<class 'discord.app_commands.errors.CommandInvokeError'>) class: CommandInvokeError

#

how do I handle UserNotFoundException, because isinstance(error, exceptions.UserNotFoundException): returns false

cloud dawn
ocean dragon
hushed galleon
# ocean dragon how do I handle ``UserNotFoundException``, because ``isinstance(error, exception...

https://discordpy.readthedocs.io/en/stable/interactions/api.html#discord.app_commands.CommandInvokeError
check for CommandInvokeError and unwrap the original exception with the .original attribute: ```py
if isinstance(error, app_commands.CommandInvokeError):
original = error.original
if isinstance(error, UserNotFoundException):
...

or, with the getattr() shorthand:

error = getattr(error, "original", error)
if isinstance(error, UserNotFoundException):
...```

unkempt canyonBOT
#

discord/app_commands/commands.py lines 877 to 880

except AppCommandError:
    raise
except Exception as e:
    raise CommandInvokeError(self, e) from e```
cloud dawn
#

Endpoint also allows history if you pass the date.

ocean dragon
#

is there a way to know if interaction is deferred

hasty rain
#

Guys, what should the initial code of the bot look like?

#

I mean the name from the 'from' command to the bot.run command

distant burrow
#

guys, I think I'm looking over something dumb, but why can't I get my custom help command working with app commands?

hushed galleon
unkempt canyonBOT
#

is_done()```
[`bool`](https://docs.python.org/3/library/functions.html#bool "(in Python v3.11)"): Indicates whether an interaction response has been done before.

An interaction can only be responded to once.
hushed galleon
distant burrow
#

can I just create a new command called /help?

strange ocean
#

what's the best way to keep track of reactions count inside a check that's going to be passed to a wait_for raw_reaction_add

hushed galleon
unkempt canyonBOT
sick birch
#

Soon ™️

smoky sinew
#

why does discord.py have cogs/extensions under the commands extension

#

so stupid

hushed galleon
#

probably wasnt worthwhile making a second extension that tries to decouple the existing prefix commands system from it, or the app command integration either

#

and we library users would have to deal with learning a new architecture too

smoky sinew
hushed galleon
#

yeah that would make sense, but we dont have a time machine and the backend for cogs/extensions are too deeply intertwined with commands for the devs to unravel it

#

not to mention its not really a problem, the combined overhead probably isnt significant and its pretty easy to write cogs/extensions without commands

#

in other words, no one is suffering (yet)

tribal wren
#

anyone know the offical discord.ext github page

hushed galleon
tribal wren
#

thanks

#

would that be the one that installed with

#

pip install discord-ext

naive briar
#

No

tribal wren
#

oh

#

thats what i was looking for

#

since its needed for this hosting i am using

#

no pip install

hushed galleon
#

neither of his two extensions are on pypi so you're required to install them by downloading the repository; if you have git, the command is simply pip install git+https://github.com/Rapptz/discord-ext-menus

tribal wren
#

this needed for req.txt

hushed galleon
tribal wren
#

ik

#

py cord is in discord file

smoky sinew
#

anyone can write a discord extension

fading marlin
#

lmao I remember having that issue with another host where I couldn't install dpy 2.0 through git (back when it was still in development). I probably tried messing around with the requirements file, but I ended up just creating a small little script that allowed me to run shell commands lol

tribal wren
#

yall might call me a dumbass

#

but i need help

#

and nothing will work

fading marlin
#

!intents

unkempt canyonBOT
#

Using intents in discord.py

Intents are a feature of Discord that tells the gateway exactly which events to send your bot. Various features of discord.py rely on having particular intents enabled, further detailed in its documentation. Since discord.py v2.0.0, it has become mandatory for developers to explicitly define the values of these intents in their code.

There are standard and privileged intents. To use privileged intents like Presences, Server Members, and Message Content, you have to first enable them in the Discord Developer Portal. In there, go to the Bot page of your application, scroll down to the Privileged Gateway Intents section, and enable the privileged intents that you need. Standard intents can be used without any changes in the developer portal.

Afterwards in your code, you need to set the intents you want to connect with in the bot's constructor using the intents keyword argument, like this:

from discord import Intents
from discord.ext import commands

# Enable all standard intents and message content
# (prefix commands generally require message content)
intents = Intents.default()
intents.message_content = True

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

For more info about using intents, see discord.py's related guide, and for general information about them, see the Discord developer documentation on intents.

tribal wren
#

i tried that before never works

fading marlin
#

try it, and send any new errors

tribal wren
#

ok

#

this code fully works on pc

#

but never on server

#

only once on this server

fading marlin
#

on your PC, you're not using dpy, but the server is

tribal wren
#

what does that mean

#

i never used python for bots

fading marlin
#

on your computer, the library that you are using to make bots is not the same library that the server is using

tribal wren
#

would that code still work on a server?

fading marlin
#

if there server would use the same library, and the code of you computer worked, yes

tribal wren
#

since there all installed

fading marlin
#

what

tribal wren
#

library

fading marlin
#

I don't follow

tribal wren
#

same

dry cedar
#

you might need to uninstall one of the libraries, if youre using two different ones

tribal wren
#

nope

#

i del all rn and imported

#

them by hand by hand

fading marlin
#

server is using library #1
the way you coded your bot is using library #2
server does not have library #2, and is trying to use library #1 to run a program that is written using library #2

I'm not sure how else to explain it

tribal wren
#

how could i get it to run on server how diff is the #1 to #2?

fading marlin
#

install library #2 instead of library #1 on the server

tribal wren
#

how?

#

this what i had
import requests
import json
import asyncio
import random
import time
import discord
import sys
from datetime import timedelta, datetime
from discord.ext import commands, tasks

fading marlin
tribal wren
#

what is it called?

fading marlin
#

🤷 I'm not the one that coded the bot

tribal wren
#

same

fading marlin
#

🤦

tribal wren
#

and my friend

#

is like banned

#

no contact

fading marlin
#

I'll take a wild guess and say what you're looking for is py-cord

tribal wren
#

its coded in py-cord

#

he said

fading marlin
#

🎉

#

slap that to your requirements file then, and remove any mentioning of discord.py

tribal wren
fading marlin
#

what discord file

#

when did I mention a discord file

tribal wren
#

never

#

i am Legally a dumbass

fading marlin
#

no it's fine

tribal wren
fading marlin
#

there should be a requirements.txt file somewhere in your server

tribal wren
fading marlin
#

in that file, you should write py-cord

tribal wren
#

ok

#

he said its in py-cord but

#

it has this

fading marlin
#

yeah don't worry about that

tribal wren
#

ok

#

but the py cord files are in discord package

fading marlin
#

yeah, that's fine

tribal wren
#

omg ty

#

so fucking much

fading marlin
#

you're welcome

tribal wren
#

also whats that id if its something all hosts use?

#

or only that host

fading marlin
#

wdym

#

idk, doesn't look like a token or a session ID

tribal wren
#

also your a real man

fading marlin
#

lol I listen to that when I play Minecraft. Can't be bothered to wait until the music comes along every 30 mins. I also couldn't be bothered in selecting something else

tribal wren
#

yea

tribal wren
fading marlin
#

used to play on the 360, now just on pc. I guess this is getting kind of off topic now though

tribal wren
#

yea rn i been getting my old xbox and ps out and playing it only well i got to go play chess

slate swan
#

Hello all! I can't seem to connect my bot to ping back

#

would it be ok if I copied and pasted the code? I'm trying to make a rock paper scissor bot

#

Could you also please recommend some good tutorials?

tribal wren
smoky sinew
#

where?

#

i don't think they did

tribal wren
#

thats after

smoky sinew
#

i'm talking about requests though

#

whenever you make an HTTP request to something, it will stop your discord bot for however long it takes to do the request

#

you should use aiohttp which uses asyncio to make sure that your bot and the http request code can run together

#

@tribal wren

tribal wren
#

wdym

smoky sinew
#

???

tribal wren
#

i am legally a dumbass

smoky sinew
#

whenever you make a request your bot is going to stop

tribal wren
#

no

smoky sinew
#

ok

tribal wren
#

it works

smoky sinew
#

yes but if you have to make a really long request your bot can stop