Appel masqué

Ce guide vous montre comment mettre en œuvre l'idée décrite dans le Cas d'utilisation de la communication vocale privée. Il vous apprend à construire un proxy vocal avec la solution de Vonage. SDK du serveur NodeLe programme est un outil d'aide à la décision, qui utilise des numéros virtuels pour cacher les numéros de téléphone réels des participants. Le code source complet est également disponible dans notre Voice Proxy utilisant le repo GitHub de Voice API. Vous pouvez également vous rendre à l'adresse suivante Code Hub pour tester l'API Masked Calling.

Vue d'ensemble

Dans certains cas, vous pouvez avoir besoin que deux utilisateurs communiquent sans révéler leurs numéros de téléphone personnels. Par exemple, dans un service de covoiturage, les utilisateurs doivent coordonner les heures de prise en charge sans divulguer leurs coordonnées, ce qui permet également d'éviter les arrangements directs qui pourraient réduire votre chiffre d'affaires.

Grâce aux API de Vonage, vous pouvez fournir aux participants des numéros temporaires qui masquent leur véritable numéro de téléphone pendant l'appel. Une fois l'appel terminé, les numéros temporaires sont révoqués, ce qui garantit la confidentialité.

Étapes

Ce guide fournit des instructions pour la construction de l'application, y compris :

Conditions préalables

Pour travailler sur ce cas d'utilisation, vous devez :

Dépôt de code

Il existe un Dépôt GitHub contenant le code.

Configuration

Vous devez créer un .env contenant la configuration. Les instructions pour ce faire sont expliquées dans la section README GitHub. Au fur et à mesure de la lecture de ce guide, vous pouvez renseigner votre fichier de configuration avec les valeurs requises pour les variables telles que la clé API, le secret API, l'ID d'application, le mode de débogage et les numéros provisionnés.

Créer une application Voice API

Une Application Voice API est une construction de Vonage. Il ne faut pas la confondre avec l'application que vous allez écrire. Il s'agit plutôt d'un "conteneur" pour les paramètres d'authentification et de configuration dont vous avez besoin pour travailler avec l'API.

Vous pouvez créer une Application Voice API avec le CLI de Vonage. Vous devez fournir un nom pour l'application et les URL de deux points de terminaison webhook : le premier est le point de terminaison auquel les API de Vonage adresseront une demande lorsque vous recevrez un appel entrant sur votre numéro virtuel, et le second est le point de terminaison où l'API peut poster des données d'événement.

Remplacez le nom de domaine dans la commande CLI de Vonage suivante par votre nom de domaine ngrok (Pour en savoir plus sur la façon de procéder, reportez-vous à la section Comment faire fonctionner ngrok ) et exécutez-le dans le répertoire racine de votre projet :

vonage apps:create "Voice Proxy" --voice_answer_url=https://example.com/proxy-call --voice_event_url=https://example.com/event

Cette commande crée un fichier appelé voice_proxy.key qui contient des informations d'authentification et renvoie un identifiant unique de l'application. Notez cet identifiant car vous en aurez besoin dans les étapes suivantes.

Créer l'application Web

Cette application utilise le Express cadre pour le routage et la SDK du serveur Node de Vonage pour travailler avec l'API Voice. dotenv est utilisé pour que l'application puisse être configurée à l'aide d'un fichier .env fichier texte.

En server.jsLe code initialise les dépendances de l'application et démarre le serveur web. Un gestionnaire de route est implémenté pour la page d'accueil de l'application (/) afin que vous puissiez tester le fonctionnement du serveur en exécutant la commande node server.js et visiter http://localhost:3000 dans votre navigateur :

"use strict";

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
app.set('port', (process.env.PORT || 3000));
app.use(bodyParser.urlencoded({ extended: false }));

const config = require(__dirname + '/../config');

const VoiceProxy = require('./VoiceProxy');
const voiceProxy = new VoiceProxy(config);

app.listen(app.get('port'), function() {
  console.log('Voice Proxy App listening on port', app.get('port'));
});

Notez que le code instancie un objet de la classe VoiceProxy pour gérer l'acheminement des messages envoyés à votre numéro virtuel vers le numéro réel du destinataire. Le processus de procuration est décrit dans la section Proxy de l'appel de ce guide. Pour l'instant, sachez que cette classe initialise le SDK du serveur Vonage à l'aide de la clé et du secret de l'API que vous configurerez à l'étape suivante. Cette configuration permet à votre application de passer et de recevoir des appels vocaux :

