Skip to content

Commit

Permalink
Merge pull request #41 from ngVenezuela/develop
Browse files Browse the repository at this point in the history
Merge a master para #39
  • Loading branch information
leocabeza authored Jan 15, 2017
2 parents 0b4e8fd + f0b67d3 commit f309123
Show file tree
Hide file tree
Showing 10 changed files with 287 additions and 87 deletions.
4 changes: 1 addition & 3 deletions eslintrc.json → .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
}
}],
"max-len": ["error", 100],
"error": {
"properties": "never"
}
"error": 0
}
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"eslint.enable": true
}
9 changes: 7 additions & 2 deletions config/config.sample.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
const config = {
telegramToken: 'MY_SUPER_SECRET_TOKEN'
telegramToken: 'MY_SUPER_SECRET_TOKEN',
morningHour: 7,
groupId: -1001031605415,
// groupId: -165387746 //test group,
goodMorningRegExp: new RegExp('buen(os)*\\sd[ií]+as', 'iu'),
blogFeedUrl: 'http://ngvenezuela.org.ve/blog/feeds/all.atom.xml',
};

module.exports = config;
module.exports = config;
1 change: 1 addition & 0 deletions config/last-blog-pubDate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"lastPubDate":"2016-09-26T21:00:00.000Z"}
16 changes: 11 additions & 5 deletions config/messages.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var messages = {
const messages = {
welcomeMsg: 'Hola #{name}, bienvenido a ngVenezuela, te invitamos a ' +
'seguirnos en twitter `@ngVenezuela` y a unirte a nuestro grupo ' +
'en Google bit.ly/ng-venezuela-google-groups Puedes colocar tus ' +
Expand All @@ -10,16 +10,22 @@ var messages = {
fridays: [
'Buenos días. Recuerden que los viernes no se hacen deploy \u{1F601}',
'Buenos días. ¡Hoy es viernes y el hardware lo sabe!',
'Buenos días comunidad. Feliz viernes'
'Buenos días comunidad. Feliz viernes',
'Buenos días. Hoy cualquier bug es un feature después de las 4pm',
],
generic: [
'Buenos días...¿tomaron café? \u{2615}',
'Buenos días. Recuerden que detrás de una persona exitosa, ' +
'esta una gran cantidad de café \u{2615}',
'Buenos días. Keep calm and drink \u{2615}',
'Buenos días \u{1F601}\u{2615}',
'Buenos días',
'Buenos días a todos',
'Buenos días comunidad'
]
}
'Buenos días comunidad',
],
},
newBlogPost: '*#{author}* ha agregado una nueva entrada al blog titulada: *#{title}*' +
' y está disponible en: #{link}',
};

module.exports = messages;
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
},
"homepage": "https://github.com/ngVenezuela/wengy-ven#readme",
"dependencies": {
"node-telegram-bot-api": "0.23.3"
"node-telegram-bot-api": "0.25.0",
"feedparser": "2.0.0"
},
"devDependencies": {
"eslint": "3.13.1",
"eslint-config-google": "0.7.1",
"jsdoc": "3.4.3",
"nodemon": "1.11.0"
}
}
136 changes: 136 additions & 0 deletions src/blog-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
'use strict';

const FeedParser = require('feedparser');
const request = require('request');
const fs = require('fs');
const config = require('../config/config');
const events = require('events');

let feedparser = new FeedParser();
let eventEmitter = new events.EventEmitter();
let articles = [];
let lastPubDate;
let req;

setInterval(readLastPubDate, 60000 * 60 * 24); // check daily

module.exports = eventEmitter;

/**
* Check the blog feed for entries
*/
function makeRequest() {
req = request(config.blogFeedUrl);

/**
* We listen to the error event,
* in case there is an error with
* the request.
*/
req.on('error', (err) => {
feedparser.emit('error', new Error(err));
});

/**
* Listening to the response event,
* if it's an error, we emit an error, otherwise
* we pipe the stream to feedparser object.
*/
req.on('response', (res) => {
if (res.statusCode !== 200) {
feedparser.emit('error', new Error('Bad status code'));
} else {
req.pipe(feedparser);
}
});
}

/**
* Read the last article publication date
* from the config/last-blog-pubDate.json file.
*/
function readLastPubDate() {
try {
let data = fs.readFileSync('./config/last-blog-pubDate.json', 'utf8');
let parsed = JSON.parse(data);
lastPubDate = new Date(parsed.lastPubDate);
makeRequest();
} catch (err) {
feedparser.emit('error', new Error(err));
}
}

/**
* It updates the config/last-blog-pubDate.json
* file with the last article publication date
*/
function lookupFinished() {
if (articles.length > 0) { // assuming that first item is latest
try {
fs.writeFileSync(
'./config/last-blog-pubDate.json',
JSON.stringify({'lastPubDate': articles[0].pubDate}),
'utf8'
);
lastPubDate = undefined;
eventEmitter.emit('newArticles', articles);
articles = [];
} catch (err) {
feedparser.emit('error', new Error('Could not save file'));
}
}
};

/**
* we print errors in console.
* we capture 'lookupFinished' 'error' and
* execute corresponding function.
*/
feedparser.on('error', (error) => {
if (error === 'lookupFinished') {
lookupFinished();
} else {
console.log('error emitted: ', error);
}
});

/**
* If we get here, it means all of the
* blog entries are not yet posted in
* the telegram group
*/
feedparser.on('end', () => {
if (lastPubDate !== undefined) {
feedparser.emit('error', 'lookupFinished');
}
});

/**
* This function is executed, every time that an
* entry is found in the xml.
* It is also assumed that articles are fetched
* from latest to oldest.
*/
feedparser.on('readable', () => {
let item;

if (lastPubDate !== undefined) {
while (item = feedparser.read()) {
let itemPubDate = new Date(item.pubDate);
if (itemPubDate <= lastPubDate) {
/**
* This is the only way we can get
* out of the loop, is not an actual error.
*/
feedparser.emit('error', 'lookupFinished');
} else {
articles.push({
title: item.title,
author: item.author,
link: item.link,
pubDate: item.pubDate,
});
}
}
}
});
70 changes: 43 additions & 27 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
'use strict';

const telegramBot = require('node-telegram-bot-api');
const config = require('../config/config');
const messages = require('../config/messages');
const TelegramBot = require('node-telegram-bot-api');
const config = require('../config/config');
const messages = require('../config/messages');
const morningEvent = require('./morning-event');
const blogEvent = require('./blog-event');

const token = config.telegramToken;
// const groupId = -165387746; //test group
const groupId = -1001031605415;
const goodMorningRegExp = new RegExp('buen(os)*\\sd[ií]+as', 'iu');
let bot = new telegramBot(token, {polling: true});
const groupId = config.groupId;
const goodMorningRegExp = config.goodMorningRegExp;

let bot = new TelegramBot(token, {polling: true});
let goodMorningGivenToday = false;
let minuteToCheck = generateRandom(0, 59);

morningEvent.event
.on('minuteMark', function(vzlanHour, vzlanMinute, weekday) {
bot
.on('new_chat_participant', newChatParticipant)
.on('text', newText);

morningEvent
.on('minuteMark', (vzlanHour, vzlanMinute, weekday) => {
if (morningConditions(vzlanHour, vzlanMinute)) {
goodMorningGivenToday = true;
minuteToCheck = generateRandom(0, 59);
Expand All @@ -25,36 +30,47 @@ morningEvent.event
}

function morningConditions(vzlanHour, vzlanMinute) {
return !goodMorningGivenToday && vzlanHour === 7 && vzlanMinute === minuteToCheck;
return !goodMorningGivenToday && vzlanHour === config.morningHour
&& vzlanMinute === minuteToCheck;
}

function getMorningMsg(weekday) {
if (weekday === 1) {
// mondays
let randomIndex = generateRandom(0, messages.goodMornings.mondays.length - 1);
return messages.goodMornings.mondays[randomIndex];
} else if (weekday === 5) {
// fridays
let randomIndex = generateRandom(0, messages.goodMornings.fridays.length - 1);
return messages.goodMornings.fridays[randomIndex];
} else {
let randomIndex = generateRandom(0, messages.goodMornings.generic.length - 1);
return messages.goodMornings.generic[randomIndex];
}
let weekDays = {
0: 'generic',
1: 'mondays',
2: 'generic',
3: 'generic',
4: 'generic',
5: 'fridays',
6: 'generic',
};

let randomIndex = generateRandom(0, messages.goodMornings[weekDays[weekday]].length - 1);
return messages.goodMornings[weekDays[weekday]][randomIndex];
}
})
.on('newDay', function() {
.on('newDay', () => {
goodMorningGivenToday = false;
});

bot
.on('new_chat_participant', newChatParticipant)
.on('text', newText);
blogEvent
.on('newArticles', (articles) => {
articles.forEach((article) => {
bot.sendMessage(
groupId,
messages.newBlogPost
.replace('#{author}', article.author)
.replace('#{link}', article.link)
.replace('#{title}', article.title),
{parse_mode: 'Markdown'}
);
});
});

function newText(msg) {
if (!goodMorningGivenToday && isGoodMorningGiven(msg.text)) {
goodMorningGivenToday = true;
}
}

function isGoodMorningGiven(text) {
return goodMorningRegExp.test(text);
Expand Down
63 changes: 14 additions & 49 deletions src/morning-event.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,25 @@
'use strict';

const events = require ('events');
const events = require('events');
const timeUtility = require('./time-utility.js');
let eventEmitter = new events.EventEmitter();

setInterval(emitMinuteMark, 60000);
setInterval(emitMinuteMark, 60000); // 60 seconds

module.exports = eventEmitter;

/**
* this function emits an event
* with the current hour/minute &
* it also emits an event when it's
* a new day
*/
function emitMinuteMark() {
let vzlanHour = getVzlanHour();
let vzlanMinute = getVzlanMinute();
let vzlanHour = timeUtility.vzlanHour();
let vzlanMinute = timeUtility.vzlanMinute();

eventEmitter.emit('minuteMark', vzlanHour, vzlanMinute, getVzlanWeekday());
eventEmitter.emit('minuteMark', vzlanHour, vzlanMinute, timeUtility.vzlanWeekday());
if (vzlanHour === 0 && vzlanMinute == 0) {
eventEmitter.emit('newDay');
}
}

function getVzlanHour(date = new Date()) {
let vzlanTime = getVzlanTime(date);
let vzlanHour = vzlanTime.getUTCHours(); // 24 hours format (0-23)

return vzlanHour;
}

function getVzlanMinute(date = new Date()) {
let vzlanTime = getVzlanTime(date);
let vzlanMinute = vzlanTime.getUTCMinutes(); // 0-59

return vzlanMinute;
}

function getVzlanWeekday(date = new Date()) {
let vzlanTime = getVzlanTime(date);
let vzlanWeekDay = vzlanTime.getUTCDay(); // sunday = 0

return vzlanWeekDay;
}

function getVzlanTime(date) {
const vzlanOffset = 4;
let actualTime = new Date(
Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
0,0
)
);
let vzlanTimeInMs = actualTime.setUTCHours(date.getUTCHours() - vzlanOffset);
let vzlanTime = new Date(vzlanTimeInMs);

return vzlanTime;
}

module.exports = {
event: eventEmitter,
getVzlanHour: getVzlanHour
};
Loading

0 comments on commit f309123

Please sign in to comment.