Learn how to handle the native notification system of the OS using electron framework and node notifier.

Using native desktop notification with Electron Framework

Thanks to webkit, you're able to customize with CSS the UI of your application as you wish. Fancy notification can be created within the window of your app, however sometimes you may want to notify something to your user, even if it isn't using the app in first plain or is minimized.

Native notification vs custom

That's why we'll need to access the notification system of the OS, which allow you to send a message to the user in the screen in any situation although they were using another app.

But remember, everything in excess is bad. You may want to be careful how often you show this messages to the user and ask for the permission to do this as the excessive use of native notifications can be annoying and irritating.

Probably you'll may be asking to yourself : why don't use the webkitNotification API ?. You can use this API with electron too, however it isn't available for windows. It works with Linux and MacOS, however it doesn't has the same native feel and look, therefore we recomend you to use the node-notifier plugin with your Electron app. 

Node notifier is a Node.js module for sending cross platform system notifications. Using Notification Center for Mac, notify-osd/libnotify-bin for Linux, Toasters for Windows 8/10, or taskbar Balloons for earlier Windows versions. If none of these requirements are met, Growl is used.

Implementation

To achieve our goal, we are going to use the node-notifier library which can be downloaded in your project using the following command :

npm install --save node-notifier

Visit the official repository of the project here. After a succesfully installation, you'll access the notifier using require('node-notifier').

Important note : electron by itself (latest build), offer you the Notification API which send a simple notification (the same way that node-notifier does) in the operative system. You can try if its available using the following snippet.

All three operating systems provide means for applications to send notifications to the user. Electron conveniently allows developers to send notifications with the HTML5 Notification API, using the currently running operating system’s native notification APIs to display it.

Note: Since this is an HTML5 API it is only available in the renderer process.

// You can use console.log(notification); to see more available properties

var notification = new Notification('Title', {
  body: 'Lorem Ipsum Dolor Sit Amet',
  title:"Hello",
  icon:'C:/images/icon.png',
  // To prevent sound
  //silent:true,
});

notification.addEventListener("click",function(){
    alert("Clicked");
},false);

notification.addEventListener("show",function(){
    alert("Shown :3");
},false);

notification.addEventListener("error",function(e){
    alert("Error :c");
},false);

notification.addEventListener("close",function(){
    alert("Closed");
},false);

If you think that you want even more, then continue reading the use of node-notifier.

Notify all

Now you just need to start using the notifier, the following snippet shows a simple message with a sound and an icon.

Note : the notify method is cross-platform, a deeper customization for every platform is possible if you read the documentation.

const notifier = require("node-notifier");

var onError = function(err,response){
    console.error(err,response);
};
            
notifier.notify({
    message: "This is the body of the notification.",
    title: "This will be the title of the notification",
    // Special sound
    // Case Sensitive string for location of sound file, or use one of OS X's native sounds
    // Only Notification Center or Windows Toasters
    sound: true,//"Bottle",
    // The absolute path to the icon of the message
    // (doesn't work on balloons) 
    // If not found, a system icon will be shown
    icon : "C:/images/ocw-logo.png",
   // Wait with callback (onClick event of the toast), until user action is taken against notification
    wait:true
},onError);

notifier.on('click', function (notifierObject, options) {
    // Triggers if `wait: true` and user clicks notification
    alert("Callback triggered");
});

The notify method is of cross-Platform standard usage, with cross-platform fallbacks. This method will work in a way or another on all platforms.

However, notifier allow you to customize according to each platform as you wish, see a detailed report of customization in the repository.

Windows

The toaster module only works in Windows >= 8.

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 an 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.

Windows 10 Note: You might have to activate banner notification for the toast to show.

const WindowsToaster = require('node-notifier').WindowsToaster;
 
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: "Title",
    message: "Message",
    icon: "c:/path/image.png", // Absolute path to Icon 
    sound: true, // true | false. 
    wait: false, // Wait for User Action against Notification 
}, function(error, response) {
    console.log(response);
});

For earlier Windows versions, the taskbar balloons are used (unless fallback is activated and Growl is running).

MacOS

Native Notification Center requires Mac OS X version 10.8 or higher. If you have an earlier version, Growl will be the fallback. If Growl isn't installed, an error will be returned in the callback.

const NotificationCenter = require('node-notifier').NotificationCenter;
 
var notifier = new NotificationCenter({
  withFallback: false, // Use Growl Fallback if <= 10.8 
  customPath: void 0 // Relative path if you want to use your fork of terminal-notifier 
});
 
notifier.notify({
  'title': "Hello world",
  'subtitle': void 0,
  'message': void 0,
  'sound': false, // Case Sensitive string for location of sound file, or use one of OS X's native sounds (see below) 
  'icon': 'Terminal Icon', // Absolute Path to Triggering Icon 
  'contentImage': void 0, // Absolute Path to Attached Image (Content Image) 
  'open': void 0, // URL to open on Click 
  'wait': false // Wait for User Action against Notification 
}, function(error, response) {
   console.log(response);
});

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.

See specific Notification Center example.

Known problems with Electron

Within Electron Packaging If packaging your Electron app as an asar, you will find node-notifier will fail to load. Due to the way asar works, you cannot execute a binary from within an asar. As a simple solution, when packaging the app into an asar please make sure you --unpack the vendor folder of node-notifier, so the module still has access to the notification binaries. To do this, you can do so by using the following command:

asar pack . app.asar --unpack "./node_modules/node-notifier/vendor/**"

Have fun


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors