Socket
Socket
Sign inDemoInstall

node-notifier

Package Overview
Dependencies
6
Maintainers
1
Versions
73
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.4.1 to 4.0.0

test/index.js

36

CHANGELOG.md
Changelog
===
### `v4.0.0`
Major changes and breaking API.
1. require('node-notifier') now returns an instance with fallbackable notifications.
```js
var notifier = require('node-notifier');
notifier.notify();
```
2. Introduced a `wait` property (default `false`), to get user input for
Notification Center, Windows Toaster, Windows Balloons and Growl. Sadly not
for notify-send.
```js
var notifier = require('node-notifier');
notifier.notify({ wait: true }, function (err, response) {
// response is response after user have interacted
// with the notification or the notification has timed out.
});
```
3. All notification instances are now event emitters, emitting events
`click` or `timeout`. This is only applicable if `{ wait: true }`.
```js
var notifier = require('node-notifier');
notifier.on('click', function (notificationObject, options) {
// options.someArbitraryData === 'foo'
});
notifier.notify({ wait: true, someArbitraryData: 'foo' });
```
4. WindowsToaster and NotificationCenter now can have sounds by doing `{ sound: true }`.
Default NotificationCenter sound is Bottle. Can still use define sound on
Mac:
```js
var notifier = require('node-notifier');
notifier.notify({ sound: true });
// For mac (same as sound: true on Windows 8)
notifier.notify({ sound: 'Morse' });
```
### `v3.4.0`

@@ -5,0 +41,0 @@ 1. Adds Growl as priority over Balloons

24

example/advanced.js

@@ -1,16 +0,12 @@

var Notify = require('../');
var notifier = new Notify();
var notifier = require('../');
var nc = new notifier.NotificationCenter();
notifier.notify({
"title": "Phil Coulson",
"subtitle": "Agent of S.H.I.E.L.D.",
"message": "If I come out, will you shoot me? 'Cause then I won't come out.",
"sound": "Funk", // case sensitive
"appIcon": __dirname + "/coulson.jpg",
"contentImage": __dirname + "/coulson.jpg",
"open": "file://" + __dirname + "/coulson.jpg"
nc.notify({
'title': 'Phil Coulson',
'subtitle': 'Agent of S.H.I.E.L.D.',
'message': 'If I come out, will you shoot me? \'Cause then I won\'t come out.',
'sound': 'Funk', // case sensitive
'appIcon': __dirname + '/coulson.jpg',
'contentImage': __dirname + '/coulson.jpg',
'open': 'file://' + __dirname + '/coulson.jpg'
});
setTimeout(function() {
console.log("Done");
}, 5000);

@@ -1,18 +0,14 @@

var Notify = require("../index");
var notifier = new Notify();
var notifier = require('../index');
notifier.notify({
"message": "Hello"
}
, function (err, data) {
if (err) {
return console.error("Error: ", err);
}
console.log(data);
});
setTimeout(function() {
console.log("Done");
}, 5000);
notifier
.notify({
'message': 'Hello',
'wait': true
}, function (err, data) {
// Will also wait until notification is closed.
console.log('Waited');
console.log(err, data);
})
.on('click', function () {
console.log(arguments);
});
var os = require('os');
var send = require('./lib/notifiers/notify-send');
var mac = require('./lib/notifiers/terminal-notifier');
var win8 = require('./lib/notifiers/toaster');
var growl = require('./lib/notifiers/growl');
var balloon = require('./lib/notifiers/balloon');
var utils = require('./lib/utils');
// All notifiers
var NotifySend = require('./lib/notifiers/notify-send');
var NotificationCenter = require('./lib/notifiers/terminal-notifier');
var WindowsToaster = require('./lib/notifiers/toaster');
var Growl = require('./lib/notifiers/growl');
var WindowsBalloon = require('./lib/notifiers/balloon');
var options = { withFallback: true };
switch(os.type()) {
case 'Linux':
module.exports = send;
module.exports = new NotifySend(options);
module.exports.Notification = NotifySend;
break;
case 'Darwin':
module.exports = mac;
module.exports = new NotificationCenter(options);
module.exports.Notification = NotificationCenter;
break;
case 'Windows_NT':
if (utils.isLessThanWin8()) {
module.exports = balloon;
module.exports = new WindowsBalloon(options);
module.exports.Notification = WindowsBalloon;
} else {
module.exports = win8;
module.exports = new WindowsToaster(options);
module.exports.Notification = WindowsToaster;
}
break;
default:
module.exports = growl;
module.exports = new Growl(options);
module.exports.Notification = Growl;
}
module.exports.NotifySend = send;
module.exports.NotificationCenter = mac;
module.exports.WindowsToaster = win8;
module.exports.WindowsBalloon = balloon;
module.exports.Growl = growl;
// Expose notifiers to give full control.
module.exports.NotifySend = NotifySend;
module.exports.NotificationCenter = NotificationCenter;
module.exports.WindowsToaster = WindowsToaster;
module.exports.WindowsBalloon = WindowsBalloon;
module.exports.Growl = Growl;

@@ -1,2 +0,2 @@

var net = require('net')
var net = require('net');

@@ -12,2 +12,3 @@ var hasGrowl = false;

socket.on('connect', function() {
socket.end();
cb(true);

@@ -17,4 +18,5 @@ });

socket.on('error', function() {
socket.end();
cb(false);
});
};
};

