npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

drachtio-fn-b2b-sugar

v0.1.2

Published

drachtio B2B function that forks multiple simultaneous call attempts

Downloads

336

Readme

drachtio-fn-b2b-sugar

A selection of useful and reusable functions dealing with common B2BUA scenarios for the drachtio SIP server.

simring function

A common need is to do a simultaneous ring of multiple SIP endpoints in response to an incoming call, connecting the caller to the first answering device and terminating the other requests.

This function provides a forking outdial B2BUA that connects the caller to the first endpoint that answers.

basic usage

In basic usage, the exported simring function acts almost exactly like Srf#createB2BUA, except that you pass an array of sip URIs rather than a single sip URI.

const {simring} = require('drachtio-fn-b2b-sugar');
srf.invite(async (req, res) {
  try {
    const {uas, uac} = await simring(req, res, ['sip:[email protected]', 'sip:[email protected]']);
    console.info(`successfully connected to ${uas.remote.uri}`);
  } catch (err) {
    console.log(err, 'Error connecting call');
  }
});

All of the options that you can pass to Srf#createB2BUA can be passed to simring.

with logging

If you want logging from simring, you can treat the exported simring reference as a factory function that you invoke with a single argument, that being the logger object that you want to be used. That object must provide 'debug', 'info', and 'error' functions (e.g. pino).

Invoking the factory function then returns another function that does the actual simring.

const logger = require('pino')();
const {simring} = require('drachtio-fn-b2b-sugar');
const doSimring = simring(logger);
srf.invite(async (req, res) {
  try {
    const {uas, uac} = await doSimring(req, res, ['sip:[email protected]', 'sip:[email protected]']);
    console.info(`successfully connected to ${uas.remote.uri}`);
  } catch (err) {
    console.log(err, 'Error connecting call');
  }
});

Simring class

A more advanced usage is to to start a simring against a list of endpoints, and then later (before any have answered) add one or more new endpoints to the simring list.

This would be useful, for instance, in a scenario where you are ringing all of the registered devices for a user and while doing that a new device registers that you also want to include.

In this case, you would use the Simring class, which exports a Simring#addUri method to do just that.

const logger = require('pino')();
const {Simring} = require('drachtio-fn-b2b-sugar');

srf.invite(async (req, res) {
  const simring = new Simring(req, res, ['sip:[email protected]', 'sip:[email protected]']);
  simring.start()
    .then(({uas, uc}) => {
      console.info(`successfully connected to ${uas.remote.uri}`);
    })
    .catch((err) => console.log(err, 'Error connecting call'));
  
  // assume we are alerted when a new device registers
  someEmitter.on('someRegisterEvent', () => {
    if (!simring.finished) simring.addUri('sip:[email protected]');
  });

transfer (REFER handler)

Handle REFER messasges in your B2B dialogs.

const {transfer} = require('drachtio-fn-b2b-sugar');

const auth = (username) => {
  // Valid username can make REFER/transfers
  //if (username == 'goodGuy') {
  //  return true;
  //} else {
  //  return false;
  //}
}

const destLookUp = (username) => {
  // do lookup on username here
  // to get an IP address or domain
  // const ipAddress = someLook();
  // return ipAddress;
};

srf.invite(async (req, res) {
  try {
    const {uas, uac} = await srf.createB2BUA(req, res, destination, {localSdpB: req.body});
    uac.on('refer', async (req, res) => {
      const opts = {
        srf, // required
        req, // required
        res,  // required
        transferor: uac, // required
        // authLookup: referAuthLookup, // optional, unless auth is true
        // destinationLookUp: this.referDestinationLookup, // optional
      }
      const { transfereeDialog, transferTargetDialog } = await transfer(opts);
    });

    uas.on('refer', async (req, res) => {
      const opts = {
        srf, // required
        req, // required
        res,  // required
        transferor: uas, // required
        authLookup: auth, // optional, unless auth is true
        destinationLookUp: destLookUp, // optional
      }
      const { transfereeDialog, transferTargetDialog } = await transfer(opts);
    });
  } catch (error) {
    console.log(error);
  }
});

Options

  • authLookup: function - used to verify endpoint sending REFER is allowed to REFER calls in your environment
  • destinationLookUp: function - used to determine what IP address (or domain) to use when calling the transferTarget (the person being transferred to). If not set, whatever is put in the Refer-To uri will be used

forwardInDialogRequests

This function forwards in-dialog requests received on one Dialog in a B2B to the paired Dialog. It does not handle in-dialog INVITEs (e.g. re-INVITEs) or UPDATE requests, however, as these usually require application-specific processing.

The signature is: forwardInDialogRequests(dlg, requestTypes), e.g.:

const {forwardInDialogRequests} = require('drachtio-fn-b2b-sugar');
const {uas, uac} = await srf.createB2BUA(..);
forwardInDialogRequests(uas, ['info', 'options', 'notify']);

The list of request types to forward is optional; if not specified all request types (except, as per above, INVITEs and UPDATEs) will for forwarded:

forwardInDialogRequests(uas); // forwards all requests (except INVITE and UPDATE)

Note that although you only provide one of the paired dialogs as an argument, in-dialog requests are forwarded in both directions (e.g. though you may specify 'uas', requests received on 'uac' are also forwarded to the uas).

Also note that you can still attach your own event listeners to the in-dialog requests (just don't try to forward the requests in your event handler, since that will already be taken care of).