【问题标题】:Can't make a discord bot send a message inside a python function无法让不和谐的机器人在 python 函数中发送消息
【发布时间】:2022-01-24 08:00:50
【问题描述】:

我想创建一个 Discord 机器人,当 Twitter 帐户关注新帐户时,它会在特定频道中发送消息。

我设法使用了 twitter API,但我无法制作它在不和谐上发送消息的部分,它只是一个要在函数中发送的字符串

我不断看到不和谐的机器人会对在频道中输入的命令做出反应,但我希望有一个机器人自己发送消息而不是等待命令。

我不太了解异步的东西 (https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py) 我自己也弄不明白,有人可以帮帮我吗

def sendDiscordMessage(friendUser, eachUserToScrape):

friendUserScreenName = friendUser.screen_name
friendUserDescription = friendUser.description
friendUserFollowersCount = str(friendUser.followers_count)
client = discord.Client() 

discordMessage = "\n\n=======================================================\n\n" + "????** User @" + eachUserToScrape + " started following : @" + friendUserScreenName + " ????**\n\nLink profile : https://twitter.com/" + friendUserScreenName + "\n\nSubscribers count : "+ friendUserFollowersCount + "\n\nDescription : " + friendUserDescription

channel = client.get_channel(...)
print(discordMessage + type(discordMessage))
await channel.send(discordMessage) 

【问题讨论】:

  • 如果您不了解异步,您应该在深入了解discord.py 之前真正考虑学习它,否则它会变得非常混乱和非常困难。另外,我确定您会收到如下错误:'await' outside async function

标签: python discord.py bots


【解决方案1】:

正如@Łukasz Kwieciński 所说,您将收到'await' outside async function 错误。为了检查代码是否有效并设置 screen_namedescription 属性,我创建了一个类,假设您的 whostartedfollowingwhoisbeingfollowed 属于类似于 user 的类:

class user:
    def __init__(self):
        self.screen_name = "screen name"
        self.description = "description"
        self.followers_count = 3

进入问题的实际部分:发送消息而无需awaiting 命令,您可以随时发送消息。例如,您可以在机器人开始使用其on_ready() 方法时发送消息,如下所示:

@client.event
async def on_ready(): #When the bot starts
    print(f"The bot is online and is logged in as {client.user}")
    #Do some scraping here and get the actual whostartedfollowing and whoisbeingfollowed (from Twitter).
    whostartedfollowing:user = user()
    whoisbeingfollowed:user = user()
    await sendDiscordMessage(whoisbeingfollowed, whostartedfollowing)
    print("sent the message")

其中sendDiscordMessage() 是您代码中的函数,但稍作修改以减少错误:

async def sendDiscordMessage(friendUser, eachUserToScrape):

    friendUserScreenName = friendUser.screen_name
    friendUserDescription = friendUser.description
    friendUserFollowersCount = str(friendUser.followers_count)
    
    discordMessage = "\n\n=======================================================\n\n" + "?** User @" + eachUserToScrape.screen_name + " started following : @" + friendUserScreenName + " ?**\n\nLink profile : https://twitter.com/" + friendUserScreenName + "\n\nSubscribers count : "+ friendUserFollowersCount + "\n\nDescription : " + friendUserDescription
                                                                                                        #Since screen_name is a string, I just used it instead of the object, so it can be joined with the rest as a string.
    channel = client.get_channel(...) #Get the channel with its ID (an `int`), for example a channel with 
    print(channel) #To check if the channel is None or not.
    print(discordMessage) #and not "print(discordMessage + type(discordMessage))", or you can use "print(discordMessage + str(type(discordMessage)))"
    await channel.send(discordMessage)

你可以在没有awaiting 的情况下做同样的事情,方法是不要让你的sendDiscordMessage(friendUser, eachUserToScrape) 函数async(让它成为sendDiscordMessage(friendUser, eachUserToScrape),而不是添加async 使其成为async def sendDiscordMessage(friendUser, eachUserToScrape)),如果你不这样做不想依赖awaited 协程的结果。但是,你会得到一个RuntimeWarning: coroutine 'Messageable.send' was never awaited

如果您必须等待等待的协程的结果,如果等待的协程崩溃,那么其余代码也将无法工作,或者执行顺序很重要,然后使用await 和将def sendDiscordMessage(friendUser, eachUserToScrape) 更改为:

async def sendDiscordMessage(friendUser, eachUserToScrape):

另外,你是using discord.Client and not discord.ext.commands.Bot。后者只是前者的延伸,具有更多的功能。你可能想切换到commands.Bot

这是完整的代码:

from discord.ext import commands

client = commands.Bot(command_prefix="")

class user:
    def __init__(self):
        self.screen_name = "screen name"
        self.description = "description"
        self.followers_count = 3

@client.event
async def on_ready(): #When the bot starts
    print(f"Bot online and logged in as {client.user}")
    #Do some scraping here and get the actual whostartedfollowing and whoisbeingfollowed (from Twitter).
    whostartedfollowing:user = user()
    whoisbeingfollowed:user = user()
    await sendDiscordMessage(whoisbeingfollowed, whostartedfollowing)
    print("sent the message")

async def sendDiscordMessage(friendUser, eachUserToScrape):

    friendUserScreenName = friendUser.screen_name
    friendUserDescription = friendUser.description
    friendUserFollowersCount = str(friendUser.followers_count)
    
    discordMessage = "\n\n=======================================================\n\n" + "?** User @" + eachUserToScrape.screen_name + " started following : @" + friendUserScreenName + " ?**\n\nLink profile : https://twitter.com/" + friendUserScreenName + "\n\nSubscribers count : "+ friendUserFollowersCount + "\n\nDescription : " + friendUserDescription
                                                                                                        #Since screen_name is a string, I just used it instead of the object, so it can be joined with the rest as a string.
    channel = client.get_channel(...)
    print(channel)
    print(discordMessage) #and not "print(discordMessage + type(discordMessage))", or you can use "print(discordMessage + str(type(discordMessage)))"
    await channel.send(discordMessage)

client.run("token")

Hereasync-await 的一些用法。

【讨论】:

  • 我的意思是,感谢您抽出宝贵的时间,我可能是为了快速学习,并在没有太多知识的情况下开始工作..
  • 你的解释很完美,谢谢你的一切!
猜你喜欢
  • 2020-05-11
  • 2021-04-30
  • 2021-04-25
  • 2022-11-02
  • 2020-09-13
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
相关资源
最近更新 更多