/
scene.checkCalendarTriggers.js
137 lines (130 loc) · 4.25 KB
/
scene.checkCalendarTriggers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const { Op } = require('sequelize');
const Promise = require('bluebird');
const dayjs = require('dayjs');
require('dayjs/locale/en');
require('dayjs/locale/fr');
const LocalizedFormat = require('dayjs/plugin/localizedFormat');
const db = require('../../models');
const logger = require('../../utils/logger');
const { EVENTS } = require('../../utils/constants');
dayjs.extend(LocalizedFormat);
/**
* @description Run every minute to check if a calendar event match
* @returns {Promise} Resolve.
* @example
* gladys.scene.checkCalendarTriggers()
*/
async function checkCalendarTriggers() {
// getting a fixed value for now, as soon as possible in the function
const now = dayjs.tz(dayjs(), this.timezone);
logger.info(`Checking calendar triggers at ${now}`);
// First, we try to constitute a list of triggers
// related to calendars events
const calendarEventTriggers = [];
Object.keys(this.scenes).forEach((sceneSelector) => {
// we check if the scene has triggers and is active
if (
this.scenes[sceneSelector].triggers &&
this.scenes[sceneSelector].triggers instanceof Array &&
this.scenes[sceneSelector].active
) {
this.scenes[sceneSelector].triggers.forEach((trigger) => {
if (trigger.type === EVENTS.CALENDAR.EVENT_IS_COMING) {
calendarEventTriggers.push({ sceneSelector, trigger });
}
});
}
});
const idsOfEventsMatching = [];
await Promise.each(calendarEventTriggers, async ({ sceneSelector, trigger }) => {
logger.debug(
`Checking calendar trigger ${trigger.calendar_event_name_comparator} ${trigger.calendar_event_name} ${trigger.duration} ${trigger.unit}`,
);
const generatedDate = now.add(trigger.duration, trigger.unit);
const twentyFiveSecondBefore = new Date(generatedDate.valueOf() - 25 * 1000);
const twentyFiveSecondAfter = new Date(generatedDate.valueOf() + 25 * 1000);
const queryParams = {
include: [
{
model: db.Calendar,
as: 'calendar',
include: [
{
model: db.User,
as: 'creator',
attributes: ['firstname', 'language'],
},
],
},
],
where: {
[trigger.calendar_event_attribute]: {
[Op.gte]: twentyFiveSecondBefore,
[Op.lte]: twentyFiveSecondAfter,
},
'$calendar.selector$': {
[Op.in]: trigger.calendars,
},
'$calendar.shared$': true,
},
};
// eslint-disable-next-line default-case
switch (trigger.calendar_event_name_comparator) {
// do nothing in that case
case 'has-any-name':
break;
case 'is-exactly':
// @ts-ignore
queryParams.where.name = trigger.calendar_event_name;
break;
case 'contains':
// @ts-ignore
queryParams.where.name = {
[Op.like]: `%${trigger.calendar_event_name}%`,
};
break;
case 'starts-with':
// @ts-ignore
queryParams.where.name = {
[Op.startsWith]: trigger.calendar_event_name,
};
break;
case 'ends-with':
// @ts-ignore
queryParams.where.name = {
[Op.endsWith]: trigger.calendar_event_name,
};
break;
}
// we search in the database if we find events that match our request
const eventsMatching = await db.CalendarEvent.findAll(queryParams);
// foreach event matching
await Promise.each(eventsMatching, (eventMatching) => {
const eventRaw = eventMatching.get({ plain: true });
idsOfEventsMatching.push(eventRaw.id);
const eventFormatted = {
name: eventRaw.name,
location: eventRaw.location,
start: dayjs(eventRaw.start)
.tz(this.timezone)
.locale(eventRaw.calendar.creator.language)
.format('LLL'),
end: dayjs(eventRaw.end)
.tz(this.timezone)
.locale(eventRaw.calendar.creator.language)
.format('LLL'),
};
// we start the scene of this trigger
this.execute(sceneSelector, {
triggerEvent: {
type: EVENTS.CALENDAR.EVENT_IS_COMING,
calendarEvent: eventFormatted,
},
});
});
});
return idsOfEventsMatching;
}
module.exports = {
checkCalendarTriggers,
};