#discord-bots

1 messages ยท Page 379 of 1

boreal sigil
#

ok

#

understood - setup only in extension

#

its in my extension.

#

do I use the load thing in the main script.py?

fast osprey
#

You use load_extension wherever you wish the extension to be loaded and you have your bot. It is entirely up to you

boreal sigil
#

ahh k

#

so this is all i need in the extension code?

fast osprey
#

Well, that will just print that and do nothing else

boreal sigil
#

yeah i realised mistake

#

and extension code

fast osprey
#

You can't have an await outside of an async method

#

Also you can't pass a string with a comma into load_extension, that's not what it expects

dark schooner
#

bopts?

open cobalt
#

hey async def .... and await are like a pair. You cant use one without it, so await cant stand alone. I think bot.load_extension() takes name as a parameter which is a string "name (str) โ€“ The extension name to load".

mild token
#

how i can typecasetypecast discord.User into a discord.Member?

wanton current
#

what

mild token
# wanton current what

i mean i am using get_user which returns discord.User but i want to use add_role which is supported by discord.Member

#

so trying to typecast it in discord.Member

wanton current
mild token
#

i need to use find_guild and then go with that

#
                user_guild = await self.bot.fetch_guild(
                    Core.SERVER_ID)
                print(user_guild, rep_id["id"])
                rep_id = int(rep_id["id"])
                print(type(rep_id))
                user = user_guild.get_member(384158530623635456)
                print(user)

i am getting guild name printed out but when i use .get_member on it , it returns None? thats my discord id above

#
test 384158530623635456
<class 'int'>
None
#

even .members is empty

wanton current
#

what is shown if you print user_guild.members

mild token
wanton current
#

do you not have guild members intents

mild token
wanton current
#

wait, why are you fetching the guild?

mild token
#

woops

mild token
wanton current
#