const VoiceProxy = function(config) {
  this.config = config;
  
  this.nexmo = new Nexmo({
      apiKey: this.config.VONAGE_API_KEY,
      apiSecret: this.config.VONAGE_API_SECRET
    },{
      debug: this.config.VONAGE_DEBUG
    });
  
  // Virtual Numbers to be assigned to UserA and UserB
  this.provisionedNumbers = [].concat(this.config.PROVISIONED_NUMBERS);
  
  // In progress conversations
  this.conversations = [];
};

Mise à disposition de Numbers virtuels

Les numéros virtuels sont utilisés pour cacher les numéros de téléphone réels aux utilisateurs de votre application.

Le diagramme de flux de travail suivant montre le processus d'approvisionnement et de configuration d'un numéro virtuel :

UserBUserAVonageAppUserBUserAVonageAppInitializationSearch NumbersNumbers FoundProvision NumbersNumbers ProvisionedConfigure NumbersNumbers Configured

Pour provisionner un numéro virtuel, vous recherchez parmi les numéros disponibles ceux qui répondent à vos critères. Par exemple, un numéro de téléphone dans un pays spécifique avec une capacité vocale :

const Nexmo = require('nexmo');

/**
 * Create a new VoiceProxy
 */
const VoiceProxy = function(config) {
  this.config = config;

  this.nexmo = new Nexmo({
    apiKey: this.config.NEXMO_API_KEY,
    apiSecret: this.config.NEXMO_API_SECRET
  },{
    debug: this.config.NEXMO_DEBUG
  });

  // Virtual Numbers to be assigned to UserA and UserB
  this.provisionedNumbers = [].concat(this.config.PROVISIONED_NUMBERS);

  // In progress conversations
  this.conversations = [];
};

/**
 * Provision two virtual numbers. Would provision more in a real app.
 */
VoiceProxy.prototype.provisionVirtualNumbers = function() {
  // Buy a UK number with VOICE capabilities.
  // For this example we'll also get SMS so we can send them a text notification
  this.nexmo.number.search('GB', {features: 'VOICE,SMS'}, function(err, res) {
    if(err) {
      console.error(err);
    }
    else {
      const numbers = res.numbers;

      // For demo purposes:
      // - Assume that at least two numbers will be available
      // - Rent just two virtual numbers: one for each conversation participant
      this.rentNumber(numbers[0]);
      this.rentNumber(numbers[1]);
    }
  }.bind(this));
};

Ensuite, louez les numéros que vous souhaitez et associez-les à votre Applications.

NOTE : Certains types de numéros peuvent nécessiter que vous fournissiez davantage d'informations, telles qu'une adresse postale. Si vous n'êtes pas en mesure d'obtenir un numéro par voie programmatique, vous pouvez consulter le site web de la Commission européenne. Tableau de bord du développeur pour demander ces numéros. Gardez à l'esprit que certains numéros peuvent nécessiter de demander des informations et que le processus ne sera pas entièrement automatisé.

Lorsqu'un événement se produit en rapport avec n'importe quel numéro associé à une application, Vonage enverra une demande à votre point de terminaison webhook avec des informations sur l'événement. Après la configuration, veillez à stocker le numéro de téléphone pour une utilisation ultérieure :

/**
 * Rent the given numbers
 */
VoiceProxy.prototype.rentNumber = function(number) {
  this.nexmo.number.buy(number.country, number.msisdn, function(err, res) {
    if(err) {
      console.error(err);
    }
    else {
      this.configureNumber(number);
    }
  }.bind(this));
};

/**
 * Configure the number to be associated with the Voice Proxy application.
 */
VoiceProxy.prototype.configureNumber = function(number) {
  const options = {
    voiceCallbackType: 'app',
    voiceCallbackValue: this.config.NEXMO_APP_ID,
  };
  this.nexmo.number.update(number.country, number.msisdn, options, function(err, res) {
    if(err) {
      console.error(err);
    }
    else {
      this.provisionedNumbers.push(number);
    }
  }.bind(this));
};

Pour approvisionner les Numbers virtuels, visitez le site http://localhost:3000/numbers/provision dans votre navigateur.

Vous disposez désormais des numéros virtuels nécessaires pour masquer la communication entre vos utilisateurs.

