nomadweb/backend/app/services/notify.py
eric f215b684f6 Wire connect-ring notifications and durable meetup RSVP.
Require login for meetup RSVP with cancel, notify organizers/authors/posters on RSVP/reply/gig/match, optional ntfy + Listmonk hooks, and honest newsletter messaging.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 19:33:07 -05:00

59 lines
1.5 KiB
Python

"""Unified in-app + optional ntfy push notifications."""
from __future__ import annotations
import asyncio
import re
from app.config import settings
from app.services import community_store, platform_store
from app.services.ntfy_push import send_push
_PREF_KEY = {
"match": "match",
"meetup": "meetup",
"community": "community",
"gig": "community",
"general": None,
}
def _topic_for(user_id: str) -> str:
safe = re.sub(r"[^a-zA-Z0-9_-]", "", user_id)[:48] or "guest"
return f"nomadro-{safe}"
def notify_user(
user_id: str,
title: str,
body: str,
link: str = "",
category: str = "general",
) -> bool:
"""Persist inbox notification; optionally fire ntfy when push prefs allow."""
if not user_id:
return False
prefs = platform_store.get_notif_prefs(user_id)
pref_key = _PREF_KEY.get(category)
if pref_key is not None and not prefs.get(pref_key, True):
return False
community_store.add_notification(user_id, title, body, link, category)
if prefs.get("push") and settings.ntfy_enabled:
click = link if link.startswith("http") else f"{settings.site_base_url.rstrip('/')}{link or '/notifications'}"
try:
loop = asyncio.get_running_loop()
loop.create_task(
send_push(
_topic_for(user_id),
title,
body,
tags=["nomadro", category],
click_url=click,
)
)
except RuntimeError:
# Outside async context — best-effort sync skip; inbox already saved
pass
return True