feat: add fiat checkout and nostr + email notification (#50)

* feat: fiat and email/nostr notifications

* make n bake
This commit is contained in:
Arc 2026-05-07 12:31:32 +01:00 committed by GitHub
commit 680b035ec9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 379 additions and 61 deletions

View file

@ -1,3 +1,12 @@
from __future__ import annotations
from asyncio.tasks import create_task
from lnbits.core.models.users import UserNotifications
from lnbits.core.services.nostr import send_nostr_dm
from lnbits.core.services.notifications import send_user_notification
from lnbits.settings import settings
from lnbits.utils.nostr import normalize_private_key, normalize_public_key
from lnurl import execute
from loguru import logger
@ -10,6 +19,12 @@ from .crud import (
)
from .models import Ticket
DEFAULT_NOSTR_RELAYS = [
"wss://relay.damus.io",
"wss://relay.primal.net",
"wss://relay.nostr.band",
]
async def set_ticket_paid(ticket: Ticket) -> Ticket:
if ticket.paid:
@ -27,6 +42,77 @@ async def set_ticket_paid(ticket: Ticket) -> Ticket:
return ticket
def send_ticket_notification_in_background(ticket: Ticket) -> None:
create_task(_send_ticket_notification(ticket))
async def _send_ticket_notification(ticket: Ticket) -> None:
event = await get_event(ticket.event)
if not event:
logger.warning(f"Event {ticket.event} not found for ticket notification.")
return
ticket_url = _ticket_url(ticket)
message = (
f"{settings.lnbits_site_title}\n"
f"Your ticket for '{event.name}' is ready.\n"
f"Open it here: {ticket_url}"
)
updated = False
if (
event.extra.email_notifications
and settings.lnbits_email_notifications_enabled
and ticket.email
):
try:
await send_user_notification(
UserNotifications(email_address=ticket.email),
message,
"text_message",
)
ticket.extra.email_notification_sent = True
updated = True
except Exception as exc:
logger.warning(f"Failed to email ticket {ticket.id}: {exc}")
if (
event.extra.nostr_notifications
and settings.is_nostr_notifications_configured()
and ticket.extra.nostr_identifier
):
try:
await _send_nostr_ticket_notification(
ticket.extra.nostr_identifier, message
)
ticket.extra.nostr_notification_sent = True
updated = True
except Exception as exc:
logger.warning(f"Failed to send nostr DM for ticket {ticket.id}: {exc}")
if updated:
await update_ticket(ticket)
async def _send_nostr_ticket_notification(identifier: str, message: str) -> None:
if "@" in identifier:
await send_user_notification(
UserNotifications(nostr_identifier=identifier),
message,
"text_message",
)
return
private_key = normalize_private_key(settings.lnbits_nostr_notifications_private_key)
public_key = normalize_public_key(identifier)
await send_nostr_dm(private_key, public_key, message, DEFAULT_NOSTR_RELAYS)
def _ticket_url(ticket: Ticket) -> str:
base_url = (ticket.extra.ticket_base_url or settings.lnbits_baseurl).rstrip("/")
return f"{base_url}/events/ticket/{ticket.id}"
async def refund_tickets(event_id: str):
"""
Refund tickets for an event that has not met the minimum ticket requirement.