Skip to main content

Node-RED Configuration

The red / yellow / green overlay at a Face Verify kiosk is decided by a small set of rules that run in Node-RED — a visual, node-based workflow engine. Each time a face is detected and matched on the Identities server, Node-RED evaluates the detection and returns an event classification (for example, AccessGranted, AccessDenied, ValidationFailed). That classification drives the color and message the customer sees at the kiosk, and the themed card the operator sees on the Identities Live Monitor.

Supplied by eConnect

Node-RED is deployed as part of your eConnect installation. The editor URL and login credentials are supplied by eConnect at the time of install. Most sites will not need to modify the default flow after deployment — it ships with a sensible access-control rule set — but the flow is a great starting point for properties that want to add their own logic, integrations, or notifications.

The Classification Flow

The default flow is four nodes wired end-to-end, turning a raw detection event into a classification message the rest of the system consumes.

The default Face Verify classification flow — AMQPS input, rules function, publish payload builder, AMQPS output

1
Detection In
AMQPS input from the message bus carrying the full detection event.
2
Rules
JavaScript that inspects tags, notes, age, and anything else you need — returns a classification.
3
Build Payload
Shapes the classification into the exact message format Identities expects on the bus.
4
Publish
AMQPS output that writes the classification back onto the message bus for Face Verify and Live Monitor to consume.

Node 1 — Detection Input (AMQPS)

The flow starts with an AMQPS subscription to the live detection stream. Every time the Identities server records a new face detection, a message arrives here carrying the full detection payload — matched person, tags, custom fields, detector name, face ID, detection timestamp, and so on.

You do not normally edit this node. Its job is to deliver fresh detections to the rules that follow.


Node 2 — Rules Function (JavaScript)

This is the heart of the flow — and the node most sites will customize. The default function inspects each detection and returns a classification string based on:

  • Tags currently active on the person (expired tags are ignored)
  • Free-form notes on the person
  • The person's Age attribute against a configurable minimum

Use this as a starting point and adapt the tag names, minimum age, note strings, and logic to match your site's policy:

// Configuration arrays for access control
const PERMITTED_TAGS = ["eC Team", "eScan"]; // Tags that grant access
const DENIED_TAGS = ["Banned", "Self Excluded", "TW", "86"]; // Tags that deny access
const VALIDATION_FAILED_NOTE = ["ID Validation: Failed"]; // Note indicating validation failure
const MINIMUM_AGE = 21; // Minimum age for access

/**
* Determines the access state based on tags, age, and notes.
* @param {Object} msg - The input message containing content with Tags, Face, and DetectorName
* @returns {Object} - The output message with access state and relevant metadata
*/
function determineAccessState(msg) {
// Extract relevant data from the input message
const { Tags, Face, SubjectItem, DetectorName, Id, DetectedDateTimeUtc } = msg.content;
const { Notes } = Face || {};
const { Age } = SubjectItem || {};

// Get the detection time for comparison
const detectionTime = new Date(DetectedDateTimeUtc);

// Filter out expired tags and extract names
const activeTags = (Tags || []).filter(tag => {
// If tag has no expiration, it's always active
if (!tag.Expires) {
return true;
}
// Check if tag hasn't expired yet
const expirationTime = new Date(tag.Expires);
return expirationTime > detectionTime;
});

const tagNames = activeTags.map(tag => tag.Name);

// Initialize the access state
let currentState = "unknown";

// Check for denied tags
const hasDeniedTag = tagNames.some(tag => DENIED_TAGS.includes(tag));
if (hasDeniedTag) {
currentState = "AccessDenied";
}
// Check for permitted tags if no denied tags
else if (tagNames.some(tag => PERMITTED_TAGS.includes(tag))) {
currentState = "AccessGranted";
}

// Override state based on notes or age if applicable
if (currentState === "AccessGranted" && Notes && Notes.includes(VALIDATION_FAILED_NOTE)) {
currentState = "validationFailed";
} else if (currentState === "AccessGranted" && Age < MINIMUM_AGE) {
currentState = "AccessDenied";
}

// Construct the output message
return {
currentState,
deviceName: DetectorName,
tags: tagNames,
faceId: Face?.FaceId,
detectId: Id
};
}

// Process the input message and return the result
return determineAccessState(msg);

Everything downstream of this node is plumbing — whatever string you return from here becomes the EventClassification value that picks which Face Verify Event Theme the customer sees at the kiosk, and which themed card the operator sees on the Identities Live Monitor.

Because you have the full detection payload in hand at this point, you can do whatever you want with the data before returning a classification — look up an external system, call an API, query a database, decorate the message with extra fields, and so on.

Design Your Vocabulary Once

Pick the exact classification strings your organization will use — for example AccessGranted, AccessDenied, VIP, ValidationFailed — and use the same values everywhere: here in the Node-RED rules, in the Face Verify theme editor, and in the Live Monitor theme editor. Consistency is what makes the kiosk and the operator see the same signal at the same moment.


Node 3 — Build Publish Payload

This node takes the output of the rules function and shapes it into the exact payload Identities expects on the message bus. You should not normally need to modify this.

const payloadObj = {
FaceId: msg.faceId,
DetectId: msg.detectId,
Name: 'EventClassification',
Value: msg.currentState
};

msg.exchange = 'facerec.tx';
msg.topic = `facerec.attributes.name.${msg.currentState}`;
msg.payload = payloadObj;
msg.amqpOptions = {
type: 'FaceDetectionBusAttributeItem'
};

return msg;

The payload carries the FaceId, the DetectId, the attribute name (EventClassification), and the classification value. The topic is set to facerec.attributes.name.{classification} so downstream consumers can subscribe to specific classifications if they want to.


Node 4 — Publish to the Message Bus (AMQPS)

The final node publishes the shaped payload back to RabbitMQ on the facerec.tx exchange. Identities subscribes to this exchange and uses the classification to update the detection event.

From there:

  • The Face Verify kiosk matches the classification to its local Event Theme and displays the colored overlay to the customer.
  • The Identities Live Monitor matches the same classification to its Event Theme and colors the detection card for the operator.

You do not normally edit this node.


Customizing the Flow

  1. Open the Node-RED editor using the URL and credentials eConnect supplied at install.
  2. Find the Face Verify Classification flow in the editor.
  3. Double-click Node 2 (the rules function) to edit the JavaScript.
  4. Adjust tag lists, minimum age, note strings, and any other logic you need.
  5. Click Done to save the node, then Deploy (top-right of the editor) to activate.

Changes take effect immediately — the next detection that flows through will use the updated rules.

Extending the Flow

Most properties only need to touch the Node 2 rules function, but the data coming out of that node is yours to route anywhere else you want. Additional flows can branch from the same starting detection to, for example, post a notification to Slack on AccessDenied, log to an external system, or trigger a hardware event. Contact eConnect support if you'd like help authoring additional flows from this starting point.