:(

mild token
drifting scaffold
#

@unkempt canyon

wheat thunder
#
from pathlib import Path

import discord
from discord import app_commands
from discord.ext import commands, tasks
from discord.ext.commands import Bot, Context

from app.cogs.abstract_cog import AbstractCog
from app.services.event_service import EventService


class EventCog(AbstractCog):
    def __init__(self, bot: Bot):
        super().__init__(bot)
        self._event_service = EventService(bot)
        self.check_event_lifetime.start()

    async def load_events(self):
        await self._event_service.load_events()

    @tasks.loop(minutes=1)
    async def check_event_lifetime(self):
        await self._event_service.check_event_lifetime()

    @check_event_lifetime.before_loop
    async def before_check_event_lifetime(self):
        await self.bot.wait_until_ready()


async def setup(bot: Bot):
    cog = EventCog(bot)
    await bot.add_cog(cog)
    # Is this way better?
    await cog.load_events()

Can I add tasks in setup? I think async processing is better in setup than in the constructor.

hushed galleon
pure glacier
#

hi i am creating a discord bot on python of pokemon weaknesses. Done with the single typing mons

with open('pokemonData.json', 'r') as f:
    pokemon_data = json.load(f)

@bot.command(name='weak')
async def weakness(ctx, pokemon_name):
    pokemon_name = pokemon_name.lower()
    if pokemon_name not in pokemon_data:
        await ctx.send(f'Pokemon "{pokemon_name}" not found.')
        return
    
    pokemon = pokemon_data[pokemon_name]
    types = pokemon['types']
    
    # Define type effectiveness
    type_effectiveness = {
        'Normal': {'SUPER EFFECTIVE': ['Fighting'], 'UNEFFECTIVE': [], 'IMMUNE': ['Ghost']},```

Now for the dual typing how can i define like Normal + fighting etc?
wheat thunder
hushed galleon
# pure glacier hi i am creating a discord bot on python of pokemon weaknesses. Done with the si...

representing the data you mean? this question is a bit more generic and better suited in #1035199133436354600, but from a quick glance at this chart https://pokemondb.net/type/dual, perhaps you would want to use tuple keys, e.g. py defense_to_attack_effectiveness = { # (defense types): {attack effectiveness} ("Normal", None): {"Fighting": 2, ...}, ("Normal", "Fire"): {"Fire": 1/2, ...}, ... } i would also consider using an SQLite database to represent this data, but you'd need some knowledge of SQL basics and design to go with that approach

wheat thunder
#

Should the design of a Service object,
handling Discord classes and storing them in a database, be assessed within the database section?

limber jolt
distant dew
#

anyone is familiar with telegram bots ? i have some questions im new in this

distant dew
limber jolt
distant dew
wild maple
#

Can anyone explain me this:
@bot.command()
async def roll(ctx, dice: str):
"""Rolls a dice in NdN format."""
try:
rolls, limit = map(int, dice.split('d'))
except Exception:
await ctx.send('Format has to be in NdN!')
return

result = ', '.join(str(random.randint(1, limit)) for r in range(rolls))
await ctx.send(result)
#

What is NdN format?

wheat thunder
#

2d6 = two 6-sided dice

boreal loom
#
intents = discord.Intents.all()
bot = discord.Bot(intents=intents, activity=discord.CustomActivity(
    "Test Bot"
))
slate swan
#

or an assert / if check [isinstance(user, discord.Member)]

foggy elbow
#

Are there any free hosting tool to keep my bot running 24/7?

fast osprey
#

Not any good ones. Someone has to pay the money to run a server, there's always a catch

wheat thunder
#

Do someone know how to test Discord commands in an automated way, without directly inputting commands?

I receive commands in a cog and handle important logic through a service.
Testing the service is feasible, but testing whether the Discord bot correctly executes commands seems challenging.

Should I mock the cog's commands for testing?

mild token
#

is there a way to give min and max value in interaction parameter?
like it should accept value btw 0 to 10 something like this?

fast osprey
#

!d discord.app_commands.Range

unkempt canyonBOT
#

class discord.app_commands.Range```
A type annotation that can be applied to a parameter to require a numeric or string type to fit within the range provided.

During type checking time this is equivalent to [`typing.Annotated`](https://docs.python.org/3/library/typing.html#typing.Annotated) so type checkers understand the intent of the code.

Some example ranges...
mild token
#
@app_commands.Argument(name="time", min_value=0, max_value=10)
 File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "D:\AFW bot\afw_bot\ext\sync.py", line 173, in <module>
    class Sync(commands.GroupCog, name='sync'):
  File "D:\AFW bot\afw_bot\ext\sync.py", line 278, in Sync
    @app_commands.Argument(name="time", min_value=0, max_value=10)
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Argument.__init__() got an unexpected keyword argument 'name'
``
mild token
fast osprey
#

Yeah the example in there will work

wheat thunder
#

If there's a view that will only be used within a single Cog,
is it acceptable to declare that view inside a class?

Or is it more common to organize a separate folder structure for views?

fast osprey
#

There is no functional reason here to nest classes

#

You can have multiple classes in a file

wheat thunder
#

Of course I know, but I declared an error class inside the class that will only be used inside that class.

I don't think it's necessary, but I wanted to know if there was a reason to avoid it.

fast osprey
#

Are you sure you're not conflating "inside class" and "inside file"

#

Because you really have no reason to put a class inside another class

wheat thunder
#

Of course it does.
I just wanted to try that.

I thought it would be a little more complete to have a View class inside a Cog class
rather than another View class inside a Cog file.

timber dragon
#

Python module*

#

A python module can hold as many classes as you want, it doesn't really matter

Nesting classes is kinda messy and discouraged

wheat thunder
#

I wanted to hear a definitive answer. If so, I'll change it.

fast osprey
#

"Cog file" is a construct that is entirely in your head. Python has modules and a module can have whatever declarations inside it that conceptually make sense

open cobalt
#

did my first bot with discord py but without ext commands. The bot gives you data about a keyword channelid video info channel info from youtube. What yall think?

fast osprey
#

Is there targeted feedback you're looking for?

open cobalt
#

I might make a version 2.0 but with command ext. I looked into the docs and is really nice

timber dragon
#

You don't have to use the extension..

open cobalt
#

you using it?

#

currently using on_message event for commands

timber dragon
#

You should be using slash commands tbh

open cobalt
#

comes that with the extension command?

#

I know on message is a bit mhh for commands

open cobalt
smoky sinew
#

For sure

#

The docs are a great way to learn

#

Especially if you're a beginner

vocal snow
open cobalt
#

you mean where to find the docs? or I dont understand

smoky sinew
#

I definitely recommend checking it out

vocal snow
#

ohhh

open cobalt
#

it is simply said how the library works

#

what methods can be accesed etc etc etc

smoky sinew
#

At first i didn't really understand how to use the docs

#

But you learn with time

#

Overall i just think it's a great learning resource

open cobalt
#

yeah that is right

smoky sinew
#

Yep for sure

glad cradle
drowsy thunder
#

How to update database with times.
Like let's say a temp role command should remove a role from a user in 2 day and 3 hr and it's in a SQLite3 db
How do I reduce the time as time passes??

wheat thunder
#

Is it possible to automate the testing of discord commands?

wheat thunder
median radish
#

i got a gen/stock bot i need help fixing, whoever can fix it i will pay

fast osprey
#

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

midnight oracle
#

I have no clue why the code is giving that error

#

Could I access the code to try to run it locally?

limber jolt
midnight oracle
#

okay

fast osprey
#

load_extension wants a singular module name

boreal sigil
#

which is?

fast osprey
#

The module name of the extension you want to load

boreal sigil
#

but like what is that tho ๐Ÿ˜ญ

fast osprey
#

Do you know how module names work in python? That's a very general thing, not library specific

#

like when you do imports

boreal sigil
#

ye ye

#

ik how they work but what is the module name

fast osprey
#

You would generate that based on your file structure

#

Let's say you had file A you were running, and you needed to import a function from file B elsewhere on your folder structure. You would have some import X in file A. X is the module name, and it's the exact same thing for using load_extension

open cobalt
#

hey ใ‚ทใƒฃใƒ‰ใ‚ฆใ‚ญใƒฃใƒƒใƒˆ, I read the docs, so I mean the bot.load_extension takes a str name which is kinda like a path were the cog is located in your folder structure. Instead of / you replace it with a dot

#

so for example you have a folder cogs and inside this folder kick.py you tell the func this path cogs.kick (tell me if I am wrong)

#

@fast osprey Is that correct what I have written there ?

fast osprey
#

Loosely. It very specifically expects a module name, which behaves the way you described for files relative to the file being run but there are other ways of referencing modules too

open cobalt
fast osprey
#

That is not advisable to do file name manipulation yourself

#

utilities like pkgutil exist to make discovery/processing of modules easier

open cobalt
#

ok might look into that

pliant marlin
#

can someone help me code a bot? I'm new to coding/py

slate swan
#

Discord bots & discord.py is not made for people new to coding/python

#

Should learn python more as well as some specific topics e.g. oop, async, etc.

vocal plover
#

I feel like it's been a while since I've said this but I think that's absolutely the wrong response to beginners asking how to build bots. People learn best doing something that they enjoy or that's beneficial to them, if you just study python then with few exceptions you'll probably just get bored and frustrated. Yes, discord bot development is a challenging place to start your programming journey, but if bots are what motivate you to program then it's not necessarily a bad place to start, even with the higher learning curve. IMO the better way to approach this is to send examples of simple bots, get people to modify those, and send links to the various good bot tutorials around, because even if you don't understand what you're writing at the very start if you're driven to make stuff through a desire to make bots you'll pick it up pretty fast.

That all said, I'd recommend:
https://tutorial.vco.sh
And
https://guide.disnake.dev

scarlet tiger
glad cradle
scarlet tiger
#

It is the original

glad cradle
#

what you said is questionable, you should motivate why it's better if you say so, tho it doesn't fits the original question

scarlet tiger
mild token
#

how i can mention a thread? <@memberid> like we do with member and all?

willow sluice
#

<#channel_id>

mild token
willow sluice
#

for thread..

mild token
#

why its givine me unknown : (

willow sluice
#

or do you think that the thread is not a channel?

mild token
willow sluice
#

invite me to server with thread you trying to ping

timber dragon
#

It's unknown if it's not cached afaik

#

It should still be click able

If the id is valid ofc

#

Make sure it's the thread's id, not whoever created it

fast osprey
# vocal plover I feel like it's been a while since I've said this but I think that's absolutely...

Very hard disagree. If the only way someone can motivate themselves to do something is by ONLY doing the end goal and not the foundations, that is a fundamental discipline issue and not something to be encouraged. Foundations are boring, but sometimes you need to learn how to do boring things. There are no shortcuts, and the people who insist there are universally put out really crappy and unmaintainable code

eager pike
#

What are the docs for the discord.py slash commands? Where can i find them

pure glacier
#
afk_users = {}

@bot.command(name='afk')
async def afk(ctx, *, reason=None):
    member = ctx.author
    try:
        if member.id in afk_users:
            afk_users.pop(member.id)
            await member.edit(nick=member.nick.replace('[AFK]', '').strip())
            await ctx.send(f'{member.mention} is no longer AFK')
        else:
            afk_users[member.id] = reason
            await member.edit(nick=f'[AFK] {member.display_name}')
            await ctx.send(f'{member.mention} is now AFK: {reason}')
    except discord.Forbidden:
        await ctx.send("I don't have permission to change your nickname!")

@bot.event
async def on_message(message):
    if message.author.id in afk_users and not message.content.startswith('!afk'):
        try:
            afk_users.pop(message.author.id)
            await message.author.edit(nick=message.author.nick.replace('[AFK]', '').strip())
            await message.channel.send(f'Welcome back, {message.author.mention}! You are no longer AFK.')
        except discord.Forbidden:
            await message.channel.send("I don't have permission to change your nickname back!")
    await bot.process_commands(message)```


With this everyone is able to go afk except me it shows "I don't have permission to change your nickname!" and it's also not able to give me roles and all. Bot had admin perms and i am owner
finite salmon
#

Make the role of your bot higher than the one you currently use in your server role settings

eager pike
pure glacier
eager pike
#

unless you pass the ownership to an alt

timber dragon
#

No bots can add roles to the owner

#

Check role positions

limber jolt
#

No matter hwat I have done i still get i have no perms when I try to use my FFMPEG file in VScode i've made sure folder and vscode have full control and ran It In admin mode

smoky sinew
pure glacier
#

btw i want help, how can i add a custom emoji in embed?

limber jolt
#

:EMOJI_ID:

#

Or liek the name then ID

#

Like*

pure glacier
#

https://pastebin.com/FR02uTeA

the emojis are like fire, grass, water etc in my server but they are not coming on the embed title. I want that like if someone does ?weak bulbasaur the bot should've shows Bulbasaur (grass emoji)Grass/(poison emoji)Poison in the title instead of just bulbasaur

timber dragon
#

You might be thinking of changing the nickname, that can't happen

smoky sinew
timber dragon
#

Indeed it's not

smoky sinew
#

unfortunately you are incorrect

timber dragon
#

And a bot is still adding roles to me

#

What

wet talon
#

I want to create a command in which if the bot sends an embed PAYMENT INVOICE to any channel, he will send a got message to specific channel

#

how i can do that

fast osprey
#

If it's your bot that's sending message A...that's your code, you can have it do whatever else you want at that point

willow sluice
#

Hello. I have a Button in my discord.ui.View and now i want to add a Select. Is there a way to change the state of View so that at the beginning only the buttons are displayed and after only select?

#

Or is the only way to do it is two different views?

turbid condor
willow sluice
#

Right. For example
At first you can see the buttons after clicking on one of it only select appears and then again the buttons

turbid condor
#

Well you for the first part where the select appears you just need to edit interaction.message at the end of your response updating it with the view containing the select and same for the second when the user makes a selection then edit the interaction.message again sending the view with buttons

hushed galleon
# willow sluice Right. For example At first you can see the buttons after clicking on one of it ...

for this i typically clear all the items and add back whichever is desired, something along the lines of: ```py
class MyView(discord.ui.View):
def init(self):
super().init()
self.selected_category = None
self._refresh_components()

def _refresh_components(self):
    self.clear_items()
    if self.selected_category is None:
        self.add_item(self.fruits_button)
        self.add_item(self.meats_button)
    elif self.selected_category == "fruits":
        self.add_item(FruitSelect(self))
    elif self.selected_category == "meats":
        self.add_item(MeatSelect(self))

@discord.ui.button(...)
async def fruits_button(self, interaction, button):
    self.selected_category = "fruits"
    self._refresh_components()
    await interaction.response.edit_message(view=self)

@discord.ui.button(...)
async def meats_button(self, interaction, button): ...```
#

when i want the original buttons, i'd update the state and refresh to add them back

#

though either approach (refreshing one view vs. editing multiple views) can be cleaner than the other depending on what you're doing

steep kindle
#

TL:DR: The bot ran successfully but no commands were registered

fast osprey
#

You should not be doing setup steps in on_ready, especially not syncing

#

You're also syncing on a guild despite declaring a global command

steep kindle
#

Right, okay

#

Nevermind slight brain malfunction!

mild token
#

2024-07-13 23:14:09 Login Failed
Reason: 403 Forbidden (error code: 50001): Missing Access
when i am logging in with new application why i am getting this?

exotic hazel
#

Nevermind that's a different issue I think, sorry for the ping

#

I just googled error 50001 and that came up

mild token
#
Traceback (most recent call last):
  File "D:\AFW bot\afw_bot\main.py", line 68, in run
    super().run(*args, **kwargs)
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\client.py", line 869, in run
    asyncio.run(runner())
  File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\client.py", line 858, in runner
    await self.start(token, reconnect=reconnect)
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\client.py", line 786, in start
    await self.login(token)
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\client.py", line 629, in login
    await self.setup_hook()
  File "D:\AFW bot\afw_bot\main.py", line 31, in setup_hook
    await self.tree.sync(guild=MY_GUILD)
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\app_commands\tree.py", line 1131, in sync
    data = await self._http.bulk_upsert_guild_commands(self.client.application_id, guild.id, payload=payload)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\http.py", line 752, in request
    raise Forbidden(response, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50001): Missing Access

dont know what exactly happened

mild token
# willow sluice show us your code
import traceback
import discord.ext
import discord.ext.commands
import discord
from discord.ext import commands
import tracemalloc
import importlib
from pathlib import Path
import inspect
import asyncio
from afw_bot.ext.reaction_based.clan_info import ClanInfoList
from afw_bot.ext.reaction_based.sync import SyncEmbed
from afw_bot.ext.reaction_based.threaded_channels import ClanApplication, ContactUs, PartnershipApplication, StaffApplication
from .ext.utils.loggers import log_message
from .ext.error_handler import CommandErrorHandler
import coc
from .constants import DevCreds, Core
tracemalloc.start()

MY_GUILD = discord.Object(id=1237351935183556651)


class MyBot(commands.Bot):

    def __init__(self, *, intents: discord.Intents):
        super().__init__(command_prefix='!', help_command=None,
                         intents=intents, tree_cls=CommandErrorHandler)

    async def setup_hook(self):
        self.tree.copy_global_to(guild=MY_GUILD)
        await self.tree.sync(guild=MY_GUILD)

        self.add_view(SyncEmbed(self))
        self.add_view(StaffApplication())
        self.add_view(ClanApplication())
        self.add_view(ContactUs())
        self.add_view(PartnershipApplication())
        self.add_view(ClanInfoList(self))

    async def on_ready(self):

        coc_client = coc.Client()
        await coc_client.login(DevCreds.DEV_SITE_EMAIL, DevCreds.DEV_SITE_PASSWORD)
        self.coc_client: coc.Client = coc_client
        log_message('DEBUG', f'Logged in as {self.user}(ID: {self.user.id})')
        print('------')

    def load_cog(self, file_path):
        module = importlib.import_module(file_path)
        for name, obj in inspect.getmembers(module):
            if inspect.isclass(obj) and issubclass(obj, (commands.Cog, commands.GroupCog)):
                asyncio.run(self.add_cog(obj(self)))
                log_message("INFO", f'Loaded {name} Cog')

    def load_all_extensions(self):

        directory = Path('afw_bot/ext')
        for item in directory.rglob('*.py'):
            module_name = item.relative_to(directory).with_suffix(
                '').as_posix().replace('/', '.')
            if module_name.split('.')[-1].startswith('_'):
                continue
            self.load_cog(f"afw_bot.ext.{module_name}")

    def run(self, *args, **kwargs):
        self.load_all_extensions()
        try:
            super().run(*args, **kwargs)
        except Exception as e:
            traceback.print_exception(e)
            log_message('CRITICAL', f"Login Failed\nReason: {e}")


def main():
    intents = discord.Intents.all()
    bot = MyBot(intents=intents)
    bot.run(Core.BOT_TOKEN)


if __name__ == "__main__":
    main()
fast osprey
#

You shouldn't be syncing every time your bot starts, for one

mild token
fast osprey
#

You should trigger it only when you need to. It has strict rate limits

willow sluice
#

make a sync command only for bot owner

fast osprey
#

Is there a specific reason why you'd want to sync to that guild rather than just globally?

mild token
#

so it will be in guild only + its in testing server

fast osprey
#

Global should be fine

mild token
#

till yesterday my code was working

#

suddenly today it stopped

fast osprey
#

Either the bot isn't in that guild, or it doesn't have the app command scope in that guild

#

Whatever that id points to

mild token
fast osprey
#

Scope has nothing to do with dev portal

fast osprey
#

And if you sync globally?

mild token
#

using guild install

mild token
fast osprey
#

But the error is on sync

#

You couldn't not sync and still get the same error

mild token
fast osprey
#

What is your code now, and your error now

#

After removing the sync

willow sluice
#
@bot.command()
@commands.guild_only()
@commands.is_owner()
async def sync(
  ctx: Context, guilds: Greedy[discord.Object], spec: Optional[Literal["~", "*", "^"]] = None) -> None:
    if not guilds:
        if spec == "~":
            synced = await ctx.bot.tree.sync(guild=ctx.guild)
        elif spec == "*":
            ctx.bot.tree.copy_global_to(guild=ctx.guild)
            synced = await ctx.bot.tree.sync(guild=ctx.guild)
        elif spec == "^":
            ctx.bot.tree.clear_commands(guild=ctx.guild)
            await ctx.bot.tree.sync(guild=ctx.guild)
            synced = []
        else:
            synced = await ctx.bot.tree.sync()

        await ctx.send(
            f"Synced {len(synced)} commands {'globally' if spec is None else 'to the current guild.'}"
        )
        return

    ret = 0
    for guild in guilds:
        try:
            await ctx.bot.tree.sync(guild=guild)
        except discord.HTTPException:
            pass
        else:
            ret += 1

    await ctx.send(f"Synced the tree to {ret}/{len(guilds)}.")```
mild token
#

and this bot is not in this server

willow sluice
#

I guess that you are getting this error because the bot is not ready yet
try to use wait_until_ready before using auto sync. and check your token and guild id is correct

mild token
#

when bot logged in i read the name and figured out ๐Ÿ˜…

fast osprey
#

That'll do it

torn solar
#
@discord.ui.Button(label="Transactions", style=discord.ButtonStyle.blurple, custom_id="transaction_button")
    async def viewTransactions(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.defer(ephemeral=True)
    
        user_id = interaction.user.id
    
        # Fetch the account name associated with the user
        cursor.execute("SELECT user_account FROM users WHERE user_id = ?", (user_id,))
        result = cursor.fetchone()
    
        if result is None:
            await interaction.followup.send("You don't have an account.", ephemeral=True)
            return
    
        account_name = result[0]

        # Fetch transactions for the account
        cursor.execute("""
        SELECT amount, executor_id, note, transaction_date
        FROM transactions
        JOIN accounts ON transactions.account_id = accounts.account_id
        WHERE accounts.account_name = ?
        ORDER BY transaction_date DESC
        """, (account_name,))
    
        transactions = cursor.fetchall()

        if not transactions:
            await interaction.followup.send("No transactions found.", ephemeral=True)
            return

        pages = create_transaction_pages(transactions, account_name)

        current_page = 0
        view = PaginationView(pages, current_page)
        await view.send_initial_message(interaction)```

```Traceback (most recent call last):
  File "c:\Users\teddy\OneDrive\Desktop\Chase Bank\Chase Bot\main.py", line 574, in <module>
    class DashboardView(discord.ui.View):
  File "c:\Users\teddy\OneDrive\Desktop\Chase Bank\Chase Bot\main.py", line 579, in DashboardView
    async def viewTransactions(self, interaction: discord.Interaction, button: discord.ui.Button):
TypeError: 'Button' object is not callable```

anyone know why im getting this error
willow sluice
#

change @discord.ui.Button to @discord.ui.button

torn solar
#

which one

#

in the decorator or in the def

willow sluice
#

im talking about decorator

torn solar
#

ok

twin gazelle
#

GUYS I MADE MY FRIST DISCORD BOT

#

๐Ÿ˜„

lethal drift
#

is PRESENCE INTENT needed if I'm checking how many users in a server are online (every status except offline)?

I don't need to know immediately (aka using the event) when it's changed per user since I'm already running the task on a loop

golden portal
#

!d discord.Intents.presences

unkempt canyonBOT
#

Whether guild presence related events are enabled.

This corresponds to the following events:

โ€ข on_presence_update()

This also corresponds to the following attributes and classes in terms of cache...

golden portal
#

eh it doesnt show

#

but you do, its written in there

torn solar
#

is there a way to do this but have the choices updated

#

basically i have a different command where i want the choices to be this list of accounts

#

but the list of accounts is going to be constantly updating

#

cursor.execute("SELECT account_name FROM accounts") thats what i want the choices to be

sick birch
#

looks like you want autocomplete

torn solar
#

but updated not set when the script runs

#

correct me if im wrong but if i do this ```from enum import Enum, auto

class Choices(Enum):
choice1 = auto()
choice2 = auto()
choice3 = auto()

@bot.tree.command(...)
async def my_command(interaction: discord.Interaction, choices: Choices) -> None:
...``` it wont be updated to what the current accounts are

#

yknow what i mean

#

since the choices are set when the script runs

#

so is there possibly a way to set the choices inside of the command so that it updates?

#

@sick birch

sick birch
#

yeah looks like you want autocomplete

torn solar
#

but updated

#

not all the accounts from when the script is ran

#

how can i do that

sick birch
torn solar
torn solar
# sick birch looks like you want autocomplete
async def register(ctx: discord.Interaction, account: Literal["Checking", "Business"]) -> None:``` like with this the choices are business and checking but for my other command i want it to list all the accounts
#

can you explain how to do that please or link something

willow sluice
#

just dynamically generate an array of options

#

that is all

torn solar
#

is that possible

sick birch
#

if you can generate the options ahead of time, then yeah you should use choice

#

but from what you're telling us you seem to want autocomplete, unless i'm mistaken

willow sluice
#

bro how do you think? ะกommand code will only be called after the call. And you need options before calling

torn solar
#

yeah the options are being updates constantly

#

so they cannot be generated ahead of time

sick birch
#

or who the user is?

willow sluice
#

wdym you can generate options before command call

torn solar
#

and it might change when someone registers a new account

#

yknow what i mean

willow sluice
#

bro.. just give us description of your command work and what choices it should have

sick birch
#

well, not need

#

but i find the experience with autocomplete to be kind of mid with the latency so i just don't use it

#

if you don't implement some sort of caching, each time the user types a letter you will hit the DB and return a result, really slow and just not a good experience

willow sluice
#
def get_accounts():
    # some sqlite actions here
    cursor.execute("SELECT account_name FROM accounts")
    return cursor.fetchall()

@app_commands.command()
@app_commands.choices(accounts=[
    app_commands.Choice(name=account, value=account)
    for account in get_accounts()
])
async def transfer(interaction: discord.Interaction, accounts: app_commands.Choice[str]):
    pass # some actions here

@transfer.autocomplete('accounts')
async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]

something like that idk what do you need

#

@torn solar

#

you must clarify what you want if i answered wrong. and maybe this code will throw an error i havent tested it

wanton current
#

import it or change it to list

torn solar
#

tried import said unknown

#

ill switch to list

wanton current
#

from typing import List

torn solar
#
  File "c:\Users\teddy\OneDrive\Desktop\Chase Bank\Chase Bot\main.py", line 887, in <module>
    async def transfer(interaction: discord.Interaction, account: app_commands.Choice[str]):
  File "C:\Users\teddy\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\app_commands\tree.py", line 887, in decorator
    command = Command(
  File "C:\Users\teddy\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\app_commands\commands.py", line 665, in __init__
    self._params: Dict[str, CommandParameter] = _extract_parameters_from_callback(callback, callback.__globals__)
  File "C:\Users\teddy\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\app_commands\commands.py", line 402, in _extract_parameters_from_callback
    _populate_choices(result, choices.copy())
  File "C:\Users\teddy\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\app_commands\commands.py", line 329, in _populate_choices        
    raise TypeError(f'unknown parameter given: {first}')
TypeError: unknown parameter given: accounts```
#
def get_accounts():
    # some sqlite actions here
    cursor.execute("SELECT account_name FROM accounts")
    return cursor.fetchall()

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
@app_commands.choices(accounts=[
    app_commands.Choice(name=account, value=account)
    for account in get_accounts()
])
async def transfer(interaction: discord.Interaction, account: app_commands.Choice[str]):
    print('hi') 
    
@transfer.autocomplete('account')
async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    account = get_accounts()
    return [
        app_commands.Choice(name=account, value=account)
        for account in account if current.lower() in account.lower()
    ]```
turbid condor
turbid condor
#

Either use asyncio.to_thread to run those function or use an async lib for db like aiosqlite

torn solar
#

im trying to have the choices for account in the transfer command be all the current accounts in cursor.execute("SELECT account_name FROM accounts") but the accounts are being updated while the bot is running so i can have it pre set

torn solar
#

also theres an error

turbid condor
#

!blocking

unkempt canyonBOT
#
Asynchronous programming

Imagine that you're coding a Discord bot and every time somebody uses a command, you need to get some information from a database. But there's a catch: the database servers are acting up today and take a whole 10 seconds to respond. If you do not use asynchronous methods, your whole bot will stop running until it gets a response from the database. How do you fix this? Asynchronous programming.

What is asynchronous programming?
An asynchronous program utilises the async and await keywords. An asynchronous program pauses what it's doing and does something else whilst it waits for some third-party service to complete whatever it's supposed to do. Any code within an async context manager or function marked with the await keyword indicates to Python, that whilst this operation is being completed, it can do something else. For example:

import discord

# Bunch of bot code

async def ping(ctx):
    await ctx.send("Pong!")

What does the term "blocking" mean?
A blocking operation is wherever you do something without awaiting it. This tells Python that this step must be completed before it can do anything else. Common examples of blocking operations, as simple as they may seem, include: outputting text, adding two numbers and appending an item onto a list. Most common Python libraries have an asynchronous version available to use in asynchronous contexts.

async libraries

  • The standard async library - asyncio
  • Asynchronous web requests - aiohttp
  • Talking to PostgreSQL asynchronously - asyncpg
  • MongoDB interactions asynchronously - motor
  • Check out this list for even more!
torn solar
#

so how can i fix the code

#

just make it an async method and await it?

turbid condor
#

Did you even read the embed?

torn solar
#

yes it says that if a function doesnt use asynchronous programming it will stop running while its waiting for that function to complete

#

so using async allows for it to keep doing other things while its communicating with the 3rd party server

turbid condor
#

And the last paragraph?

#

It tells you to use async lib

torn solar
#

im just confused bruh

turbid condor
#

So switch from sqlite to aiosqlite

torn solar
#

can i still use my current db and are the functions the same

eager pike
#

does commands.Bot require intents?

turbid condor
turbid condor
turbid condor
torn solar
#

so ill have to await each one of them

turbid condor
#

Yes

#

!pip aiosqlite

unkempt canyonBOT
#

asyncio bridge to the standard sqlite3 module

Released on <t:1708409573:D>.

turbid condor
#

This is asynchronous module for sqlite

torn solar
#

what do i need to change to fix my current error first ik u told me but im still confused

eager pike
#
class myBot(commands.Bot):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=Intents.all())
``` Why can't i do this?
turbid condor
#

In choices you are using the argument name as accounts while in declaration u are using account

torn solar
tropic tartan
torn solar
#

thats the full thing sorry left that bottom line out

eager pike
torn solar
#

i use command tree

turbid condor
torn solar
#

works fine for me @bot.tree.command(name="", description="")

#

that as the decorator then define it

turbid condor
#

Just initialize your class and do it as you normally do

eager pike
#

it takes an hour or so for the slash commands to show up right?

torn solar
#

no just restart ur discord

eager pike
#

unless i specifically enable them for a server

eager pike
#

oh what

#

ok thx

turbid condor
#

Just refresh discord

torn solar
# eager pike oh what
class ChaseBot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.all()
        super().__init__(command_prefix=".", intents=intents)
        
    async def setup_hook(self) -> None:
        self.add_view(PersistentConfirmation())
        self.add_view(PersistentCloseButton())
        self.add_view(PersistentTicket())
        self.add_view(DashboardView())
        
bot = ChaseBot()

@bot.event
async def on_ready():
    await bot.change_presence(activity=presence,status=status)
    print(f'{bot.user} Loaded')
    synced = await bot.tree.sync()
    print("Command Tree Synced")```
turbid condor
torn solar
#

no need to define synced but i have it for some reason

torn solar
turbid condor
#

Cuz you don't need to sync everytime your bot starts

#

Only once

eager pike
#

What if you edit or remove commands?

#

Would you not need to sync again

torn solar
#

the alternative is to make a regular command for syncing

turbid condor
#

And on_ready can trigger many times instead of once during a cycle

torn solar
#

for example !sync

turbid condor
turbid condor
#

Also you will need to sync if you add or change an argument for the command

torn solar
#

basically sync anyytime you edit anything about/within the command

#

and if its not showing up refresh ur discord

torn solar
#

fr?

turbid condor
#

You can change logic and no need to sync

turbid condor
# torn solar basically sync anyytime you edit anything about/within the command
### Sync when you...
- Basic
  - Added/Removed a command
  - Added/Modified/Removed autocomplete (decorator, transformer)
  - Added/Removed an argument
  - Added/Modified/Removed locale strings
  - Converted the global/guild command to a guild/global command
- Modify 
  - Changed a command's...
    - name (`name=` kwarg, function name)
    - description (`description=` kwarg, docstring)
  - Changed an argument's...
    - name (rename decorator, param name)
    - choices (Literal, choices decorator, enum type)
    - description (describe decorator, docstring)
    - type (`arg: str` str is the type here)
- Permissions
  - Added/Modified/Removed permissions:
    - `default_permissions` (decorator, kwarg)
    - `nsfw` (kwarg)
  - Changed installs or contexts (decorators):
    - `allowed_installs`
    - `allowed_contexts`
    - `guild_install`, `user_install`, `guild_only`, `dm_only`, `private_channel_only`
### Do not sync when you...
- Changed anything in the command/autcomplete function's body (after the `async def ():` part)
- Added/Modified/Removed library side checks:
  - `(@)app_commands.checks...`
  - `(@)commands...(.check)`
  - `@app_commands.checks.(dynamic_)cooldown(...)`

*This is the same for hybrid app commands*
#

This is when u need to sync and when not to

torn solar
#

is syncing too much really bad

#

like does it affect it that much

turbid condor
#

There's a 200 commands per day cap i think

torn solar
#

oh shit

#

never knew that

eager pike
#

@turbid condor so i just add a sync slash commands that syncs once i run the cmd?

turbid condor
eager pike
#

oh ok

finite salmon
#

It doesn't really matter if it's slash or prefix

willow sluice
turbid condor
finite salmon
#

Sync it in the setup_hook or somewhere temporarily and remove it once it's synced

finite salmon
#

just a one time thing

#

And remove it from setup_hook or wherever and use the command from then on

turbid condor
#

But no type it in setup hook and then remove it after starting the bot once

finite salmon
#

If you wanna make it hybrid then sure

finite salmon
willow sluice
willow sluice
#

tysm

eager pike
#

what is process_commands?

willow sluice
#

!d discord.ext.commands.Bot.process_commands

unkempt canyonBOT
#

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

This function processes the commands that have been registered to the bot and other groups. Without this coroutine, none of the commands will be triggered.

By default, this coroutine is called inside the [`on_message()`](https://discordpy.readthedocs.io/en/latest/api.html#discord.on_message) event. If you choose to override the [`on_message()`](https://discordpy.readthedocs.io/en/latest/api.html#discord.on_message) event, then you should invoke this coroutine as well.

This is built using other low level tools, and is equivalent to a call to [`get_context()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.get_context) followed by a call to [`invoke()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.invoke).

This also checks if the messageโ€™s author is a bot and doesnโ€™t call [`get_context()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.get_context) or [`invoke()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.invoke) if so.

Changed in version 2.0: `message` parameter is now positional-only.
torn solar
#
def get_accounts():
    cursor.execute("SELECT account_name FROM accounts")
    list = cursor.fetchall()
    return list(list)

async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
@app_commands.autocomplete(account=transfer_autocomplete)
async def transfer(interaction: discord.Interaction, account: str):
    print('hi')```
#

its not autocompleting anything

turbid condor
torn solar
#

ur right

#

i forgot to make it an asyncio method i just noticed that

#

wait

#

its async im tweaking

turbid condor
#

Autocomplete is an interaction type that shows a set autocomplete values/options to the user as they type in an option.
Autocomplete is only available for str, int, and float types, and only available in chat-input (slash) commands.

To add an autocomplete option to a command, it is recommended for it to be done in one of two ways:

You can use the @command.autocomplete('option_name') decorator, where the str argument passed as the first parameter to the decorator
is the name of the parameter you want to provide autocomplete to:

@app_commands.command(...)
async def foo(interaction: discord.Interaction, bar: str):
    ...

@foo.autocomplete('bar')
async def autocomplete_callback(interaction: discord.Interaction, current: str):
    # Do stuff with the "current" parameter, e.g. querying it search results...

    # Then return a list of app_commands.Choice
    return [
        app_commands.Choice(name='Option 1', value='Option 1')
    ]

As seen above, the parameters in autocomplete_callback are interaction (the autocomplete interaction received) and current (the incomplete value the user is entering).

You can also use it as @app_commands.autocomplete(option_name=callback). Every kwarg name is the option name and the value of it is the function/callback of the autocomplete callback, taking and returning the same exact arguments as above.

TODO: Autocomplete example not in master branch
Documentation:
https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.Command.autocomplete
https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.autocomplete
Source: discord.py server

#

Now compare the example here with your code

torn solar
#
async def fruit_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    fruits = ['Banana', 'Pineapple', 'Apple', 'Watermelon', 'Melon', 'Cherry']
    return [
        app_commands.Choice(name=fruit, value=fruit)
        for fruit in fruits if current.lower() in fruit.lower()
    ]

@app_commands.command()
@app_commands.autocomplete(fruit=fruit_autocomplete)
async def fruits(interaction: discord.Interaction, fruit: str):
    await interaction.response.send_message(f'Your favourite fruit seems to be {fruit}')``` this is what it said to do on the docs
#

ill tryout ur method

torn solar
#

cus for that i have to set individual choices

dusky elk
turbid condor
#

Just put that under the auto complete deco

#

!pip pymongo

unkempt canyonBOT
torn solar
#

ok

turbid condor
#

!pip motor

unkempt canyonBOT
#

Non-blocking MongoDB driver for Tornado or asyncio

Released on <t:1720643803:D>.

dusky elk
#

gee thanks thats very useful Sigh

turbid condor
#

Cuz pymongo seems to be a synchronous lib

dusky elk
#

I am aware of motor and its docs, I am specifically asking wether read operations for pymongo are blocking

#

I guess there's one way to find out

torn solar
#
def get_accounts():
    cursor.execute("SELECT account_name FROM accounts")
    list = cursor.fetchall()
    return list(list)

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
async def transfer(interaction: discord.Interaction, account: str):
    print('hi') 
    
@transfer.autocomplete('account')
async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]``` stil faililng to autcomplete
turbid condor
torn solar
#

if thats what ur asking

turbid condor
willow sluice
#

Why did you call the variable a reserved word?...
This is also autocomplete so you shouldnyt have default options bro..

torn solar
#
Command Tree Synced```
turbid condor
#

And you reloaded your discord?

torn solar
#

yuh

#

ill refresh my discord again one sec

willow sluice
#

Check what your function returns

torn solar
#

get_accounts or the callback

turbid condor
#

The autocomplete

#

Print the return value

torn solar
#

k

#

where should i print it tho

willow sluice
#

get_accounts

torn solar
#

like when

turbid condor
#

In console

torn solar
#

ik but where do i put the print

willow sluice
#

bro just call print func

torn solar
#

just inside the method

willow sluice
#

just inside

torn solar
#

k

#

ill print both

#
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]``` how do i even print this
willow sluice
#

do you know basics of python? just put it inside variable and print it

torn solar
#
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ])``` ill just do this
#

its not printing anything

#
def get_accounts():
    cursor.execute("SELECT account_name FROM accounts")
    list = cursor.fetchall()
    print('get_account print: ' + list(list))
    return list(list)

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
async def transfer(interaction: discord.Interaction, account: str):
    print('hi') 
    
@transfer.autocomplete('account')
async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    print([
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ])
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]
willow sluice
#

@turbid condor yo
what do you think about this part of code? lemon_grimace

def get_accounts():
    cursor.execute("SELECT account_name FROM accounts")
    list = cursor.fetchall()
    print('get_account print: ' + list(list))
    return list(list)
torn solar
#

why u dr me

#

can u not just help

turbid condor
torn solar
#

im printing the list wrong?

turbid condor
#

I mean rather than formatting it to a list

#

Just print(list)

#

And also make sure the db is actually loaded with data

torn solar
#

im pretty sure fetchall() returns a tuple

turbid condor
willow sluice
turbid condor
torn solar
turbid condor
#

list() converts the tuple to list

torn solar
#

whats wrong with that

#

because the autocomplete needs a list

willow sluice
#

guys try to run this code

test_var = (1, 2, 3)
print(test_var)
print(list(test_var))

print('=' * 20)

list = test_var
print(list)
print(list(list))
#

It seems to me that you dont understand whats going on at all

torn solar
#
def get_accounts():
    cursor.execute("SELECT account_name FROM accounts")
    accounts = cursor.fetchall()
    print('get_account print: ' + accounts)
    return list(accounts)

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
async def transfer(interaction: discord.Interaction, account: str):
    print('hi') 
    
@transfer.autocomplete('account')
async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    print([
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ])
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]``` still not printing anything
#

its only printing the "hi"

turbid condor
#

Ahh ambiguity

hushed galleon
#

do you have logging configured and/or are you using await bot.start(token)? you should have seen an error in your console during the autocompletion

torn solar
#

there was no error

hushed galleon
#

were there other log messages that showed, stuff like INFO Connected to gateway or of the sort

torn solar
#
2024-07-14 01:12:03 INFO     discord.gateway Shard ID None has connected to Gateway (Session ID: b20118b324b697bc3ea9c046cc6caceb).````
hushed galleon
#

hmm, so logging should be configured if you used bot.run(token)

#

wait derp you just showed that

turbid condor
#

may be an errorhandler is at work

hushed galleon
#

anyway, when you used the command did it show an autocomplete box above it?

willow sluice
torn solar
#

yes, but nothing in there

#

said failed to load options

turbid condor
torn solar
hushed galleon
willow sluice
#

invite me to the server where you are testing command

torn solar
#

anyone else need an invite

willow sluice
hushed galleon
torn solar
#

yall speaking a foreign language rn

willow sluice
#

just add app_commands.autocomplete decorator

turbid condor
torn solar
#

think i tried that before ill try again tho

turbid condor
#

but it eats away most errors that occur

torn solar
hushed galleon
torn solar
#

the transfer callback needs to be below the command

#

and for the app_commands.autcdomplete decorator it needs to be above the command

hushed galleon
#

oh yeah i dont think we asked, do you have any error handlers?

willow sluice
torn solar
#
    cursor.execute("SELECT account_name FROM accounts")
    accounts = cursor.fetchall()
    print('get_account print: ' + accounts)
    return list(accounts)

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
async def transfer(interaction: discord.Interaction, account: str):
    print('hi') 
    
@transfer.autocomplete('account')
async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    print([
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ])
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]``` sending this here to save the current code incase that one dont work
willow sluice
#
list(list)
hushed galleon
willow sluice
#

you are also dont sure that autocomplete errors are handling

#

and im sure that this code is not executed otherwise something would be printed to the console

torn solar
#

@hushed galleon it got called with that one you said should work

#

[('Chase',), ('Fluffy Personal',), ('Town of Greenville',)] it printed

#

its not autocompleting tho

hushed galleon
unkempt canyonBOT
#

discord/app_commands/tree.py lines 1301 to 1305

try:
    await command._invoke_autocomplete(interaction, focused, namespace)
except Exception:
    # Suppress exception since it can't be handled anyway.
    _log.exception('Ignoring exception in autocomplete for %r', command.qualified_name)```
torn solar
#

not sure why its printing tuples inside of a list

#

is that the issue

hushed galleon
#

ya, fetchall() normally returns a list of tuples

#

in case you select multiple columns

torn solar
#

how do i get it to return the correct thing

willow sluice
#

i thougt tuple of tuples, no?

willow sluice
torn solar
#

dunno how to do that ngl

hushed galleon
#

[0] to get the first element, [1] to get the second, etc.

torn solar
#

yeah but that grabs a tuple

#

i need the value

willow sluice
#

oh god

#
    return [
        app_commands.Choice(name=account, value=account[0])
        for account in accounts if current.lower() in account.lower()
    ]

Thats all

hushed galleon
#

!e its a bit more clear if you tweak the variable names: py rows = [('Chase',), ('Fluffy Personal',), ('Town of Greenville',)] names = [row[0] for row in rows] print(names)

unkempt canyonBOT
torn solar
#

correct me if im wrong but its a list of tuples right so list[0] would return the first tuple

willow sluice
#

You really need to learn basics of python

torn solar
hushed galleon
willow sluice
# torn solar why are u dick riding

I will be happy to help people who have a problem but you dont even know the basics of python at all and want us to write all the code for you

#

"how to get element of tuple by index?"

torn solar
#

ik how to get a value by index i was confused cus it was tuples inside of a list

torn solar
hushed galleon
#

ya, thats fine

torn solar
#

k ill test it out

hushed galleon
#

oh wait, you have an extra s there

torn solar
#

where

turbid condor
#

accounts[0] here

torn solar
#
    cursor.execute("SELECT account_name FROM accounts")
    accounts = cursor.fetchall()
    names = [account[0] for account in accounts]
    return names```
#

epic now to see if it updates when a new account is created

turbid condor
hushed galleon
#

naming a variable in singular form vs abbreviating it... at least my type checker can complain when i typo it

torn solar
#

will it take long

#

or immediate

turbid condor
hushed galleon
#

discord caches your autocompletion results iirc, though im not sure when it resets

torn solar
#

it works ty guys, also how many options are there allowed to be

hushed galleon
#

well, typing something would get a new result, but thats a bit awkward for the user

turbid condor
#

didn't they change that in recent updates

torn solar
#

cus im worried if theres too many accounts it might break

turbid condor
#

that's the limit

torn solar
#

is it scrollable or just the first 25

turbid condor
#

just first 25 matching results

torn solar
#

oh ok

#

thank you guys so much u really been helpful

turbid condor
#

now my brain ain't braining

torn solar
#

felt the same way

unkempt canyonBOT
#
Discord Bot Hosting

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

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

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

torn solar
#

wheres the link for discord

mild token
#

bot can edit role higher than its hierarchy ?

turbid condor
turbid condor
#

that would destroy the point having roles

hushed galleon
torn solar
turbid condor
torn solar
turbid condor
chilly cloud
#

yo, I got a slash command that requests stuff from an api everytime someone uses it, is it better practice to request from the api every few minutes and write it to a text file, get the data from the text file instead?

turbid condor
#

and how sharp they are

torn solar
#

yeah i tried making a bot for the stock market and stuff but the free apis had rate limits

#

it was sad

chilly cloud
#

whats the benefit of requesting each interaction, compared to a text file

chilly cloud
#

I feel like text file might help my code run faster

turbid condor
torn solar
#

i mean you can test it but i dont think it will make a difference

willow sluice
turbid condor
#

like in real time

torn solar
chilly cloud
chilly cloud
turbid condor
#

like stock market

torn solar
willow sluice
#

you can request for example every 5 minutes using discord.ext.tasks

turbid condor
torn solar
#

yeah if it was for the stock market you wouldnt need to use a db since all that data is changed multiple times a second

turbid condor
#

and we don't know what type of data they are fetching

chilly cloud
torn solar
chilly cloud
#

doesnt have to be pinpoint accurate

turbid condor
#

then storing is good

torn solar
#

ok then a txt file is fine

chilly cloud
#

alright bet

turbid condor
#

if it's changing by seconds then no need for storing

turbid condor
chilly cloud
#

actually, once every 1 to 2 hours should be good to

vocal shoal
#

Hey mates, we are a team building an AI learning platform:
https://cone.ai
Need insights and reviews for it. Can you please check and provide me with your feedback or suggest something innovative you want in any learning platform...

turbid condor
#

that's faster

torn solar
chilly cloud
#

its like a rap thing for a game, only updates every hour anyways

chilly cloud
turbid condor
#

the txt will take longer time as more data gets added

chilly cloud
#

true

#

hm

torn solar
#

its lightweight and easy

turbid condor
#

and txt is more likely to get corrupted

#

then a database

chilly cloud
#

how would I use the database to do autocompletes

torn solar
#

lol we were just going over this

chilly cloud
turbid condor
#

for god sake use aiosqlite

#

or some similar lib

chilly cloud
torn solar
# chilly cloud how would I use the database to do autocompletes
def get_accounts():
    cursor.execute("SELECT account_name FROM accounts")
    accounts = cursor.fetchall()
    names = [account[0] for account in accounts]
    return names

async def transfer_autocomplete(
    interaction: discord.Interaction,
    current: str,
) -> List[app_commands.Choice[str]]:
    accounts = get_accounts()
    return [
        app_commands.Choice(name=account, value=account)
        for account in accounts if current.lower() in account.lower()
    ]

@bot.tree.command(name="transfer", description="Transfer funds to another account.")
@app_commands.autocomplete(account=transfer_autocomplete)
async def transfer(interaction: discord.Interaction, account: str):
    print('hi')``` heres a example of my command autcompleting with values from my db
turbid condor
#

actually u are the first one I have seen doing that

chilly cloud
hushed galleon
#

does this data have to persist between restarts? its extra simple if you can store it in memory instead

chilly cloud
#

took me like a day to understand the syntax because I didnt read the docs LOL

#

way easier than I thought

torn solar
#

idk i havent used it

torn solar
#

yeah ill switch to aioqlite later

#

just tryna make my bot functional rn

chilly cloud
#

instead of cursor, you need to do something like

async with db.execute("SELECT * FROM JOE") as cur:
data = await cur.fetchall()

#

I can send some examples I wrote

chilly cloud
#

might be shit though

chilly cloud
#

just set a global variable of your data base when your bot starts up

#

then you dont need to connect to it every command

torn solar
# chilly cloud ye

yeah if u got examples send them to me lol im gonna switch once my bot is working fully

mild token
#

editing normal message can ping?

chilly cloud
#

!paste

turbid condor
chilly cloud
#

code is kinda ass but it works

torn solar
#

it will light up the gold color tho

drowsy thunder
#

!paste

unkempt canyonBOT
#
Pasting large amounts of code

If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/

After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.

chilly cloud
#

wassup other ryan

torn solar
#

is it for personal use or a public bot

chilly cloud
chilly cloud
#

I dont have anywhere to host it yet

chilly cloud
turbid condor
#

it also depends on the db you are using

chilly cloud
#

should I make another python file in the same project folder or start a new one

chilly cloud
torn solar
#

idk how good it is for commercial use but it works good for personal use

chilly cloud
turbid condor
torn solar
chilly cloud
torn solar
#

on the most basic option i think

chilly cloud
#

saw some people reccomending AWS

#

idk if it works for discord bots

torn solar
#

its pretty cheap

chilly cloud
#

ooh not bad

turbid condor
torn solar
#

still hosted my bot well with no issues

turbid condor
#

petradoctyle is the panel

torn solar
#

ik but idk the differences

turbid condor
#

and vps is a whole server

#

and those specs are not good for a public bot especially the RAM imo

drowsy thunder
#

https://paste.pythondiscord.com/VRNQ This code should delete the old webhook if there is one and make a new webhook on the specified channel but it isn't .
The first time when there is no data it makes a new webhook the second time it shows NoneType error in embed and deletes the webhook and the third time it makes the new webhook
I want to merge the second and third command without any errors.
Can y'all help?

torn solar
#

they have a scalable tier and there are more features

drowsy thunder
#

I'm sick of asking ai to help me with this code ๐Ÿ˜ญ

torn solar
#

their scalable tier has pretty good specs

torn solar
#

idk anything about webhooks or how they work sorry

drowsy thunder
#

@chilly cloud Ryan help ๐Ÿ’€

chilly cloud
#

use aiosqlite for discord bots

hushed galleon
chilly cloud
#

will run much faster

drowsy thunder
chilly cloud
torn solar
chilly cloud
#

your code stops while editing or reading data

drowsy thunder
#

So what to do

chilly cloud
#

nvm lemme see the problem

drowsy thunder
#

I guess I will ask ai to edit it for aiosqlite

chilly cloud
#

do you get an error

chilly cloud
hushed galleon
#

bare sqlite3 can work in an async discord bot since most queries can complete in microseconds, the main risk is deadlocking if you have two connections operating at the same time

drowsy thunder
chilly cloud
#

just get good

#

we cant help you learn stuff if you use ai

drowsy thunder
#

I learn alot from it aswell

turbid condor
#

rather than learn you are getting fed

wild maple
#

Is there anyway i can get the repository of a specific bot in discord?

chilly cloud
wild maple
#

Mike i want to make a bot similar to the "UB3R-BOT"

drowsy thunder
turbid condor
drowsy thunder
#

@turbid condor btw isn't RejectModders the owner of UniBot?

drowsy thunder
turbid condor
#

yes

drowsy thunder
#

Oh ok

turbid condor
#

that's a team project instead of solo so there are others too

drowsy thunder
turbid condor
#

you can ask in forum help there might be someone who is interested

torn solar
#
@bot.event
async def on_member_leave(member):
    cursor.execute("DELETE FROM users WHERE user_id = ?", (member.id))
    conn.commit()``` why is this not working is it cus the user left so it cant grab the id?
#

i didnt even notice till now its not deleting them from my table

golden portal
#

on_member_leave isn't a thing, it should be on_member_remove

torn solar
#

lollll

#

ty im stupid my vscode has ai tabcomplete and it completed to that and i didnt even think about

golden portal
#

huh, good thing AI isn't good enough to replace us

torn solar
#

like if i make an add command and start a remove command it can automatically make the remove command for me

#

its good in cases like that

golden portal
#

imo, current AI is pretty mediocre at programming, a lot of the time i'm using it on something advance and it spew terrible code. Maybe in the future it would be good to consider

torn solar
#

this is it

golden portal
#

i see, i've seen tabnine before

#

eats lots of ram tho

torn solar
#

fr?

golden portal
#

iirc it was like 1 gb extra

turbid condor
#

use codium or copilot better than this imo

torn solar
#

idk its just useful in some cases like i made a /admin-add-money and it managed to create a /admin-remove-money on its own

turbid condor
#

well I only use it for adding comments and docs

mild token
#

how i can create hollow circle like we do for filled circle using discord formatting?

golden portal
#

if you're comfortable with it go ahead, but do note it does write wrong code sometimes

mild token
#
  • this i know i dont know hollow one
torn solar
#
  • hi
#
  • hi
    -- hi
golden portal
#
  • a
    • b
mild token
#

aight

golden portal
#

its a child

torn solar
#

i did it wrong

#

dont do what i did

#
  • hi
  • hi
#

its a space before the second one so ```- hi

  • hi```
#

@mild token

sick pier
#

Discord formatting, as in a subclass of Markdown formatting, cause that is what Discord uses.

mild token
torn solar
#

huh

#

hm

mild token
#

is there a way to do that?

torn solar
#
 - test2```
mild token
#

yeh how u did that

#

tnx

#
Traceback (most recent call last):
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\commands\bot.py", line 1216, in get_prefix
    ret = list(ret)  # type: ignore
          ^^^^^^^^^
TypeError: 'NoneType' object is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\client.py", line 449, in _run_event
    await coro(*args, **kwargs)
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\commands\bot.py", line 1411, in on_message
    await self.process_commands(message)
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\commands\bot.py", line 1406, in process_commands
    ctx = await self.get_context(message)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\commands\bot.py", line 1305, in get_context
    prefix = await self.get_prefix(origin)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\commands\bot.py", line 1223, in get_prefix
    raise TypeError(
TypeError: command_prefix must be plain string, iterable of strings, or callable returning either of these, not NoneType

i am using slash command so did command_prefix=None is there a way to make the command prefix none?

quick gust
#

what are u defining your bot as

slate swan
torn solar
#
Traceback (most recent call last):
  File "C:\Users\teddy\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\app_commands\commands.py", line 842, in _do_call
    return await self._callback(interaction, **params)  # type: ignore
  File "c:\Users\teddy\OneDrive\Desktop\Chase Bank\Chase Bot\main.py", line 623, in dashboard
    cursor.execute("SELECT user_account FROM users WHERE user_id = ?", (interaction.user.id))
ValueError: parameters are of unsupported type``` not sure what happened this was working before
eager pike
#
@bot.hybrid_command(name="sync", with_app_command=true,description="Synchronize the command tree globally")
@app_commands.describe(ctx = 'Synchronize the command tree globally')
async def sync_commands(self, ctx: commands.Context):
    await self.tree.sync()
    await ctx.send("Commands have been synchronized globally.")

why does this throw an error

eager pike
#
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\*\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\commands\bot.py", line 290, in decorator
    result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
torn solar
#

is that the full error?

#

also never heard of a hybrid command

mild token
mild token
unkempt canyonBOT
#

@discord.ext.commands.hybrid_command(name=..., *, with_app_command=True, **attrs)```
A decorator that transforms a function into a [`HybridCommand`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HybridCommand).

A hybrid command is one that functions both as a regular [`Command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command) and one that is also a [`app_commands.Command`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.Command).

