diff --git a/README.md b/README.md index d9f30ca..d6521cf 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,81 @@ p.send( msg, function( err, result ) { }) ``` +### Sending a message with an attachment (blocking) +```javascript + +var Push = require( 'pushover-notifications' ) + +var p = new Push( { + user: process.env['PUSHOVER_USER'], + token: process.env['PUSHOVER_TOKEN'], + // httpOptions: { + // proxy: process.env['http_proxy'], + //}, + // onerror: function(error) {}, + // update_sounds: true // update the list of sounds every day - will + // prevent app from exiting. +}) + +var msg = { + // These values correspond to the parameters detailed on https://pushover.net/api + // 'message' is required. All other values are optional. + message: 'omg node test', // required + title: "Well - this is fantastic", + sound: 'magic', + device: 'devicename', + priority: 1, + file: '/tmp/fantastic.png' // this will read using fs.readFileSync()! +} + +p.send( msg, function( err, result ) { + if ( err ) { + throw err + } + + console.log( result ) +}) +``` + +### Sending a message with an attachment (non-blocking) +```javascript + +var Push = require( 'pushover-notifications' ) +var fs = require( 'fs' ) + +fs.readFile('/tmp/fantastic.png', function(err, data) { + var p = new Push( { + user: process.env['PUSHOVER_USER'], + token: process.env['PUSHOVER_TOKEN'], + // httpOptions: { + // proxy: process.env['http_proxy'], + //}, + // onerror: function(error) {}, + // update_sounds: true // update the list of sounds every day - will + // prevent app from exiting. + }) + + var msg = { + // These values correspond to the parameters detailed on https://pushover.net/api + // 'message' is required. All other values are optional. + message: 'omg node test', // required + title: "Well - this is fantastic", + sound: 'magic', + device: 'devicename', + priority: 1, + file: { name: 'fantastic.png', data: data } + } + + p.send( msg, function( err, result ) { + if ( err ) { + throw err + } + + console.log( result ) + }) +}) +``` + ### Sending a message to multiple users ```javascript @@ -80,6 +155,8 @@ var msg = { title: "Well - this is fantastic", sound: 'magic' // optional priority: 1 // optional, + file: '/tmp/fancy_image.png' // optional + // see test/test_img.js for more examples of attaching images } for ( var i = 0, l = users.length; i < l; i++ ) { diff --git a/lib/pushover.js b/lib/pushover.js index 04c7964..e3721a9 100644 --- a/lib/pushover.js +++ b/lib/pushover.js @@ -1,8 +1,10 @@ +var fs = require('fs') var https = require('https') var http = require('http') var url = require('url') var qs = require('querystring') var pUrl = 'https://api.pushover.net/1/messages.json' +var path = require('path') function setDefaults (o) { var def = [ @@ -26,8 +28,62 @@ function setDefaults (o) { return o } +function loadImage(imgPath) { + var o = {} + o.name = path.basename(imgPath) + o.data = fs.readFileSync(imgPath) + return o +} + + +function reqString2MP(rs, b, imgObj) { + var a = [] + var parts = [] + var o = qs.parse(rs) + + a.push(b) + + for (var p in o) { + if (o[p] !== '') { + a.push('Content-Disposition: form-data; name="' + p + '"') + a.push("") + a.push(o[p]) + a.push(b) + } + } + + if (imgObj) { + a.push('Content-Disposition: form-data; name="attachment"; filename="' + imgObj.name + '"') + if (imgObj.hasOwnProperty('type')) { + a.push('Content-Type: ' + imgObj.type) + } else { + a.push('Content-Type: application/octet-stream') + } + a.push('') + a.push('') + } else { + a.splice(-1, 1) + } + + var payload + if (imgObj) { + payload = Buffer.concat([ + Buffer.from(a.join('\r\n'), 'utf8'), + Buffer.from(imgObj.data, 'binary'), + Buffer.from('\r\n' + b + '--\r\n', 'utf8') + ]) + } else { + payload = Buffer.concat([ + Buffer.from(a.join('\r\n'), 'utf8'), + Buffer.from(b + '--\r\n', 'utf8') + ]) + } + return payload +} + function Pushover (opts) { var self = this + this.boundary = "--" + Math.random().toString(36).substring(2) this.token = opts.token this.user = opts.user this.httpOptions = opts.httpOptions @@ -72,6 +128,7 @@ function Pushover (opts) { } } + Pushover.prototype.errors = function (d, res) { if (typeof d === 'string') { d = JSON.parse(d) @@ -125,13 +182,30 @@ Pushover.prototype.send = function (obj, fn) { var p for (p in obj) { - reqString[ p ] = obj[p] + if (obj[p] !== '') { + if (p !== 'file') { + reqString[ p ] = obj[p] + } + } } reqString = qs.stringify(reqString) + var mp + if (obj.file) { + if (typeof obj.file === 'string') { + mp = reqString2MP(reqString, self.boundary, loadImage(obj.file)) + } + if (typeof obj.file === 'object') { + mp = reqString2MP(reqString, self.boundary, obj.file) + } + } else { + mp = reqString2MP(reqString, self.boundary) + } + o.headers = { - 'Content-Length': reqString.length + 'Content-type': 'multipart/form-data; boundary=' + self.boundary.substring(2), + 'Content-Length': mp.length } var httpOpts = self.httpOptions || {} @@ -151,7 +225,7 @@ Pushover.prototype.send = function (obj, fn) { } var request - if (httpOpts.proxy && httpOpts.proxy !== '') { + if ((httpOpts.proxy && httpOpts.proxy !== '') || pUrl.match(/http:/)) { request = http.request } else { request = https.request @@ -187,7 +261,8 @@ Pushover.prototype.send = function (obj, fn) { if (self.debug) { console.log(reqString.replace(self.token, 'XXXXX').replace(self.user, 'XXXXX')) } - req.write(reqString) + + req.write(mp) req.end() } diff --git a/test/test-onerror.js b/test/test-onerror.js index b2e07cf..b899ea2 100644 --- a/test/test-onerror.js +++ b/test/test-onerror.js @@ -25,7 +25,5 @@ var msg = { } p.send(msg, function (err, result, res) { - console.log('error', err) - console.log('result', result) - console.log('res.headers', res.headers) + console.log('====> On error test') }) diff --git a/test/test.js b/test/test.js index a97564f..482e6ab 100644 --- a/test/test.js +++ b/test/test.js @@ -13,11 +13,11 @@ var msg = { title: 'Well - this is fantastic' } -// console.log( p ); - p.send(msg, function (err, result, res) { - console.log('error', err) - console.log('result', result) - console.log('res.headers', res.headers) - // process.exit(0); + console.log('====> Regular test') + if (err) { + console.log(err) + process.exit(1) + } + process.exit(0) }) diff --git a/test/test_img.js b/test/test_img.js new file mode 100644 index 0000000..29b6b1b --- /dev/null +++ b/test/test_img.js @@ -0,0 +1,55 @@ +var Push = require('../lib/pushover.js') +var fs = require('fs') + +var p = new Push({ + user: process.env['PUSHOVER_USER'], + token: process.env['PUSHOVER_TOKEN'], + update_sounds: false, + debug: true +}) + +var msg = { + message: 'test from ' + process.argv[1], + sound: 'magic', + title: 'Image loaded sync', + file: 'test/test_img.png' +} + +p.send(msg, function (err, result, res) { + console.log('====> Sync image test') + if (err) { + console.log(err) + process.exit(1) + } + process.exit(0) +}) + +fs.readFile('test/test_img.png', function(err, data) { + var ap = new Push({ + user: process.env['PUSHOVER_USER'], + token: process.env['PUSHOVER_TOKEN'], + update_sounds: false, + debug: true + }) + + var o = { + name: 'pushover.png', + data: data + } + + var amsg = { + message: 'test from ' + process.argv[1], + sound: 'magic', + title: 'Image loaded async', + file: o + } + + ap.send(msg, function (err, result, res) { + console.log('====> Async image test') + if (err) { + console.log(err) + process.exit(1) + } + process.exit(0) + }) +}) diff --git a/test/test_img.png b/test/test_img.png new file mode 100644 index 0000000..f853575 Binary files /dev/null and b/test/test_img.png differ diff --git a/test/test_multi.js b/test/test_multi.js index 1762770..1982160 100644 --- a/test/test_multi.js +++ b/test/test_multi.js @@ -12,10 +12,11 @@ var msg = { user: process.env['PUSHOVER_USER'] } -// console.log( p ); - p.send(msg, function (err, result) { - console.log(err) - console.log(result) + console.log('====> Multi test') + if (err) { + console.log(err) + process.exit(1) + } process.exit(0) }) diff --git a/test/test_proxy.js b/test/test_proxy.js index e70087e..56fce1a 100644 --- a/test/test_proxy.js +++ b/test/test_proxy.js @@ -16,10 +16,11 @@ var msg = { title: 'test from' } -// console.log( p ); - p.send(msg, function (err, result) { - console.log('error', err) - console.log('result', result) - // process.exit(0); + console.log('====> Proxy test') + if (err) { + console.log(err) + process.exit(1) + } + process.exit(0) })