Pycord中从列表调用bot.get_channel()返回None的问题
问题:bot.get_channel()返回None但频道ID打印正确
我通过斜杠命令让用户指定频道,把频道ID存入列表esendChannel。所有print语句(包括bot.get_channel()调用前的print(a_string))都能输出正确的ID,但bot.get_channel()始终返回None。问题出在EmbedConfirmButton类的按钮回调逻辑里,esendChannel变量由底部的embedsend斜杠命令赋值。
完整代码如下:
eEdit = ["blank"] esendChannel = ["blank"] eTitle = ["blank"] eDescription = ["blank"] channel = [] class EmbedSend(discord.ui.Modal): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.add_item(discord.ui.InputText(label="Title", value = eTitle[0])) self.add_item(discord.ui.InputText(label="Message Content", style=discord.InputTextStyle.long, value = eDescription[0])) async def callback(self, interaction: discord.Interaction): eTitle[0] = self.children[0].value eDescription[0] = self.children[1].value esend = discord.Embed(title=''.join(eTitle), description=''.join(eDescription)) eEdit[0] = [esend] print(eEdit) await interaction.response.send_message(embed = esend, view = EmbedConfirmButton(), ephemeral=True) class EmbedConfirmButton(discord.ui.View): def __init__(self): super().__init__(timeout=None) @discord.ui.button(label="Send", custom_id="button-embededit", style=discord.ButtonStyle.blurple) async def first_button_callback(self, button, interaction): finalembed = discord.Embed(title=eTitle, description=eDescription) finalembed.set_image(url="") s = [str(integer) for integer in esendChannel] a_string = "".join(s) print(a_string) await bot.get_channel(a_string).send(embed = finalembed) await interaction.response.send_message("test", ephemeral = True) @discord.ui.button(label="Edit", custom_id="button-embededit2", style=discord.ButtonStyle.blurple) async def second_button_callback(self, button, interaction): modal = EmbedSend(title=eTitle[0]) await interaction.response.send_modal(modal) await interaction.followup.send("test") @discord.ui.button(label="Cancel", custom_id="button-embedcancel", style=discord.ButtonStyle.blurple) async def third_button_callback(self, button, interaction): await interaction.response.send_message("Canceled Interaction", ephemeral = True) return @bot.slash_command() @option("channel") async def embedsend(ctx, channel:discord.TextChannel): modal = EmbedSend(title = "Embed Create") await ctx.send_modal(modal) await ctx.respond("Success", ephemeral = True) esendChannel[0] = str(channel.id) print(esendChannel)
问题原因
bot.get_channel()方法要求传入整数类型的频道ID,但你在代码里做了两个错误操作:
- 在
embedsend命令里把channel.id(原本是整数)转成字符串存入esendChannel - 在按钮回调里又把字符串拼接后传给
get_channel(),而该方法不接受字符串参数,因此返回None
修复方案
方案1:修正类型问题(快速修复)
- 修改
embedsend命令,直接存储整数ID:@bot.slash_command() @option("channel") async def embedsend(ctx, channel:discord.TextChannel): modal = EmbedSend(title = "Embed Create") await ctx.send_modal(modal) await ctx.respond("Success", ephemeral = True) esendChannel[0] = channel.id # 去掉str(),存整数 print(esendChannel) - 修改按钮回调,直接使用整数ID:
@discord.ui.button(label="Send", custom_id="button-embededit", style=discord.ButtonStyle.blurple) async def first_button_callback(self, button, interaction): finalembed = discord.Embed(title=''.join(eTitle), description=''.join(eDescription)) finalembed.set_image(url="") target_channel = bot.get_channel(esendChannel[0]) # 直接用整数ID if target_channel: await target_channel.send(embed = finalembed) await interaction.response.send_message("消息已发送", ephemeral = True) else: await interaction.response.send_message("无法找到目标频道", ephemeral = True)
方案2:避免全局变量(更健壮的写法)
全局列表存储状态容易引发并发冲突(比如多个用户同时使用命令时会覆盖数据),建议把频道ID通过参数传递给Modal和View:
- 修改
EmbedSend类,接收并存储目标频道ID:class EmbedSend(discord.ui.Modal): def __init__(self, *args, target_channel_id=None, **kwargs) -> None: super().__init__(*args, **kwargs) self.target_channel_id = target_channel_id self.add_item(discord.ui.InputText(label="Title", value = eTitle[0])) self.add_item(discord.ui.InputText(label="Message Content", style=discord.InputTextStyle.long, value = eDescription[0])) async def callback(self, interaction: discord.Interaction): eTitle[0] = self.children[0].value eDescription[0] = self.children[1].value esend = discord.Embed(title=''.join(eTitle), description=''.join(eDescription)) eEdit[0] = [esend] print(eEdit) # 把频道ID传递给View await interaction.response.send_message(embed = esend, view = EmbedConfirmButton(target_channel_id=self.target_channel_id), ephemeral=True) - 修改
EmbedConfirmButton类,接收目标频道ID:class EmbedConfirmButton(discord.ui.View): def __init__(self, target_channel_id=None): super().__init__(timeout=None) self.target_channel_id = target_channel_id @discord.ui.button(label="Send", custom_id="button-embededit", style=discord.ButtonStyle.blurple) async def first_button_callback(self, button, interaction): finalembed = discord.Embed(title=''.join(eTitle), description=''.join(eDescription)) finalembed.set_image(url="") target_channel = bot.get_channel(self.target_channel_id) if target_channel: await target_channel.send(embed = finalembed) await interaction.response.send_message("消息已发送", ephemeral = True) else: await interaction.response.send_message("无法找到目标频道", ephemeral = True) - 修改
embedsend命令,传递频道ID给Modal:@bot.slash_command() @option("channel") async def embedsend(ctx, channel:discord.TextChannel): modal = EmbedSend(title = "Embed Create", target_channel_id=channel.id) await ctx.send_modal(modal) await ctx.respond("Success", ephemeral = True)
内容的提问来源于stack exchange,提问作者Andrew Barnett
相关产品推荐
相关产品推荐

