-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
103 lines (89 loc) · 3.1 KB
/
index.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
const express = require('express');
const fetch = require('node-fetch');
const cors = require('cors');
const rp = require('request-promise');
const token = process.env.EVENTBRITE_TOKEN;
const organizer = process.env.ORGANIZER_TOKEN;
const cache = {
eventId: null,
attendees: []
}
console.log(`Starting lottery for ${organizer} with token ${token}`);
const range = (start, end) => {
let pages = []
for (var i = start ; i < end; i++) {
pages.push(i);
}
return pages
}
const get = (path) => fetch(path).then(payload => payload.json())
const getRandomIds = (max, numbers) => {
if (numbers >= max) {
return range(0, max)
}
console.log(`Generating ${numbers} random numbers for ${max}`)
return range(0, numbers).reduce((acc, _) => {
let index
do {
index = Math.floor(Math.random() * max)
} while (acc.includes(index));
acc.push(index)
return acc
}, [])
}
const getAttendees = (event_id) => {
return get(`https://www.eventbriteapi.com/v3/events/${event_id}/attendees/?token=${token}`)
.then(attendees =>
Promise.all(
range(attendees.pagination.page_number +1, attendees.pagination.page_count)
.reduce((acc, val) => acc.concat([get(`https://www.eventbriteapi.com/v3/events/${event_id}/attendees?token=${token}&page=${val}`).then(data => data.attendees)]), attendees.attendees))
.then(values => [].concat.apply([], values))
)
}
const errorRequest = (res, status, error) => {
console.error(error)
res.status(status);
res.json(error);
}
const fetchCache = () => {
get(`https://www.eventbriteapi.com/v3/events/search/?sort_by=date&organizer.id=${organizer}&token=${token}`)
.then(data => {
if (data.events.length < 1) {
return Promise.reject(new Error("No event available"))
}
cache.eventId = data.events[0].id
return cache.eventId
})
.then(event_id => getAttendees(event_id))
.then(attendees => cache.attendees = attendees)
.catch(error => cache.eventId = null)
.then(_ => setTimeout(fetchCache, 3600000));
}
const app = express();
app.use(cors());
app.get('/winners', function(req, res){
const nb_winner = req.query.nb
if (nb_winner == undefined || isNaN(nb_winner) || nb_winner < 0) {
res.status(400)
res.json({error: 'Nb param should be a positive integer'})
} else if (nb_winner == 0) {
res.json([])
} else {
console.log(`Generating ${nb_winner} winners`)
new Promise((success, reject) => {
if (cache.eventId == null) {
reject(new Error("No event available"))
} else {
success(cache.attendees)
}
}).then(attendees => getRandomIds(attendees.length, nb_winner).map((index) => attendees[index]))
.then(winners => {console.log("Found winners"); return winners})
.then(winners => winners.map(({profile: {first_name: first_name, last_name: last_name}}) => { return {first_name: first_name, last_name: last_name}}))
.then(winners => res.json(winners))
.catch(error => errorRequest(res, 500, error))
}
});
console.log("Start cache warmup")
fetchCache()
console.log("Start web server")
app.listen(3000);