https://a.storyblok.com/f/270183/35355/4fdbf7840e/embed-vbc.png

Faça chamadas telefônicas com o Microsoft Excel e o SDK do Vonage Open ContactPad

Publicado em February 14, 2022

Tempo de leitura: 7 minutos

Introdução

Nesta página, explicarei como criei uma integração funcional do VBC com uma plataforma de terceiros em pouco tempo, utilizando o novo Vonage Open ContactPad. Primeiro, aqui está um Video que demonstra as funcionalidades disponíveis da integração.

Aplicativo selecionado - Microsoft Excel Online

Eu selecionei o Microsoft Excel Online porque tinha lido recentemente que a Microsoft lançou uma API em JavaScript para o Excel. Muitas pessoas usam o programa para trabalhar com planilhas e achei que era uma maneira razoavelmente simples de lidar com os dados. O Microsoft Excel permite integrações por meio de complementos do Office. Um complemento muito legal é o Script Lab, que permite que os desenvolvedores experimentem a criação de complementos. O objetivo deste guia prático será explicar como adicionar o código ao Script Lab usando funções do Excel e do JavaScript da Vonage e, em seguida, publicar o resultado em um GitHub Gist. Para dar continuidade a partir daí, o leitor pode se interessar por publicar complementos do Office.

Acompanhando no Microsoft Excel Online

Para aproveitar ao máximo este guia prático, recomenda-se instalar o complemento Script Lab para o Office e importar o Gist do GitHub:

O Gist contém o código-fonte completo para você personalizar de acordo com seu projeto. Os exemplos abaixo são, às vezes, muito específicos e não incluem tudo o que você precisa para fazer uma determinada função funcionar.

Introdução ao Vonage Open ContactPad

O SDK do Vonage Open ContactPad é um kit de ferramentas de desenvolvimento de software em JavaScript que permite aos desenvolvedores incorporar um interface de discagem do Vonage Unified Communications (UC) em um aplicativo baseado na web. Embora seja necessário fazer login com uma conta da Vonage Business Communications para usá-lo, é possível desenvolver com o SDK sem a necessidade de usuários de API adicionais ou cadastros. Isso resulta em uma estrutura de integração muito leve para desenvolvedores que desejam incorporar clientes de comunicação em seus aplicativos.

Por que o Microsoft Excel Online e não o aplicativo para PC/Mac?

É importante observar que o produto Vonage Open ContactPad SDK foi desenvolvido para ser incorporado em aplicativos da web e funciona melhor quando o desenvolvedor tem controle total sobre o espaço em que ele está incorporado. Há uma observação na parte inferior da página de introdução que destaca exatamente esse ponto.

Configurando o Script Lab e as primeiras linhas de código

Ao instalar o Script Lab no Excel, ele cria um item de menu “Script Lab” à direita do item de menu “Ajuda”. Clique nessa guia e você verá três botões que ajudam a trabalhar com o Script Lab: “Código”, “Executar” e “Funções”. Em seguida, clique em Código: uma janela será exibida, integrada à interface do Excel, semelhante a uma janela do Visual Studio, onde você poderá inserir seu código. Contanto que você não limpe o cache do navegador, seu código do Script Lab permanecerá lá. Se preferir que ele permaneça por mais tempo, use a opção Compartilhar para salvar seu código como um gist no GitHub. Nas minhas experiências, acabei criando muitos gists privados. Se estivesse trabalhando em um projeto de integração de verdade, provavelmente transferiria meu código para o Visual Studio Code e trabalharia com um controle de versão mais preciso.

Assim que me familiarizei com o Script Lab, comecei pela seção de HTML, onde já sabia que queria incorporar meu discador. Para acompanhar, confira as instruções aqui sobre carregar o Open ContactPad. Isso inclui uma exemplo ao vivo de como fazer isso usando o Plunker.

No meu caso, eu queria fornecer um <div> contêiner para que meu aplicativo fosse exibido na interface completa do discador e não como um ponto móvel na página. Defini o data-provider como uc para carregar o discador do Unified Communications.

<div class="vonage-dialer-container"></div>
<script data-provider="uc" data-autoload="false" src="https://apps.gunify.vonage.com/cti/common/vonage.dialer.sdk.js">
</script>

O mais incrível é que você pode PARAR AQUI, executar o código e já ter um discador integrado no Microsoft Excel Online! No entanto, há muito mais que os desenvolvedores podem fazer para personalizar a experiência.

Explorando a API do Excel – Configurando os dados de exemplo