NOTE : Dans une application de production, vous choisirez parmi un pool de numéros virtuels. Toutefois, il est important de conserver cette fonctionnalité pour louer des numéros supplémentaires à la volée.

Créer un appel

Le flux de travail pour créer un appel est présenté dans le diagramme :

UserBUserAVonageAppUserBUserAVonageAppConversation StartsBasic Number InsightNumber Insight responseMap Real/Virtual Numbersfor Each ParticipantSMS to UserASMSSMS to UserBSMS

L'appel suivant :

/**
 * Create a new tracked conversation so there is a real/virtual mapping of numbers.
 */
VoiceProxy.prototype.createConversation = function(userANumber, userBNumber, cb) {
  this.checkNumbers(userANumber, userBNumber)
    .then(this.saveConversation.bind(this))
    .then(this.sendSMS.bind(this))
    .then(function(conversation) {
      cb(null, conversation);
    })
    .catch(function(err) {
      cb(err);
    });
};

Valider les Numbers de téléphone

Lorsque les utilisateurs de votre application fournissent leurs numéros de téléphone, utilisez Number Insight pour vous assurer qu'ils sont valides. Vous pouvez également voir dans quel pays les numéros de téléphone sont enregistrés :

/**
 * Ensure the given numbers are valid and which country they are associated with.
 */
VoiceProxy.prototype.checkNumbers = function(userANumber, userBNumber) {
  const niGetPromise = (number) => new Promise ((resolve) => {
    this.nexmo.numberInsight.get(number, (error, result) => {
      if(error) {
        console.error('error',error);
      }
      else {
        return resolve(result);
      }
    })
  });

  const userAGet = niGetPromise({level: 'basic', number: userANumber});
  const userBGet = niGetPromise({level: 'basic', number: userBNumber});

  return Promise.all([userAGet, userBGet]);
};

Associer des numéros de téléphone à des Numbers réels

Une fois que vous êtes sûr que les numéros de téléphone sont valides, faites correspondre chaque numéro réel à un numéro virtuel et enregistrer l'appel :

/**
 * Store the conversation information.
 */
VoiceProxy.prototype.saveConversation = function(results) {
  let userAResult = results[0];
  let userANumber = {
    msisdn: userAResult.international_format_number,
    country: userAResult.country_code
  };

  let userBResult = results[1];
  let userBNumber = {
    msisdn: userBResult.international_format_number,
    country: userBResult.country_code
  };

  // Create conversation object - for demo purposes:
  // - Use first indexed LVN for user A
  // - Use second indexed LVN for user B
  let conversation = {
    userA: {
      realNumber: userANumber,
      virtualNumber: this.provisionedNumbers[0]
    },
    userB: {
      realNumber: userBNumber,
      virtualNumber: this.provisionedNumbers[1]
    }
  };

  this.conversations.push(conversation);

  return conversation;
};

Envoyer un SMS de confirmation

Dans un système de communication privé, lorsqu'un utilisateur en contacte un autre, l'appelant appelle un numéro virtuel depuis son téléphone.

Envoyez un SMS pour informer chaque participant à la conversation du numéro virtuel qu'il doit appeler :

/**
 * Send an SMS to each conversation participant so they know each other's
 * virtual number and can call either other via the proxy.
 */
VoiceProxy.prototype.sendSMS = function(conversation) {
  // Send UserA conversation information
  // From the UserB virtual number
  // To the UserA real number
  this.nexmo.message.sendSms(conversation.userB.virtualNumber.msisdn,
                             conversation.userA.realNumber.msisdn,
                             'Call this number to talk to UserB');

  // Send UserB conversation information
  // From the UserA virtual number
  // To the UserB real number
  this.nexmo.message.sendSms(conversation.userA.virtualNumber.msisdn,
                             conversation.userB.realNumber.msisdn,
                             'Call this number to talk to UserB');

  return conversation;
};

Les utilisateurs ne peuvent pas s'envoyer de SMS entre eux. Pour activer cette fonctionnalité, vous devez configurer Communication privée par SMS.

Dans ce guide, chaque utilisateur a reçu le numéro virtuel dans un SMS. Dans d'autres systèmes, ce numéro pourrait être fourni à l'aide d'un courriel, de notifications in-app ou d'un numéro prédéfini.

Traiter les appels entrants

Lorsque Vonage reçoit un appel entrant à votre numéro virtuel, il fait une demande au point de terminaison webhook que vous avez défini lorsque vous avez création d'une application Voice API:

