1

我创建了一个脚本,它接受格式为!notice [MM/DD/YY HH:mm], message, target的消息,然后使用threading.Timer调用函数在UTC中的消息中给出的时间调用该函数。为什么我不能通过函数Discord.py发送消息?

如果我遇到麻烦的是从这个函数发送消息,我似乎无法得到从函数发送的消息,而不管消息的输入如何。

见下文:

import discord 
import asyncio 
from datetime import * 
import threading 

client = discord.Client() 

@client.event 
async def on_message(message): 
    if message.content[:7].lower() == "!notice".lower(): 
     try: 
      notice = [datetime.strptime(message.content[message.content.find("[")+1:message.content.find("]")], "%m/%d/%y %H:%M"), message.content.split(", ")[1], message.content.split(", ")[2]] 
      await client.send_message(message.channel, 'Created notice "'+notice[1]+'" to be sent to '+notice[2]+' at '+str(notice[0])+' UTC.') 
      threading.Timer((notice[0] - datetime.utcnow()).total_seconds(), lambda a=notice[1], b=notice[2]: func(a, b)).start() 
      print(str((notice[0] - datetime.utcnow()).total_seconds())+" seconds until message is sent") 
     except (ValueError, IndexError): 
      await client.send_message(message.channel, 'Incorrect Notice Format.\nMust be "!notice [MM/DD/YY HH:mm], Notice contents, Target".\nEG: "!notice [01/01/2017 12:00], This is a notice, Siren Raid Team".') 

def func(message, target): 
    print("Func called") 
    for i in client.servers: 
     for c in i.channels: 
      client.send_message(c, target+message) 

client.run(MY_SESSION_KEY) 

这将返回"Func called",所以我知道该函数被调用,但没有异常升高,没有消息发布在我的聊天。

我也试图与替代func

async def func(message, target): 
    print("Func called") 
    for i in client.servers: 
     for c in i.channels: 
      await client.send_message(c, target+message) 

然而,这引发了一个异常:

RuntimeWarning:协同程序 '功能' 是从来没有期待已久的

坦率地说,我我的深度在这里。这有什么理由不起作用吗?

我在线看到asyncio不是线程安全的。但是,除非我误解,否则我的第一个示例没有在该函数中使用该库。可能仍然会造成问题?

+0

现在,你的'FUNC()'将尝试在每个服务器将消息发送到每个通道,直到它遇到一个它不能发送到和崩溃。您应该考虑使用['discord.utils.get'](https://discordpy.readthedocs.io/en/latest/api.html#discord.utils.get)来查找要发送到的实际目标。 – squaswin

+0

@squaswin这是为了排除故障的目的,在我将消息对象传递给函数并尝试将通知发送到message.channel之前,检查是否能够在任何通道上获取消息。另外,如果我设置'logging'来获取有关错误的更多信息,我不会得到任何我通常会做的错误,如果我尝试发送声音频道或我没有权限的频道。 –

回答

1

discord.py的discord.Client.send_message是一个协程,必须是awaited,就像你在第二个代码片段中做的那样。但是,threading.Timer不支持协程。 您正在寻找的是create_task,它使您能够在事件循环中运行协程。由于大部分协程在睡眠(模拟threading.Timer),因此您的on_message将继续运行,因为您使用的是asyncio.sleep而不是time.sleep - 后者会阻止事件循环。下面是一个例子,其中包括向函数传递参数:

相关问题