Not able to integrate custom node

I a real noobie to creating nodes.I wanted to add an output property to the build in delay node which gives the total delay applied while random delay is selected. This info will be send as msg.delay_time. I was able to find this js code for the same and package.json. I even packaged the things using npm pack. but when i try to add the tgz file to nodered, I get the error

Failed to install: delay-modified-1.0.0.tgz

Module not found

Check the log for more information

delay-modified.js

module.exports = function(RED) {
    function DelayNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        var queue = [];
        var timing = false;

        function processQueue() {
            if (queue.length > 0) {
                var message = queue.shift();
                node.send([message, {payload: message.delay_time}]); // send new msg with delay_time property
                if (queue.length > 0) {
                    var diff = queue[0].delay - message.delay;
                    if (diff < 0) { diff = 0; }
                    timing = setTimeout(processQueue, diff);
                } else {
                    timing = false;
                }
            }
        }

        this.on('input', function(msg) {
            var delay = Number(msg.delay || config.delay || 0);
            if (isNaN(delay)) {
                delay = 0;
            }
            msg.delay_time = delay; // add delay_time property to input msg
            queue.push({
                msg: msg,
                delay: delay + (config.random ? Math.floor(Math.random()*delay) : 0)
            });
            if (!timing) {
                timing = setTimeout(processQueue, delay);
            }
        });

        this.on('close', function() {
            if (timing) {
                clearTimeout(timing);
            }
        });
    }
    RED.nodes.registerType("delay-modified",DelayNode);
}

package.json

{
  "name": "delay-modified",
  "version": "1.0.0",
  "description": "Modified delay node for Node-RED",
  "main": "delay-modified.js",
  "author": "Xhex2 Xehasalam@gmail.com",
  "license": "MIT"
}

the package was with name delay-modified-1.0.0.tgz

Hope someone can help.

Your package.json file is missing the node-red section required to identify your nodes...

https://nodered.org/docs/creating-nodes/packaging#packagejson

I assume you also have an html file for your node?

I added the node red section in package.json and i was able to install the node but when I check the package manager, I see the node is inactive. Why so?

Did you include the html file for the node as well?

YES, index.html file looks like

<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Delay Modified UI</title>
	<script type="text/javascript" src="vendor/jquery/jquery.min.js"></script>
	<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.min.js"></script>
	<link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css">
	<link rel="stylesheet" href="style.css">
	<script type="text/javascript" src="script.js"></script>
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-md-6">
				<div class="form-group">
					<label for="node-input-name">Name</label>
					<input type="text" id="node-input-name" placeholder="Name">
				</div>
				<div class="form-group">
					<label for="node-input-delay">Delay</label>
					<input type="number" id="node-input-delay" placeholder="Delay">
				</div>
				<div class="form-group">
					<label for="node-input-delay-time">Delay Time</label>
					<input type="text" id="node-input-delay-time" placeholder="Delay Time" readonly>
				</div>
			</div>
			<div class="col-md-6">
				<p><strong>Description:</strong></p>
				<p>This is a modified delay node for Node-RED with added delay_time property.</p>
				<p><strong>Usage:</strong></p>
				<p>Use this node to delay messages in your flow with a random or fixed delay time. The delay time can be specified in milliseconds, seconds, or minutes. The actual delay time applied to each message will be shown in the output message's delay_time property.</p>
			</div>
		</div>
	</div>
</body>
</html>

Node-RED node HTML files don't look like that.

They do not have head or body sections and must have the same name as the js file e.g. delay-modified.html

The docs for the html file are here: HTML File : Node-RED

Thanks. Will it be possbile to add the feature of sending a msg.delay_time with the output when the random delay is selected to inbuilt delay node in the coming update?

I actually tried to design another node called time-number-limit node. I have also generated the html file but still inactive. the files are as follows.

time-number-limit.js

module.exports = function(RED) {
    function TimeNumberLimitNode(config) {
        RED.nodes.createNode(this, config);
        var node = this;
        var limit = config.limit;
        var interval = config.interval;
        var startTime = config.start_time;
        var endTime = config.end_time;
        var messages = [];
        
        function checkLimits() {
            var currentTime = new Date().getTime();
            if (startTime && endTime) {
                if (currentTime < startTime || currentTime > endTime) {
                    return false;
                }
            } else if (interval) {
                if (messages.length >= limit) {
                    var oldestMessageTime = messages[0].time;
                    if (currentTime - oldestMessageTime < interval) {
                        return false;
                    } else {
                        messages.shift();
                    }
                }
            }
            return true;
        }
        
        function sendMessages() {
            for (var i = 0; i < messages.length; i++) {
                var msg = messages[i].msg;
                var outputIndex = messages[i].outputIndex;
                node.send([null, msg]); // send to second output
                if (outputIndex === 0) {
                    node.send([msg, null]); // send to first output
                }
            }
            messages = [];
        }
        
        function addMessage(msg, outputIndex) {
            var currentTime = new Date().getTime();
            messages.push({msg: msg, time: currentTime, outputIndex: outputIndex});
        }
        
        node.on('input', function(msg) {
            if (checkLimits()) {
                addMessage(msg, 0);
            } else {
                addMessage(msg, 1);
            }
            if (messages.length >= limit || (!interval && startTime && endTime)) {
                sendMessages();
            }
        });
        
        node.on('close', function() {
            if (messages.length > 0) {
                sendMessages();
            }
        });
    }
    RED.nodes.registerType("time-number-limit", TimeNumberLimitNode);
}

package.json

{
    "name": "node-red-contrib-time-number-limit",
    "version": "1.0.0",
    "description": "A Node-RED node to limit the number of messages sent in a set interval or within a specified time range.",
    "keywords": [
        "node-red",
        "node",
        "time",
        "number",
        "limit"
    ],
    "author": "Your Name <your.email@example.com>",
    "license": "MIT",
    "main": "time-number-limit.js",
    "dependencies": {
        "moment": "^2.29.1"
    },
    "node-red": {
        "nodes": {
            "time-number-limit": "time-number-limit.js"
        }
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/your-username/node-red-contrib-time-number-limit.git"
    }
}

time-number-limit.html

<script type="text/javascript">
    $(function() {
        // Function to handle changes to the "Limit Type" dropdown
        function updateLimitType() {
            var limitType = $('#node-input-limittype').val();
            if (limitType == 'interval') {
                $('#node-row-interval').show();
                $('#node-row-timerange').hide();
            } else if (limitType == 'timerange') {
                $('#node-row-interval').hide();
                $('#node-row-timerange').show();
            }
        }

        // Initialize the UI based on the initial value of the "Limit Type" dropdown
        updateLimitType();

        // Register a handler for changes to the "Limit Type" dropdown
        $('#node-input-limittype').change(updateLimitType);
    });
</script>

<script type="text/x-red" data-template-name="time-number-limit">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>

    <div class="form-row">
        <label for="node-input-limittype"><i class="fa fa-clock-o"></i> Limit Type</label>
        <select id="node-input-limittype">
            <option value="interval">Interval</option>
            <option value="timerange">Time Range</option>
        </select>
    </div>

    <div class="form-row" id="node-row-interval">
        <label for="node-input-interval"><i class="fa fa-clock-o"></i> Interval (ms)</label>
        <input type="text" id="node-input-interval" placeholder="1000">
    </div>

    <div class="form-row" id="node-row-timerange">
        <label for="node-input-starttime"><i class="fa fa-calendar"></i> Start Time</label>
        <input type="text" id="node-input-starttime" placeholder="yyyy-mm-dd hh:mm:ss">

        <label for="node-input-endtime"><i class="fa fa-calendar"></i> End Time</label>
        <input type="text" id="node-input-endtime" placeholder="yyyy-mm-dd hh:mm:ss">
    </div>

    <div class="form-row">
        <label for="node-input-count"><i class="fa fa-hashtag"></i> Message Count</label>
        <input type="text" id="node-input-count" placeholder="10">
    </div>

    <div class="form-row">
        <label><i class="fa fa-sort-amount-desc"></i> Outputs</label>
        <select id="node-input-outputs">
            <option value="split">Split</option>
            <option value="filter">Filter</option>
        </select>
    </div>

    <div class="form-tips">
        <p>Limit the number of messages sent through this node based on either:</p>
        <ul>
            <li>An interval of time (e.g. limit to 10 messages per second)</li>
            <li>A range of time (e.g. limit to 100 messages between 9am and 5pm)</li>
        </ul>
    </div>
</script>

<script type="text/x-red" data-help-name="time-number-limit">
    <p>A node that limits the number of messages sent in a set interval or within a specified time range.</p>
    <p>The node has two outputs: one for payloads that fit the criteria and the second for those that do not.</p>
    <h4>Limit Type</h4>
    <p>Select the type of limit you want to apply to the messages:</p>
    <ul>
        <li><strong>Interval</strong>: limit the number of messages sent in a set interval of time (e.g. 10 messages per second).</li>
        <li><strong>Time Range</strong>: limit the number of messages sent within a specified time range (e.g. 100 messages between 9am and 5pm).</li>
    </ul>
    <h4>Interval Limit</h4>
    <p>If you selected <strong>Interval</strong> as the limit type, set the interval time (in milliseconds) and the maximum number of messages to be sent during that interval:</p>
    <ul>
        <li><strong>Interval Time</strong>: the interval of time (in milliseconds) during which the messages will be sent.</li>
        <li><strong>Message Count</strong>: the maximum number of messages to be sent during the interval time.</li>
    </ul>
    <h4>Time Range Limit</h4>
    <p>If you selected <strong>Time Range</strong> as the limit type, set the start and end times of the time range and the maximum number of messages to be sent during that time range:</p>
    <ul>
        <li><strong>Start Time</strong>: the start time of the time range (in YYYY-MM-DD HH:mm:ss format).</li>
        <li><strong>End Time</strong>: the end time of the time range (in YYYY-MM-DD HH:mm:ss format).</li>
        <li><strong>Message Count</strong>: the maximum number of messages to be sent during the time range.</li>
    </ul>
    <h4>Outputs</h4>
    <p>Select the output mode:</p>
    <ul>
        <li><strong>Split</strong>: split the input messages into two output messages: one for payloads that fit the criteria and the second for those that do not.</li>
        <li><strong>Filter</strong>: filter the input messages and send only the payloads that fit the criteria to the first output. All other messages are sent to the second output.</li>
    </ul>
</script>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.