UserBUserAVonageAppUserBUserAVonageAppUserA calls UserB'sVonage NumberCalls virtual numberInbound Call(from, to)

Extrait to et from du webhook entrant et les transmet à la logique métier du proxy vocal :

app.get('/proxy-call', function(req, res) {
  const from = req.query.from;
  const to = req.query.to;

  const ncco = voiceProxy.getProxyNCCO(from, to);
  res.json(ncco);
});

Inverser la carte des numéros de téléphone réels vers les numéros virtuels

Maintenant que vous connaissez le numéro de téléphone qui passe l'appel et le numéro virtuel du destinataire, inversez la correspondance entre le numéro virtuel entrant et le numéro de téléphone réel sortant :

UserBUserAVonageAppUserBUserAVonageAppFind the real number for UserBNumber mapping lookup

La direction de l'appel peut être identifiée comme suit :

  • Les from est un nombre réel UserA et le nombre to le numéro est le numéro de UserB Vonage
  • Les from est un nombre réel UserB et le nombre to est le numéro de UserA Vonage
const fromUserAToUserB = function(from, to, conversation) {
  return (from === conversation.userA.realNumber.msisdn &&
          to === conversation.userB.virtualNumber.msisdn);
};
const fromUserBToUserA = function(from, to, conversation) {
  return (from === conversation.userB.realNumber.msisdn &&
          to === conversation.userA.virtualNumber.msisdn);
};

/**
 * Work out real number to virtual number mapping between users.
 */
VoiceProxy.prototype.getProxyRoute = function(from, to) {
  let proxyRoute = null;
  let conversation;
  for(let i = 0, l = this.conversations.length; i < l; ++i) {
    conversation = this.conversations[i];

    // Use to and from to determine the conversation
    const fromUserA = fromUserAToUserB(from, to, conversation);
    const fromUserB = fromUserBToUserA(from, to, conversation);

    if(fromUserA || fromUserB) {
      proxyRoute = {
        conversation: conversation,
        to: fromUserA? conversation.userB : conversation.userA,
        from: fromUserA? conversation.userA : conversation.userB
      };
      break;
    }
  }

  return proxyRoute;
};

Une fois la recherche de numéro effectuée, il ne reste plus qu'à passer l'appel.

Proxy de l'appel

Proxy l'appel vers le numéro de téléphone auquel le numéro virtuel est associé. Le numéro from est toujours le numéro virtuel, et le numéro to est un vrai numéro de téléphone.

UserBUserAVonageAppUserBUserAVonageAppProxy Inboundcall to UserB'sreal numberUserA has calledUserB. But UserAdoes not have the real numberof UserB, nor vice versa.Connect (proxy)Call

Pour ce faire, créez un NCCO (Nexmo Call Control Object). Ce BCN utilise un talk pour lire un texte. Lorsque le talk est terminée, un connect transfère l'appel vers un numéro réel.

/**
 * Build the NCCO response to instruct Nexmo how to handle the inbound call.
 */
VoiceProxy.prototype.getProxyNCCO = function(from, to) {
  // Determine how the call should be routed
  const proxyRoute = this.getProxyRoute(from, to);

  if(proxyRoute === null) {
    const errorText = 'No conversation found' +
                    ' from: ' + from +
                    ' to: ' + to;
    throw new Error(errorText);
  }

  // Build the NCCO
  let ncco = [];

  const textAction = {
    action: 'talk',
    text: 'Please wait whilst we connect your call'
  };
  ncco.push(textAction);

  const connectAction = {
    action: 'connect',
    from: proxyRoute.from.virtualNumber.msisdn,
    endpoint: [{
      type: 'phone',
      number: proxyRoute.to.realNumber.msisdn
    }]
  };
  ncco.push(connectAction);

  return ncco;
};

Le NCCO est renvoyé à Vonage par le serveur web.

app.get('/proxy-call', function(req, res) {
  const from = req.query.from;
  const to = req.query.to;

  const ncco = voiceProxy.getProxyNCCO(from, to);
  res.json(ncco);
});

Conclusion

Vous avez appris à créer un proxy vocal pour les communications privées. Vous avez approvisionné et configuré des numéros de téléphone, effectué une recherche de numéros, mis en correspondance des numéros réels avec des numéros virtuels pour garantir l'anonymat, traité un appel entrant et transféré l'appel à un autre utilisateur.

Plus d'informations