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 - 後者會阻止事件循環。下面是一個例子,其中包括向函數傳遞參數:

相關問題