Search code examples
asteriskasterisk-ari

How to get the dialed number in Stasis app


I am trying to wrap my head around ARI and Asterisk, my goal is to dial from an extension to another. I dialed 5001 from extension 5002. Now in the stasisStart function, I want to create a new channel, and used the dialed number (5001) and pass 'PJSIP/5001' to the endpoint. How do I get the dialed number?

Dialplan:

exten  => _500Z, 1, Stasis(test-app)

test-app.js

    function stasisStart(event, channel) {

    // I want to dial 'PJSIP/5001' (the dialed number)
    client.channels.originate({ endpoint: 'PJSIP/5001', app: 'test-app' },)
    .then(function (originatedChannel) {
        console.log(' originated ');
        console.log(util.format('originated channel id %s  - name: %s', originatedChannel.id, originatedChannel.name));
    })
    .catch(function (err) { console.log('error happened'); });

}


Channel  
id: "1603812843.140"
name: "PJSIP/5002-0000004e"
state: "Ring"
caller: {"name":"","number":"5002"}
connected: {"name":"","number":""}
accountcode: ""
dialplan: {"context":"internal","exten":"5001","priority":1,"app_name":"Stasis","app_data":"test-app"}
creationtime: "2020-10-27T11:34:03.251-0400"
language: "en"

Solution

  • I found this example that works. I guess I was confused about the endpoint, I thought I had to specify it in the dialplan, but not.

    /**
     *  This example shows how a call can be originated from a channel entering a
     *  Stasis application to an endpoint. The endpoint channel will then enter the
     *  Stasis application and the 2 channels will be placed into a mixing bridge.
     *      exten => _500Z,1,NoOp()
     *      same => n,Stasis(originate-example)
     *      same => n,Hangup()
     */
    
    'use strict';
    
    var client = require('ari-client');
    
    var ENDPOINT = 'PJSIP/5001'; // TODO: enter your endpoint here
    
    
    // TODO: replace with your Asterisk instance: host, user and secret
    client.connect('http://localhost:8088', 'asterisk', 'asterisk', 
        /**
         *  Setup event listeners and start application.
         *
         *  @callback connectCallback
         *  @memberof originate-example
         *  @param {Error} err - error object if any, null otherwise
         *  @param {module:ari-client~Client} ari - ARI client
         */
        function (err, ari) {
    
      // Use once to start the application to ensure this listener will only run
      // for the incoming channel
      ari.once('StasisStart',
          /**
           *  Once the incoming channel has entered Stasis, answer it and originate
           *  call to the endpoint (outgoing channel).
           *
           *  @callback incomingStasisStartCallback
           *  @memberof originate-example
           *  @param {Object} event - the full event object
           *  @param {module:resources~Channel} incoming -
           *    the incoming channel entering Stasis
           */
          function (event, incoming) {
    
        incoming.answer(function (err) {
          originate(incoming);
        });
      });
    
      /**
       *  Originate the outgoing channel
       *
       *  @function originate
       *  @memberof originate-example
       *  @param {module:resources~Channel} incoming - the incoming channel that
       *    will originate the call to the endpoint
       */
      function originate (incoming) {
        incoming.once('StasisEnd',
            /**
             *  If the incoming channel ends, hangup the outgoing channel.
             *
             *  @callback incomingStasisEndCallback
             *  @memberof originate-example
             *  @param {Object} event - the full event object
             *  @param {module:resources~Channel} channel -
             *    the incoming channel leaving Stasis
             */
            function (event, channel) {
    
          outgoing.hangup(function (err) {});
        });
    
        var outgoing = ari.Channel();
    
        outgoing.once('ChannelDestroyed',
            /**
             *  If the endpoint rejects the call, hangup the incoming channel.
             *
             *  @callback outgoingChannelDestroyedCallback
             *  @memberof originate-example
             *  @param {Object} event - the full event object
             *  @param {module:resources~Channel} channel -
             *    the channel that was destroyed
             */
            function (event, channel) {
    
          incoming.hangup(function (err) {});
        });
    
        outgoing.once('StasisStart',
            /**
             *  When the outgoing channel enters Stasis, create a mixing bridge
             *  and join the channels together.
             *
             *  @callback outgoingStasisStartCallback
             *  @memberof originate-example
             *  @param {Object} event - the full event object
             *  @param {module:resources~Channel} outgoing -
             *    the outgoing channel entering Stasis
             */
            function (event, outgoing) {
    
          var bridge = ari.Bridge();
    
          outgoing.once('StasisEnd',
              /**
               *  If the outgoing channel ends, clean up the bridge.
               *
               *  @callback outgoingStasisEndCallback
               *  @memberof originate-example
               *  @param {Object} event - the full event object
               *  @param {module:resources~Channel} channel -
               *    the outgoing channel leaving Stasis
               */
              function (event, channel) {
    
            bridge.destroy(function (err) {});
          });
    
          outgoing.answer(
              /**
               *  Once the outgoing channel has been answered, create a mixing
               *  bridge and add the incoming and outgoing channels to it.
               *
               *  @callback outgoingAnswerCallback
               *  @memberof originate-example
               *  @param {Error} err - error object if any, null otherwise
               */
              function (err) {
    
            bridge.create({type: 'mixing'},
                /**
                 *  Once the mixing bridge has been created, join the incoming and
                 *  outgoing channels to it.
                 *
                 *  @callback bridgeCreateCallback
                 *  @memberof originate-example
                 *  @param {Error} err - error object if any, null otherwise
                 *  @param {module:resources~Bridge} bridge - the newly created
                 *    mixing bridge
                 */
                function (err, bridge) {
    
              bridge.addChannel(
                {channel: [incoming.id, outgoing.id]},
                function (err) {}
              );
            });
          });
        });
    
        var playback = ari.Playback();
        incoming.play({media: 'sound:vm-dialout'}, playback, function (err) {});
    
        // Originate call from incoming channel to endpoint
        outgoing.originate(
          {endpoint: ENDPOINT, app: 'originate-example', appArgs: 'dialed'},
          function (err, channel) {}
        );
      }
    
      // can also use ari.start(['app-name'...]) to start multiple applications
      ari.start('originate-example');
    });