Skip to content

Commit

Permalink
Add ability to generate test notification
Browse files Browse the repository at this point in the history
  • Loading branch information
micahmo committed May 13, 2024
1 parent 8422608 commit 8792458
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/database/models/account_notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ AccountNotification.init(
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
},
testQueued: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
},
delayedTestQueued: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false
}
},
{ sequelize }
Expand Down
23 changes: 21 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
import sequelize from "./database/database";

// Helper functions
import { addAccountNotification } from "./notifications/notifications";
import { addAccountNotification, generateTestNotification } from "./notifications/notifications";

// Start cron job
import notificationService from "./notifications/service/notification_service";
import { notificationService, checkNotifications } from "./notifications/service/notification_service";
import AccountNotification from "./database/models/account_notification";
notificationService.start();

Expand Down Expand Up @@ -66,6 +66,25 @@ app.delete("/notifications", (req, res) => {
}
});

app.post("/test", async (req: Request, res: Response) => {
const { jwt } = req.body as NotificationRequest;

if (!jwt)
return res.status(400).send("Missing one or more required parameters");

try {
let result = await generateTestNotification(jwt);

res.status(201).json(result);

// Do a check right away
checkNotifications();
} catch (error) {
console.error("Error creating test notification:", error);
res.status(500).json({ error: "Internal Server Error" });
}
});

// Start the server and connect to the database
app.listen(port, async () => {
console.log(`Server is running on http://localhost:${port}`);
Expand Down
8 changes: 7 additions & 1 deletion src/notifications/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,10 @@ async function deleteAccountNotification(
return await AccountNotification.destroy({ where: { token } });
}

export { addAccountNotification, getAccountNotification, deleteAccountNotification };
async function generateTestNotification(
jwt: string | undefined,
): Promise<[affectedCount: number]> {
return AccountNotification.update({ testQueued: true }, { where: { jwt } });
}

export { addAccountNotification, getAccountNotification, deleteAccountNotification, generateTestNotification };
44 changes: 40 additions & 4 deletions src/notifications/service/notification_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import cron from "node-cron";
import { Op } from "sequelize";
import { isAfter, subMinutes } from "date-fns";
import { LemmyHttp } from "lemmy-js-client";
import { Sequelize } from "sequelize";

import AccountNotification from "../../database/models/account_notification";
import { provider, createAPNSNotification } from "../apns/apns";
import { createUnifiedPushNotification, sendUnifiedPushNotification } from "../unifiedpush/unifiedpush";
import { createUnifiedPushNotification, sendTestUnifiedPushNotification, sendUnifiedPushNotification } from "../unifiedpush/unifiedpush";

// The interval in minutes to check for new notifications
const INTERVAL = 1;
Expand Down Expand Up @@ -147,14 +148,48 @@ async function checkUnreadMessages(
}
}

async function checkTests(notification: AccountNotification) {
if (notification.get("testQueued") as boolean) {
console.log('Found 1 test queued');

const notificationType = notification.get("type") as string;
const token = notification.get("token") as string;

switch (notificationType) {
case "apn":
// TODO: Implement this for APN
case "unifiedPush":
await sendTestUnifiedPushNotification(token);
break;
default:
break;
}
}

if (notification.get("delayedTestQueued") as boolean) {
const notificationType = notification.get("type") as string;
const token = notification.get("token") as string;

switch (notificationType) {
case "apn":
// TODO: Implement this for APN
case "unifiedPush":
await sendTestUnifiedPushNotification(token);
break;
default:
break;
}
}
}

/**
* The main function that checks for new notifications. This is triggered from a cron job and is ran at every `INTERVAL` minutes.
*/
const checkNotifications = async () => {
triggerDateTime = new Date();

const notifications = await AccountNotification.findAll({
where: { timestamp: { [Op.lt]: subMinutes(triggerDateTime, INTERVAL) } },
where: Sequelize.or({ timestamp: { [Op.lt]: subMinutes(triggerDateTime, INTERVAL) } }, { testQueued: true }, { delayedTestQueued: true }),
});

console.log("Found " + notifications.length + " notifications to check");
Expand Down Expand Up @@ -191,9 +226,10 @@ const checkNotifications = async () => {
await checkUnreadReplies(client, notification);
await checkUnreadMentions(client, notification);
await checkUnreadMessages(client, notification);
await checkTests(notification);

// Update the notification timestamp
await notification.update({ timestamp: triggerDateTime });
await notification.update({ timestamp: triggerDateTime, testQueued: false, delayedTestQueued: false });
} catch (error) {
console.error(error);
}
Expand Down Expand Up @@ -221,4 +257,4 @@ const notificationService = cron.schedule(
}
);

export default notificationService;
export { notificationService, checkNotifications };
17 changes: 16 additions & 1 deletion src/notifications/unifiedpush/unifiedpush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,19 @@ async function sendUnifiedPushNotification(
});
}

export { createUnifiedPushNotification, sendUnifiedPushNotification };
/**
* Sends the notification through UnifiedPush.
*/
async function sendTestUnifiedPushNotification(
token: string
) {
fetch(token, {
method: "POST",
body: 'test',
headers: {
"Content-type": "application/json; charset=UTF-8",
},
});
}

export { createUnifiedPushNotification, sendUnifiedPushNotification, sendTestUnifiedPushNotification };

0 comments on commit 8792458

Please sign in to comment.