I have created a script which takes in a message formatted as !notice [MM/DD/YY HH:mm], message, target which then calls a function using threading.Timer to call it at the time given in the message in UTC.
Where I am having trouble is sending a message from this function, I can't seem to get a message to send from the function regardless of the input of the message.
See below:
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)
This returns "Func called" so I know the function is being called, but no exceptions are raised and no message is posted in my chat.
I also tried substituting func with:
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)
However this throws up an exception:
RuntimeWarning: coroutine 'func' was never awaited
Frankly, I'm out of my depth here. Is there any reason why this won't work?
I saw online that asyncio is not thread-safe. But, unless I'm misunderstanding, my first example didn't use that library in the function. Could is still be causing problems?
discord.py's
discord.Client.send_messageis a coroutine and must beawaited, like you did in your second code snippet. However,threading.Timerdoes not support coroutines. What you're looking for iscreate_task, which enables you to run a coroutine on the event loop. Since most of what your coroutine does is sleeping (mimickingthreading.Timer), youron_messagewill proceed to run, given that you useasyncio.sleepand nottime.sleep- the latter blocks the event loop. Here's an example, including passing arguments to functions: