0

I'm trying to create a Discord bot using discord.py that will mention certain roles at certain times of the day. I'm currently using schedule to set the times at which these mentions will occur.

I'm running into a problem where I'm getting the following TypeError when trying to await the async function that sends the message with the mention:

File "c:\codebase\my-bot\scheduler.py", line 47, in set_schedules
    schedule.every().day.at("05:30").do(await ping_role, bot)
TypeError: object function can't be used in 'await' expression

Below is the code for my Discord bot (bot.py) and scheduler (scheduler.py).

bot.py

import discord
from discord.ext import commands

import os

from scheduler import run_continuously, set_schedules

token = "{redacted}"

description = "Test"

intents = discord.Intents.default()
intents.members = True

bot = commands.Bot(command_prefix='!', description=description, intents=intents)

BOT_CHANNELS = ('bot-spam', 'spam-bot')

@bot.event
async def on_ready():
    print("Logged in as")
    print(bot.user.name)
    print(bot.user.id)
    print("------------")

    await set_schedules(bot)

    stop_run_continuously = run_continuously()

...

if __name__ == "__main__":
    bot.run(token)

scheduler.py

import threading
import time

import schedule
import discord

def run_continuously(interval=1):
    cease_continuous_run = threading.Event()

    class ScheduleThread(threading.Thread):
        @classmethod
        def run(cls):
            while not cease_continuous_run.is_set():
                schedule.run_pending()
                time.sleep(interval)

    continuous_thread = ScheduleThread()
    continuous_thread.start()
    return cease_continuous_run

async def ping_role(bot):
    for guild in bot.guilds:
        channels = [channel for channel in guild.channels if channel.name in ('bot-spam', 'spam-bot')]
        role = [role for role in guild.roles if role.name == "to_mention_role"][0]

        for channel in channels:
            await channel.send(f"{role.mention}: You have been mentioned!")

async def set_schedules(bot):
    schedule.every().day.at("5:30").do(await ping_role, bot)

I've also tried the following:

async def set_schedules(bot):
    schedule.every().day.at("5:30").do(ping_role, bot)

This gives RuntimeWarning: coroutine 'ping__role' was never awaited self._run_job(job)

def ping_role(bot):
    ...
    await ...

This gives SyntaxError: 'await' outside async function

Any help or insight is greatly appreciated! Thank you!

Michael
  • 68
  • 8
  • 4
    Does this answer your question? [How can I run an async function using the schedule library?](https://stackoverflow.com/questions/51530012/how-can-i-run-an-async-function-using-the-schedule-library) – Ceres Apr 07 '21 at 05:28
  • 1
    II wouldn't recommend you using the `schedule` library as it is blocking ([What does "blocking" mean?](https://discordpy.readthedocs.io/en/latest/faq.html#what-does-blocking-mean)), discord.py already has an extension for background tasks, take a look at the docs: https://discordpy.readthedocs.io/en/latest/ext/tasks/index.html – Łukasz Kwieciński Apr 07 '21 at 06:15

0 Answers0