Skip to content

Commit

Permalink
start emails
Browse files Browse the repository at this point in the history
  • Loading branch information
ngoerlitz committed Dec 9, 2023
1 parent 26cde55 commit 183400e
Show file tree
Hide file tree
Showing 19 changed files with 424 additions and 99 deletions.
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ node_modules
dist
.github

misc/mail-templates
mist/crontab.txt

package.json
package-lock.json

Expand Down
26 changes: 0 additions & 26 deletions misc/DBConn.js

This file was deleted.

31 changes: 0 additions & 31 deletions misc/SendReminderMail.js

This file was deleted.

3 changes: 2 additions & 1 deletion misc/crontab.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
0 1 * * * cd /opt/trainingcenter_backend && node /opt/trainingcenter_backend/misc/CheckEndorsements.js >> /var/log/check_endorsement.log
0 1 * * * cd /opt/trainingcenter_backend && node ./dist/misc/scripts/CheckEndorsements.ts >> /var/log/check_endorsement.log
0 */1 * * * cd /opt/trainingcenter_backend && node ./dist/misc/scripts/SendReminderMail.ts >> /var/log/check_endorsement.log
53 changes: 53 additions & 0 deletions misc/mail-templates/message.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!doctype html>
<html lang="de" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>VATGER Trainingcenter</title>
</head>

<body style="font-family: Inter, sans-serif; font-size: 15px; font-weight: 400; justify-content: center">
<!-- Hero Start -->
<div style="margin-top: 50px;">
<table style="font-family: Inter, sans-serif; font-size: 15px; font-weight: 400; max-width: 600px; border: none; margin: 0 auto; border-radius: 6px; overflow: hidden; background-color: #fff; box-shadow: 0 0 3px rgba(60, 72, 88, 0.15);">
<thead>
<tr style="background-color: #2f55d4; padding: 3px 0; line-height: 68px; text-align: center; color: #fff; font-size: 24px; font-weight: 700; letter-spacing: 1px;">
<th scope="col">
<img src="https://cdn.vatsim-germany.org/img/vacc_logo_white.png" height="48" alt="VATSIM Germany" style="margin-bottom: 10px; vertical-align: middle">
</th>
</tr>
</thead>

<tbody>
<tr>
<td style="padding: 24px 24px 15px; color: #8492a6;">
Hallo {{ name }},<br/>
{{ message }}
</td>
</tr>

<tr>
<td style="padding: 24px 24px 0; color: #8492a6;">
Solltest du noch Fragen haben wende dich bitte an <a href="mailto:[email protected]">[email protected]</a>.
</td>
</tr>

<tr>
<td style="padding: 15px 24px 15px; color: #8492a6;">
VATSIM Germany Trainingssystem
</td>
</tr>

<tr>
<td style="padding: 16px 8px; color: #8492a6; background-color: #f8f9fc; text-align: center; font-size: 0.7rem">
Diese automatische Nachricht wurde am {{date_now}} generiert.<br/>
Bitte antworte nicht auf diese E-Mail.
</td>
</tr>
</tbody>
</table>
</div>
<!-- Hero End -->
</body>
</html>
60 changes: 60 additions & 0 deletions misc/mail-templates/reminder.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!doctype html>
<html lang="de" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>VATGER Trainingcenter</title>
</head>

<body style="font-family: Inter, sans-serif; font-size: 15px; font-weight: 400; justify-content: center">
<!-- Hero Start -->
<div style="margin-top: 50px;">
<table style="font-family: Inter, sans-serif; font-size: 15px; font-weight: 400; max-width: 600px; border: none; margin: 0 auto; border-radius: 6px; overflow: hidden; background-color: #fff; box-shadow: 0 0 3px rgba(60, 72, 88, 0.15);">
<thead>
<tr style="background-color: #2f55d4; padding: 3px 0; line-height: 68px; text-align: center; color: #fff; font-size: 24px; font-weight: 700; letter-spacing: 1px;">
<th scope="col">
<img src="https://cdn.vatsim-germany.org/img/vacc_logo_white.png" height="48" alt="VATSIM Germany" style="margin-bottom: 10px; vertical-align: middle">
</th>
</tr>
</thead>

<tbody>
<tr>
<td style="padding: 24px 24px 15px; color: #8492a6;">
Hallo {{ name }},<br/>
eine deiner Trainingsanfragen läuft am {{ expiry_date }} ab. Solltest du noch weiteres Interesse an einem Training haben, bitten wir dich
dies durch einen Click auf folgenden Link zu bestätigen. Beachte bitte, dass dies innerhalb von vier Wochen geschehen muss, da sonst deine Anfrage verfällt.
</td>
</tr>

<tr>
<td style="padding: 0 24px 15px; color: #8492a6;">
<a href="{{link}}">{{link}}</a>
</td>
</tr>

<tr>
<td style="padding: 24px 24px 0; color: #8492a6;">
Solltest du noch Fragen haben wende dich bitte an <a href="mailto:[email protected]">[email protected]</a>.
</td>
</tr>

<tr>
<td style="padding: 15px 24px 15px; color: #8492a6;">
VATSIM Germany Trainingssystem
</td>
</tr>

<tr>
<td style="padding: 16px 8px; color: #8492a6; background-color: #f8f9fc; text-align: center; font-size: 0.7rem">
Diese automatische Nachricht wurde am {{date_now}} generiert.<br/>
Bitte antworte nicht auf diese E-Mail.
</td>
</tr>
</tbody>
</table>
</div>
<!-- Hero End -->
</body>
</html>
19 changes: 9 additions & 10 deletions misc/CheckEndorsements.js → misc/scripts/CheckEndorsements.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
const Sequelize = require("sequelize");
const dayjs = require("dayjs");
const DBConn = require("./DBConn");

/**
* This script periodically checks, if a user has an endorsement bound to a solo, whilst the solo has already passed
* Once every 24 Hours.
*/

DBConn.connectToDatabase()
.then(async (seq) => {
import DBConn from "./DBConn";
import { Sequelize, QueryTypes } from "sequelize";
import dayjs from "dayjs";

DBConn.connectToDatabase().then(async (seq: Sequelize | null) => {
if (seq == null) return;

const q = seq.query(
const q = (await seq.query(
"SELECT endorsement_groups_belong_to_users.id, endorsement_groups_belong_to_users.user_id, endorsement_groups_belong_to_users.solo_id, user_solos.current_solo_start, user_solos.current_solo_end FROM endorsement_groups_belong_to_users JOIN user_solos ON user_solos.id = endorsement_groups_belong_to_users.solo_id",
{
type: Sequelize.QueryTypes.SELECT,
type: QueryTypes.SELECT,
}
)
)) as any[];

for (const solo of q) {
if (dayjs.utc(solo.current_solo_end).isBefore(dayjs.utc())) {
console.log(`Solo ID ${solo.solo_id} [user_id = ${solo.user_id}] has expired. Removing Endorsement Group...`);
await seq.query("DELETE FROM endorsement_groups_belong_to_users WHERE ID = ?", {
replacements: [solo.id],
type: Sequelize.QueryTypes.DELETE
type: QueryTypes.DELETE,
});
} else {
console.log(
Expand Down
26 changes: 26 additions & 0 deletions misc/scripts/DBConn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { SequelizeConfig } from "../../src/core/Config";
import { Sequelize } from "sequelize";

async function connectToDatabase() {
const newConf = {
...SequelizeConfig,
logging: (message: string) => {
console.log(message);
},
};

const seq = new Sequelize(newConf);

try {
await seq.authenticate();
} catch (e) {
console.log(`[SEQ] Failed to authenticate: ${e}.`);
return null;
}

return seq;
}

export default {
connectToDatabase,
};
File renamed without changes.
49 changes: 49 additions & 0 deletions misc/scripts/SendReminderMail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* This script sends a mail to all users that have an open training request which is about to expire
* If the expiration date is within a week. Will send up to one E-Mail per week for the next 4 weeks after the expiration.
* All requests that have expired will be removed automatically.
*/

import DBConn from "./DBConn";
import dayjs from "dayjs";
import { QueryTypes } from "sequelize";
import { Config } from "../../src/core/Config";
import EmailHelper from "../../src/utility/helper/EmailHelper";

DBConn.connectToDatabase().then(async seq => {
if (seq == null) return;

const now = dayjs.utc();

const query = (await seq.query(
`SELECT TR.id AS id, uuid, user_id, status, expires, first_name, last_name FROM training_requests as TR JOIN users U ON U.id = TR.user_id WHERE status = 'requested' AND expires <= ?`,
{
type: QueryTypes.SELECT,
replacements: [now.format("YYYY-MM-DD").toString()],
}
)) as any[];

// TODO: Add DB to store all the reminder E-Mail Dates.
// This is to ensure we only send one mail per Week
// In the backend, we can then delete all those corresponding to the request UUID :)

for (const request of query) {
const token = btoa(`${request.uuid}.${request.user_id}.${dayjs.utc(request.expires).unix()}`);
let replacements = {
name: request.first_name + " " + request.last_name,
expiry_date: dayjs.utc().format(Config.DATE_FORMAT),
link: `${Config.FRONTEND_URI}/confirm-interest?token=${token}`,
date_now: dayjs.utc().format(Config.DATETIME_FORMAT),
};

await EmailHelper.sendMail(
Config.APP_DEBUG ? Config.DEBUG_EMAIL : request.email,
"Weiteres Interesse an Trainings",
"reminder.html",
replacements,
true
);
}

await seq.close();
});
Loading

0 comments on commit 183400e

Please sign in to comment.