UNPKG

brasil-consultas

Version:

Facilita a consulta de CNPJs na receita federal e de inscrições estaduais no SEFAZ de cada estado

213 lines (180 loc) 7.01 kB
var http = require('http'), request = require('request'), iconv = require('iconv-lite'), removerMascara = require('brasil').formatacoes.removerMascara, hostReceitaFederal = 'www.receita.fazenda.gov.br'; function executarParseDoHtml(body) { body = iconv.decode(body, 'iso-8859-1'); if(body.indexOf('Esta página tem como objetivo') > -1) { throw new Error('A solução do captcha estava errada!'); } if(body.indexOf('O nmero do CNPJ no vlido') > -1) { throw new Error('O número do CNPJ não é válido!'); } function obterRegExp(atributo) { atributo = atributo.replace(/\(/g, '\\(').replace(/\)/g, '\\)'); return new RegExp('<font face="Arial" style="font-size: 6pt">[\\s]*' + atributo + '[\\s]*</font>[\\s]*<br>[\\s]*<font face="Arial" style="font-size: 8pt">[\\s]*<b>(.*)</b>[\\s]*</font>[\\s]*', 'ig'); } function extrair(atributo) { if(typeof atributo === 'string') { atributo = obterRegExp(atributo); } var matches = atributo.exec(body), match; if(matches) { match = matches.length > 1 ? matches[1] : matches[0]; return match.trim(); } return ''; } var regexes = { naoEncontrado: /No existe no Cadastro de Pessoas Jurdicas o nmero de CNPJ informado/g, cnpj: /[0-9]{2}\.[0-9]{3}\.[0-9]{3}\/[0-9]{4}\-[0-9]{2}/g, tipo: /MATRIZ|FILIAL/g, datas: /[0-9]{2}\/[0-9]{2}\/[0-9]{4}/g, hora: /[0-2]{1}[0-9]{1}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}/g, atividadeEconomicaSecundaria: /[\s]*<b>[\s]*([0-9]{2}\.[0-9]{2}-[0-9]{1}-[0-9]{2})\s-\s(.*)<\/b>/g, apenasAsteriscos: /^[\*]+$/g, email: /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/g, telefone: /\([0-9]{2}\)\s?[1-9]{1}[0-9]{3,4}-?[0-9]{4}/g }; if(regexes.naoEncontrado.test(body)) { throw new Error('O cnpj informado não existe'); } var datas = body.match(regexes.datas), atividadeEconomicaPrincipal = extrair('C.DIGO E DESCRI..O DA ATIVIDADE ECON.MICA PRINCIPAL').split(' - '), atividadeEconomicaSecundaria, atividadesEconomicasSecundarias = [], naturezaJuridica = extrair('C.DIGO E DESCRI..O DA NATUREZA JUR.DICA').split(' - '), horaDaConsulta = body.match(regexes.hora); var i = 0; while(atividadeEconomicaSecundaria = regexes.atividadeEconomicaSecundaria.exec(body)) { if(i++ === 0) { continue; } atividadesEconomicasSecundarias.push({ codigo: removerMascara(atividadeEconomicaSecundaria[1]), descricao: atividadeEconomicaSecundaria[2].trim() }); } var resultados = { nome: { empresarial: extrair('NOME EMPRESARIAL'), fantasia: extrair('T.TULO DO ESTABELECIMENTO (NOME DE FANTASIA)') }, cnpj: removerMascara(extrair(regexes.cnpj)), email: extrair(regexes.email), telefone: removerMascara(extrair(regexes.telefone)), tipo: extrair(regexes.tipo), dataDeAbertura: datas && datas.length > 0 ? datas[0] : null, atividadesEconomicas: { principal: { codigo: removerMascara(atividadeEconomicaPrincipal[0]), descricao: atividadeEconomicaPrincipal[1] }, secundarias: atividadesEconomicasSecundarias }, naturezaJuridica: { codigo: removerMascara(naturezaJuridica[0]), descricao: naturezaJuridica[1] }, situacao: { cadastral: { descricao: extrair('SITUA..O CADASTRAL'), motivo: extrair('MOTIVO DE SITUA..O CADASTRAL') || null, data: datas && datas.length > 1 ? datas[1] : null }, especial: { descricao: extrair('SITUA..O ESPECIAL'), data: datas && datas.length > 4 ? datas[2] : null }, }, endereco: { logradouro: extrair('LOGRADOURO'), numero: extrair('N.MERO'), complemento: extrair('COMPLEMENTO'), cep: removerMascara(extrair('CEP')), bairro: extrair('BAIRRO/DISTRITO'), municipio: extrair('MUNIC.PIO'), uf: extrair('UF') }, consulta: { data: datas ? (datas.length > 4 ? datas[3] : datas[2]) : null, hora: horaDaConsulta ? horaDaConsulta[0] : null, fuso: 'America/Sao_Paulo' } }; if(regexes.apenasAsteriscos.test(resultados.nome.fantasia)) { resultados.nome.fantasia = null; } if(regexes.apenasAsteriscos.test(resultados.situacao.especial.descricao)) { resultados.situacao.especial.descricao = null; } return resultados; } function funcaoVazia() { } function obterDados(cnpj, captcha, callback, tentativa) { var jar = request.jar(), url = 'http://' + hostReceitaFederal + '/PessoaJuridica/CNPJ/cnpjreva/valida.asp'; tentativa = tentativa || 0; jar.setCookie(request.cookie(captcha.sessionId), url, funcaoVazia); jar.setCookie(request.cookie('flag=1'), url, funcaoVazia); request({ method: 'POST', url: url, jar: jar, encoding: null, followAllRedirects: true, form: { origem: 'comprovante', cnpj: removerMascara(cnpj), txtTexto_captcha_serpro_gov_br: captcha.solucao, search_type: 'cnpj' } }, function(err, res, body) { if(err) { return callback(err); } try { callback(null, executarParseDoHtml(body)); } catch(err) { if(tentativa < 1) { return obterDados(cnpj, captcha, callback, ++tentativa); } callback(err); } }); } function obterCaptcha(callback) { http.get({ host: hostReceitaFederal, path: '/PessoaJuridica/CNPJ/cnpjreva/captcha/gerarCaptcha.asp' }, function(res) { if(res.statusCode !== 200) { return callback(new Error('O request retornou o código ' + res.statusCode + ', que não era esperado')); } var captchaEmBase64 = '', sessionId = res.headers['set-cookie'] && res.headers['set-cookie'][0]; sessionId = sessionId.match(/^(ASPSESSIONID.*=.*;).*$/); if(!sessionId) { return callback(new Error('Impossível carregar sessionId')); } sessionId = sessionId[1]; res.setEncoding('base64'); res.on('data', function(chunk) { captchaEmBase64 += chunk; }); res.on('end', function() { return callback(null, { captchaEmBase64: captchaEmBase64, contentType: res.headers['content-type'], sessionId: sessionId }); }); }); } module.exports = { obterCaptcha: obterCaptcha, obterDados: obterDados };