Skip to content

Commit 56bdf92

Browse files
committed
demo script for email notifications
1 parent ca68c6a commit 56bdf92

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Trigger and render demo Email Notifications.
2+
3+
This script does 2 things:
4+
5+
- update demo data created by `npm run local:init` inside the DB in such a way that it would create situation for Email Notifications which would be triggered by the scheduler to demonstrate all possible cases.
6+
- start Kafka Consumer that would listen to the Kafka Topic `config.NOTIFICATIONS_CREATE_TOPIC` and if there is email notification created, it would render it using provided email template `data/notifications-email-template.html` into `out` folder.
7+
8+
## Usage
9+
10+
1. Config scheduler to run more often so we don't have to wait to long for triggering notification, like every minute:
11+
12+
```sh
13+
CRON_CANDIDATE_REVIEW=0 */1 * * * *
14+
CRON_INTERVIEW_COMING_UP=0 */1 * * * *
15+
CRON_INTERVIEW_COMPLETED=0 */1 * * * *
16+
CRON_POST_INTERVIEW=0 */1 * * * *
17+
CRON_UPCOMING_RESOURCE_BOOKING=0 */1 * * * *
18+
```
19+
20+
2. Recreate demo data by:
21+
22+
```sh
23+
npm run local:init`
24+
25+
3. Run TaaS API by:
26+
27+
```sh
28+
npm run dev
29+
```
30+
31+
4. Run this demo script:
32+
33+
```sh
34+
node scripts/demo-email-notifications
35+
```
36+
37+
Check the rendered emails inside `out` folder.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const Kafka = require('no-kafka')
2+
const fs = require('fs')
3+
const config = require('config')
4+
const moment = require('moment')
5+
const handlebars = require('handlebars')
6+
const logger = require('../../src/common/logger')
7+
const { Interview, JobCandidate, ResourceBooking } = require('../../src/models')
8+
const { Interviews } = require('../../app-constants')
9+
10+
const consumer = new Kafka.GroupConsumer({ connectionString: process.env.KAFKA_URL, groupId: 'test-render-email' })
11+
12+
const localLogger = {
13+
debug: message => logger.debug({ component: 'render email content', context: 'test', message }),
14+
info: message => logger.info({ component: 'render email content', context: 'test', message })
15+
}
16+
17+
const template = handlebars.compile(fs.readFileSync('./data/notifications-email-template.html', 'utf8'))
18+
19+
/**
20+
* Reset notification records
21+
*/
22+
async function resetNotificationRecords () {
23+
// reset coming up interview records
24+
localLogger.info('reset coming up interview records')
25+
const interview = await Interview.findById('976d23a9-5710-453f-99d9-f57a588bb610')
26+
const startTimestamp = moment().add(moment.duration(`PT1H`)).add('PT1M').toDate()
27+
await interview.update({ startTimestamp, duration: 30, status: Interviews.Status.Scheduled, guestNames: ['test1', 'test2'], hostName: 'hostName' })
28+
29+
// reset completed interview records
30+
localLogger.info('reset completed interview records')
31+
const pastTime = moment.duration('PT1H')
32+
const endTimestamp = moment().subtract(pastTime).toDate()
33+
const completedInterview = await Interview.findById('9efd72c3-1dc7-4ce2-9869-8cca81d0adeb')
34+
const duration = 30
35+
const completedStartTimestamp = moment().subtract(pastTime).subtract(30, 'm').toDate()
36+
await completedInterview.update({ startTimestamp: completedStartTimestamp, duration, endTimestamp, status: Interviews.Status.Scheduled, guestNames: ['guest1', 'guest2'], hostName: 'hostName' })
37+
38+
// reset post interview candidate action reminder records
39+
localLogger.info('reset post interview candidate action reminder records')
40+
const jobCandidate = await JobCandidate.findById('881a19de-2b0c-4bb9-b36a-4cb5e223bdb5')
41+
await jobCandidate.update({ status: 'interview' })
42+
const c2Interview = await Interview.findById('077aa2ca-5b60-4ad9-a965-1b37e08a5046')
43+
await c2Interview.update({ startTimestamp: completedStartTimestamp, duration, endTimestamp, guestNames: ['guest1', 'guest2'], hostName: 'hostName' })
44+
45+
// reset upcoming resource booking expiration records
46+
localLogger.info('reset upcoming resource booking expiration records')
47+
const resourceBooking = await ResourceBooking.findById('62c3f0c9-2bf0-4f24-8647-2c802a39cbcb')
48+
await resourceBooking.update({ endDate: moment().add(1, 'weeks').toDate() })
49+
}
50+
51+
/**
52+
* Init consumer.
53+
*/
54+
async function initConsumer () {
55+
await consumer
56+
.init([{
57+
subscriptions: [config.NOTIFICATIONS_CREATE_TOPIC],
58+
handler: async (messageSet, topic, partition) => {
59+
localLogger.debug(`Consumer handler. Topic: ${topic}, partition: ${partition}, message set length: ${messageSet.length}`)
60+
for (const m of messageSet) {
61+
const message = JSON.parse(m.message.value.toString('utf8'))
62+
if (!fs.existsSync('out')) {
63+
fs.mkdirSync('out')
64+
}
65+
if (message.payload.notifications) {
66+
message.payload.notifications.forEach((notification) => {
67+
const email = template(notification.details.data)
68+
fs.writeFileSync(`./out/${notification.details.data.subject}-${Date.now()}.html`, email)
69+
})
70+
}
71+
}
72+
}
73+
}])
74+
.then(() => {
75+
localLogger.info('Initialized.......')
76+
localLogger.info([config.NOTIFICATIONS_CREATE_TOPIC])
77+
localLogger.info('Kick Start.......')
78+
}).catch(err => {
79+
logger.logFullError(err, { component: 'app' })
80+
})
81+
}
82+
83+
/**
84+
* Main function
85+
*/
86+
async function main () {
87+
await resetNotificationRecords()
88+
await initConsumer()
89+
}
90+
91+
main()

0 commit comments

Comments
 (0)