@@ -18,2 +18,7 @@ /**

// Kill codes:
2 = Timeout
3 = Clicked
*/

@@ -27,47 +32,47 @@ var path = require('path'),

var EventEmitter = require('events').EventEmitter;
var util = require('util');
var hasGrowl = void 0;
var Notifier = function (options) {
if (!(this instanceof Notifier)) {
return new Notifier();
module.exports = WindowsBalloon;
function WindowsBalloon (options) {
options = options || {};
if (!(this instanceof WindowsBalloon)) {
return new WindowsBalloon(options);
}
this.options = options;
};
var allowedArguments = ["t", "d", "p", "m", "i", "e", "q", "w", "xp"];
var doNotification = function (options, callback) {
options = utils.mapToNotifu(options);
options.p = options.p || 'Node Notification:';
if (!options.m) {
callback(new Error('Message is required.'));
return this;
}
var argsList = utils.constructArgumentList(options, {
wrapper: '',
noEscape: true,
allowedArguments: allowedArguments
});
utils.windowsCommand(notifier, argsList, callback);
EventEmitter.call(this);
}
util.inherits(WindowsBalloon, EventEmitter);
Notifier.prototype.notify = function (options, callback) {
WindowsBalloon.prototype.notify = function (options, callback) {
var fallback, notifierOptions = this.options;
callback = callback || function (err, data) {};
callback = callback || function () {};
var actionJackedCallback = utils.actionJackerDecorator(this, options, callback, function (data) {
var cleaned = data.toLowerCase().trim();
if (cleaned === 'activate') {
return 'click';
}
if (cleaned === 'timeout') {
return 'timeout';
}
return false;
});
if (utils.isWin8()) {
fallback = new Toaster(notifierOptions);
if (!!this.options.withFallback && utils.isWin8()) {
fallback = fallback || new Toaster(notifierOptions);
return fallback.notify(options, callback);
}
if (!utils.isLessThanWin8() || hasGrowl === true) {
fallback = new Growl(notifierOptions);
if (!!this.options.withFallback && (!utils.isLessThanWin8() || hasGrowl === true)) {
fallback = fallback || new Growl(notifierOptions);
return fallback.notify(options, callback);
}
if (hasGrowl === false) {
doNotification(options, callback);
if (!this.options.withFallback || hasGrowl === false) {
doNotification(options, notifierOptions, actionJackedCallback);
return this;

@@ -80,7 +85,7 @@ }

if (hasGrowl) {
fallback = new Growl(notifierOptions);
fallback = fallback || new Growl(notifierOptions);
return fallback.notify(options, callback);
}
doNotification(options, callback);
doNotification(options, notifierOptions, actionJackedCallback);
});

@@ -91,2 +96,40 @@

module.exports = Notifier;
var allowedArguments = ["t", "d", "p", "m", "i", "e", "q", "w", "xp"];
function doNotification (options, notifierOptions, callback) {
options = options || {};
options = utils.mapToNotifu(options);
options.p = options.p || 'Node Notification:';
var localNotifier = notifierOptions.customPath || notifier;
if (!options.m) {
callback(new Error('Message is required.'));
return this;
}
var argsList = utils.constructArgumentList(options, {
wrapper: '',
noEscape: true,
allowedArguments: allowedArguments
});
if (!!options.wait) {
return utils.fileCommand(localNotifier, argsList, function (error, data) {
var action = fromErrorCodeToAction(error.code);
if (action === 'error') return callback(error, data);
return callback(null, action);
});
}
utils.immediateFileCommand(localNotifier, argsList, callback);
}
function fromErrorCodeToAction (errorCode) {
if (errorCode === 2) {
return 'timeout';
}
if (errorCode === 3) {
return 'activate';
}
return 'error';
}
/**
* Wrapper for the growly module
*/
var os = require('os'),
utils = require('../utils'),
var utils = require('../utils'),
checkGrowl = require('../checkGrowl');
growly = require('growly');
var Notifier = function (options) {
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var errorMessageNotFound = 'Couldn\'t connect to growl (might be used as a fallback). Make sure it is running';
module.exports = Growl;
var hasGrowl = void 0;
function Growl (options) {
options = options || {};
if (!(this instanceof Notifier)) {
return new Notifier(options);
if (!(this instanceof Growl)) {
return new Growl(options);
}
this.name = options.name || 'Node';
this.isRegistered = false;
};
var doNotification = function (options, callback) {
options.title = options.title || 'Node Notification:';
growly.notify(options.message, options, callback);
};
growly.appname = options.name || 'Node';
Notifier.prototype.notify = function (options, callback) {
var that = this;
EventEmitter.call(this);
}
util.inherits(Growl, EventEmitter);
Growl.prototype.notify = function (options, callback) {
options = options || {};
callback = (callback || function () {}).bind(this);
callback = utils.actionJackerDecorator(this, options, callback, function (data) {
var cleaned = data.toLowerCase().trim();
if (cleaned === 'click') {
return 'click';
}
if (cleaned === 'timedout') {
return 'timeout';
}
return false;
});

@@ -34,23 +50,18 @@ options = utils.mapToGrowl(options);

if (this.isRegistered) {
return doNotification(options, callback);
options.title = options.title || 'Node Notification:';
if (hasGrowl || !!options.wait) {
var localCallback = !!options.wait ? callback : function () {};
growly.notify(options.message, options, localCallback);
if (!options.wait) callback();
return this;
}
growly.register(this.name, function(err) {
if (err) {
if (!that.hasError) {
that.hasError = true;
callback(err);
}
return false;
}
that.isRegistered = true;
that.hasError = false;
doNotification(options, callback);
checkGrowl(function (didHaveGrowl) {
hasGrowl = didHaveGrowl;
if (!didHaveGrowl) return callback(new Error(errorMessageNotFound));
growly.notify(options.message, options);
callback();
});
return this;
};
module.exports = Notifier;
/**
* Node.js wrapper for "notify-send".
*/
var path = require('path'),
os = require('os'),
var os = require('os'),
which = require('which'),
utils = require('../utils');
var notifier = 'notify-send';
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Notifier = function () {
if (!(this instanceof Notifier)) {
return new Notifier();
}
this.isNotifyChecked = false;
this.hasNotifier = false;
};
var notifier = 'notify-send', hasNotifier = void 0;
var allowedArguments = [
"urgency",
"expire-time",
"icon",
"category",
"hint"
];
module.exports = NotifySend;
var doNotification = function (options, callback) {
var initial, argsList;
function NotifySend (options) {
options = options || {};
if (!(this instanceof NotifySend)) {
return new NotifySend(options);
}
options = utils.mapToNotifySend(options);
options.title = options.title || 'Node Notification:';
this.options = options;
initial = [options.title, options.message];
delete options.title;
delete options.message;
EventEmitter.call(this);
}
util.inherits(NotifySend, EventEmitter);
argsList = utils.constructArgumentList(options, {
initial: initial,
keyExtra: '-',
allowedArguments: allowedArguments
});
NotifySend.prototype.notify = function (options, callback) {
options = options || {};
utils.command(notifier, argsList, callback);
return this;
};
Notifier.prototype.notify = function (options, callback) {
var that = this;
callback = callback || function () {};
options = options || {};
if (!options.message) {

@@ -64,9 +40,9 @@ callback(new Error('Message is required.'));

if (this.isNotifyChecked && this.hasNotifier) {
doNotification(options, callback);
if (hasNotifier === false) {
callback(new Error('notify-send must be installed on the system.'));
return this;
}
if (this.isNotifyChecked && !this.hasNotifier) {
callback(new Error('notify-send must be installed on the system.'));
if (hasNotifier || !!this.options.suppressOsdCheck) {
doNotification(options, callback);
return this;

@@ -76,4 +52,3 @@ }

which(notifier, function (err) {
that.isNotifyChecked = true;
that.hasNotifier = !err;
hasNotifier = !err;

@@ -84,3 +59,3 @@ if (err) {

return doNotification(options, callback);
doNotification(options, callback);
});

@@ -90,2 +65,27 @@ return this;

module.exports = Notifier;
var allowedArguments = [
"urgency",
"expire-time",
"icon",
"category",
"hint"
];
function doNotification (options, callback) {
var initial, argsList;
options = utils.mapToNotifySend(options);
options.title = options.title || 'Node Notification:';
initial = [options.title, options.message];
delete options.title;
delete options.message;
argsList = utils.constructArgumentList(options, {
initial: initial,
keyExtra: '-',
allowedArguments: allowedArguments
});
utils.command(notifier, argsList, callback);
}
/**
* A Node.js wrapper for terminal-notify.
*
* Requirements:
* - Mac OS X 10.8
* A Node.js wrapper for terminal-notify (with fallback).
*/
var path = require('path'),
notifier = path.resolve(__dirname, '../../vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier'),
notifier = path.join(__dirname, '../../vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier'),
utils = require('../utils'),
Growl = require('./growl');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var fallbackNotifier = null;
var Notifier = function (options) {
if (!(this instanceof Notifier)) {
return new Notifier();
var errorMessageOsX = 'You need Mac OS X 10.8 or above to use NotificationCenter,' +
' or use Growl fallback with constructor option {withFallback: true}.';
module.exports = NotificationCenter;
function NotificationCenter (options) {
options = options || {};
if (!(this instanceof NotificationCenter)) {
return new NotificationCenter(options);
}
this.options = options;
this.isOSX = false;
fallbackNotifier = null;
};
Notifier.prototype.notify = function (options, callback) {
EventEmitter.call(this);
}
util.inherits(NotificationCenter, EventEmitter);
NotificationCenter.prototype.notify = function (options, callback) {
var fallbackNotifier = null;
options = options || {};
callback = callback || function () {};
var actionJackedCallback = utils.actionJackerDecorator(this, options, callback, function (data) {
var cleaned = data.toLowerCase().trim();
if (cleaned === 'activate') {
return 'click';
}
if (cleaned === 'timeout') {
return 'timeout';
}
return false;
});
options = utils.mapToMac(options);
if (!!options.wait) {
options.wait = 'YES';
}
if (!options.message && !options.group && !options.list && !options.remove) {
callback(new Error('Message, group, remove or list property is required.'));
return this;
}
var argsList = utils.constructArgumentList(options);
callback = callback || function (err, data) {};
if(this.isOSX) {
utils.command(notifier, argsList, callback);
if(utils.isMountainLion()) {
utils.command(this.options.customPath || notifier, argsList, actionJackedCallback);
return this;
}
if(fallbackNotifier) {
fallbackNotifier.notify(options, callback);
return this;
if (fallbackNotifier || !!this.options.withFallback) {
fallbackNotifier = fallbackNotifier || new Growl(this.options);
return fallbackNotifier.notify(options, callback);
}
var self = this;
utils.isMacOSX(function (error, errorMsg) {
if (error && error !== 'old') {
return callback(new Error(errorMsg));
}
if (error && error === 'old') {
fallbackNotifier = new Growl(self.options);
return fallbackNotifier.notify(options, callback);
}
utils.command(notifier, argsList, callback);
self.isOSX = true;
});
callback(new Error(errorMessageOsX));
return this;
};
module.exports = Notifier;

@@ -9,14 +9,37 @@ /**

var Notifier = function (options) {
if (!(this instanceof Notifier)) {
return new Notifier();
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var fallback = void 0;
module.exports = WindowsToaster;
function WindowsToaster (options) {
options = options || {};
if (!(this instanceof WindowsToaster)) {
return new WindowsToaster(options);
}
this.options = options;
};
Notifier.prototype.notify = function (options, callback) {
var fallback;
EventEmitter.call(this);
}
util.inherits(WindowsToaster, EventEmitter);
WindowsToaster.prototype.notify = function (options, callback) {
options = options || {};
callback = callback || function () {};
var actionJackedCallback = utils.actionJackerDecorator(this, options, callback, function (data) {
var cleaned = data.toLowerCase().trim();
if (cleaned === 'activated') {
return 'click';
}
if (cleaned === 'timeout') {
return 'timeout';
}
return false;
});
options.title = options.title || 'Node Notification:';
callback = callback || function (err, data) {};

@@ -28,4 +51,4 @@ if (!options.message) {

if (!utils.isWin8()) {
fallback = new Balloon(this.options);
if (!utils.isWin8() && !!this.options.withFallback) {
fallback = fallback || new Balloon(this.options);
return fallback.notify(options, callback);

@@ -39,6 +62,4 @@ }

});
utils.windowsCommand(notifier, argsList, callback);
utils.fileCommand(this.options.customPath || notifier, argsList, actionJackedCallback);
return this;
};
module.exports = Notifier;
var cp = require('child_process'),
os = require('os'),
fs = require('fs'),
osVersionError = 'Incorrect OS. node-notify requires Mac OS 10.8 or higher',
shellwords = require('shellwords'),
semver = require('semver');
semver = require('semver'),
clone = require('clone');
var escapeQuotes = function (str) {

@@ -41,3 +42,4 @@ if (typeof str === 'string') {

module.exports.command = function (notifier, options, cb) {
return cp.exec(shellwords.escape(notifier) + ' ' + options.join(' '), function (error, stdout, stderr) {
var notifier = shellwords.escape(notifier);
return cp.exec(notifier + ' ' + options.join(' '), function (error, stdout, stderr) {
if (error) return cb(error);

@@ -48,5 +50,5 @@ cb(stderr, stdout);

module.exports.windowsCommand = function (notifier, options, cb) {
module.exports.fileCommand = function (notifier, options, cb) {
return cp.execFile(notifier, options, function (error, stdout, stderr) {
if (error && !!stderr) return cb(error);
if (error) return cb(error, stdout);
cb(stderr, stdout);

@@ -56,2 +58,17 @@ });

module.exports.immediateFileCommand = function (notifier, options, cb) {
notifierExists(notifier, function (exists) {
if (!exists) return cb(new Error('Notifier (' + notifier + ') not found on system.'));
cp.execFile(notifier, options);
cb();
});
};
function notifierExists (notifier, cb) {
return fs.stat(notifier, function (err, stat) {
if (err) return cb(false);
cb(stat.isFile());
});
}
var mapAppIcon = function (options) {

@@ -124,5 +141,26 @@ if (options.appIcon) {

if (options.sound === true) {
options.sound = 'Bottle';
}
if (options.sound === false) {
delete options.sound;
}
return options;
};
module.exports.actionJackerDecorator = function (emitter, options, fn, mapper) {
options = clone(options);
fn = fn || function (err, data) {};
return function (err, data) {
fn.apply(emitter, [err, data]);
if (err || !mapper || !data) return;
var key = mapper(data);
if (!key) return;
emitter.emit(key, emitter, options);
};
};
module.exports.constructArgumentList = function (options, extra) {

@@ -153,30 +191,2 @@ var args = [];

module.exports.getOSXVersion = function (cb) {
return cp.exec("sw_vers -productVersion", cb);
}
module.exports.isMacOSX = function (cb) {
if (os.type().toLowerCase() != 'darwin') {
return cb(true, "You can't use the terminal-notifier reporter unless you are on a Mac.");
}
return module.exports.getOSXVersion(function (error, stdout, stderr) {
if (error) {
return cb(true, error, stderr);
}
var version = garanteeSemverFormat(stdout.toString().trim());
if (semver.satisfies(version, '>=10.8')) {
return cb(false);
}
return cb('old', osVersionError);
});
};
function garanteeSemverFormat (version) {
if (version.split('.').length === 2) {
version += '.0';
}
return version;
};
module.exports.mapToWin8 = function (options){

@@ -202,2 +212,24 @@

if (options.quiet || options.silent) {
options.q = options.quiet || options.silent;
delete options.quiet;
delete options.silent;
}
if (options.q !== false) {
options.q = true;
} else {
delete options.q;
}
if (options.sound) {
delete options.q;
delete options.sound;
}
if (options.wait) {
options.w = options.wait;
delete options.wait;
}
return options;

@@ -226,15 +258,46 @@ };

if (options.time) {
options.t = options.time;
options.d = options.time;
delete options.time;
}
if (options.q !== false) {
options.q = true;
} else {
delete options.q;
}
if (options.sound) {
delete options.q;
delete options.sound;
}
if (options.t) {
options.d = options.t;
delete options.t;
}
return options;
};
module.exports.isMac = function() {
return os.type() === 'Darwin';
};
module.exports.isMountainLion = function() {
return os.type() === 'Darwin' && semver.satisfies(garanteeSemverFormat(os.release()), '>=12.0.0');
};
module.exports.isWin8 = function() {
return os.type() === 'Windows_NT' && semver.satisfies(os.release(), '>=6.2.9200');
return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '>=6.2.9200');
};
module.exports.isLessThanWin8 = function() {
return os.type() === 'Windows_NT' && semver.satisfies(os.release(), '<6.2.9200');
};
return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '<6.2.9200');
};
function garanteeSemverFormat (version) {
if (version.split('.').length === 2) {
version += '.0';
}
return version;
}
{
"name": "node-notifier",
"version": "3.4.1",
"version": "4.0.0",
"description": "A Node.js module for sending notifications on native Mac, Windows (post and pre 8) and Linux (or Growl as fallback)",

@@ -31,7 +31,8 @@ "main": "index.js",

"dependencies": {
"semver": "^3.0.1",
"semver": "^4.0.3",
"shellwords": "^0.1.0",
"which": "^1.0.5",
"growly": "^1.1.1"
"growly": "^1.1.1",
"clone": "^0.1.18"
}
}
# node-notifier [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][depstat-image]][depstat-url]
A node module for sending notification using node. Uses terminal-notifier on mac,
notify-send for Linux, toaster for Windows 8, balloons for Windows pre 8 or Growl for others.
A Node.js module for sending cross platform system notification. Using
Notification Center for Mac, notify-osd for Linux, Toasters for
Windows 8, or lovely taskbar Balloons for earlier Windows versions. If none of
these requirements are met, be it older version of Windows or OS X,
Growl is used.

@@ -10,46 +13,59 @@ ![Mac Screenshot](https://github.com/mikaelbr/node-notifier/blob/master/example/mac.png)

## Requirements
- Mac OS X >= 10.8.
- Linux with the notify-osd/notify-send module
- Windows. Using "toasters" for Win8, Balloons for pre Win8 (if Growl isn't found).
- Or if no of the above requirements are met, Growl is used.
## Easy Usage
If using Linux, `notify-osd` must be installed on your system.
For Mac, [terminal-notifier](https://github.com/alloy/terminal-notifier), comes
bundled in the module. So on Mac, not additional installations is necessary.
Show native notifications on Mac, Windows, Linux or using Growl!
This also goes for native Windows (version >=8) as well, where
[toaster.exe](https://github.com/nels-o/toaster) is bundled. Note, for native
Windows notifications [a toast must have a shortcut installed](http://msdn.microsoft.com/en-in/library/windows/apps/hh779727.aspx)
(though not necessarily pinned) to the Start screen or in the Apps view, but
this happens automatically.
```javascript
var notifier = require('node-notifier');
notifier.notify({
'title': 'My notification'
'message': 'Hello, there!'
});
```
Growl takes precidence over Windows balloons. So if Growl is active,
growl is used, if not, balloons are shown.
## Requirements
- **Mac OS X**: >= 10.8 or Growl if earlier.
- **Linux**: notify-osd installed (Ubuntu should have this by default)
- **Windows**: >= 8, task bar balloon if earlier or Growl if that is installed.
- **General Fallback**: Growl
If no of the other requirements are met, node-notifier will use Growl.
You have to have Growl installed on your system. See
[Growl for Windows](http://www.growlforwindows.com/gfw/) or
[Growl for Mac](http://growl.info/).
Growl takes precedence over Windows balloons.
See [documentation and flow chart for reporters](./DECISION_FLOW.md)
See [documentation and flow chart for reporter choice](./DECISION_FLOW.md)
## Install
```
$ npm install node-notifier
$ npm install --save node-notifier
```
## Standard Usage
## Cross-Platform Advanced Usage
Standard usage, with cross-platform fallbacks as defined in the
[reporter flow chart](./DECISION_FLOW.md). All of the options
below will work in a way or another on all platforms.
```javascript
var Notification = require('node-notifier');
var notifier = new Notification();
var notifier = require('node-notifier');
notifier.notify({
title: 'My awesome title',
message: 'Hello from node, Mr. User!'
message: 'Hello from node, Mr. User!',
icon: path.join(__dirname, 'coulson.jpg'), // absolute path (not balloons)
sound: true, // Only Notification Center or Windows Toasters
wait: true // wait with callback until user action is taken on notification
}, function (err, response) {
// response is response from notification
});
notifier.on('click', function (notifierObject, options) {
// Happens if `wait: true` and user clicks notification
});
notifier.on('timeout', function (notifierObject, options) {
// Happens if `wait: true` and notification closes
});
```
`Notification` also has specifications for all types of notifications, to be used
manually.
You can also specify what reporter you want to use if you
want to customize it or have more specific options per system.
See documentation for each reporter below.

@@ -60,17 +76,20 @@ Example:

new nn.NotificationCenter().notify();
new nn.NotifySend().notify();
new nn.WindowsToaster().notify(options);
new nn.WindowsBalloon().notify(options);
new nn.Growl().notify(options);
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
### Mapping between notifiers
Common options between the modules (i.e. `icon`) is mapped. This means,
if you are using a Mac and someone on your project is using Linux, you
can both see icons.
## Documentation
* [Notification Center documentation](#usage-notificationcenter)
* [Windows Toaster documentation](#usage-windowstoaster)
* [Windows Balloon documentation](#usage-windowsballoon)
* [Growl documentation](#usage-growl)
* [Notify-send documentation](#usage-notifysend)
## Usage NotificationCenter
### Usage NotificationCenter
Same usage and parameter setup as [terminal-notifier](https://github.com/alloy/terminal-notifier).

@@ -80,41 +99,33 @@

earlier versions, Growl will be the fallback. If Growl isn't installed, an error
will be thrown.
will be returned in the callback.
---
### Note: Output parsing from Notification Center is deprecated as of `3.0.0`.
#### Example
**Parsing of output given by terminal-notifier is removed as of node-notifier `3.0.0`.**
You can still use both `remove` and `list` but the output given will not be parsed into a object.
It is a wrapper around [terminal-notifier](https://github.com/alloy/terminal-notifier), and you can
do all terminal-notifier can do through properties to the `notify` method. E.g.
if `terminal-notifier` say `-message`, you can do `{message: 'Foo'}`, or
if `terminal-notifier` say `-list ALL` you can do `{list: 'ALL'}`. Notification
is the primary focus for this module, so listing and activating do work,
but isn't documented.
See removed documentation for pre version `3.0.0` in [Deprecated documentation](DEPRECATED.md)
### All notification options with their defaults:
---
### Example
Where [terminal-notifier](https://github.com/alloy/terminal-notifier) say to use the ```-message``` option, you can do this in node-notifier
```javascript
var Notification = require('node-notifier');
var NotificationCenter = require('node-notifier').NotificationCenter;
var notifier = new Notification();
notifier.notify({
message: 'Hello World'
});
```
You can specify the second argument as a callback for getting ```error``` and ```response```.
```javascript
var Notification = require('node-notifier');
var notifier = new Notification({
// Options passed to Growl if fallback
withFallback: false, // use Growl if <= 10.8?
customPath: void 0 // Relative path if you want to use your fork of terminal-notifier
});
notifier.notify({
title: 'My application',
message: 'New notification'
'title': void 0,
'subtitle': void 0,
'message': void 0,
'sound': false, // Case Sensitive string of sound file (see below)
'icon': 'Terminal Icon', // Set icon? (Absolute path to image)
'contentImage': void 0, // Attach image? (Absolute path)
'open': void 0, // URL to open on click
'wait': false // if wait for notification to end
}, function(error, response) {

@@ -125,70 +136,86 @@ console.log(response);

As of version `3.0.0`, you can also specify image used as icon or content image. **For Mac OS notifications, requires 10.9.**
**For Mac OS notifications, icon and contentImage requires OS X 10.9.**
Sound can be one of these: `Basso`, `Blow`, `Bottle`, `Frog`, `Funk`, `Glass`,
`Hero`, `Morse`, `Ping`, `Pop`, `Purr`, `Sosumi`, `Submarine`, `Tink`. If
sound is simply `true`, `Bottle` is used.
```javascript
See [specific Notification Center example](./example/advanced.js).
notifier.notify({
"title": "Phil Coulson",
"subtitle": "Agent of S.H.I.E.L.D.",
"message": "If I come out, will you shoot me? 'Cause then I won't come out.",
"sound": "Funk", // case sensitive
"contentImage": __dirname + "/coulson.jpg",
"appIcon": __dirname + "/coulson.jpg",
"open": "file://" + __dirname + "/coulson.jpg"
});
### Usage WindowsToaster
```
**Note:** There are some limitations for images in native Windows 8 notifications:
The image must be a PNG image, and cannot be over 1024x1024 px, or over over 200Kb.
You also need to specify the image by using absolute path. These limitations are
due to the Toast notification system. A good tip is to use something like
`path.join` or `path.delimiter` to have cross-platform pathing.
See [terminal-notifier](https://github.com/alloy/terminal-notifier) for more options.
[toaster](https://github.com/nels-o/toaster) is used to get native Windows Toasts!
## Usage NotifySend
```javascript
var Notification = require('node-notifier');
var WindowsToaster = require('node-notifier').WindowsToaster;
var notifier = new Notification({
// Options passed to Growl if fallback
var notifier = new WindowsToaster({
withFallback: false, // Fallback to Growl or Balloons?
customPath: void 0 // Relative path if you want to use your fork of toast.exe
});
notifier.notify({
title: 'Foo',
message: 'Hello World',
icon: __dirname + "/coulson.jpg",
// .. and other notify-send flags
title: void 0,
message: void 0,
icon: void 0, // absolute path to an icon
sound: false, // true | false.
wait: false, // if wait for notification to end
}, function(error, response) {
console.log(response);
});
```
See flags and options [on the man pages](http://manpages.ubuntu.com/manpages/gutsy/man1/notify-send.1.html)
### Usage Growl
## Usage Native Windows 8
```javascript
var Notification = require('node-notifier');
var Growl = require('node-notifier').Growl;
var notifier = new Notification({
// Options passed to Growl if fallback
var notifier = new Growl({
name: 'Growl Name Used' // Defaults as 'Node'
});
notifier.notify({
title: 'Foo',
message: 'Hello World',
icon: __dirname + "/coulson.jpg"
icon: fs.readFileSync(__dirname + "/coulson.jpg"),
wait: false, // if wait for user interaction
// and other growl options like sticky etc.
sticky: false,
label: void 0,
priority: void 0
});
```
## Usage Native Windows Version 7 and below
See more information about using
[growly](https://github.com/theabraham/growly/).
For earlier Windows versions, the taskbar balloons are used.
For balloons a great project called
[notifu](http://www.paralint.com/projects/notifu/) is used.
### Usage WindowsBalloon
For earlier Windows versions, the taskbar balloons are used (unless
fallback is activated and Growl is running). For balloons a great
project called [notifu](http://www.paralint.com/projects/notifu/) is used.
```javascript
var Notification = require('node-notifier');
var WindowsBalloon = require('node-notifier').WindowsBalloon;
var notifier = new Notification({
// Options passed to Growl if fallback
var notifier = new WindowsBalloon({
withFallback: false, // Try Windows 8 and Growl first?
customPath: void 0 // Relative path if you want to use your fork of notifu
});
notifier.notify({
p: 'Foo', // Title (can use title:)
m: 'Hello World', // Message (can use message:)
d: 1000 // Show for 1000 ms
title: void 0,
message: void 0,
sound: false, // true | false.
time: 5000, // How long to show balloons in ms
wait: false, // if wait for notification to end
}, function(error, response) {
console.log(response);
});

@@ -200,10 +227,10 @@ ```

## Usage Growl
### Usage NotifySend
Note: notify-send doesn't support the wait flag.
```javascript
var Notification = require('node-notifier');
var NotifySend = require('node-notifier').NotifySend;
var notifier = new Notification({
name: 'Growl Name Used' // Defaults as 'Node'
});
var notifier = new NotifySend();

@@ -213,14 +240,25 @@ notifier.notify({

message: 'Hello World',
icon: fs.readFileSync(__dirname + "/coulson.jpg")
// and other growl options like sticky etc.
icon: __dirname + "/coulson.jpg",
// .. and other notify-send flags:
urgency: void 0,
time: void 0,
category: void 0,
hint: void 0,
});
```
See more information for constructor options in
[growler](https://github.com/theabraham/growly/).
See flags and options [on the man pages](http://manpages.ubuntu.com/manpages/gutsy/man1/notify-send.1.html)
## Thanks to OSS
A very special thanks to all the modules `node-notifier` uses.
* [terminal-notifier](https://github.com/alloy/terminal-notifier)
* [toaster](https://github.com/nels-o/toaster)
* [notifu](http://www.paralint.com/projects/notifu/)
* [growly](https://github.com/theabraham/growly/)
[![NPM downloads][npm-downloads]][npm-url]
## License

@@ -227,0 +265,0 @@

@@ -30,5 +30,3 @@ var Notify = require('../').NotifySend

var notifier = new Notify();
notifier.isNotifyChecked = true;
notifier.hasNotifier = true;
var notifier = new Notify({ suppressOsdCheck: true });

@@ -52,5 +50,3 @@ notifier.notify({

var notifier = new Notify();
notifier.isNotifyChecked = true;
notifier.hasNotifier = true;
var notifier = new Notify({ suppressOsdCheck: true });

@@ -73,5 +69,3 @@ notifier.notify({

var notifier = new Notify();
notifier.isNotifyChecked = true;
notifier.hasNotifier = true;
var notifier = new Notify({ suppressOsdCheck: true });

@@ -94,5 +88,3 @@ notifier.notify({

var notifier = new Notify();
notifier.isNotifyChecked = true;
notifier.hasNotifier = true;
var notifier = new Notify({ suppressOsdCheck: true });

@@ -115,5 +107,3 @@ notifier.notify({

var notifier = new Notify();
notifier.isNotifyChecked = true;
notifier.hasNotifier = true;
var notifier = new Notify({ suppressOsdCheck: true });

@@ -138,5 +128,3 @@ notifier.notify({

var notifier = new Notify();
notifier.isNotifyChecked = true;
notifier.hasNotifier = true;
var notifier = new Notify({ suppressOsdCheck: true });

@@ -143,0 +131,0 @@ notifier.notify({

@@ -12,17 +12,23 @@ var nn = require('../')

var originalUtils = utils.command;
var originalMacVersion = utils.getOSXVersion;
var originalMacVersion = utils.isMountainLion;
var originalType = os.type;
describe('Mac fallback', function () {
var original = utils.isMacOSX;
var original = utils.isMountainLion;
var originalMac = utils.isMac;
after(function () {
utils.isMacOSX = original;
utils.isMountainLion = original;
utils.isMac = originalMac;
})
it('should default to Growl notification if older Mac OSX than 10.8', function(done){
utils.isMacOSX = function (cb) {
cb('old');
utils.isMountainLion = function () {
return false;
};
var n = new NotificationCenter();
utils.isMac = function () {
return true;
};
var n = new NotificationCenter({ withFallback: true });
n.notify({

@@ -36,2 +42,20 @@ message: "Hello World"

});
it('should not fallback to Growl notification if withFallback is false', function(done){
utils.isMountainLion = function () {
return false;
};
utils.isMac = function () {
return true;
};
var n = new NotificationCenter();
n.notify({
message: "Hello World"
}, function (err, response) {
err.should.be.ok;
(this instanceof Growl).should.be.false;
done();
});
});
});

@@ -46,4 +70,4 @@

utils.getOSXVersion = function (cb) {
return cb(null, "10.8");
utils.isMountainLion = function () {
return true;
}

@@ -58,2 +82,3 @@ });

os.type = originalType;
utils.isMountainLion = originalMacVersion;
});

@@ -101,3 +126,3 @@

cb(null, fs.readFileSync(__dirname + '/fixture/listAll.txt').toString());
}
};

@@ -104,0 +129,0 @@ notifier.notify({

@@ -8,66 +8,4 @@ var should = require('should'),

var originalType = os.type;
var originalVersion = _.getOSXVersion;
describe('utils', function(){
before(function () {
os.type = function () {
return "Darwin";
};
});
after(function () {
os.type = originalType;
_.getOSXVersion = originalVersion;
});
it('should support mac 10.8', function (done) {
_.getOSXVersion = function (cb) {
cb(null, "10.8");
};
_.isMacOSX(function (error, msg) {
error.should.be.false;
(msg === void 0).should.be.true;
done();
});
});
it('should support not mac 10.7', function (done) {
_.getOSXVersion = function (cb) {
cb(null, "10.7");
};
_.isMacOSX(function (error, msg) {
error.should.equal('old');
(msg === void 0).should.be.false;
done();
});
});
it('should support 10.10', function (done) {
_.getOSXVersion = function (cb) {
cb(null, "10.10");
};
_.isMacOSX(function (error, msg) {
error.should.be.false;
(msg === void 0).should.be.true;
done();
});
});
it('should sopport 10.10 with newline', function (done) {
_.getOSXVersion = function (cb) {
cb(null, "10.10\n");
};
_.isMacOSX(function (error, msg) {
error.should.be.false;
(msg === void 0).should.be.true;
done();
});
});
describe('mapping', function () {

@@ -74,0 +12,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc