Advanced Action Flows – Part 7. How to limit notification rate

Quite often you want to setup a geofence at a very popular place, such as at an venue entrance. However, you don’t want to annoy your application users with too frequent notifications, and therefore want to limit how often the same person can receive notifications.

In this tutorial, we are going to learn how to limit notification rate through the action flow. Note: this flow limits the events triggered from all geofences.


  • Add t least one geofence on the portal.
  • Login to the management app or use your own app to get the push messages sent.

Step 1 : Import the following piece of code into the action flow clipboard from top right corner.

[{"id":"1fa96689.8cca69","type":"proximiio-event-receiver","z":"4e634c31.3c1ef4","delete_event":true,"x":152,"y":97,"wires":[["235aba5e.510726","4bb5c25a.c33bec"],[]]},{"id":"5189710b.65579","type":"function","z":"4e634c31.3c1ef4","name":"Example push notification","func":"return {\n    type: 'push',\n    title: 'Welcome to the demo!',\n    _proximi_id: msg._proximi_id,\n    _proximi_visitor_id: msg._proximi_visitor_id\n}","outputs":1,"noerr":0,"x":253,"y":363,"wires":[["a88674d3.f25758"]]},{"id":"a88674d3.f25758","type":"proximiio-event-transmitter","z":"4e634c31.3c1ef4","x":567,"y":390,"wires":[]},{"id":"235aba5e.510726","type":"debug","z":"4e634c31.3c1ef4","name":"Debug the event","active":true,"console":"false","complete":"true","x":477,"y":108,"wires":[]},{"id":"4bb5c25a.c33bec","type":"function","z":"4e634c31.3c1ef4","name":"Rate limiting","func":"// rate limit visitor event for 60 minutes\nvar rateLimit = 60; // Desired time to throttle in minutes\nvar tzOffset = 3600; // compensate timezone offset\n\n// default offset when previous event is not available defaults to -1 hour\nvar defaultOffset = 1000 * 60 * 60;\nvar lastEventTimestamp = new Date().getTime() - defaultOffset;\n\nif (msg.lastEventTimestamp !== undefined) {\n    lastEventTimestamp = new Date(msg.lastEventTimestamp).getTime();\n}\n\nvar now = new Date().getTime();\nvar diff = (now - lastEventTimestamp) / 1000 - tzOffset;\n\ = now;\nmsg.diff = diff;\nmsg.lastEventTimestamp = lastEventTimestamp;\nmsg.rateLimit = diff <= rateLimit;\n\nreturn msg;","outputs":1,"noerr":0,"x":265,"y":173,"wires":[["c9e038c4.e10488","66af3968.4d4588","c5607450.85a168","3932e92b.35cfe6","6575b5eb.e2b97c"]]},{"id":"c9e038c4.e10488","type":"switch","z":"4e634c31.3c1ef4","name":"Rate limit checker","property":"rateLimit","propertyType":"msg","rules":[{"t":"false"}],"checkall":"true","outputs":1,"x":284,"y":265,"wires":[["5189710b.65579"]]},{"id":"66af3968.4d4588","type":"debug","z":"4e634c31.3c1ef4","name":"Details","active":true,"console":"false","complete":"now","x":617,"y":210,"wires":[]},{"id":"c5607450.85a168","type":"debug","z":"4e634c31.3c1ef4","name":"Details","active":true,"console":"false","complete":"lastEventTimestamp","x":617,"y":250,"wires":[]},{"id":"3932e92b.35cfe6","type":"debug","z":"4e634c31.3c1ef4","name":"Details","active":true,"console":"false","complete":"rateLimit","x":617,"y":290,"wires":[]},{"id":"6575b5eb.e2b97c","type":"debug","z":"4e634c31.3c1ef4","name":"Details","active":true,"console":"false","complete":"diff","x":617,"y":330,"wires":[]}]


Step 2 : The action flow should look like this:


Here’s the full walk-through of each of the steps and what’s happening in the action flows: Event Receiver
This node listens for visitors entering or exiting any of the defined geofences. When a proximity event occurs, the node get’s triggered and it will pass all the event data as an output payload.

Function node
A Function node can be used to add any custom logic through JavaScript. In this case, we are specifying the required rate limit in the first function node.

The rate is specified in minutes. Important to note that the backend is running in Helsinki, Finland time, and you also need to consider the summer/winter timezone differences. You can also specify, if you want to set a default throttle time for those instances, when the previous event cannot be read for some reason.

If the difference between time now and time of last event is smaller than your specified rate, the function returns value ‘true’. If the difference is larger, the returned value is ‘false’.

Switch node
A Switch node can be used to determine different options. In this flow, we only want to trigger something, when the value passed from the previous node is “false”.

Function node #2
With the second Function node you can specify the action that will be limited. In this case it is a push message. native SDK’s include a helper that will show a local push notification when it receives a payload with type: ‘push’. The message content is specified in the ‘Title’.
detail_ratelimiting3 Event Transmitter
Event Transmitter sends a payload to the visitor’s device. Node requires _proximi_id and _proximi_visitor_id to be present in msg object which are present in every received event from Event Receiver.

Debug nodes
It is a very good practice to add Debug nodes in your flows. They will help you to ensure that the values passed by the flow are correct.

Step 3: Deploying the action flow :

You can deploy the action flow from the top right corner of the editor. Usually it’s good idea to select the first option “Full”.

Deploying the action flow

About Annina Koskiola

CEO and Co-founder of Loves exploring new ways for technology to intertwine with our everyday lives. Passion for history, traveling, eating and the Valais Blacknose sheep.