Então, por que configurar dados de exemplo? Bem, eu queria dar aos usuários exemplos de como eu quero que seja o formato e a localização dos dados na planilha, para que o código saiba onde encontrá-los. Eu queria uma área clicável para iniciar uma ligação para cada “contato” (linha) e definir um campo para o número de telefone. Comecei com o HTML do aplicativo no Script Lab e adicionei um botão que preencheria os dados na seção desejada da planilha. Se você pressionar esse botão várias vezes, ele simplesmente sobrescreverá o que está na planilha.

<center><button onclick="populateSampleData()">Populate Sample Data</button></center>

O próximo passo é implementar a função `populateSampleData()` em JavaScript. Felizmente, a documentação da API do JavaScript do Microsoft Excel apresenta alguns exemplos.

function populateSampleData() {
 return Excel.run(function(context) {
   var worksheet = context.workbook.worksheets.getItem("Sheet1");
 
   var data = [
     ["Company", "Contact Last", "Contact First", "Number", ""],
     ["Widget Zone", "Anderson", "Wendy", "555-555-5555", "Dial"],
     ["Widgets Galore", "Burns", "Ryan", "555-555-5555", "Dial"],
     ["Widgets Emporium", "Johnson", "Amanda", "555-555-5555", "Dial"]
   ];
 
   var range = worksheet.getRange("A2:E5");
   range.values = data;
   range.format.autofitColumns();
 
   return context.sync().then(function() {});
 }).catch(errorHandlerFunction);
}

Primeiro, selecione a primeira planilha, que, em um arquivo vazio do Excel, normalmente se chama “Sheet1”. Em seguida, crie um objeto com os dados que serão inseridos na planilha. Em seguida, defina o intervalo para abranger o número de células que os dados ocuparão e atribua os valores do intervalo ao objeto de dados. Ajustar automaticamente as colunas deixa a aparência um pouco mais organizada.

Também criei algumas formatações que são aplicadas quando o aplicativo é carregado. Isso posiciona a seleção na célula superior esquerda. Além disso, torna os “botões” do meu Dial clicáveis e altera as cores de fundo e do texto deles.

//start with selection at upper left
 var worksheet = context.workbook.worksheets.getItem("Sheet1");
 var initSelection = worksheet.getRange("A1");
 initSelection.select();
 
 //format dial buttons
 var range = worksheet.getRange("E:E");
 var conditionalFormat = range.conditionalFormats.add(Excel.ConditionalFormatType.containsText);
 
 conditionalFormat.textComparison.format.font.color = "white";
 conditionalFormat.textComparison.format.fill.color = "purple";
 conditionalFormat.textComparison.rule = {
   operator: Excel.ConditionalTextOperator.contains,
   text: "Dial"
 };

Ativando o “botão” do seletor

Uma das conquistas mais gratificantes deste projeto é a capacidade de clicar em algo na planilha do Excel e iniciar uma ligação para um número que consta nessa planilha. No meu caso, trata-se do “botão” “Discar” que aparece em cada linha de dados. Uso “botão” entre aspas porque não se trata de um botão de verdade — é apenas uma célula com a palavra “Ligar”. Criei um manipulador que verifica se houve alterações na seleção e reage quando o texto da célula clicada corresponde à palavra “Ligar”.

function handleSelectionChanged(event) {
 return Excel.run(function(context) {
   var range = context.workbook.getSelectedRange().load();
 
   return context.sync().then(function() {
     const selectedContent = JSON.stringify(range.values, null, 4);
 
     const rowString = JSON.stringify(range.rowIndex, null, 4);
 
     const rowIndex = Number(rowString) + 1;
 
     if (selectedContent.match("Dial")) {
       placeCall(rowIndex);
     }
   });
 }).catch(errorHandlerFunction);
}
 
function placeCall(row) {
 return Excel.run(function(context) {
   var toNumberRange = context.workbook.worksheets
     .getItem("Sheet1")
     .getRange("D" + row)
     .load();
 
   return context.sync().then(function() {
     const toNumber = JSON.stringify(toNumberRange.values, null, 4);
 
     VonageDialer.placeCall(toNumber);
   });
 }).catch(errorHandlerFunction);
}

Reações aos eventos da Vonage Communications

Outro recurso poderoso do Open ContactPad permite que você execute ações dentro do seu aplicativo integrado com base no momento em que ele recebe eventos da Vonage. Basta verificar o tipo de evento (event.type) e criar um código para reagir a ele. Os detalhes sobre o que meu código faz em relação a esses eventos serão descritos na seção “Tópicos avançados”. CALL_START, CALL_ANSWER e CALL_END são apenas algumas das opções disponíveis. Para mais informações, consulte os Modelos de Dados do SDK.

