f5203e0466
Strip markdown formatting (bold, italic, headers, code, links, lists) from LLM responses before sending via iMessage. Add scheduled messages feature with CRUD API, background scheduler loop, and admin frontend panel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
import asyncio
|
|
import logging
|
|
from datetime import datetime, timezone
|
|
|
|
from .models import ScheduledMessage, MessageChannel, MessageStatus
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
POLL_INTERVAL = 15
|
|
|
|
|
|
async def scheduled_messages_loop():
|
|
"""Background loop that polls for and sends due scheduled messages."""
|
|
logger.info(f"Scheduled messages loop started (interval={POLL_INTERVAL}s)")
|
|
|
|
while True:
|
|
try:
|
|
now = datetime.now(timezone.utc)
|
|
due = await ScheduledMessage.filter(
|
|
status=MessageStatus.PENDING,
|
|
scheduled_at__lte=now,
|
|
).all()
|
|
|
|
for msg in due:
|
|
try:
|
|
if msg.channel == MessageChannel.IMESSAGE:
|
|
from blueprints.imessage import send_imessage
|
|
from utils.strip_markdown import strip_markdown
|
|
|
|
await send_imessage(msg.recipient, strip_markdown(msg.content))
|
|
|
|
elif msg.channel == MessageChannel.EMAIL:
|
|
from blueprints.email import send_email_reply
|
|
|
|
await send_email_reply(
|
|
to=msg.recipient,
|
|
subject=msg.subject or "(no subject)",
|
|
body=msg.content,
|
|
)
|
|
|
|
msg.status = MessageStatus.SENT
|
|
msg.error_message = None
|
|
await msg.save()
|
|
logger.info(
|
|
f"Sent scheduled {msg.channel.value} message {msg.id} to {msg.recipient}"
|
|
)
|
|
|
|
except Exception as e:
|
|
msg.status = MessageStatus.FAILED
|
|
msg.error_message = str(e)
|
|
await msg.save()
|
|
logger.error(f"Failed to send scheduled message {msg.id}: {e}")
|
|
|
|
except Exception:
|
|
logger.exception("Error in scheduled messages loop")
|
|
|
|
await asyncio.sleep(POLL_INTERVAL)
|