v0.3.5: restore full push notification system (14 channels)
Restored from v0.2.4: - notifiers/: 14 push channels (bark/serverchan/telegram/lark/webhook/wechat/discord/smtp/...) - push-user.service.ts: multi-user push config linked to cloud_configs.promotion_account - notification.service.ts: full dispatcher with per-config + global fallback New integrations: - cloud.service.ts: notifyConfigEvent on save_success/cookie_expire/save_fail - admin.routes.ts: 7 new API endpoints for push users, notify providers, channel test - database.ts: migration for cloud_configs.notify_config column How it works: - Configure push channels in /admin/system-configs (global_notify_config JSON) - Or per-cloud: link push_users.account = cloud_configs.promotion_account - Notify events: save_success (green), cookie_expire (red), save_fail >=3 consecutive (yellow)
This commit is contained in:
@@ -8,6 +8,8 @@ import { getCloudConfigs, getCloudConfigById, saveCloudConfig, deleteCloudConfig
|
||||
import { dailyCheckIn, skipCheckin, getCheckinSummary, getDrivesForCheckin } from '../cloud/checkin.service';
|
||||
import { getAllCloudTypes } from '../cloud/cloud-types.service';
|
||||
import { login, authMiddleware, verifyToken, changePassword } from '../admin/auth.service';
|
||||
import { getAllPushUsers, upsertPushUser, updatePushUser, deletePushUser } from '../cloud/push-user.service';
|
||||
import { getAllNotifierParams, testChannel, saveConfigNotifySettings, getConfigNotifySettingsJSON } from '../cloud/notification.service';
|
||||
import { getStats } from '../admin/stats.service';
|
||||
import { getAllSystemConfigs, updateSystemConfig, updateSystemConfigs, getSystemConfig } from '../admin/system-config.service';
|
||||
import { getDb } from '../database/database';
|
||||
@@ -672,4 +674,106 @@ router.post('/admin/update-pansou', async (_req: Request, res: Response) => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// ======================== Notification / Push Users ========================
|
||||
|
||||
/** GET /api/admin/cloud-configs/:id/notify */
|
||||
router.get('/admin/cloud-configs/:id/notify', (req: Request, res: Response) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id as string);
|
||||
const settings = getConfigNotifySettingsJSON(id);
|
||||
res.json(settings);
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ error: err.message || 'Failed to get notification settings' });
|
||||
}
|
||||
});
|
||||
|
||||
/** PUT /api/admin/cloud-configs/:id/notify */
|
||||
router.put('/admin/cloud-configs/:id/notify', (req: Request, res: Response) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id as string);
|
||||
const settings = req.body;
|
||||
saveConfigNotifySettings(id, settings);
|
||||
res.json({ success: true, message: 'Push config saved' });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ error: err.message || 'Failed to save notification settings' });
|
||||
}
|
||||
});
|
||||
|
||||
/** POST /api/admin/notify/test */
|
||||
router.post('/admin/notify/test', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { channelType, account, configId, params } = req.body;
|
||||
const ctx = account || (configId ? String(configId) : undefined);
|
||||
const result = await testChannel(channelType, ctx, params);
|
||||
res.json(result);
|
||||
} catch (err: any) {
|
||||
res.json({ success: false, message: err.message || 'Test send failed' });
|
||||
}
|
||||
});
|
||||
|
||||
/** GET /api/admin/notify/providers */
|
||||
router.get('/admin/notify/providers', (_req: Request, res: Response) => {
|
||||
try {
|
||||
const providers = getAllNotifierParams();
|
||||
res.json(providers);
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: err.message || 'Failed to get providers' });
|
||||
}
|
||||
});
|
||||
|
||||
/** GET /api/admin/push-users */
|
||||
router.get('/admin/push-users', (_req: Request, res: Response) => {
|
||||
try {
|
||||
const users = getAllPushUsers();
|
||||
const parsed = users.map(u => ({
|
||||
...u,
|
||||
notify_config: (() => { try { return JSON.parse(u.notify_config); } catch { return {}; } })(),
|
||||
}));
|
||||
res.json(parsed);
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: err.message || 'Failed to list push users' });
|
||||
}
|
||||
});
|
||||
|
||||
/** POST /api/admin/push-users */
|
||||
router.post('/admin/push-users', (req: Request, res: Response) => {
|
||||
try {
|
||||
const { account, notify_config } = req.body;
|
||||
if (!account) return res.status(400).json({ error: 'account is required' });
|
||||
const configStr = typeof notify_config === 'string' ? notify_config : JSON.stringify(notify_config || {});
|
||||
const user = upsertPushUser(account, configStr);
|
||||
res.json({ ...user, notify_config: JSON.parse(user!.notify_config) });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ error: err.message || 'Failed to save push user' });
|
||||
}
|
||||
});
|
||||
|
||||
/** PUT /api/admin/push-users/:id */
|
||||
router.put('/admin/push-users/:id', (req: Request, res: Response) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id as string);
|
||||
const { account, notify_config } = req.body;
|
||||
if (!account) return res.status(400).json({ error: 'account is required' });
|
||||
const configStr = typeof notify_config === 'string' ? notify_config : JSON.stringify(notify_config || {});
|
||||
const user = updatePushUser(id, account, configStr);
|
||||
res.json({ ...user, notify_config: JSON.parse(user!.notify_config) });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ error: err.message || 'Failed to update push user' });
|
||||
}
|
||||
});
|
||||
|
||||
/** DELETE /api/admin/push-users/:id */
|
||||
router.delete('/admin/push-users/:id', (req: Request, res: Response) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id as string);
|
||||
const ok = deletePushUser(id);
|
||||
if (ok) res.json({ success: true });
|
||||
else res.status(404).json({ error: 'Push user not found' });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ error: err.message || 'Failed to delete push user' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user