|
|
|
|
@@ -69,7 +69,7 @@ function userDisplayName(user) {
|
|
|
|
|
|
|
|
|
|
function hasTimedSettings(user) {
|
|
|
|
|
const settings = notificationSettingsForUser(user)
|
|
|
|
|
return settings.eventsToday || settings.eventsTomorrow || settings.ownTeamMatches ||
|
|
|
|
|
return settings.newNews || settings.eventsToday || settings.eventsTomorrow || settings.ownTeamMatches ||
|
|
|
|
|
settings.allTeamMatches || settings.selectedTeamSlugs.length > 0 || settings.birthdays
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -126,6 +126,11 @@ function expiringNewsOn(news, dateKey) {
|
|
|
|
|
.map(entry => ({ title: entry.item.title, source: 'news', item: entry.item }))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatNewsExpirySummary(news, fallback) {
|
|
|
|
|
if (news.length === 1) return String(news[0].title || fallback).slice(0, 140)
|
|
|
|
|
return `${news.length} News laufen heute ab: ${news.slice(0, 3).map(item => item.title).filter(Boolean).join(', ')}`.slice(0, 140)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatEventSummary(events, fallback) {
|
|
|
|
|
if (events.length === 1) return String(events[0].title || fallback).slice(0, 140)
|
|
|
|
|
return `${events.length} Einträge: ${events.slice(0, 3).map(event => event.title).filter(Boolean).join(', ')}`.slice(0, 140)
|
|
|
|
|
@@ -285,8 +290,11 @@ export async function runNotificationSchedulerTick(now = new Date()) {
|
|
|
|
|
const tomorrowKey = berlinDateKey(addDays(now, 1))
|
|
|
|
|
const [termine, news, season] = await Promise.all([readTermine(), readNews(), getDefaultSpielplanSeason()])
|
|
|
|
|
const [spielplan, teamRows] = await Promise.all([readSpielplanData({ season }), readTeamMembers(season)])
|
|
|
|
|
const todayEvents = [...eventsOn(termine, dateKey), ...expiringNewsOn(news, dateKey)]
|
|
|
|
|
const tomorrowEvents = [...eventsOn(termine, tomorrowKey), ...expiringNewsOn(news, tomorrowKey)]
|
|
|
|
|
const todayTermine = eventsOn(termine, dateKey)
|
|
|
|
|
const tomorrowTermine = eventsOn(termine, tomorrowKey)
|
|
|
|
|
const expiringNewsToday = expiringNewsOn(news, dateKey)
|
|
|
|
|
const todayEvents = [...todayTermine, ...expiringNewsToday]
|
|
|
|
|
const tomorrowEvents = tomorrowTermine
|
|
|
|
|
const todayMatches = matchesOn(spielplan.data || [], dateKey)
|
|
|
|
|
const tomorrowMatches = matchesOn(spielplan.data || [], tomorrowKey)
|
|
|
|
|
const todaysBirthdays = await birthdaysOn(dateKey)
|
|
|
|
|
@@ -301,6 +309,14 @@ export async function runNotificationSchedulerTick(now = new Date()) {
|
|
|
|
|
failureLabel: 'FCM Termine-heute-Push'
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
results.expiringNews = await sendIfDue(state, dateKey, time, 'expiringNews', expiringNewsToday.length > 0, () => sendPushToUsers({
|
|
|
|
|
title: 'News laufen heute ab',
|
|
|
|
|
body: formatNewsExpirySummary(expiringNewsToday, 'Heute laufen News ab.'),
|
|
|
|
|
data: { type: 'news_expiring', date: dateKey },
|
|
|
|
|
predicate: (_user, settings) => settings.notificationTime === time && settings.newNews && !settings.eventsToday,
|
|
|
|
|
failureLabel: 'FCM News-Ablauf-Push'
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
results.eventsTomorrow = await sendIfDue(state, dateKey, time, 'eventsTomorrow', tomorrowEvents.length > 0, () => sendPushToUsers({
|
|
|
|
|
title: 'Termine morgen',
|
|
|
|
|
body: formatEventSummary(tomorrowEvents, 'Morgen stehen Termine an.'),
|
|
|
|
|
|