feat: Add consent change and deletion notifications (Phase 4)

- Integrate sendConsentChangeNotification() into management.js PUT /consents
- Integrate sendGroupDeletedNotification() into management.js DELETE /:token
- Refactor sendConsentChangeNotification() to accept structured changeData
- Add platform name lookup for social media consent notifications
- Non-blocking async notifications (won't fail consent changes on error)

Phase 4 complete: Tested successfully with:
- Workshop consent revoke → Telegram notification received
- Group deletion → Telegram notification received

Changes:
- Workshop consent: Shows action (revoke/restore) and new status
- Social media consent: Shows platform and action
- Deletion: Shows uploader, year, title, image count
This commit is contained in:
Matthias Lotz 2025-11-30 10:22:52 +01:00
parent 62be18ecaa
commit 8cceb8e9a3
2 changed files with 76 additions and 32 deletions

View File

@ -5,6 +5,10 @@ const deletionLogRepository = require('../repositories/DeletionLogRepository');
const dbManager = require('../database/DatabaseManager');
const { rateLimitMiddleware, recordFailedTokenValidation } = require('../middlewares/rateLimiter');
const auditLogMiddleware = require('../middlewares/auditLog');
const TelegramNotificationService = require('../services/TelegramNotificationService');
// Singleton-Instanz des Telegram Service
const telegramService = new TelegramNotificationService();
// Apply middleware to all management routes
router.use(rateLimitMiddleware);
@ -211,6 +215,20 @@ router.put('/:token/consents', async (req, res) => {
[newValue, groupData.groupId]
);
// Sende Telegram-Benachrichtigung (async, non-blocking)
if (telegramService.isAvailable()) {
telegramService.sendConsentChangeNotification({
name: groupData.name,
year: groupData.year,
title: groupData.title,
consentType: 'workshop',
action: action,
newValue: newValue === 1
}).catch(err => {
console.error('[Telegram] Consent change notification failed:', err.message);
});
}
return res.json({
success: true,
message: `Workshop consent ${action}d successfully`,
@ -263,6 +281,26 @@ router.put('/:token/consents', async (req, res) => {
}
}
// Sende Telegram-Benachrichtigung (async, non-blocking)
if (telegramService.isAvailable()) {
// Hole Platform-Name für Benachrichtigung
const platform = await dbManager.get(
'SELECT name FROM social_media_platforms WHERE id = ?',
[platformId]
);
telegramService.sendConsentChangeNotification({
name: groupData.name,
year: groupData.year,
title: groupData.title,
consentType: 'social_media',
action: action,
platform: platform ? platform.name : `Platform ${platformId}`
}).catch(err => {
console.error('[Telegram] Consent change notification failed:', err.message);
});
}
return res.json({
success: true,
message: `Social media consent ${action}d successfully`,
@ -1007,6 +1045,18 @@ router.delete('/:token', async (req, res) => {
console.log(`✓ Group ${groupId} deleted via management token (${imageCount} images)`);
// Sende Telegram-Benachrichtigung (async, non-blocking)
if (telegramService.isAvailable()) {
telegramService.sendGroupDeletedNotification({
name: groupData.name,
year: groupData.year,
title: groupData.title,
imageCount: imageCount
}).catch(err => {
console.error('[Telegram] Group deletion notification failed:', err.message);
});
}
res.json({
success: true,
message: 'Group and all associated data deleted successfully',

View File

@ -145,58 +145,52 @@ Social Media: ${socialMediaIcons || '❌ Keine'}
/**
* Phase 4: Sendet Benachrichtigung bei Consent-Änderung
*
* @param {Object} oldConsents - Alte Consent-Werte
* @param {Object} newConsents - Neue Consent-Werte
* @param {Object} groupData - Gruppen-Informationen
* @param {Object} changeData - Änderungs-Informationen
* @param {string} changeData.name - Name des Uploaders
* @param {number} changeData.year - Jahr
* @param {string} changeData.title - Titel
* @param {string} changeData.consentType - 'workshop' oder 'social_media'
* @param {string} changeData.action - 'revoke' oder 'restore'
* @param {string} [changeData.platform] - Plattform-Name (nur bei social_media)
* @param {boolean} [changeData.newValue] - Neuer Wert (nur bei workshop)
*/
async sendConsentChangeNotification(oldConsents, newConsents, groupData) {
async sendConsentChangeNotification(changeData) {
if (!this.isAvailable()) {
console.log('[Telegram] Service not available, skipping consent change notification');
return null;
}
try {
const workshopChange = oldConsents.workshopConsent !== newConsents.workshopConsent;
const socialMediaChange = JSON.stringify(oldConsents.socialMediaConsents) !== JSON.stringify(newConsents.socialMediaConsents);
if (!workshopChange && !socialMediaChange) {
console.log('[Telegram] No consent changes detected, skipping notification');
return null;
}
let changes = [];
if (workshopChange) {
const oldIcon = oldConsents.workshopConsent ? '✅' : '❌';
const newIcon = newConsents.workshopConsent ? '✅' : '❌';
changes.push(`Workshop: ${newIcon} ${newConsents.workshopConsent ? 'Ja' : 'Nein'} (vorher: ${oldIcon})`);
}
if (socialMediaChange) {
const oldSocial = this.formatSocialMediaIcons(oldConsents.socialMediaConsents) || 'Keine';
const newSocial = this.formatSocialMediaIcons(newConsents.socialMediaConsents) || 'Keine';
changes.push(`Social Media: ${newSocial} (vorher: ${oldSocial})`);
const { name, year, title, consentType, action, platform, newValue } = changeData;
let changeDescription;
if (consentType === 'workshop') {
const icon = newValue ? '✅' : '❌';
const status = newValue ? 'Ja' : 'Nein';
const actionText = action === 'revoke' ? 'widerrufen' : 'wiederhergestellt';
changeDescription = `Workshop-Consent ${actionText}\nNeuer Status: ${icon} ${status}`;
} else if (consentType === 'social_media') {
const actionText = action === 'revoke' ? 'widerrufen' : 'erteilt';
changeDescription = `Social Media Consent ${actionText}\nPlattform: ${platform}`;
}
const message = `
User-Änderung
Consent-Änderung
Aktion: Consent aktualisiert
Gruppe: ${groupData.year} - ${groupData.title}
Uploader: ${groupData.name}
Gruppe: ${year} - ${title}
Uploader: ${name}
Neu:
${changes.join('\n')}
${changeDescription}
🔗 Details: ${this.getAdminUrl()}
`.trim();
const response = await this.bot.sendMessage(this.chatId, message);
console.log(`[Telegram] Consent change notification sent for group: ${groupData.title}`);
console.log(`[Telegram] Consent change notification sent for: ${title}`);
return response;
} catch (error) {
console.error('[Telegram] Failed to send consent change notification:', error.message);
return null;
throw error;
}
}