-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
131 lines (117 loc) · 4.27 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
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
'use strict';
const request = require('request-promise');
const mongoose = require('mongoose');
const Promise = require('bluebird');
const sources = require('./resource/source.json');
const FacebookEvent = mongoose.model('FacebookEvent', mongoose.Schema({
id: String
}));
/*
* Use mongo db to store visited event IDs
*/
const mongoUri = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/rc_test';
const db = mongoose.createConnection(mongoUri, {promiseLibrary: Promise});
mongoose.connect(mongoUri);
db.on('error', console.error.bind(console, 'connection error'));
db.once('open', function callback () {
console.log('Connection with database succeeded.');
});
function getFacebookEvents (accountName) {
const events = [];
function getPage (uri) {
return request(uri)
.then(body => {
body = JSON.parse(body);
events.push(...body.data);
if (body.paging.next) {
return getPage(body.paging.next);
} else {
return events;
}
});
}
return getPage(`https://graph.facebook.com/v2.8/${accountName}/events?access_token=${process.env.FB_TOKEN}&limit=100&fields=id,name,description,start_time,attending_count,place,interested_count`);
}
function postNewEvent (source, event) {
if (source === 'resistance-calendar') {
return Promise.resolve(null);
} else {
return request({
uri: process.env.SLACK_ENDPOINT,
method: 'POST',
json: true,
body: {
text: `${source}: <https://www.facebook.com/events/${event.id}|${event.name}> (${event.attending_count} attending, ${event.interested_count} interested)`
}
});
}
}
function filterFacebookEvents (now, facebookEvents) {
const upcomingEvents = facebookEvents.filter(event => {
const eventStartTime = new Date(event.start_time);
return eventStartTime > now;
});
// In order to avoid posting low attended events to the slack
// channel, only add events above some threshold of attendance.
// Subsequent runs of this servce will eventually add the events
// once they meet this threshold
const attendedEvents = upcomingEvents.filter(event => {
return event.attending_count > 5;
});
return attendedEvents;
}
function main () {
const now = new Date();
// Lazily load all events from the resistance-calendar page to initialize the
// database so that already added events are ignored and the process does
// not require an additional initialization step
getFacebookEvents('resistance-calendar')
.then(facebookEvents => {
const events = filterFacebookEvents(now, facebookEvents);
events.forEach(function (event) {
FacebookEvent.findOne({id: event.id}, function (err, doc) {
if (err) console.err(err);
if (!doc) {
const mongoEvent = new FacebookEvent({id: event.id});
mongoEvent.save(function (err) {
if (err) console.err(err);
});
}
});
});
}).then(() => {
// Iterate over entries in the facebook array in the organizations list
sources['facebook'].forEach(function (source) {
return getFacebookEvents(source)
.then(facebookEvents => {
const events = filterFacebookEvents(now, facebookEvents);
console.log(`Found ${events.length} upcoming and semi-attended events for ${source}.`);
events.sort((a, b) => b.attending_count - a.attending_count);
function sendNextEvent () {
const event = events.pop();
FacebookEvent.findOne({id: event.id}, function (err, doc) {
if (err) console.err(err);
if (!doc) {
postNewEvent(source, event)
.then(() => {
const mongoEvent = new FacebookEvent({id: event.id});
mongoEvent.save(function (err) {
if (err) console.err(err);
console.log('. ');
});
});
}
});
if (events.length) {
setTimeout(sendNextEvent, 1000);
}
}
if (events.length) sendNextEvent();
})
.then(() => {
console.log(`Updates for ${source} complete`);
});
});
});
}
main();