The callback being attached to the command must be representable as an application command callback. Converters are silently converted into a [`Transformer`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.app_commands.Transformer) with a [`discord.AppCommandOptionType.string`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.AppCommandOptionType.string) type.

Checks and error handlers are dispatched and called as-if they were commands similar to [`Command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command). This means that they take [`Context`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context) as a parameter rather than [`discord.Interaction`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.Interaction).

All checks added using the [`check()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.check) & co. decorators are added into the function. There is no way to supply your own checks through this decorator.

New in version 2.0.
torn solar
#

i assumed thats what it does but why

#

๐Ÿ˜‚ why would anyone want that

torn solar
mild token
eager pike
# torn solar is that the full error?
  File "d:\Stuff\Py\discord\renewed bot.py", line 45, in <module>
    @bot.hybrid_command(name="sync", with_app_command=true,description="Synchronize the command tree globally")
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\*\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\commands\bot.py", line 290, in decorator
    result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\*\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\commands\hybrid.py", line 893, in decorator
    return HybridCommand(func, name=name, with_app_command=with_app_command, **attrs)  # type: ignore  # ???
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\*\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\commands\hybrid.py", line 509, in __init__
    HybridAppCommand(self) if self.with_app_command else None
    ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\*\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\commands\hybrid.py", line 306, in __init__
    super().__init__(
  File "C:\Users\*\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\app_commands\commands.py", line 666, in __init__
    self._params: Dict[str, CommandParameter] = _extract_parameters_from_callback(callback, callback.__globals__)
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#

there's more but idk if you'll need it

#

oh wow normal app_command does not work either.

upbeat otter
#

and if you don't have any text commands there's no harm in setting the prefix

timber dragon
#

command_prefix can be set to an empty iterable like ()

#

But it won't stop listening no

timber dragon
pseudo geode
#

Anyone know?

#

My bot ainโ€™t replying at ALL

slate swan
#

Hello everyone

#

Do i have the right to ask someone if I can pay him to help me setup and continue the code of a discord bot pls ? I will also pay him every month to maintain and check if everything is okey . If anyone is interested pls let me know and have a good day everyone โค๏ธ

unkempt canyonBOT
#

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

slate swan
#

Ok sorry

mild token
#

how i can get the last message of a channel? i want to delete the last message of a channel

#

and which event is that which tells if someone edited a message or deleted it?

mild token
#

If i copy command to my guild with bot command and if the same command is present in the guild will it's permission will get overwritten

By permission i meant the channel locking feature

fast osprey
#

What exactly do you mean by "copy command to my guild"?

mild token
midnight herald
#

Im gonna take the chance to ask if im not interrupting anyone:
If i where to make it so the bot can take the values of a personโ€™s command (lets say for example, a person writes down โ€œIntelligence:14โ€ the bot makes a temporary json and takes that intelligence 14 as a variable), what system (as in, discord.py?) and commands should i use if its possible? Im not aiming to save things in a database, but instead make it so users of the bot can temporarily assign values and after a while or using a command said values are deleted/rest.

mild token
#

is it possible to trigger a different command from a different command?

slate swan
#

Yes

fast osprey
#

You should not be calling commands yourself

#

if two things need to share logic, that should be abstracted into a simplified helper function

fast osprey
midnight herald
fast osprey
#

Then you can just keep them in memory no?

midnight herald
# fast osprey Then you can just keep them in memory no?

I mean, i dont really know what exactly you mean by memory, but if it means that the bot can run using said temporary values using the memory as long as it is using the variables specified by the user, then thats all i need. Sorry if im being annoying, im still getting the hang of how python mostly works in general regarding discord

fast osprey
#

No you're totally fine. By "in memory" I just mean variables/data structures in python yeah

midnight herald
# fast osprey No you're totally fine. By "in memory" I just mean variables/data structures in ...

Ah perfect! Then yeah. Basically i dont wanna use a database since im using kanka (a thing to make ttrpgs and stuff like that), so saving player data is not really needed, just all that is needed is to specify certain variables and thats it. After the bot is not being used, it does not save said data.
Hence why i asked if its possible in the first place to make it so the bot can specify the values the user specified in the command. Im not asking as a โ€œhow do i do itโ€ but moreso โ€œis it possibleโ€, cuz if it is, then basically i can def make the bot

fast osprey
#

Yeah bots don't have any less capabilities than any other python program. You could put whatever values you wanted in a data structure and then access/modify them as needed as long as that program is running

midnight herald
fast osprey
#

gl prettythumbsup

#

A common pattern is to set data structures (like dictionaries and such) as attributes on your bot object. That singular bot object lives for as long as the bot is operational and is generally accessible wherever you'd need it

midnight herald
fast osprey
#

Yup, it would just be up to you to design a data structure that would accomplish what you needed. Spitballing, a dictionary of {user : <whatever>} is pretty common

midnight herald
fast osprey
#

You'd probably want something more involved, such as a custom class with attributes you declare

midnight herald
fast osprey
#

General OOP principles. A class describes a Thing, including all the properties and methods of it. Such as a Character, in your case perhaps

midnight herald
#

Aaaaaa i see! So class basically means group of properties?

fast osprey
#

If you haven't worked with classes or done general OOP before, it would behoove you to do some focused learning. The official python docs have a good intro and there's plenty of material. This is a core fundamental principle of python, and advanced things like discord bots are built on top of it

midnight herald
#

Perfect, thx! Ill stop the questions for now cuz im a nerd and ill not stop if i continue๐Ÿ˜… ill check the docs now!

fast osprey
mild token
#
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "D:\AFW bot\afw_bot\main.py", line 79, in main
    bot.run(Core.BOT_TOKEN)
  File "D:\AFW bot\afw_bot\main.py", line 68, in run
    self.load_all_extensions()
  File "D:\AFW bot\afw_bot\main.py", line 65, in load_all_extensions
    self.load_cog(f"afw_bot.ext.{module_name}")
  File "D:\AFW bot\afw_bot\main.py", line 54, in load_cog
    asyncio.run(self.add_cog(obj(self)))
                             ^^^^^^^^^
  File "D:\AFW bot\afw_bot\ext\auto_sync_update.py", line 20, in __init__
    self.my_task.start()
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\tasks\__init__.py", line 401, in start  
    self._task = asyncio.create_task(self._loop(*args, **kwargs), name=self._name)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\HP\AppData\Local\Programs\Python\Python312\Lib\asyncio\tasks.py", line 417, in create_task
    loop = events.get_running_loop()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: no running event loop
sys:1: RuntimeWarning: coroutine 'Loop._loop' was never awaited
Object allocated at (most recent call last):
  File "C:\Users\HP\AppData\Local\pypoetry\Cache\virtualenvs\afw-bot-0qM92z9o-py3.12\Lib\site-packages\discord\ext\tasks\__init__.py", lineno 401

class AutoSync(commands.Cog):
    def __init__(self, bot: MyBot) -> None:
        self.bot = bot
        self.file_path = os.path.join(
             'ext', 'utils', 'sync', 'data.json')

        if os.path.isfile(self.file_path):
            self.load_sync_data()
        else:
            self.initialize_sync_file()
        self.my_task.start()

dont know why its giving error

fast osprey
#

When are you calling asyncio.run?

mild token
fast osprey
#

Show the code. You generally should only have one asyncio.run ever in your entire code

mild token
#
class MyBot(commands.Bot):

    def __init__(self, *, intents: discord.Intents):
        super().__init__(command_prefix='supersecretjutsu', help_command=None,
                         intents=intents, tree_cls=CommandErrorHandler)

    async def setup_hook(self):

        self.add_view(SyncEmbed(self))
        self.add_view(StaffApplication())
        self.add_view(ClanApplication())
        self.add_view(ContactUs())
        self.add_view(PartnershipApplication())
        self.add_view(ClanInfoList(self))
        self.add_view(RulesEmbed())

    async def on_ready(self):

        coc_client = coc.Client()
        await coc_client.login(DevCreds.DEV_SITE_EMAIL, DevCreds.DEV_SITE_PASSWORD)
        self.coc_client: coc.Client = coc_client
        log_message('DEBUG', f'Logged in as {self.user}(ID: {self.user.id})')
        print('------')

    def load_cog(self, file_path):
        module = importlib.import_module(file_path)
        for name, obj in inspect.getmembers(module):
            if inspect.isclass(obj) and issubclass(obj, (commands.Cog, commands.GroupCog)):
                asyncio.run(self.add_cog(obj(self)))
                log_message("INFO", f'Loaded {name} Cog')

    def load_all_extensions(self):

        directory = Path('afw_bot/ext')
        for item in directory.rglob('*.py'):
            module_name = item.relative_to(directory).with_suffix(
                '').as_posix().replace('/', '.')
            if module_name.split('.')[-1].startswith('_'):
                continue
            self.load_cog(f"afw_bot.ext.{module_name}")

    def run(self, *args, **kwargs):
        self.load_all_extensions()
        try:
            super().run(*args, **kwargs)
        except Exception as e:
            traceback.print_exception(e)
            log_message('CRITICAL', f"Login Failed\nReason: {e}")


def main():
    intents = discord.Intents.all()
    bot = MyBot(intents=intents)
    bot.run(Core.BOT_TOKEN)


if __name__ == "__main__":
    main()
mild token
#

i am using poetry

slate swan
#

so question whatโ€™s different between client.event and commands.command

mild token
#

if i make main async then it wont start

fast osprey
#

You don't need asyncio.run anywhere

mild token
fast osprey
#

nope

#

make that async and just await

mild token
#

load cog is called inside load_extensions

#

and load exension inside run

#

and run is called inside main

#

if i make main async then i cant use poetry start script

#
[tool.poetry.scripts]
start = "afw_bot.main:main"

this is how i am starting

fast osprey
#

you don't need main to be async

mild token
fast osprey
#

Do you generally understand how asyncio works?

mild token
fast osprey
#

So the function needs to be async if there are async calls in it

mild token
#

yes but if i make it all async then bot.run will also ask for await

fast osprey
#

No it won't

#

bot.run isn't a coroutine

mild token
# fast osprey No it won't
    async def load_all_extensions(self):

        directory = Path('afw_bot/ext')
        for item in directory.rglob('*.py'):
            module_name = item.relative_to(directory).with_suffix(
                '').as_posix().replace('/', '.')
            if module_name.split('.')[-1].startswith('_'):
                continue
            await self.load_cog(f"afw_bot.ext.{module_name}")

    def run(self, *args, **kwargs):
        self.load_all_extensions()
        try:
            super().run(*args, **kwargs)
        except Exception as e:
            traceback.print_exception(e)
            log_message('CRITICAL', f"Login Failed\nReason: {e}")
#

see if i make load_all_extension async then only i can await load self.load_cog

#

and if i make load_all_extension async then i have to make run async because self.load_all_extension is getting called there which is async

fast osprey
#

If a function has an async call in it, make it async

mild token
#

i think i should load the extension on on_ready

fast osprey
#

no

mild token
#

then?

fast osprey
#

read what on_ready does

mild token
fast osprey
#

Wherever you want shrug

mild token
fast osprey
#

It's unclear the ordering of what you want to happen here. Also why are you passing a string into load_cog?

#

I think you're probably overloading cogs and extensions

fast osprey
#

These are two different terms which mean very different things

mild token
#

ext is my folder name under which cogs files are there

fast osprey
#

"cog file" isn't a thing

#

there are extensions, which are files that have a setup method which you load with load_extension

#

those extensions can have cogs in them, but they don't have to, and that's entirely up to the extension

mild token
#

just curious if i start my task at on_ready what can be implications of doing that?

fast osprey
#

!d discord.on_ready

unkempt canyonBOT
#

discord.on_ready()```
Called when the client is done preparing the data received from Discord. Usually after login is successful and the [`Client.guilds`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Client.guilds) and co. are filled up.

Warning

This function is not guaranteed to be the first event called. Likewise, this function is **not** guaranteed to only be called once. This library implements reconnection logic and thus will end up calling this event whenever a RESUME request fails.
fast osprey
#

Read the warning very carefully and it should be clear you do not want to use this

mild token
#

oh

#

then it can be called multiple times

#

is there any function which is called before guild is ready for sure

#

and only once it is called?

fast osprey
#

What do you mean by a guild being "ready"/

mild token
fast osprey
#

There is setup_hook, which is an async method that is called by the library exactly once between login and connect

finite salmon
#

You can load the cogs in your setup_hook

mild token
winged grotto
#

f

hearty matrix
#

I decided to try to make a bot available everywhere (user installation), I did it as needed using Tree.command(). As a result, on servers where there is a bot, everything works, but in messages and other servers it no longer works. How to fix?

Code:

import discord
from discord.ext import commands
from discord import app_commands
from tokenpy import TOKEN

bot = commands.Bot(command_prefix=None, intents=None)
group = app_commands.Group(name="action", description="actions")

@group.command(name="hug", description="Hug user")
@app_commands.user_install()
async def _hug(interaction: discord.Interaction, member: discord.Member):
    await interaction.response.send_message(f'{interaction.user.mention} hugged {member.mention} <3')

@group.command(name="kiss", description="Kiss")
async def _kiss(interaction: discord.Interaction, member: discord.Member):
    await interaction.response.send_message(f'{interaction.user.mention} Kissed {member.mention} โค')

@group.command(name="hit", description="Hit")
@app_commands.user_install()
async def _hit(interaction: discord.Interaction, member: discord.Member):
    await interaction.response.send_message(f'{interaction.user.mention} hit {member.mention} โค')

@group.command(name="send", description="Send messages")
@app_commands.user_install()
async def _send(interaction: discord.Interaction, mesg: str):
    await interaction.response.send_message(f'{mesg}')

@bot.event
async def on_ready():
    await bot.tree.sync()

bot.tree.add_command(group)
bot.run(TOKEN)

discord.py latest version, user install included

boreal sigil
#
# DROPDOWN MENU
class Select(discord.ui.Select):
    def __init__(self):
        options=[
            discord.SelectOption(label="Server Rules",emoji="โ›”",description="Read our server rules."),
            discord.SelectOption(label="Reaction Roles",emoji="๐Ÿ’ป",description="Get some fancy roles."),
            discord.SelectOption(label="Custom Name Color",emoji="๐ŸŽญ",description="Make your name any color."),
            discord.SelectOption(label="Help and Support",emoji="๐ŸŽซ",description="Reach out to staff for help etc."),
            discord.SelectOption(label="General Info",emoji="๐Ÿ“œ",description="Read some extra server info."),
            discord.SelectOption(label="Invite Rewards",emoji="๐Ÿ†",description="Get some rewards for inviting new members! ***Ends soon***"),
            discord.SelectOption(label="Boost Rewards",emoji="๐Ÿš€",description="Get some rewards for boosting our server.")
            ]
        super().__init__(placeholder="Select an option",max_values=1,min_values=1,options=options)
    async def callback(self, interaction: discord.Interaction):
        if self.values[0] == "Server Rules":
            await interaction.response.edit_message(content="This is the first option from the entire list!")
        elif self.values[0] == "Option 2":
            await interaction.response.send_message("This is the second option from the list entire wooo!",ephemeral=False)
        elif self.values[0] == "Option 3":
            await interaction.response.send_message("Third One!",ephemeral=True)

class SelectView(discord.ui.View):
    def __init__(self, *, timeout = 180):
        super().__init__(timeout=timeout)
        self.add_item(Select())

@bot.command()
async def menu(ctx):
    await ctx.send("Awh... you found the menus. ๐Ÿฅบ",view=SelectView())

I basically need each of the options to take you to a certain channel. The stuff i have in there atm is mostly just placeholder code.

boreal sigil
#

@fast osprey

fast osprey
#

What do you mean by "take you to a certain channel"?

boreal sigil
#

Basically

#

if they press the rules button it takes them to the rules channel

fast osprey
#

interacting with components can't force a user's client to go somewhere else if that's what you mean

boreal sigil
#

or basically have a channel url and when they press it it takes them to that url then

fast osprey
#

You could send a message with a channel mention

boreal sigil
#

i swear ive seen menus which take you to channels-

fast osprey
#

But at that point why make them choose from a drop down when you could just have a list of channels

boreal sigil
#

tidiness

fast osprey
#

At the expense of having a user click two buttons instead of just one? Your call

boreal sigil
#

Iโ€™m tryna make this not take up my whole screen

#

and each of those buttons rn takes you to a channel

#

and im tryna change it for a dropdown menu

fast osprey
#

Then you'd have to do what I suggested

boreal sigil
#

alright

boreal sigil
fast osprey
#

Set the timeout to None when creating the view

willow sluice
#

Im talking about connect your application to user not a guild

#

do you know

dense falcon
#

Any reason why this returns an error? the result array contains a user ID in the first of each Tuple contained, and the error occurs on the third line when fetching the user. I've tried using get_user however that seems to only return None even when I have the permission set up for Members intent.
The error in question:

Traceback (most recent call last):
  File "/home/spacepogam/.local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 235, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/spacepogam/Documents/GitHub/AntennaTower/profiles.py", line 478, in ltest
    currentuser = await bot.fetch_user(result[i][0])
  File "/home/spacepogam/.local/lib/python3.10/site-packages/discord/client.py", line 2531, in fetch_user
    data = await self.http.get_user(user_id)
  File "/home/spacepogam/.local/lib/python3.10/site-packages/discord/http.py", line 605, in request
    if not self._global_over.is_set():
AttributeError: '_MissingSentinel' object has no attribute 'is_set'

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

Traceback (most recent call last):
  File "/home/spacepogam/.local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
    await ctx.command.invoke(ctx)
  File "/home/spacepogam/.local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1029, in invoke
    await injected(*ctx.args, **ctx.kwargs)  # type: ignore
  File "/home/spacepogam/.local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 244, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: '_MissingSentinel' object has no attribute 'is_set'
fast osprey
#

Where is this code being run?

dense falcon
#

Inside a cog using a hybrid command (is this what you meant)

midnight oracle
dense falcon
willow sluice
#

Send us a part of code that raises an error

dense falcon
#

i did, it's the screenshot below the error

willow sluice
#

damn :/ show more if you want to get help
It is impossible to understand the problem from two lines of code..

#

show the function that contains the above code and how you run the bot

dense falcon
#

alrighty but it's long and very messy

willow sluice
#

It sounds like you are currently deleting extra code so that someone does not steal it
Nobody needs it lol

fast osprey
#

Yeah more code is going to be helpful

pseudo geode
#

#help

dense falcon
willow sluice
#

this code inside a ltest command, right?

dense falcon
#

yep

fast osprey
#

Please include all of the bot startup, minus your token

#

also you should very much not be doing anything you're doing in on_ready given how it behaves

#

!d discord.on_ready

unkempt canyonBOT
#

discord.on_ready()```
Called when the client is done preparing the data received from Discord. Usually after login is successful and the [`Client.guilds`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Client.guilds) and co. are filled up.

Warning

This function is not guaranteed to be the first event called. Likewise, this function is **not** guaranteed to only be called once. This library implements reconnection logic and thus will end up calling this event whenever a RESUME request fails.
dense falcon
#

Oh, I didnt think that it would cause problems when resuming as well

pseudo geode
fast osprey
#

Generally all of that would be in the bot's setup_hook, minus the sync which you should not be doing automatically at all

dense falcon
#

Yeah I gathered it with the sync, it's just for testing purposes since I'm not launching the bot fully yet and need to make sure the commands are up-to-date. Haven't been rate-limited yet though afaik

fast osprey
#

And when you do get rate limited and you can't develop any more you'll probably wish you hadn't shrug

dense falcon
#

sounds strict but i get it

willow sluice
#

_global_over is Missing by default so this is _MissingSentinel object
This is setting inside static_login method
static_login is called by the client's login method

so as i say before you got this error because bot are trying to get the user before the bot is started
idk how this is possible because if you able to call the command then the bot is 100% running

#

i need more code to determine what is wrong. you can show the demonstration of your code in discord btw

dense falcon
timber dragon
#

Getting that errors means you're doing an api request before the bot is even logged in

timber dragon
#

Instead of using the one that passed from setup to the class and added as an attribute called bot which would make it self.bot.fetch_user(...)

dense falcon
#

I have to define bot in each Cog, otherwise the code wont run. It works fine normally

timber dragon
#

Oh god don't do that

timber dragon
#

You should only have one bot instance throughout the whole project

dense falcon
#

I think im about to sound really thick

#

How could I pass bot to the cog ๐Ÿ˜ญ

fast osprey
#

That is the main point of extensions. To make the bot object available to external files

#

cogs really have nothing to do with that

timber dragon
dense falcon
#

oh crap

#

wait so what do i need to do differently then

#

im so lost in my own code ๐Ÿ˜ญ

timber dragon
#

Use the same instance as the one you pass to your class

#

Or ctx.bot / interaction.client works too

dense falcon
#

alrighty

dense falcon
willow sluice
dense falcon
#

I saw, and I have fixed my mistakes

#

I was wondering why it wasnt working for 10 million years before I noticed it was fetch_member and not fetch_user, which I switched out when trying anything and everything

#

finally i can sleep

pseudo geode
vapid parcel
#

I remember that Danny made a bot that does translations if I remember correctly.. does anyone have the link to that repo?

#

actually I found it I think.

shrewd apex
#

the i8n thing?

wild gate
#

Weird question, but anyways I want to create a discord bot that takes commands from users then takes those commands sends it to a python terminal thats waiting for those commands in a VM then runs those commands what would that look like this is the chatgpt response:

#

To achieve this, you can use a combination of a Discord bot to receive commands from users and a Python script running on your VM to execute those commands. Here's a high-level overview of how you can set this up:

Set Up a Discord Bot: Create a Discord bot that listens for commands in your server.
Receive and Parse Commands: Have the bot parse the commands and send them to your Python script running on the VM.
Execute Commands on the VM: The Python script on the VM executes the received commands.
Here's an example setup using discord.py for the Discord bot and a simple Python script to execute commands.

Step 1: Set Up a Discord Bot
Create a Discord Bot:

Go to the Discord Developer Portal.
Create a new application and add a bot to it.
Copy the bot token.
Install discord.py:

#

sh
Copy code
pip install discord.py
Create the Discord Bot Script:

python
Copy code
import discord
import requests

TOKEN = 'YOUR_DISCORD_BOT_TOKEN'
VM_URL = 'http://YOUR_VM_IP:5000/execute'

intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

@client.event
async def on_ready():
print(f'We have logged in as {client.user}')

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

if message.content.startswith('!execute'):
    command = message.content[len('!execute '):]
    response = requests.post(VM_URL, json={'command': command})

    if response.status_code == 200:
        await message.channel.send(f'Command executed: {command}')
    else:
        await message.channel.send(f'Failed to execute command: {command}')

client.run(TOKEN)
Step 2: Set Up the Python Script on the VM
Create a Simple Flask API to Receive Commands:

#

Install Flask:

sh
Copy code
pip install flask
Create the Flask API:

python
Copy code
from flask import Flask, request, jsonify
import subprocess

app = Flask(name)

@app.route('/execute', methods=['POST'])
def execute_command():
data = request.get_json()
command = data.get('command')

try:
    result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True)
    return jsonify({'result': result})
except subprocess.CalledProcessError as e:
    return jsonify({'error': str(e.output)}), 400

if name == 'main':
app.run(host='0.0.0.0', port=5000)
Run the Flask API:

sh
Copy code
python path_to_your_flask_script.py
Step 3: Testing
Start your Flask server on the VM.

Run your Discord bot.

In your Discord server, use the !execute command to send commands to the VM:

plaintext
Copy code
!execute echo Hello, World!
The bot should respond with the result of the command.

Security Considerations
Authentication: Add authentication to the Flask API to ensure only authorized requests are processed.
Command Sanitization: Sanitize commands to prevent injection attacks.
HTTPS: Use HTTPS for communication between the bot and the Flask server.
This setup provides a basic framework for executing commands on a VM based on user input from a Discord server. You can expand and customize it based on your specific requirements.

fast osprey
wild gate
#

yeah idk

#

no one is responding to that shit