event notification update
This commit is contained in:
@@ -15,37 +15,32 @@ const router = express.Router();
|
||||
// Posts a plain system message to each assigned user group's DM channel
|
||||
// when an event is created or updated.
|
||||
|
||||
async function postEventNotification(schema, eventId, actorId, isUpdate) {
|
||||
async function sendEventMessage(schema, dmGroupId, actorId, content) {
|
||||
const r = await queryResult(schema,
|
||||
"INSERT INTO messages (group_id,user_id,content,type) VALUES ($1,$2,$3,'system') RETURNING id",
|
||||
[dmGroupId, actorId, content]
|
||||
);
|
||||
const msg = await queryOne(schema, `
|
||||
SELECT m.*, u.name AS user_name, u.display_name AS user_display_name,
|
||||
u.avatar AS user_avatar, u.role AS user_role, u.status AS user_status,
|
||||
u.hide_admin_tag AS user_hide_admin_tag, u.about_me AS user_about_me, u.allow_dm AS user_allow_dm
|
||||
FROM messages m JOIN users u ON m.user_id = u.id WHERE m.id = $1
|
||||
`, [r.rows[0].id]);
|
||||
if (msg) { msg.reactions = []; io.to(R(schema, 'group', dmGroupId)).emit('message:new', msg); }
|
||||
}
|
||||
|
||||
async function postEventNotification(schema, eventId, actorId) {
|
||||
try {
|
||||
const event = await queryOne(schema, 'SELECT * FROM events WHERE id=$1', [eventId]);
|
||||
if (!event) return;
|
||||
|
||||
const dateStr = new Date(event.start_at).toLocaleDateString('en-US', {
|
||||
weekday: 'short', month: 'short', day: 'numeric',
|
||||
});
|
||||
const verb = isUpdate ? 'updated' : 'added';
|
||||
const content = `📅 Event ${verb}: "${event.title}" on ${dateStr}`;
|
||||
|
||||
const dateStr = new Date(event.start_at).toLocaleDateString('en-US', { weekday:'short', month:'short', day:'numeric' });
|
||||
const groups = await query(schema, `
|
||||
SELECT ug.dm_group_id
|
||||
FROM event_user_groups eug
|
||||
SELECT ug.dm_group_id FROM event_user_groups eug
|
||||
JOIN user_groups ug ON ug.id = eug.user_group_id
|
||||
WHERE eug.event_id = $1 AND ug.dm_group_id IS NOT NULL
|
||||
`, [eventId]);
|
||||
|
||||
for (const { dm_group_id } of groups) {
|
||||
const r = await queryResult(schema,
|
||||
"INSERT INTO messages (group_id,user_id,content,type) VALUES ($1,$2,$3,'system') RETURNING id",
|
||||
[dm_group_id, actorId, content]
|
||||
);
|
||||
const msg = await queryOne(schema, `
|
||||
SELECT m.*, u.name AS user_name, u.display_name AS user_display_name,
|
||||
u.avatar AS user_avatar, u.role AS user_role, u.status AS user_status,
|
||||
u.hide_admin_tag AS user_hide_admin_tag, u.about_me AS user_about_me, u.allow_dm AS user_allow_dm
|
||||
FROM messages m JOIN users u ON m.user_id = u.id WHERE m.id = $1
|
||||
`, [r.rows[0].id]);
|
||||
if (msg) { msg.reactions = []; io.to(R(schema, 'group', dm_group_id)).emit('message:new', msg); }
|
||||
}
|
||||
for (const { dm_group_id } of groups)
|
||||
await sendEventMessage(schema, dm_group_id, actorId, `📅 Event added: "${event.title}" on ${dateStr}`);
|
||||
} catch (e) {
|
||||
console.error('[Schedule] postEventNotification error:', e.message);
|
||||
}
|
||||
@@ -291,7 +286,7 @@ router.post('/', authMiddleware, async (req, res) => {
|
||||
for (const ugId of groupIds)
|
||||
await exec(req.schema, 'INSERT INTO event_user_groups (event_id,user_group_id) VALUES ($1,$2) ON CONFLICT DO NOTHING', [eventId, ugId]);
|
||||
if (groupIds.length > 0)
|
||||
await postEventNotification(req.schema, eventId, req.user.id, false);
|
||||
await postEventNotification(req.schema, eventId, req.user.id);
|
||||
const event = await queryOne(req.schema, 'SELECT * FROM events WHERE id=$1', [eventId]);
|
||||
res.json({ event: await enrichEvent(req.schema, event) });
|
||||
} catch (e) { res.status(500).json({ error: e.message }); }
|
||||
@@ -317,6 +312,14 @@ router.patch('/:id', authMiddleware, async (req, res) => {
|
||||
}
|
||||
const fields = { title, eventTypeId, startAt, endAt, allDay, location, description, isPublic, trackAvailability, recurrenceRule, origEvent: event };
|
||||
|
||||
// Capture group/DM mapping before applyEventUpdate modifies event_user_groups
|
||||
const prevGroupRows = await query(req.schema, `
|
||||
SELECT eug.user_group_id, ug.dm_group_id FROM event_user_groups eug
|
||||
JOIN user_groups ug ON ug.id=eug.user_group_id
|
||||
WHERE eug.event_id=$1 AND ug.dm_group_id IS NOT NULL
|
||||
`, [req.params.id]);
|
||||
const prevGroupIdSet = new Set(prevGroupRows.map(r => r.user_group_id));
|
||||
|
||||
await applyEventUpdate(req.schema, req.params.id, fields, userGroupIds);
|
||||
|
||||
// Recurring future scope — update this and all future occurrences
|
||||
@@ -356,9 +359,47 @@ router.patch('/:id', authMiddleware, async (req, res) => {
|
||||
}
|
||||
|
||||
const updated = await queryOne(req.schema, 'SELECT * FROM events WHERE id=$1', [req.params.id]);
|
||||
const finalGroups = await query(req.schema, 'SELECT user_group_id FROM event_user_groups WHERE event_id=$1', [req.params.id]);
|
||||
if (finalGroups.length > 0)
|
||||
await postEventNotification(req.schema, req.params.id, req.user.id, true);
|
||||
|
||||
// Targeted notifications — only for meaningful changes, only to relevant groups
|
||||
try {
|
||||
const finalGroupRows = await query(req.schema, `
|
||||
SELECT eug.user_group_id, ug.dm_group_id FROM event_user_groups eug
|
||||
JOIN user_groups ug ON ug.id=eug.user_group_id
|
||||
WHERE eug.event_id=$1 AND ug.dm_group_id IS NOT NULL
|
||||
`, [req.params.id]);
|
||||
const allDmIds = finalGroupRows.map(r => r.dm_group_id);
|
||||
const dateStr = new Date(updated.start_at).toLocaleDateString('en-US', { weekday:'short', month:'short', day:'numeric' });
|
||||
|
||||
// Newly added groups → "Event added" only to those groups
|
||||
if (Array.isArray(userGroupIds)) {
|
||||
for (const { user_group_id, dm_group_id } of finalGroupRows) {
|
||||
if (!prevGroupIdSet.has(user_group_id))
|
||||
await sendEventMessage(req.schema, dm_group_id, req.user.id, `📅 Event added: "${updated.title}" on ${dateStr}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Date/time changed → "Event updated" to all groups
|
||||
const timeChanged = (startAt && new Date(startAt).getTime() !== new Date(event.start_at).getTime())
|
||||
|| (endAt && new Date(endAt).getTime() !== new Date(event.end_at).getTime())
|
||||
|| (allDay !== undefined && !!allDay !== !!event.all_day);
|
||||
if (timeChanged) {
|
||||
for (const dmId of allDmIds)
|
||||
await sendEventMessage(req.schema, dmId, req.user.id, `📅 Event updated: "${updated.title}" on ${dateStr}`);
|
||||
}
|
||||
|
||||
// Location changed → "Location updated" to all groups
|
||||
const locationChanged = location !== undefined && (location || null) !== (event.location || null);
|
||||
if (locationChanged) {
|
||||
const locContent = updated.location
|
||||
? `📍 Location updated to "${updated.location}": "${updated.title}" on ${dateStr}`
|
||||
: `📍 Location removed: "${updated.title}" on ${dateStr}`;
|
||||
for (const dmId of allDmIds)
|
||||
await sendEventMessage(req.schema, dmId, req.user.id, locContent);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[Schedule] event update notification error:', e.message);
|
||||
}
|
||||
|
||||
res.json({ event: await enrichEvent(req.schema, updated) });
|
||||
} catch (e) { res.status(500).json({ error: e.message }); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user