diff --git a/README.md b/README.md new file mode 100644 index 0000000..11eada0 --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +# Ver.bot-notify + +
+ +
+
+ +
+ +[![node (6.10.x)](https://img.shields.io/badge/node-6.10.x-brightgreen.svg)]() +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SVRBTQKRQ5VGE) + +
+ +Ver.bot notify part. + +Webhook part in [here][4]. + +## Deploy by yourself + +**NOTE:** You should deploy the same **major version** as [webhook part][4]. + +### AWS Lambda(`master` branch) +1. install dependency +```bash +npm i +``` + +2. before deploy to AWS, [install AWS CLI][1] and [configure it][2]. + +3. create lambda function. + +4. set following environment variables. +``` +CHECK_DAYS +SKYPE_APP_ID +SKYPE_APP_SECRET +SLACK_BOT_TOKEN +TELEGRAM_BOT_TOKEN +``` + +5. If you want to update lambda function: +```bash +sh update-lambda.sh +``` + +6. set a cron job ( e.g. [CloudWatch Events][3]) to match `CHECK_DAYS` in environment variables. + + +### General server(`normal-server` branch) +1. install dependency +```bash +npm i +``` +2. set following environment variables. +``` +AWS_ACCESS_ID +AWS_SECRET_KEY +CHECK_DAYS +SKYPE_APP_ID +SKYPE_APP_SECRET +SLACK_BOT_TOKEN +TELEGRAM_BOT_TOKEN +``` +3. set a cron job to match `CHECK_DAYS` in environment variables. + + +## LICENSE +[AGPL-3.0](LICENSE) + +[1]: http://docs.aws.amazon.com/cli/latest/userguide/installing.html +[2]: http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html +[3]: http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html +[4]: https://github.com/RPing/Ver.bot diff --git a/bot.js b/bot.js index 034f1d6..c0deb5b 100644 --- a/bot.js +++ b/bot.js @@ -6,6 +6,11 @@ const site = require('./lib/site-utils') const checkTime = new Date() checkTime.setDate(checkTime.getDate() - process.env.CHECK_DAYS) // current time - CHECK_DAYS +const postNotifyMsg = + 'If you have any question, post an issue in\nhttps://github.com/RPing/Ver.bot-notify/issues\n' + + 'Or if you find some security issue, contact me\ng1222888@gmail.com\n' + + 'To support AWS Lambda and EC2 running, please donate\nhttps://goo.gl/9czXSn (paypal link)' + function needToNotify(results) { const hasNewVer = results.info.length > 0 const hasSubscriber = results.subscribers.length > 0 @@ -41,12 +46,42 @@ function notify(projectPlatform, projectName, releasePage, results, cb) { ) } +function postNotify(subscribers, cb) { + const fnList = [] + subscribers.forEach((subscriber) => { + fnList.push((inner_cb) => { + site.siteUtil(subscriber.platform) + .send(subscriber.id, postNotifyMsg, (err) => { + if (err) { + console.error('---- error when post-notify ----') + console.error(subscriber.platform, subscriber.id) + console.error(err) + return inner_cb(err) + } + inner_cb(null) + }) + }) + }) + + async.parallel( + async.reflectAll(fnList), + function parallelCallback(err, parallel_results) { + const hasSomeError = parallel_results.some(result => result.error !== undefined) + + cb(hasSomeError) + } + ) +} + function checkAndNotify(results, projectInfo, projectName, projectPlatform, cb) { if (needToNotify(results)) { async.series([ function (inner_cb) { const releasePage = site.siteUtil(projectPlatform).getReleasesPage(projectInfo) notify(projectPlatform, projectName, releasePage, results, inner_cb) + }, + function (inner_cb) { + postNotify(results.subscribers, inner_cb) } ], function seriesCallback(err) { if (err) diff --git a/lib/db.js b/lib/db.js index 08aa142..1581a04 100644 --- a/lib/db.js +++ b/lib/db.js @@ -64,7 +64,7 @@ exports.getAllSubscriber = function (project_name, cb) { ExpressionAttributeValues: { ':x': project_name }, - ProjectionExpression: 'subscriber_and_platform' + ProjectionExpression: 'subscriber_id, subscriber_platform' } function onQuery(err, data) { @@ -73,13 +73,9 @@ exports.getAllSubscriber = function (project_name, cb) { const list = [] data.Items.forEach((item) => { - const a = item.subscriber_and_platform.split('-') - const platform = subscriberPlatform(parseInt(a[1])) - const id = a[0] - list.push({ - platform: platform, - id: id + platform: subscriberPlatform(item.subscriber_platform), + id: item.subscriber_id }) }) diff --git a/lib/sites/project/github.js b/lib/sites/project/github.js index 3f80a54..5835fc5 100644 --- a/lib/sites/project/github.js +++ b/lib/sites/project/github.js @@ -23,7 +23,7 @@ class Github { getNewVersionInfo(check_date, project, cb) { const url = `https://github.com/${project.project_author}/${project.project_name}/releases.atom` - const req = request(url, { timeout: 1500 }) + const req = request(url, { timeout: 3000 }) const feedparser = new FeedParser({ addmeta: false }) const info = [] diff --git a/lib/sites/subscriber/skype.js b/lib/sites/subscriber/skype.js index 80efe91..022c38d 100644 --- a/lib/sites/subscriber/skype.js +++ b/lib/sites/subscriber/skype.js @@ -11,6 +11,18 @@ class skype { _singleton = this } + send(chat_id, msg, cb) { + const appId = process.env.SKYPE_APP_ID + const appSecret = process.env.SKYPE_APP_SECRET + + this._requestToken(appId, appSecret, (err, token) => { + if (err) + return cb(err) + + this._sendMsg(token, chat_id, msg, cb) + }) + } + notify(chat_id, project_name, release_page, version_info, cb) { const appId = process.env.SKYPE_APP_ID const appSecret = process.env.SKYPE_APP_SECRET diff --git a/lib/sites/subscriber/slack.js b/lib/sites/subscriber/slack.js index 6c7270f..3aace79 100644 --- a/lib/sites/subscriber/slack.js +++ b/lib/sites/subscriber/slack.js @@ -13,6 +13,32 @@ class slack { _singleton = this } + send(chat_id, msg, cb) { + const bot_token = process.env.SLACK_BOT_TOKEN + const options = { + url: 'https://slack.com/api/chat.postMessage', + method: 'POST', + timeout: 3000, + form: { + token: bot_token, + text: msg, + channel: chat_id, + }, + } + + request(options, (err, res) => { + if (err) + return cb(err) + + if (typeof res === 'undefined') + return cb(new Error(`Timeout Error. res object is ${res}`)) + else if (res.statusCode !== 200) + return cb(new Error(`res code is ${res.statusCode}`)) + + cb(null) + }) + } + notify(chat_id, project_name, release_page, version_info, cb) { const bot_token = process.env.SLACK_BOT_TOKEN const options = { diff --git a/lib/sites/subscriber/telegram.js b/lib/sites/subscriber/telegram.js index 6e458fc..9d9fcf9 100644 --- a/lib/sites/subscriber/telegram.js +++ b/lib/sites/subscriber/telegram.js @@ -13,6 +13,32 @@ class telegram { _singleton = this } + send(chat_id, msg, cb) { + const bot_token = process.env.TELEGRAM_BOT_TOKEN + const options = { + url: `https://api.telegram.org/bot${bot_token}/sendMessage`, + method: 'POST', + timeout: 3000, + json: { + chat_id: chat_id, + text: msg, + parse_mode: 'Markdown', + }, + } + + request(options, (err, res) => { + if (err) + return cb(err) + + if (typeof res === 'undefined') + return cb(new Error(`Timeout Error. res object is ${res}`)) + else if (res.statusCode !== 200) + return cb(new Error(`res code is ${res.statusCode}`)) + + cb(null) + }) + } + notify(chat_id, project_name, release_page, version_info, cb) { const bot_token = process.env.TELEGRAM_BOT_TOKEN const options = {