No artigo de hoje vamos falar um pouco sobre validação de números de telefone seguindo o E164, permitindo assim verificar se um dado telefone é válido ou não. Este Padrão E164 é um padrão internacional que garante que os planos de numeração utilizados ao redor do mundo são únicos.
Quando se trata de validação de telefones, sempre foi algo bastante chato de ser validado, afinal aqui no Brasil temos formatos diferentes, muitas vezes a instancia não trabalha apenas com telefones brasileiros e você como um bom consultor que sei que é, não vai deixar o usuário entrar com quaisquer valores neste campo!
O script abaixo foi um achado que tenho certeza que será muito útil para quiser estiver nessa empreitada de validar telefones E164.
Antes de ir para o script, vale a pena falar um pouco sobre como o ServiceNow trata máscaras de telefone e localização.
Existem três tabelas que armazenam todo o motor da validação de telefones que são:
- sys_phone_territory
- sys_phone_format
- sys_phone_validate.
A tabela sys_phone_territory é responsável por representar os países e suas respectivas configurações de telefone. Veja abaixo um exemplo para o Brasil:

A tabela sys_phone_format basicamente armazena a máscara e algumas configurações de como o número de telefone deve seguir para atender determinado layout. Já a tabela sys_phone_validate armazena as regras para que o número informado esteja no formato correto.
Não vou entrar muito no detalhe de todos os campos, pois o mais importante aqui é sabermos que todas as máscaras e validações que precisamos já está no ServiceNow! E para que isso vai servir, você deve estar se perguntando? Elas fazem toda a diferença! Vou te mostrar.
Existe um script include chamado PhoneNumberFormatter que extende a classe AbstractAjaxProcessor, isso é, ele é feito para chamadas client-side, aonde o script de request passa o número de telefone no parâmetro sysparm_phoneNumber e devolve um objeto JSON stringificado (existe essa palavra?) informando se aquele telefone se encaixa em algum perfil de formatação cadastrado.
var PhoneNumberFormatter = Class.create(); // Classe extende AbstractAjaxProcessor, então ela é feita para chamadas Client-Side PhoneNumberFormatter.prototype = Object.extendsObject(AbstractAjaxProcessor, { process: function() { var local = (this.getParameter('sysparm_local') == 'true'); var strict = (this.getParameter('sysparm_strict') == 'true'); var showText = (this.getParameter('sysparm_showText') == 'true'); var phoneNumber = this.getParameter('sysparm_phoneNumber'); var gePN = new GlideElementPhoneNumber(); var valid = gePN.setPhoneNumber(phoneNumber, strict); var matchType = gePN.getPartialMatchType()+""; var returnValue = null; if (valid) { if (local) returnValue = gePN.getLocalDisplayValue(); else returnValue = gePN.getGlobalDisplayValue(); var country = gePN.getTerritory(); var optionValue = gePN.getGlobalDialingCode() + "," + gePN.getLocalDialingCode() + "," + gePN.isLocalFollowsGlobal(); return escape(returnValue) + "," + escape(country) + "," + escape(optionValue); } var country = gePN.getTerritory(); if (matchType == 'GLOBAL') // Failed to match global part of phone number country = gs.getMessage("Other / Unknown"); return "NO_MATCH" + "," + escape(country) + "," + escape(optionValue); }, type: 'PhoneNumberFormatter' });
Uma coisa muito interessante nesse código, é que ele utiliza um classe não documentada chamada GlideElementPhoneNumber, que faz toda a mágica que precisamos para validar o telefone. É dificil afirmar exatamente o que cada linha está fazendo, mas o que é certo é que o número que foi informado está sendo testado contra aquelas validações, identificação do território através do DDI, entre outros!
Então, após uma chamada de teste, temos como resultado:
// +551199887766 *** Script: {"isValid":true,"country":"Brazil"} // +550099887766 - Usei um DDD inválido 00 *** Script: {"isValid":false,"country":"Brazil"} // +1888-333-5555 *** Script: {"isValid":true,"country":"North%20America"} // +18883335555 - Sem separadores *** Script: {"isValid":true,"country":"North%20America"}
Bacana não é mesmo?
Espero que tenham gostado e até a próxima!