UNPKG

@minscof/node-red-contrib-asterisk-ari

Version:
1,111 lines (994 loc) 37.2 kB
<script src="resources/topics.js"></script> <script> //console.log("Topics loaded:", availableTopics); //console.log("Default Topics loaded:", defaultTopicsNodeType); </script> <script type="text/javascript"> // Function to update the application dropdown list function updateAppList(node) { let dropdown = $("#node-input-app"); dropdown.empty(); // Clear the list before populating console.log("updateAppList START app:", node.app); let serverId = $("#node-input-server").val(); // ID of the selected server if (!serverId) return; let serverConfig = RED.nodes.node(serverId); // Get the server node //console.debug("🔍 serverConfig récupéré :", serverConfig); if (serverConfig && serverConfig.apps) { let apps = serverConfig.apps.split(","); console.debug("📜 List of applications :", apps); apps.forEach(app => { dropdown.append(new Option(app, app)); }); // 🔄 Wait for the list to be updated before restoring the selected value setTimeout(() => { if (node.app && dropdown.find(`option[value="${node.app}"]`).length > 0) { dropdown.val(node.app); } else { dropdown.val($("#node-input-app option:first").val()); } console.debug("✔️ Selected value after update :", dropdown.val()); }, 50); // Petit délai pour laisser le DOM se mettre à jour } else { console.warn("⚠️ No server selected or empty application list !"); } } // Function to populate the topics <select> function populateTopicsSelect(node) { /* $.getScript('resources/topics.js', function() { console.log("topics.js loaded"); }); */ //const availableTopics = ['StasisStart', 'StasisEnd']; console.debug(`debug populateTopicsSelect`); const select = $("#node-input-topics"); select.empty(); // Clear existing options availableTopics.forEach(topic => { select.append($("<option></option>").attr("value", topic).text(topic)); }); // Restore previously selected values or defaults values select.val(node.topics || defaultTopicsNodeType[node.type]); } </script> <script type="text/javascript"> RED.nodes.registerType('ari_listen', { category: 'asterisk', color: '#989898', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Listen" }, server: { value: "", type: "asterisk_ari", required: true }, app: { value: "" }, topics: { value: "" } }, inputs: 1, outputs: 2, outputLabels: ["start", "event"], label: function () { return this.name || "Application"; }, palletteLabel: "Application", oneditprepare: function () { // Call this function when preparing the editor let node = this; // Load the application list at startup updateAppList(node); // Update the list when the server changes $("#node-input-server").on("change", function () { updateAppList(node); }); populateTopicsSelect(node); }, oneditsave: function () { // Save the selected values this.app = $("#node-input-app").val(); this.topics = $('#node-input-topics').val() || defaultTopicsNodeType[this.type]; } }); </script> <script type="text/html" data-template-name="ari_listen"> <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-server"><i class="fa fa-tag"></i>Asterisk</label> <input type="text" id="node-input-server"> </div> <div class="form-row"> <label for="node-input-app"><i class="fa fa-tag"></i>Application</label> <select id="node-input-app"> <!-- Options will be added dynamically --> </select> </div> <div class="form-row" > <label for="node-input-topics"><i class="fa fa-tag"></i>Topics</label> <select id="node-input-topics" name="node-input-topics" size="5" multiple></select> </div> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_listen"> <!-- data-help-name identifies the node type this help is for --> <!-- This content appears in the Info sidebar when a node is selected --> <!-- The first <p> is used as the pop-up tool tip when hovering over a --> <!-- node in the palette. --> <p>Listen</p> <p>This Node-RED node listens to configured events (topics) from an Asterisk Stasis application and emits messages accordingly.</p> <p>event values <ul> <li>StasisStart,</li> <li>ChannelHangupRequest,</li> <li>StasisEnd,</li> <li>others...</li> </ul> </p> <h3>Outputs</h3> <dl class="message-properties"> <dt>start</dt> <dd> <p>Output an object called <b>msg</b> when the stasis application starts. msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> <dt>event</dt> <dd> <p>Output an object called <b>msg</b> each time the stasis application receives events. msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Details</h3> <p> The node listens to events for the configured stasis application. Put this name in the dialplan. ex exten => _+.,1,Stasis(TestApp), to receive events for an incoming call. </p> <h3>Node Configuration</h3> <dl class="message-properties"> <dt>application name <span class="property-type">string</span> </dt> <dd> The name of the stasis application to register. Stasis applications are configured in the Asterisk config node. </dd> <dt>Asterisk server <span class="property-type">object</span> </dt> <dd> The url of the Asterisk server to use. </dd> </dl> <h3>Example of Use:</h3> <p>Connect the Starting output to trigger call-handling logic when a call enters the Stasis application. Use the Event output to handle specific Asterisk events such as ChannelDtmfReceived, ChannelHangupRequest, etc. </p> <p> This node receives all the events for the stasis application configured in the node. </p> </script> <script type="text/javascript"> RED.nodes.registerType('ari_playback', { category: 'asterisk', color: '#FF9966', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Playback" }, media2: { value: "" }, media2Type: { value: "msg" } }, inputs: 1, outputs: 2, outputLabels: ["end", "event"], label: function () { return this.name || "Playback"; }, palletteLabel: "Playback", oneditprepare: function () { $('#node-input-media2').typedInput({ default: '', typeField: $("#node-input-media2Type"), //type:"msg", types: ["msg", "flow", "global", "str"], }); }, oneditsave: function () { //this.exampleText = this.editor.getValue(); //this.editor.destroy(); media2Type = $('#node-input-media2Type').val() delete this.editor; }, oneditcancel: function () { this.editor.destroy(); delete this.editor; }, }); </script> <script type="text/html" data-template-name="ari_playback"> <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-media2"><i class="fa fa-tag"></i>Media</label> <input type="text" id="node-input-media2" style="width:70%" placeholder="sound:weasels-eaten-phonesys"> <input type="hidden" id="node-input-media2Type"> </div> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_playback"> <!-- data-help-name identifies the node type this help is for --> <!-- This content appears in the Info sidebar when a node is selected --> <!-- The first <p> is used as the pop-up tool tip when hovering over a --> <!-- node in the palette. --> <p>Playback</p> <p>Input and output node.</p> <p> Plays a sound message. The sound message must be configured in the node or provided in the input message. ex : sound:tt-weasels The sound file must be present on the asterisk server. </p> <h3>Input</h3> <dl class="message-properties"> <dt>1</dt> <dd> <p>Input an <b>msg</b> composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the playback is finished msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> <dt>event</dt> <dd> <p>Output an object called <b>msg</b> when the playback starts and finishs. msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Configuration</h3> <dl class="message-properties"> <dt>media</dt> <dd> <p>Node is configured to determine how getting the name of the sound file (media) to play <ul> <li><b>string</b> name of the sound file ex sound:tt-weasels (string), </li> <li><b>flow</b> use a flow variable to get name of the sound file, ex media (string) -> flow.get("media"), </li> <li><b>global</b> use a global variable to get name of the sound file, ex media (string) -> global.get("media"),</li> <li><b>msg</b> use the input msg to get name of the sound file, ex payload.media (string) -> msg.payload.media,</li> </ul> </p> </dd> </dl> </script> <script type="text/javascript"> RED.nodes.registerType('ari_hangup', { category: 'asterisk', color: '#FF6633', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Hangup" } }, inputs: 1, outputs: 1, outputLabels: ["end"], label: function () { return this.name || "Hangup"; }, palletteLabel: "Hangup" }); </script> <script type="text/html" data-template-name="ari_hangup"> <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> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_hangup"> <p> Hangup The Channel</p> <p>Input and output node.</p> <p> </p> <h3>Input</h3> <dl class="message-properties"> <dt>1</dt> <dd> <p>Input an <b>msg</b> composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the hangup is processed msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> </script> <!-- ari_answer section start --> <script type="text/javascript"> RED.nodes.registerType('ari_answer', { category: 'asterisk', color: '#66ff66', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Answer" } }, inputs: 1, outputs: 1, outputLabels: ["answered"], label: function () { return this.name || "Answer"; }, palletteLabel: "Answer" }); </script> <script type="text/html" data-template-name="ari_answer"> <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> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_answer"> <p> Answer the Channel</p> <p>Input and output node.</p> <p> </p> <h3>Input</h3> <dl class="message-properties"> <dt>1</dt> <dd> <p>Input an <b>msg</b> composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the answer is processed msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> </script> <!-- ari_answer section end --> <!-- ari_continueindialplan section start --> <script type="text/javascript"> RED.nodes.registerType('ari_continueindialplan', { category: 'asterisk', color: '#66ff66', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Continue in dialplan" } }, inputs: 1, outputs: 1, outputLabels: ["end"], label: function () { return this.name || "Continue in dialplan"; }, palletteLabel: "Continue in dialplan" }); </script> <script type="text/html" data-template-name="ari_continueindialplan"> <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> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_continueindialplan"> <p>Return to dialplan without closing the channel</p> <p>Input and output node.</p> <p> Return to dialplan configured in asterisk server and keep the channel open. </p> <h3>Input</h3> <dl class="message-properties"> <dt>1</dt> <dd> <p>Input an <b>msg</b> composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the continue to Dialplan is processed msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> </script> <!-- ari_continueindialplan section end --> <!-- ari_bridgedial section start --> <script type="text/javascript"> RED.nodes.registerType('ari_bridgedial', { category: 'asterisk', color: '#339933', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Bridge Dial" }, destination: { value: "" }, callerId: {} }, inputs: 1, outputs: 2, outputLabels: ["end", "event"], label: function () { return this.name || "Bridge Dial"; }, palletteLabel: "Bridge Dial" }); </script> <script type="text/html" data-template-name="ari_bridgedial"> <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-destination"><i class="fa fa-tag"></i>Destination</label> <input type="text" id="node-input-destination" placeholder="PJSIP/1000"> </div> <div class="form-row"> <label for="node-input-callerId"><i class="fa fa-tag"></i>Caller ID</label> <input type="text" id="node-input-callerId" placeholder="2000"> </div> </script> <script type="text/html" data-help-name="ari_bridgedial"> <!-- data-help-name identifies the node type this help is for --> <!-- This content appears in the Info sidebar when a node is selected --> <!-- The first <p> is used as the pop-up tool tip when hovering over a --> <!-- node in the palette. --> <p>Bridge Dial</p> <p>Input and output node.</p> <p>Connect the caller (active channel) to an endpoint</p> <p>Endpoint can be configured in the node settings, or overridden by values in the incoming message's request body (payload.destination property : ex PJSIP/1000) </p> <p>event values <ul> <li>StasisStart,</li> <li>ChannelHangupRequest,</li> <li>StasisEnd,</li> <li>others...</li> </ul> </p> <h3>Inputs</h3> <dl class="message-properties"> <dt>payload <span class="property-type">object</span> </dt> <dd> Incoming message's <code>payload</code> can have destination property to define endpoint to call.. </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the call is done <b>msg.payload</b>. msg.payload is composed of <ul> <li><b>event</b> (string), </li> <li><b>channel</b> (object),</li> <li><b>details</b> (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> <dt>event</dt> <dd> <p>Output an object called <b>msg</b> containing <b>msg.payload</b>. msg.payload is composed of <ul> <li><b>event</b> (string), </li> </ul> </p> </dd> </dl> <h3>Details</h3> <p> to be completed.. <ul> <li>Each incoming message's ...</li> <li>Once </li> <li>Then </li> </ul> </p> <h3>Node Configuration</h3> <dl class="message-properties"> <dt>destination <span class="property-type">string</span> </dt> <dd> Endpoint to call. </dd> <dt>callerid <span class="property-type">string</span> </dt> <dd> Identifier of the caller (optional). </dd> </dl> <h3>Examples of Use:</h3> <ul> <li><strong>Example 1:</strong> <ul> </ul> </li> </ul> </script> <!-- ari_bridgedial section end --> <!-- ari_orginate section start --> <script type="text/javascript"> RED.nodes.registerType('ari_originate', { category: 'asterisk', color: '#339933', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Originate" }, server: { value: "", type: "asterisk_ari", required: true }, app: { value: "" }, topics: { value: "" }, destination: { value: "" }, callerId: {} }, inputs: 1, outputs: 2, outputLabels: ["calling", "event"], label: function () { return this.name || "Originate"; }, palletteLabel: "Originate", oneditprepare: function () { console.debug("ari_originate - oneditprepare START"); let node = this; // Load the application list at startup updateAppList(node); // Update the list when the server changes $("#node-input-server").on("change", function () { updateAppList(node); }); populateTopicsSelect(node); }, oneditsave: function () { let app = $("#node-input-app").val(); console.log(`🔍 oneditsave - app: ${app}`); if (!app) { console.warn("⚠️ No value selected for app !"); } // Save the selected values this.app = $("#node-input-app").val(); this.topics = $('#node-input-topics').val() || defaultTopicsNodeType[this.type]; } }); </script> <script type="text/html" data-template-name="ari_originate"> <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-server"><i class="fa fa-tag"></i>Asterisk</label> <input type="text" id="node-input-server"> </div> <div class="form-row"> <label for="node-input-app"><i class="fa fa-tag"></i>Application</label> <select id="node-input-app"> <!-- Options will be added dynamically --> </select> </div> <div class="form-row"> <label for="node-input-topics"><i class="fa fa-tag"></i>Topics</label> <select id="node-input-topics" name="node-input-topics" size="5" multiple></select> </div> <div class="form-row"> <label for="node-input-destination"><i class="fa fa-tag"></i>Endpoint</label> <input type="text" id="node-input-destination" placeholder="PJSIP/number[@trunk name]"> </div> <div class="form-row"> <label for="node-input-callerId"><i class="fa fa-tag"></i>Caller ID</label> <input type="text" id="node-input-callerId" placeholder="2000"> </div> </script> <script type="text/html" data-help-name="ari_originate"> <!-- data-help-name identifies the node type this help is for --> <!-- This content appears in the Info sidebar when a node is selected --> <!-- The first <p> is used as the pop-up tool tip when hovering over a --> <!-- node in the palette. --> <p>Originate (Call)</p> <p>Input and output node.</p> <p>Define and registered an ari application, call an endpoint and receive all the events to the application</p> <p>Endpoint can be configured in the node settings, or overridden by values in the incoming message's request body (payload.destination property : ex PJSIP/1000) </p> <p>event values <ul> <li>StasisStart,</li> <li>ChannelHangupRequest,</li> <li>StasisEnd,</li> <li>others...</li> </ul> </p> <h3>Inputs</h3> <dl class="message-properties"> <dt>payload <span class="property-type">object</span> </dt> <dd> Incoming message's <code>payload</code> can have destination property to define endpoint to call.. </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the call is done <b>msg.payload</b>. msg.payload is composed of <ul> <li><b>event</b> (string), </li> <li><b>channel</b> (object),</li> <li><b>details</b> (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> <dt>event</dt> <dd> <p>Output an object called <b>msg</b> containing <b>msg.payload</b>. msg.payload is composed of <ul> <li><b>event</b> (string), </li> </ul> </p> </dd> </dl> <h3>Details</h3> <p> to be completed.. <ul> <li>Each incoming message's ...</li> <li>Once </li> <li>Then </li> </ul> </p> <h3>Node Configuration</h3> <dl class="message-properties"> <dt>application name <span class="property-type">string</span> </dt> <dd> The name of the stasis application to register. This application didn't require to be declared in the dialplan. Default: <code>Originate</code>. </dd> <dt>Asterisk server <span class="property-type">object</span> </dt> <dd> The id of the Asterisk server to use. </dd> </dl> <h3>Examples of Use:</h3> <ul> <li><strong>Example 1:</strong> <ul> <li>Configuration: <code>?</code>, <code>.</code>.</li> <li>Behavior: After receiving messages,</li> </ul> </li> </ul> <p> This node receives all the events for the stasis application. </p> </script> <!-- ari_originate section end --> <script type="text/javascript"> RED.nodes.registerType('ari_dtmf_listen', { category: 'asterisk', color: '#66ff66', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "Dtmf_listen" }, codes: { value: "123#,789*" }, codeLength : { value: 4 }, codeTimeout : { value: 5000 } }, inputs: 1, outputs: 3, outputLabels: ["dtmf","code","end"], label: function () { return this.name || "Dtmf_listen"; }, palletteLabel: "Dtmf_listen" }); </script> <script type="text/html" data-template-name="ari_dtmf_listen"> <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-codes"><i class="fa fa-tag"></i>PINs</label> <input type="text" id="node-input-codes" placeholder="123#,789*"> </div> <div class="form-row"> <label for="node-input-code-length"><i class="fa fa-tag"></i>PIN's length</label> <input type="number" id="node-code-length" placeholder="4"> </div> <div class="form-row"> <label for="node-input-code-delay"><i class="fa fa-tag"></i>PIN's delay</label> <input type="number" id="node-code-timeout" placeholder="5000"> </div> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_dtmf_listen"> <p> Dtmf received</p> <p>Input and output node.</p> <p> Listen an opened channel, output DTMF and verify DTMF PIN entered. </p> <h3>Input</h3> <dl class="message-properties"> <dt>1</dt> <dd> <p>Input an <b>msg</b> composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>code</dt> <dd> <p>Output an object called <b>msg</b> when the DTMF PIN entered has been verified msg is composed of <ul> <li><b>code</b> verified DTMF PIN (string), received ex : *49# , </li> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> <dt>dtmf</dt> <dd> <p>Output an object called <b>msg</b> when a DTMF message is received msg is composed of <ul> <li><b>dtmf</b> dtmf received ex : 4 (string), </li> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when channel is closed msg is composed of <ul> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Node Configuration</h3> <dl class="message-properties"> <dt>PINs <span class="property-type">string</span> </dt> <dd> List of DTMF PIN, separated by comma that trigger output ex *86#,7845 Default: <code>123#,789*</code>. </dd> <dt>PINs length <span class="property-type">number</span> </dt> <dd> Length of a DTMF PIN Default: <code>4*</code>. </dd> <dt>PINs timeout <span class="property-type">number</span> </dt> <dd> delay in ms between 2 digits Default: <code>5000</code> 5s. </dd> <dt>Asterisk server <span class="property-type">object</span> </dt> <dd> The id of the Asterisk server to use. </dd> </dl> </script> <!-- ari_dtmf_listen section end --> <!-- ari_dtmf_send section start --> <script type="text/javascript"> RED.nodes.registerType('ari_sendDTMF', { category: 'asterisk', color: '#66ff66', icon: 'font-awesome/fa-asterisk', defaults: { name: { value: "SendDTMF" }, dtmf: { value: "" } }, inputs: 1, outputs: 1, outputLabels: ["dtmf"], label: function () { return this.name || "SendDTMF"; }, palletteLabel: "SendDTMF" }); </script> <script type="text/html" data-template-name="ari_sendDTMF"> <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> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/html" data-help-name="ari_sendDTMF"> <p> sendDTMF</p> <p>Input and output node.</p> <p> </p> <h3>Input</h3> <dl class="message-properties"> <dt>1</dt> <dd> <p>Input an <b>msg</b> composed of <ul> <li><b>dtmf</b> DTMF to send (string), </li> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> <h3>Outputs</h3> <dl class="message-properties"> <dt>end</dt> <dd> <p>Output an object called <b>msg</b> when the sendDTMF is processed msg is composed of <ul> <li><b>dtmf</b> DTMF sent (string), </li> <li><b>event</b> name (string), </li> <li><b>app</b> name (string), </li> <li><b>asteriskId</b> identifier of ari asterisk connection (string),</li> <li><b>channelId</b> identifier of channel (string) - optional</li> <li><b>payload</b> event (object)</li> <li><b>_msgid</b> (string).</li> </ul> </p> </dd> </dl> </script> <!-- ari_sendDTMF section end -->