Ways of Getting Active Notifications to a Mac—Application
Now that you understand about active notifications and how they work, this second tutorial will show you how to apply that knowledge. I'll show two ways of working with active notifications using a Node.js server. This same approach can easily be applied to other server types.
Active Notifications Using the DDNS
The download file for this tutorial contains the code for a small, Express.js web server that can be run on a Virtual Private Server or VPS. I have an account with FilpHost that I use for my Custom Computer Tools website. Just upload these files to a VPS, install Node.js, and run a command in the directory:
1 |
npm install
|
This will install all the needed libraries for Express.js and Pug template engine. Most of the files in this directory are supporting files for the server. The support files display a web page that has a single button. Clicking the button will send a notification to the server to ping my home computer. The main files of interest are the two types of server files: freeddns-Router.js and local-Router.js.
The server file for referring to the home computer through a DDNS, freeddns-Router.js, contains this code:
1 |
//
|
2 |
// Load the libraries used.
|
3 |
//
|
4 |
var express = require("express"); |
5 |
var http = require("http"); |
6 |
|
7 |
//
|
8 |
// Setup the applicaiton variables.
|
9 |
//
|
10 |
var app = express(); |
11 |
var port = 3030; |
12 |
var data = { |
13 |
title: "Notification Server Main Page", |
14 |
app: "Notification Server" |
15 |
};
|
16 |
var homeComputer = "http://customct.freeddns.org:4490/action.html?macro=998C71BC-00CE-42B1-9478-306AA747A86A&value=Notice+from+"; |
17 |
|
18 |
//
|
19 |
// Setup the Express routes.
|
20 |
//
|
21 |
app.use(express.static("static")); |
22 |
app.set("views", "./views") |
23 |
app.set("view engine", "pug") |
24 |
|
25 |
//
|
26 |
// Handle the Home page. This gives the client
|
27 |
// a button to press to send a notification. This
|
28 |
// will render the PEG template in the "views"
|
29 |
// directory.
|
30 |
//
|
31 |
app.get("/", function (req, res) { |
32 |
res.render("index",data); |
33 |
});
|
34 |
|
35 |
//
|
36 |
// Handle the request from the client to send
|
37 |
// the home computer a notification.
|
38 |
//
|
39 |
app.get("/api/notifyOwner", function(req,res) { |
40 |
//
|
41 |
// Quickly reply to the client.
|
42 |
//
|
43 |
res.send("okay"); |
44 |
|
45 |
//
|
46 |
// Get the IP of the client.
|
47 |
//
|
48 |
var ip = req.ip || req.connection.remote; |
49 |
ip = ip.split(":")[3]; |
50 |
|
51 |
//
|
52 |
// Send the client IP to the home computer using
|
53 |
// Keyboard Maestro"s Web interface.
|
54 |
//
|
55 |
http.get(homeComputer + ip, (res) => { |
56 |
console.log(`Got response: ${res.statusCode}`); |
57 |
// consume response body
|
58 |
res.resume(); |
59 |
}).on("error", (e) => { |
60 |
console.log(`Got error: ${e.message}`); |
61 |
});
|
62 |
});
|
63 |
|
64 |
//
|
65 |
// Start the server listening to the http port specified.
|
66 |
//
|
67 |
app.listen(port, function () { |
68 |
console.log("Notification Server listening on port ' + port + "!"); |
69 |
});
|
You will need to edit line 16 to match your particular DDNS setup. Lines 35–62 defines the route /api/notifyOwner
that the client’s browser will call to send a notification to the home computer.
The link for the home computer, in the homeComputer variable, calls port 4490 on the domain name for the home computer. This is the default port setup for Keyboard Maestro’s Personal Web Server.
The rest of the link, /action.html?macro=998C71BC-00CE-42B1-9478-306AA747A86A&value=Notice+from+
, gets the action.html page on the server for Keyboard Maestro with the variables macro and value. The macro variable contains the unique identification code for the macro in Keyboard Maestro.
The value variable contains whatever you want to send to the macro that is URL encoded. The information in the value variable is in the %TriggerValue%
variable for the Keyboard Maestro script to use.



Now, install the Keyboard Maestro macro that is in the download file for this tutorial. This macro will display the %TriggerValue%
to the user. The server code sends the IP of the client that pressed the button on the web site.



Next, open the Keyboard Maestro preferences and click on the Web Server option at the top. Set the options to the following values: Web Server Enabled checked, HTTP Port set to 4490, and Web Browser Access Enabled checked.



If you open your web browser to http://localhost:4490
, you will see the Keyboard Maesto’s web server page. If the macro you loaded from the download is the only macro you have that triggers from the web server, it will show up in the Public Macro list.
If it isn’t showing, click on the drop down menu and select the Test macro. Type This is a test in the Value area and press the Execute button.



You'll see the notification displayed with the text Testing: This is a test. The link that now shows in the address bar of the browser should have the same macro value as the link in the server script on line 16. If not, change the script to match this value.
Testing on the VPS
Once you have the server software uploaded, libraries installed, edits made to the server program, and the Keyboard Maestro macro loaded and setup, you can then test.
To start the server on your VPS, type the following:
1 |
node freeddns-Router.js |
Then navigate to the server's address at port 3030.



You should see the bare minimum web page with the button to press for sending the notification.



When you press the notice button, you should get the alert dialog telling you the server recieved the notification okay. Then the Display Text notice from Keyboard Maestro should show the IP address of the client that sent the notification.
Since I live in Thailand and my VPS is in the United States, the message went from my browser in Thailand, to the VPS in the United States, and then back to my system in Thailand all within one minute.
'Roll Your Own' Active Notifications
If you do not want to use a DDNS, you can create your own version with your server. The local-Router.js file is the exact same router code as freeddns-Router.js, but has one new route: /api/homecomputer
.
It also has a new global variable homeComputerIP that will store the IP address of the system that calls it.
1 |
//
|
2 |
// Load the libraries used.
|
3 |
//
|
4 |
var express = require("express"); |
5 |
var http = require("http"); |
6 |
|
7 |
//
|
8 |
// Setup the applicaiton variables.
|
9 |
//
|
10 |
var app = express(); |
11 |
var port = 3030; |
12 |
var data = { |
13 |
title: "Notification Server Main Page", |
14 |
app: "Notification Server" |
15 |
};
|
16 |
var homeComputerPortLink = ":4490/action.html?macro=998C71BC-00CE-42B1-9478-306AA747A86A&value=Notice+from+"; |
17 |
var homeComputerIP = ""; |
18 |
|
19 |
//
|
20 |
// Setup the Express routes.
|
21 |
//
|
22 |
app.use(express.static("static")); |
23 |
app.set("views", "./views") |
24 |
app.set("view engine", "pug") |
25 |
|
26 |
//
|
27 |
// Handle the Home page. This gives the client
|
28 |
// a button to press to send a notification. This
|
29 |
// will render the PEG template in the "views"
|
30 |
// directory.
|
31 |
//
|
32 |
app.get("/", function (req, res) { |
33 |
res.render("index",data); |
34 |
});
|
35 |
|
36 |
//
|
37 |
// Handle the request from the client to send
|
38 |
// the home computer a notification.
|
39 |
//
|
40 |
app.get("/api/notifyOwner", function(req,res) { |
41 |
//
|
42 |
// Quickly reply to the client.
|
43 |
//
|
44 |
res.send("okay"); |
45 |
|
46 |
//
|
47 |
// Get the IP of the client.
|
48 |
//
|
49 |
var ip = req.ip || req.connection.remote; |
50 |
ip = ip.split(":")[3]; |
51 |
|
52 |
//
|
53 |
// Send the client IP to the home computer using
|
54 |
// Keyboard Maestro"s Web interface.
|
55 |
//
|
56 |
http.get("http://" + homeComputerIP + homeComputerPortLink + ip, (res) => { |
57 |
console.log(`Got response: ${res.statusCode}`); |
58 |
// consume response body
|
59 |
res.resume(); |
60 |
}).on("error", (e) => { |
61 |
console.log(`Got error: ${e.message}`); |
62 |
});
|
63 |
});
|
64 |
|
65 |
app.get("/api/homecomputer", function(req,res) { |
66 |
//
|
67 |
// Quickly reply to the client.
|
68 |
//
|
69 |
res.send("okay"); |
70 |
|
71 |
//
|
72 |
// Get the IP of the client.
|
73 |
//
|
74 |
homeComputerIP = req.ip || req.connection.remote; |
75 |
homeComputerIP = homeComputerIP.split(":")[3]; |
76 |
console.log("Home computer IP is " + homeComputerIP); |
77 |
});
|
78 |
|
79 |
//
|
80 |
// Start the server listening to the http port specified.
|
81 |
//
|
82 |
app.listen(port, function () { |
83 |
console.log("Notification Server listening on port ' + port + "!"); |
84 |
});
|
Lines 65–77 manages this new route. When you open that route in your web browser, you will get back a plain text okay. But, the server will save your IP address and use it as the IP address to send the notification.
This cuts out the DDNS middleman and just ships the notification straight to your computer.
To run this server, type the following line:
1 |
node local-Router.js |
In order for this to work well, you will have to either go to the address for setting the IP address each time you connect to the internet, or run a background task that does that for you.
Clockwise is a great application for making scripts that periodically run. I have a Clockwise tutorial, on Envato Tuts+, that you may wish to consult.



The download file also has the above Keyboard Maestro macro for periodically calling the server to set the IP address.
Since Keyboard Maestro doesn’t have an Internet reset trigger, a periodical trigger is the next best thing. You will have to modify the script to reference your VPS.
Security
Since this tutorial is about getting an active notification to your local computer, I did not add anything to address security. These small servers are currently insecure.
If you use these in the wild, I strongly suggest creating some type of security for identification of the client that sets the IP address.
You can create a password system or a token passing system that is secure, but these ideas are beyond the scope of this tutorial.
Conclusion
Now that you know how active notifications work, create your own system. The ideas here are easily translated to PHP, Ruby, or Python. You can also expand the Keyboard Maestro macro to process the incoming information.
I have it setup to call an Alfred workflow to count visits to my website. You could use this to notify if someone needs help on a website as well. The possibilities are only bounded by your imagination.