Last active
August 10, 2018 04:22
-
-
Save cameri/8d04222eb3f6417668ee85fb4cfb70db to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const moment = require('moment') | |
/** | |
* Draws table fields | |
*/ | |
const FIELDS = [ | |
'draws.draw_date', | |
'draws.lowest_crs', | |
'draws.invitations_issued', | |
'draws.tie_break', | |
'draws.date_modified', | |
'draws.hash' | |
] | |
/** | |
* Gets the latest known draw from database | |
* @param {any} db Database instance | |
*/ | |
async function getLatestRecordedDraw (db) { | |
const [ result ] = await db.select(FIELDS) | |
.from('express_entry_draws as draws') | |
.orderBy('draws.date_modified', 'DESC') | |
.limit(1) | |
const recordedDraw = { | |
...result, | |
draw_date: moment.utc(result.draw_date), | |
date_modified: moment.utc(result.date_modified), | |
tie_break: moment.utc(result.tie_break) | |
} | |
return recordedDraw | |
} | |
/** | |
* Persists a draw to database | |
* @param {any} db Database instance | |
* @param {any} draw Draw record | |
*/ | |
function save (db, draw) { | |
return db('express_entry_draws').insert(draw) | |
} | |
const API = { | |
save, | |
getLatestRecordedDraw | |
} | |
module.exports = API |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const axios = require('axios') | |
const Promise = require('bluebird') | |
const {logger} = require('./util') | |
const readFileAsync = Promise.promisify(require('fs').readFile) | |
const config = require('../config/config') | |
const DEFAULT_TEMPLATE_PATH = './templates/telegram-message-text.html' | |
const DEFAULT_HEADERS = { | |
headers: { | |
'Cache-Control': 'no-cache' | |
} | |
} | |
/** | |
* Gets the template from a gist or from a local file | |
*/ | |
async function getGist () { | |
logger.debug('getGist()') | |
try { | |
const response = await axios.get(config.telegram_message_text_url, { ...DEFAULT_HEADERS }) | |
return response.data | |
} catch (err) { | |
if (err.status === 404) { | |
return getTemplateFromDisk() | |
} | |
logger.error('getGist() unexpected error: %s. err.stack: %s', err, err.stack) | |
throw err | |
} | |
} | |
/** | |
* Gets template from disk | |
*/ | |
async function getTemplateFromDisk () { | |
logger.debug('getTemplateFromDisk()') | |
return readFileAsync(DEFAULT_TEMPLATE_PATH, 'utf8') | |
} | |
const API = { | |
getGist | |
} | |
module.exports = API |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const { compile } = require('handlebars') | |
const db = require('./db/knex') | |
const { logger, emoji } = require('./util') | |
const { DrawsDao, DrawChatsDao } = require('./db/dao') | |
const { getCurrentDraw } = require('./express-entry-rounds-service') | |
const { sendTelegramMessage } = require('./telegram-service') | |
const { getGist } = require('./gist-service') | |
/** | |
* Date format to be used when displaying the draw date | |
* @see {@link https://momentjs.com/docs/#/displaying/format/|Format} | |
*/ | |
const DRAW_DATE_FORMAT = 'MMMM DD YYYY' | |
/** | |
* Inflates a message template with emojis and information about the draw | |
* @param {string} template Message template | |
* @param {any} drawData Current draw information | |
* @returns {string} Message text | |
*/ | |
function prepareMessageText (template, drawData) { | |
logger.debug('prepareMessageText() drawData: %s', JSON.stringify(drawData)) | |
const date = drawData.draw_date.format(DRAW_DATE_FORMAT) | |
const context = { ...drawData, date, emoji } | |
return compile(template)(context) | |
} | |
/** | |
* Gets list of chats from DB | |
* @param {string} template | |
* @param {*} data | |
*/ | |
async function sendUpdates (template, data) { | |
logger.debug('sendUpdates() data: %s', JSON.stringify(data)) | |
// Prepare text message to be sent | |
const text = await prepareMessageText(template, data) | |
// Get array of chats from DB | |
const chats = await DrawChatsDao.getAll(db.getInstance()) | |
// Sends message to each chat sequentially | |
return chats.forEach(async ({ chat_id: chatId }) => { | |
try { | |
await sendTelegramMessage(chatId, text) | |
} catch (err) { | |
logger.error('sendUpdates() Unable to send message to chat with Id %s. Reason: %s', chatId, err) | |
} | |
}) | |
} | |
/** | |
* Gets latest draw from CIC, previously saved draw, compares | |
* both and sends an update to chat rooms if there's a new draw | |
*/ | |
async function run () { | |
try { | |
// Get latest recorded draw from database and current draw from CIC in parallel | |
const [ previous, current ] = await Promise.all([ | |
DrawsDao.getLatestRecordedDraw(db.getInstance()), | |
getCurrentDraw() | |
]) | |
logger.debug('run() previous draw: %s. current draw: %s', JSON.stringify(previous), JSON.stringify(current)) | |
if (previous.draw_date.isBefore(current.draw_date)) { | |
// Save new draw | |
await DrawsDao.save(db.getInstance(), current) | |
// Get message template from gist | |
const template = await getGist() | |
// Send updates to chats | |
await sendUpdates(template, current) | |
} | |
} finally { | |
// Release db connection(s) | |
db.release() | |
} | |
} | |
const API = { | |
run | |
} | |
module.exports = API |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const axios = require('axios') | |
const config = require('../config/config') | |
const { logger } = require('./util') | |
const TELEGRAM_API_BASE_URL = 'https://api.telegram.org/bot' | |
/** | |
* Sends a text message to a Telegram chat | |
* @param {number} chatId Telegram Chat ID | |
* @param {string} text Message text | |
*/ | |
function sendTelegramMessage (chatId, text) { | |
logger.debug('sendTelegramMessage() chatId:', chatId, 'text:', text) | |
return axios.get(getSendTelegramMessageUrl(config.telegram_api_key), { | |
params: { | |
text, | |
chat_id: chatId, | |
parse_mode: 'HTML' | |
} | |
}) | |
} | |
/** | |
* Gets the URL for Telegram's sendMessage endpoint | |
* @param {string} apiKey Telegram Bot Api Key | |
* @returns {string} Telegram's sendMessage endpoint URL | |
*/ | |
function getSendTelegramMessageUrl (apiKey) { | |
return `${TELEGRAM_API_BASE_URL}${apiKey}/sendMessage` | |
} | |
const API = { | |
sendTelegramMessage | |
} | |
module.exports = API |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment