#discord.py #discord.py-rewrite
#discord.py
Вопрос:
Итак, я работаю над небольшим проектом здесь, и в значительной степени я хочу иметь одну из этих функций «Пожалуйста, введите имя канала на этом сервере».
В общем, бот запрашивает название канала, и я ввожу, например, «#changelog», А затем он запрашивает, что он должен написать в этом канале и т. Д. И т. Д. Поэтому нужно получить идентификатор канала (я предполагаю), но я не хочу, чтобы пользователи вводили идентификатор, вместо этого только записывая #server-name . И затем всякий раз, когда я это делал, бот должен писать в этом канале.
Вот мой текущий код!
class Changelog(commands.Cog):
def __init__(self, client):
self.client = client
@commands.Cog.listener()
async def on_ready(self):
print('Changelog is loaded')
@commands.command()
async def clhook(self, ctx):
await ctx.send('Write text-channel: ')
text_channel = await self.client.wait_for("message", check=lambda message: message.author == ctx.author, timeout=300)
clhook = self.client.get_channel(text_channel)
def setup(client):
client.add_cog(Changelog(client))
Редактировать:
Идентификатор канала должен быть сохранен «навсегда», что означает, что мне не нужно переписывать название канала, куда должно идти сообщение!
Ответ №1:
Вы можете использовать discord.utils.get()
в этом примере:
text_channel = await self.client.wait_for("message", check=lambda message: message.author == ctx.author, timeout=300)
channel = discord.utils.get(ctx.guild.text_channels, name=text_channel)
await channel.send('Bla Bla')
Поэтому, когда вы вводите (prefix)clhook
только имя канала, например general, он будет отправлен Bla Bla
на канал с именем general .
Есть другой способ сделать это, и я думаю, что это проще, чем первый вариант, вот он:
@commands.command()
async def clhook(self, ctx, channel: discord.TextChannel):
await channel.send('Bla Bla')
Итак, в этой команде использование изменено. Вы можете использовать это с помощью этого: (prefix)clhook #general(mention the channel)
. Я предлагаю это решение, и я думаю, что оно более полезно.
Комментарии:
1. Хорошо, давайте посмотрим, понял ли я это. Первое, что дало мне некоторые ошибки
'NoneType' object has no attribute send
, это в шестеренке. Нужно лиself
где-то включать? Или что означает эта ошибка?2. Это означает, что канал не существует или, возможно, связан с self. Вы пробовали второе решение?
3. Ну, во втором решении есть. Я не тестировал — как мне получить канал, который вводит пользователь?
4. Во втором решении used просто введет
(prefix)clhook #channel-name
, а затем отправит сообщение на этот канал.5. Или ооо, поэтому каждый раз, когда мне нужно написать сообщение для этого конкретного канала, мне нужно запускать
!!clhook #text-channel
? Я хотел, чтобы это было больше похоже на то, что вы пишете это один раз, и оно всегда будет применяться к этому каналу. Так!!clhook #text-channel
будет команда «hook», и после этого все, что мне нужно написать!!changelog <text-goes-here>
, и оно всегда будет там записываться.
Ответ №2:
Вы можете использовать message.channel_mentions
. Это вернет list
список всех каналов, которые были упомянуты с использованием #channel-name
обозначения. Таким образом, вы можете просто использовать channel.id
для получения id
канала, который они упомянули.
Однако не забудьте проверить, действительно ли пользователь пометил канал (который вы также можете добавить в свой check
). Я поместил его в отдельную функцию, чтобы сделать его немного более читаемым для этого ответа, но вы можете поместить это в свой лямбда-код, если действительно хотите.
Кроме того, обязательно проверьте, является ли это a Text Channel
, а не a Voice Channel
или Category Channel
.
@commands.command()
async def clhook(self, ctx):
def check(self, message):
author_ok = message.author == ctx.author # Sent by the same author
mentioned_channel = len(message.channel_mentions) == 1 and isinstance(message.channel_mentions[0], discord.TextChannel)
return author_ok and mentioned_channel
await ctx.send("Write text-channel: ")
text_channel = await self.client.wait_for("message", check=check)
chlhook = text_channel.channel_mentions[0]
Я поставил два условия в mentioned_channel
строке, потому что, если первое не выполняется, второе может вызвать ошибку IndexError. В качестве альтернативы вы также можете использовать if-statement
, чтобы вернуться раньше в этом месте, чтобы решить ту же проблему.
Комментарии:
1. Аааа, я понимаю, но
chlhook
будет ли это там, где имя канала «сохранено»? Или как мне отправить «тестовое» сообщение на этот канал?2. Нет, он не сохраняет
name
, но вы извлекаете фактическийchannel
экземпляр из списка, поэтому вы можете простоclhook.send()
отправлять ему сообщения или использоватьclhook.id
для получения его идентификатора. Таким образом, вам не нужно использоватьutils.get()
для поиска объекта channel, поскольку он у вас уже есть. Возможно, вы захотите переименовать его, так как это может все испортить (у него то же имя, что и у вашей функции).