VonageDialer.init({ /* dialer config options */ }, (dialer) => {
 dialer.setOnDialerEvent((event) => {
   switch (event.type) {
     case 'CALL_START': {
       break;
     }
     case 'CALL_ANSWER': { // available only for UC
       break;
     }
     case 'CALL_END': {
       // do something based on event.data (screen pop, store interaction, etc.)
       break;
     }
     default: {
       console.log('Unhandled event', event);
     }
  }
 });
});

Tópicos avançados

Esta seção abordará outras personalizações para que você possa adaptar a integração às suas necessidades, como implementar a busca de contatos e definir o contato de interação.

Implementação da pesquisa de contatos — onde as linhas do Excel se transformam em contatos pesquisáveis

Vamos ver como tornar os contatos da planilha pesquisáveis no ContactPad.

Recurso “Adicionar Provedor de Contatos”

A primeira coisa a fazer para que os contatos sejam exibidos é habilitar o recurso contactsProvider como parte da inicialização do discador. Conforme mostrado na próxima seção abaixo, basta definir o valor como true em features, e pronto! Esta documentação contém mais informações sobre como criar um provedor de integração.

Registrar ícone SVG

Se você registrar um ícone, ele será usado para indicar visualmente de onde vêm os contatos. Como se trata de uma integração com o Excel, optei por usar o ícone do Excel. Obtive o código base64 em Icon Scout.

