working push notifiations
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { asyncHandler } from '../utils/asyncHandler';
|
||||
import { db } from '../db';
|
||||
import { users } from '../db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { AppError } from '../middleware/errorHandler';
|
||||
import { z } from 'zod';
|
||||
import { sendPushNotification, isExpoPushToken, createTaskReminderPayload } from '../services/pushNotifications';
|
||||
|
||||
const router = Router();
|
||||
|
||||
const registerPushTokenSchema = z.object({
|
||||
pushToken: z.string().min(1),
|
||||
});
|
||||
|
||||
router.post('/push-token', asyncHandler(async (req: Request, res: Response) => {
|
||||
if (!req.user) {
|
||||
throw new AppError('UNAUTHORIZED', 'Authentication required', 401);
|
||||
}
|
||||
|
||||
const data = registerPushTokenSchema.parse(req.body);
|
||||
|
||||
if (!isExpoPushToken(data.pushToken)) {
|
||||
throw new AppError('INVALID_PUSH_TOKEN', 'Invalid Expo push token format', 400);
|
||||
}
|
||||
|
||||
await db
|
||||
.update(users)
|
||||
.set({
|
||||
expoPushToken: data.pushToken,
|
||||
pushTokenUpdatedAt: Date.now(),
|
||||
})
|
||||
.where(eq(users.id, req.user.userId));
|
||||
|
||||
res.json({ success: true });
|
||||
}));
|
||||
|
||||
router.delete('/push-token', asyncHandler(async (req: Request, res: Response) => {
|
||||
if (!req.user) {
|
||||
throw new AppError('UNAUTHORIZED', 'Authentication required', 401);
|
||||
}
|
||||
|
||||
await db
|
||||
.update(users)
|
||||
.set({
|
||||
expoPushToken: null,
|
||||
pushTokenUpdatedAt: Date.now(),
|
||||
})
|
||||
.where(eq(users.id, req.user.userId));
|
||||
|
||||
res.json({ success: true });
|
||||
}));
|
||||
|
||||
router.post('/test', asyncHandler(async (req: Request, res: Response) => {
|
||||
if (!req.user) {
|
||||
throw new AppError('UNAUTHORIZED', 'Authentication required', 401);
|
||||
}
|
||||
|
||||
const user = await db.select().from(users).where(eq(users.id, req.user.userId)).limit(1);
|
||||
if (user.length === 0 || !user[0].expoPushToken) {
|
||||
throw new AppError('NO_PUSH_TOKEN', 'No push token registered', 400);
|
||||
}
|
||||
|
||||
const ticket = await sendPushNotification({
|
||||
to: user[0].expoPushToken!,
|
||||
title: 'Test Notification',
|
||||
body: 'Push notifications are working!',
|
||||
data: { type: 'test' },
|
||||
sound: 'default',
|
||||
});
|
||||
|
||||
res.json({ success: true, ticket });
|
||||
}));
|
||||
|
||||
router.post('/send-reminder', asyncHandler(async (req: Request, res: Response) => {
|
||||
if (!req.user) {
|
||||
throw new AppError('UNAUTHORIZED', 'Authentication required', 401);
|
||||
}
|
||||
|
||||
const { taskId, taskTitle, dueTime, repeat } = req.body;
|
||||
if (!taskId || !taskTitle || !dueTime) {
|
||||
throw new AppError('INVALID_PAYLOAD', 'Missing required fields', 400);
|
||||
}
|
||||
|
||||
const user = await db.select().from(users).where(eq(users.id, req.user.userId)).limit(1);
|
||||
if (user.length === 0 || !user[0].expoPushToken) {
|
||||
throw new AppError('NO_PUSH_TOKEN', 'No push token registered', 400);
|
||||
}
|
||||
|
||||
const ticket = await sendPushNotification(
|
||||
createTaskReminderPayload(user[0].expoPushToken!, taskTitle, dueTime, taskId, repeat)
|
||||
);
|
||||
|
||||
res.json({ success: true, ticket });
|
||||
}));
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user