无法让不和谐的机器人在 python 函数内发送消息

Can't make a discord bot send a message inside a python function

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

我设法使用 Twitter API,但我无法在 discord 上发送消息的部分,它只是一个要在函数中发送的字符串

我一直看到 discord 机器人对频道中输入的命令做出反应,但我想要一个自己发送消息而不是等待命令的机器人。

我不太了解异步的东西 (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) 

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

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

来到问题的实际部分:无需 await 命令即可发送消息,您可以随时发送消息。例如,您可以在机器人开始使用其 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 协程的结果。但是,你会得到一个 .

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

async def sendDiscordMessage(friendUser, eachUserToScrape):

此外,您 。后者只是前者的延伸,功能更多。您可能想切换到 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")

async-await.

的一些用法