How to get a channel object using the client (in select callback) discord.py

Question:

I have an issue getting a channel object (using the client) within a select callback. I don’t want to fetch using a guild id because one user will be in a DM channel (this command will have to work for one user in a normal channel, and the other in a text channel).

    @discord.ui.button(label="Confirm", custom_id='confirm', style=discord.ButtonStyle.green)
    async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):

        initialize_trade(self.user.id, interaction.user.id, self.user_channel, interaction.channel.id, self.user_message, self.own_message)

        inventory = get_inventory(interaction.user.id)
        user1_inv, user2_inv = [], []

        formatted_inventory = []
        count_dict = {}
        for item in inventory:
            count_dict[item] = count_dict.get(item, 0) + 1
            formatted_inventory.append(f"{item} ({count_dict[item]})" if count_dict[item] > 1 else item)

        await interaction.response.edit_message(content='Trade confirmed!', view=TradeView(self.user, 2, formatted_inventory, user1_inv, user2_inv))
class TradeView(discord.ui.View):
    def __init__(self, other_user: discord.User, usertype, inventory, user1inv, user2inv):
        super().__init__(timeout=60)


        self.other_user = other_user
        self.inventory = inventory
        self.user1inv = user1inv
        self.user2inv = user2inv

        self.usertype = usertype

        self.select_callback.options = [discord.SelectOption(label=item) for item in inventory]

        self.select_callback.max_values = len(inventory)


    @discord.ui.select(placeholder="Select Items to Trade", min_values=1, options=[])
    async def select_callback(self, interaction: discord.Interaction, select):
        if self.usertype == 1:
            configure_user1_inv(interaction.user.id, self.other_user.id, select.values)
            channel_id, msg_id = get_user2_message(interaction.user.id, self.other_user.id)
        else:
            configure_user2_inv(interaction.user.id, self.other_user.id, select.values)
            channel_id, msg_id = get_user1_message(self.other_user.id, interaction.user.id)



        channel = self.bot.get_channel(channel_id)
        message = await channel.fetch_message(msg_id)

        await message.edit(content=f'EDITED MESSAGE! {select.values}')
        await interaction.response.edit_message(content=f"{select.values}")

Anything helps :)! Sorry if this is a little confusing/not clear.

Asked By: hyperrr

||

Answers:

You can simply pass the bot into another argument of the __init__ method:

class TradeView(discord.ui.View):
    def __init__(self, other_user: discord.User, usertype, inventory, user1inv, user2inv, bot):
        super().__init__(timeout=60)

        self.bot = bot

        self.other_user = other_user
        self.inventory = inventory
        self.user1inv = user1inv
        self.user2inv = user2inv

        self.usertype = usertype

        self.select_callback.options = [discord.SelectOption(label=item) for item in inventory]

        self.select_callback.max_values = len(inventory)

    # ...rest of the code

And simply pass the bot instance when creating the view:

    @discord.ui.button(label="Confirm", custom_id='confirm', style=discord.ButtonStyle.green)
    async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):

        initialize_trade(self.user.id, interaction.user.id, self.user_channel, interaction.channel.id, self.user_message, self.own_message)

        inventory = get_inventory(interaction.user.id)
        user1_inv, user2_inv = [], []

        formatted_inventory = []
        count_dict = {}
        for item in inventory:
            count_dict[item] = count_dict.get(item, 0) + 1
            formatted_inventory.append(f"{item} ({count_dict[item]})" if count_dict[item] > 1 else item)

        await interaction.response.edit_message(
            content='Trade confirmed!', 
            view=TradeView(
                self.user, 2, formatted_inventory, user1_inv, user2_inv, interaction.client  # important
            )
        )
Answered By: Łukasz Kwieciński
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.