jarvis-tasks/jarvis_tasks/tasks/reminder.py
2022-02-19 17:03:07 -07:00

71 lines
2.7 KiB
Python

"""JARVIS reminders."""
import asyncio
from datetime import datetime, timedelta
from logging import Logger
from dis_snek import Snake
from jarvis_core.db import q
from jarvis_core.db.models import Reminder
from jarvis_core.util import build_embed
async def remind(bot: Snake, logger: Logger) -> None:
"""
Run reminders in the background.
Args:
bot: Snake instance
logger: Global logger
"""
while True:
await asyncio.sleep(5)
reminders = Reminder.find(
q(remind_at__lte=datetime.utcnow() + timedelta(seconds=5), active=True)
)
async for reminder in reminders:
user = await bot.fetch_user(reminder.user)
if not user:
logger.warning(f"Failed to get user with ID {reminder.user}")
await reminder.delete()
continue
embed = build_embed(
title="You have a reminder!", description=reminder.message, fields=[]
)
embed.set_author(
name=user.username + "#" + user.discriminator, icon_url=user.avatar.url
)
embed.set_thumbnail(url=user.avatar.url)
try:
await user.send(embed=embed)
logger.info(f"Reminder {reminder.id} sent to user")
await reminder.delete()
except Exception:
logger.info("User has closed DMs")
guild = await bot.fetch_guild(reminder.guild)
member = await bot.fetch_member(user.id)
if not member:
logger.warning("User no longer member of origin guild, deleting reminder")
await reminder.delete()
continue
channel = await guild.fetch_channel(reminder.channel) if guild else None
if channel and not reminder.private:
await channel.send(f"{member.mention}", embed=embed)
logger.debug(f"Reminder {reminder.id} sent to origin channel")
await reminder.delete()
elif channel:
await channel.send(
f"{member.mention}, you had a private reminder set for now,"
" but I couldn't send it to you.\n"
f"Use `/reminder fetch {str(reminder.id)}` to view"
)
logger.info(
f"Reminder {reminder.id} private, sent notification to origin channel"
)
reminder.update(q(active=False))
await reminder.commit()
else:
logger.warning("No way to contact user, deleting reminder")
await reminder.delete()