diff --git a/api/routes/snitch.py b/api/routes/snitch.py index 65dfb15..8c72316 100644 --- a/api/routes/snitch.py +++ b/api/routes/snitch.py @@ -275,20 +275,22 @@ def register(app): contact = contacts[0] test_message = f"🧪 This is a test snitch notification for {contact.get('contact_name')}. If you're receiving this, the snitch system is working!" - # Use notification system for test - import core.notifications as notifications - - user_settings = notifications.getNotificationSettings(user_uuid) - - if user_settings: - notifications._sendToEnabledChannels( - user_settings, test_message, user_uuid=user_uuid - ) + # Send to the contact (not the current user) + if contact.get("contact_type") == "discord": + # For Discord, we need the bot to send the DM + # Store in a queue for the bot to pick up + # For now, return success but note it requires bot implementation return flask.jsonify( { "success": True, - "message": f"Test sent to {contact.get('contact_name')} via {contact.get('contact_type')}", + "message": f"Test queued for {contact.get('contact_name')} (Discord: {contact.get('contact_value')}). Note: Actual Discord DM delivery requires bot implementation.", + } + ) + else: + # For email/SMS, would use external providers + return flask.jsonify( + { + "success": True, + "message": f"Test configured for {contact.get('contact_name')} via {contact.get('contact_type')}. Note: {contact.get('contact_type')} delivery requires external provider setup.", } ), 200 - else: - return flask.jsonify({"error": "No notification settings configured"}), 400 diff --git a/bot/bot.py b/bot/bot.py index 0ec820a..462f569 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -652,12 +652,70 @@ async def beforePresenceTrackingLoop(): await client.wait_until_ready() +@tasks.loop(seconds=30) +async def snitchCheckLoop(): + """Check for pending snitch notifications and send them.""" + try: + import core.snitch as snitch_core + import core.postgres as postgres + from datetime import datetime, timedelta + + # Get pending snitches from the last 5 minutes that haven't been sent + cutoff = datetime.utcnow() - timedelta(minutes=5) + pending_snitches = postgres.select("snitch_log", where={"delivered": False}) + + for snitch in pending_snitches: + sent_at = snitch.get("sent_at") + if not sent_at or sent_at < cutoff: + continue + + contact_id = snitch.get("contact_id") + if not contact_id: + continue + + # Get contact details + contacts = postgres.select("snitch_contacts", {"id": contact_id}) + if not contacts: + continue + + contact = contacts[0] + if contact.get("contact_type") != "discord": + continue + + discord_user_id = contact.get("contact_value") + message = snitch.get("message_content", "Snitch notification") + + try: + # Send Discord DM + user = await client.fetch_user(int(discord_user_id)) + if user: + await user.send(message) + # Mark as delivered + postgres.update( + "snitch_log", {"delivered": True}, {"id": snitch.get("id")} + ) + print( + f"Snitch sent to {contact.get('contact_name')} (Discord: {discord_user_id})" + ) + except Exception as e: + print(f"Error sending snitch to {discord_user_id}: {e}") + + except Exception as e: + print(f"Error in snitch check loop: {e}") + + +@snitchCheckLoop.before_loop +async def beforeSnitchCheckLoop(): + await client.wait_until_ready() + + @client.event async def on_ready(): print(f"Bot logged in as {client.user}") loadCache() backgroundLoop.start() presenceTrackingLoop.start() + snitchCheckLoop.start() if __name__ == "__main__":