Calendar reminders as push notifications
A job every minute finds the event reminders that fell due — repeating events and moved occurrences expanded as the calendar view does — and pushes each once to every device with notifications on (sdk.push, new: plugins can notify through the new-mail push delivery). A reminder missed while the worker was down is still sent within 10 minutes; cancelled events and declined invitations stay quiet. Title, then "In 15 minutes, 14:00 · Room 2" in the user's zone and clock format; it stays until dismissed and shows even with the app open; clicking it opens that day (/p/calendar?date=…, new deep link). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -200,6 +200,26 @@ async def notify(user_id: uuid.UUID, message_ids: list[uuid.UUID]) -> int:
|
||||
pushes were delivered to push services."""
|
||||
from app.db import session_scope
|
||||
|
||||
async with session_scope() as db:
|
||||
if not await db.scalar(
|
||||
select(PushSubscription.id).where(PushSubscription.user_id == user_id).limit(1)
|
||||
):
|
||||
return 0
|
||||
messages = await _news(db, user_id, message_ids)
|
||||
if not messages:
|
||||
return 0
|
||||
payloads = _payloads(messages, await _unread(db, user_id))
|
||||
return await deliver(user_id, payloads)
|
||||
|
||||
|
||||
async def deliver(user_id: uuid.UUID, payloads: list[dict[str, object]]) -> int:
|
||||
"""Push ``payloads`` to every device of the user that is still signed in
|
||||
(for new mail, and for plugins: calendar reminders); returns how many were
|
||||
handed to push services. Devices that are gone are forgotten."""
|
||||
from app.db import session_scope
|
||||
|
||||
if not payloads:
|
||||
return 0
|
||||
async with session_scope() as db:
|
||||
# Plain values: the rows expire when the key pair is first saved below.
|
||||
subs = [
|
||||
@@ -210,10 +230,6 @@ async def notify(user_id: uuid.UUID, message_ids: list[uuid.UUID]) -> int:
|
||||
]
|
||||
if not subs:
|
||||
return 0
|
||||
messages = await _news(db, user_id, message_ids)
|
||||
if not messages:
|
||||
return 0
|
||||
payloads = _payloads(messages, await _unread(db, user_id))
|
||||
key = await vapid(db)
|
||||
subject = _subject(await db.get(AppSettings, 1))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user