VonageDialer.init(
 {
   features: {
     contactsProvider: true,
     openContact: true
   }
 },
 (dialer) => {
   dialer.registerSvgIcon(
     "excel",
     "data: image / svg + xml; utf8; base64, **excel icon SVG data goes here**
   );

Fornecimento dos dados de contato – Implementação dos manipuladores

Screenshot of Microsoft Excel and the Vonage Open ContactPad with the number 55 in the Contact Number section with search results displayed belowSearch Contact Data

Aventuras na formatação de números de telefone

Formatar, armazenar e pesquisar números de telefone pode se tornar uma tarefa bastante complexa. Para ter uma ideia, dê uma olhada neste artigo do SitePoint que descreve essa complexidade. Felizmente, no meu próprio projeto, tenho controle sobre algumas coisas. Para começar, sei que meu usuário tem apenas um número dos EUA. Por isso, defini explicitamente o código de país do meu discador como EUA.

var countryCode = "US";
VonageDialer.setCountryCode(countryCode);

Também presumo que todos os números de telefone que serão inseridos sejam dos EUA, por isso uso libphonenumber com o código do país dos EUA para formatar os números tanto para pesquisa quanto para exibição.

<script src="https://unpkg.com/libphonenumber-js@1.9.6/bundle/libphonenumber-max.js">
</script>
filteredContacts.push(sortedContacts[i]);
const ph = libphonenumber.parsePhoneNumber(sortedContacts[i].phoneNumber, countryCode);

Para dar um exemplo rápido, meu código é suficiente, mas, dependendo dos seus objetivos com essa implementação, é recomendável dedicar algum tempo para analisar os números dos seus usuários, os números que serão considerados contatos, e implementar suas funções de busca com muito cuidado.

Funções para tradução e filtragem dos dados de contatos

Estas são as funções que criei para converter os dados dos contatos do formato esperado pelo JavaScript do Excel para o formato esperado pelo JavaScript da Vonage. Elas são chamadas no código que permite pesquisar os contatos.

   function translateContacts(excelData) {
     excelData = JSON.parse(excelData);
     let len = excelData.length,
       contactsData = [],
       obj = new Object(),
       objString = "",
       i;
     for (i = 0; i < len; i += 1) {
       if (excelData[i][4] == "Dial") {
         obj["provider"] = "excel";
         obj["id"] = i;
         obj["label"] = excelData[i][2] + " " + excelData[i][1] + " of " + excelData[i][0];
         obj["type"] = "Contact";
         const ph = libphonenumber.parsePhoneNumber(excelData[i][3], countryCode);
         obj["phoneNumber"] = ph.format("INTERNATIONAL").replace(/\D/g, "");
         objString = JSON.stringify(obj);
         contactsData.push(JSON.parse(objString));
       }
     }
     return contactsData;
   }
   function filterContacts(query, contacts) {
     const sortedContacts = contacts.sort(function (a, b) {
       const labelA = a.label.toUpperCase(); // ignore upper and lowercase
       const labelB = b.label.toUpperCase(); // ignore upper and lowercase
       if (labelA < labelB) {
         return -1;
       }
       if (labelA > labelB) {
         return 1;
       }
       // names must be equal
       return 0;
     });
     let filteredContacts = [];
     for (let i = 0; i < sortedContacts.length; i++) {
       if (
         JSON.stringify(Object.values(sortedContacts[i]).filter(item => item !== "excel"))
           .toUpperCase()
           .indexOf(query.toUpperCase()) > 0
       ) {
         filteredContacts.push(sortedContacts[i]);
         const ph = libphonenumber.parsePhoneNumber(sortedContacts[i].phoneNumber, countryCode);
         sortedContacts[i].phoneNumber = ph.format("INTERNATIONAL");
       }
     }
     return filteredContacts;
   }
Criação das sugestões de discagem
   const searchContactables = (query, callback) => {
     Excel.run(function(context) {
       var worksheet = context.workbook.worksheets.getItem("Sheet1");
 
       var range = worksheet.getRange("A3:E999");
       range.load("values");
 
       return context.sync().then(function() {
         const excelData = JSON.stringify(range.values, null, 4);
         const contactsData = translateContacts(excelData);
 
         const filteredContacts = filterContacts(query.replace(/[^A-Za-z0-9_]/g, ""), contactsData);
 
         callback(filteredContacts);
       });
     }).catch(errorHandlerFunction);
   };
   dialer.setOnSearchContactables(searchContactables);

Configurando o contato de interação — Exibição dos dados de contato na interface do discador

Essa funcionalidade é descrita na seção “Definir conteúdo de interação” da documentação do Open ContactPad. Aqui, mostro como implementei a funcionalidade para que as informações de contato do número remoto apareçam no discador durante uma chamada.

Screenshot of the Code Window of the Vonage Open ContactPad interface while in a call.Dialer Interface

 dialer.setOnDialerEvent((event) => {
   //search for contact
   Excel.run(function(context) {
     var worksheet = context.workbook.worksheets.getItem("Sheet1");
     var range = worksheet.getRange("A3:E999");
     range.load("values");
     return context.sync().then(function() {
       const excelData = JSON.stringify(range.values, null, 4);
       const contactsData = translateContacts(excelData);
       const query = "" + event.data.phoneNumber;
       const filteredContacts = filterContacts(query.replace(/[^A-Za-z0-9_]/g, ""), contactsData);
       const interactionContact = filteredContacts[0];
       switch (event.type) {
         case "CALL_START": {
           if (filteredContacts.length > 0) {
             dialer.setInteractionContact(event.data.id, {
               provider: interactionContact.provider,
               id: "" + interactionContact.id,
               label: interactionContact.label,
               type: interactionContact.type
             });
           }
           break;
         }

Implementação da função de “abrir” o contato

Screenshot of Microsoft Excel and the Vonage Open ContactPad with the number 555 in the Contact Number section with search results displayed below and the first match highlighted in the Excel sheetOpen Contact

Adicionar recurso “Abrir contato”

Este código destacará o contato na planilha do Excel quando o usuário clicar no ícone do link na pesquisa de contatos. Para funcionar, é necessário openContact: true nos recursos do discador init recursos do discador.

case "OPEN_CONTACT": {
     const rowNumber = event.data.id + 3;
     const rowString = "A" + rowNumber + ":D" + rowNumber;
     const row = worksheet.getRange(rowString);
     row.select();
     break;
   }
// Dialer init
VonageDialer.init({
  features: {
    contactsProvider: true,
    openContact: true,
    openActivity: 'acme',
    eventsHistory: true
  }
}, (dialer) => { /* <-- dialer instance */ });

Resumo

Espero que, ao ler este artigo, você consiga criar um discador da Vonage personalizável que possa ser usado em diversas Applications. Compartilhe sua experiência na canal business-communications-api da Comunidade Vonage no Slack, caso você tenha usado essas informações para criar suas próprias implementações úteis.

Compartilhar:

https://a.storyblok.com/f/270183/400x453/37e0b25a78/lisa-venezia.png
Lisa Venezia

Lisa helps connect business communications with customer workflows by working closely with the teams that create Vonage integrations with CRMs such as Salesforce, Microsoft Dynamics and HubSpot. Through adding developer solutions for Vonage Apps, she looks forward to unlocking powerful capabilities for people to work and communicate seamlessly within the platforms they use the most. Outside of work, Lisa enjoys singing choral music, playing the mellophone bugle, and spending time with her husband and their corgi.