Jump to content

Karina Harumi

Administradores
  • Contagem de Conteúdo

    933
  • Ingressou

  • Última visita

  • Dias Ganhos

    184

Tudo que foi postado por Karina Harumi

  1. Tópico originalmente criado por: @Jonathan Santos ecentemente encontrei um problema de Memory Leak em uma aplicação, devido a causa do problema estou fazendo este post para evitar esse tipo de erro. No Delphi a diretiva virtual permite que seu método seja sobrescrito com o mesmo nome, ou seja, em uma subclasse você pode reescrever um método de acordo com suas necessidades. Ja a diretiva override significa que o método esta sobrescrevendo o método original, então na frase acima o método sobrescrito deve conter a diretiva override , e o método original a diretiva virtual . Um erro simples de esquecer uma dessas diretivas pode acontece de ao dar .Free em uma classe não chamar o destructor , ocasionando na não liberação de memória de alguns objetos. Exemplo: Abaixo temos a classe TRetornoWebService , nessa classe declaramos que o Create pode ser sobrescrito por uma subclasse, e o Destroy está sendo reescrito, pois, a classe TObject do delphi já possui um virtual em seu Destroy . Agora na subclasse TRetornoConsultaNFe , que é “filha” da TRetornoWebService , sobreescrevemos o Create e o Destroy das classes ancestrais, nesse caso não foi necessário adicionar o virtual no Destroy da TRetornoWebService, pois, a TObject já possuí um Destroy declarado com virtual. Na imagem acima o inherited 2 chama o método original da classe pai após realizar as chamadas acima dele. Algumas outras diretivas: virtual - Usado para definir um método que pode ser sobrescrito. override - Utilizado para definir um método que está sobrescrevendo um método virtual. abstract - É usado com virtual ou override para definir um método sem implementação que deve ser sobrescrito na subclasse, senão o mesmo não será chamado. final - Usado com virtual ou override para definir um método que não pode ser sobrescrito. reintroduce - É como o override, porem, funciona com métodos não dinamicos e não virtuais. Utilizado se você quiser reintroduzir um método e comunicar para o compilador que você não cometeu um engano escrevendo um método com mesmo nome da classe pai. overload - Essa diretiva permite que você declare um método com mesmo nome, porem, com parâmetros diferentes.
  2. Tópico originalmente criado por: @Jonathan Santos O Report Builder é uma ferramenta muito utilizada por desenvolvedores para edição e apresentação de relatórios. Um dos seus pontos principais é a facilidade de manuseio, levando em conta que a mesma é bem intuitiva. Mostraremos a seguir, de forma bem prática, algumas funcionalidades bastante úteis que podemos encontrar na ferramenta. Abordaremos a formatação de campos utilizando o componente Rich Text, o tratamento diferenciado à determinados dados usando SubReport, explorando informações do sistema com o auxílio do componente System Variable, dentre outros recursos que podem nos ser úteis no desenvolvimento de relatórios utilizando Report Builder. Rich Text (Texto formatado) Este componente nos permite formatar a apresentação do texto de diversas formas. Após adicioná-lo ao relatório, podemos selecionar a opção Editar, abrindo uma janela de edição. É possível adicionar o conteúdo de um campo da base de dados na própria janela e, formatá-lo utilizando os recursos que o componente oferece. Figura 1: Adicionando o componente Rich Text e selecionando a opção Editar. Para podermos ter acesso às informações contidas na base de dados, o checkbox “Mail Merge” deve estar ativo. Figura 2: Formatando o texto. Após salvarmos e fecharmos a janela de edição, visualizamos o relatório. Figura 3: Visualizando relatório após formatação do texto. Perceba que a propriedade “Ajustar”( Stretch ) deve estar selecionada para que o campo fique com tamanho dinâmico, assim como a estrutura na qual ele está contido. Essa propriedade também existe no componente Memo. Figura 4: Propriedade Ajustar( Stretch ) selecionada. SubReport Este componente é bastante utilizado para tratar com mais riqueza de detalhes determinados dados. Com ele podemos ilustrar dados de um relatório do tipo mestre-detalhe, e relacioná-los com o relatório principal ou até mesmo com outro sub-relatório, de forma que tenham a aparência de serem apenas um. É importante ressaltar que, devemos configurar a propriedade “DataPipeline” com a base dos dados que serão utilizados nesse sub-relatório. Figura 5: Adicionando SubReport e configurando a propriedade DataPipeline. No rodapé do relatório será criada uma nova aba referente ao sub-relatório que foi adicionado, todas as alterações serão feitas lá. Figura 6: Editando sub-relatório. Figura 7: Visualizando sub-relatório. System Variable Este componente é utilizado para exibir alguns recursos como data e hora, número da página e contador de páginas. É necessário configurar o recurso desejado na propriedade “VarType”. Alguns exemplos de formatação podem ser encontrados na propriedade “DisplayFormat”. Figura 8: Opções da propriedade VarType. Figura 9: Adicionando componente System Variable e suas propriedades. Algumas propriedades são bastante utilizadas no Report Builder, tais como: ParentHeight: deixa o componente em questão com a mesma altura do seu antecessor. ParentWidth: deixa o componente em questão com a mesma largura do seu antecessor. BottomOffset: reserva um espaço abaixo do componente. WordWrap: quebra de linha automática do texto. StretchWithParent: ajusta o componente de acordo com o seu antecessor. ShiftRelativeTo: especifica o posicionamento vertical do componente. A estrutura do relatório também pode ser alterada através de algumas propriedades na aba Grupos, tais como: iniciar uma nova página na mudança de grupo, iniciar em página ímpar, reimprimir cabeçalho do grupo em página subsequente, dentre outros. Esta aba encontra-se no menu Relatório/Grupos. Figura 10: Aba Grupos. Além dos recursos aqui demonstrados, ainda temos componentes capazes de representar gráficos, código de barras, QRCode, imagens, entre outras opções. Por fim, podemos concluir que o Report Builder é uma ferramenta interessante e merece ser testada, porém é importante ressaltar que apesar de possuir uma grande variedade de componentes para criação e edição de relatórios, ela peca em alguns detalhes importantes, como: atalhos que não funcionam, funções nativas limitadas para realização de cálculos e alinhamentos no relatório necessitam de esforço visual do usuário, pois não possui recurso de aproximação.
  3. Comentário originalmente feito por: "normapappasseofy25": If two or more Eiffel Tower symbols appear during a free spin, then the feature is retriggered. The crème de la crème prize in Paris Beauty is the randomly triggered progressive jackpot. The Sloto’ Cash LIVE카지노 Facebook page also offers some interesting freebies. The current members are invited to share a Sloto’ Cash banner on their profiles.
  4. Tópico originalmente criado por: @Jonathan Santos Em nosso cenário atual de utilização do Manager Edoc sentimos a necessidade de realizarmos testes cada vez mais próximos da sua realidade de uso. Esse tipo de cenário exige que o Manager Edoc seja capaz de responder a um grande número de requisições Http simultâneas, sem aumentar a memória a ponto de causar um “estouro de memória”. Uma suite de testes normal não consegue simular situações de grande demanda por determinada funcionalidade, como por exemplo a impressão. Para casos como esse utilizamos uma ferramente chamada Apache JMeter . O Apache JMeter é uma aplicação desktop desenvolvida para realizar testes de desempenho e estresse em aplicações cliente/servidor tais como aplicações Web. Ele pode ser usado para simular cargas de trabalho de determinada funcionalidade do Manager Edoc, testando sua robustez. Por ser uma ferramenta livre e inteiramente escrita em Java, o JMeter é compatível com qualquer ambiente capaz de suportar a máquina virtual Java versão 1.4 ou superior. O JMeter permite a criação de testes para diversos protocolos, como HTTP, JDBC, FTP e SOAP. A execução dos testes com o JMeter, pode ser feita de duas formas: em uma máquina só ou de forma distribuída, onde o esforço do teste de determinada funcionalidade é dividido entre diversas máquinas. A partilha do esforço do teste de uma funcionalidade é uma característica necessária e muito importante para a correta execução dos testes de desempenho e estresse, pois através dela os testadores podem conseguir uma maior fidelidade na recriação de determinado cenário de teste. A divisão do esforço de teste vai evitar gargalos tanto de processamento quando de caminhos na rede do sistema sob teste. No JMeter a estrutura dos testes e de seus elementos é feita através de uma estrutura de árvore hierárquica, onde a raiz é o Plano de Teste. Na figura 1 é mostrada a interface inicial do Apache JMeter. E na figura 1.2 é possível visualizar a estrutura em árvore hierárquica. Figura 1. Figura 1.2 Na figura 1.2 podemos observar a estrutura em árvore onde a raiz é o “Plano de Teste WorkFlows NFe” (Test Plan) e os Grupos (Thread Group) que pertencem a esse plano de teste. Plano de Teste (Test Plan): representa o cenário global do plano de teste. Grupo de Usuários (Thread Group): armazena as configurações do grupo de usuários virtuais, onde cada usuário corresponde a uma Thread que simula a navegação de um usuário utilizando determinada funcionalidade. Área de trabalho: utilizada somente como uma área de armazenamento temporário para elementos dos testes que não serão executados. Cada grupo é especifico para uma funcionalidade do Manager Edoc. Dentro de cada Grupo temos os elementos: Gerenciador de Cabeçalhos HTTP: armazena o cabeçalho da requisição Http. No cenário do Manager Edoc ele salva o campo authorization para fazer a autenticação básica do Edoc. (Figura 2) Figura 2. Requisição Http (Exporta NF-e HTTP): armazena as configurações gerais da requisição HTTP. Nesse componente colocamos o ip do servidor onde está o Manger Edoc, a porta, o método POST ou GET, o caminho a interface Web e no campo Parameters, colocamos os parâmetros necessários para a requisição que desejamos fazer, conforme figura 3. Figura 3. Ver Árvore de Resultados (Ouvintes ou Listeners): armazenam o resultado das requisições do grupo de usuários. Armazenam requisições com falha quanto as corretas. Conforme figura 4 e 5 podemos ver dois tipos de ouvintes. O ouvinte da figura 4 possui um estrutura em árvore para visualização dos resultados, enquanto o da figura 5 possui um estrutura em tabela. Figura 4. Figura 5. O JMeter possui uma gama muito grande de componentes e controladores. Foi explicado somente os componentes que estão sendo utilizados no momento para fazer os testes de desempenho e estresse do Manager Edoc. Criando um plano de testes para a função Modo do Manager Edoc Primeiramente vamos fazer o download do Apache JMeter no site da Apache, no seguinte link: http://jmeter.apache.org/download_jmeter.cgi conforme figura 6. E faça o download do arquivo .zip. Lembrando que é necessário ter o Java instalado antes de executar esses passos a seguir. Figura 6. Após fazer o download do arquivo, faça a descompactação do seu conteúdo em uma pasta de sua preferência. Dentro do arquivo estará a pasta contendo todos os arquivos do JMeter. Figura 7. Figura 7. Com a pasta do JMeter extraida, localiza a pasta “bin” dentro da pasta raiz do JMeter. Figura 8. Figura 8. Entre na pasta bin e localize o arquivo ApacheJMeter.jar e execute. Assim o JMeter será aberto e podemos começar a criar um plano de testes contendo um grupo de usuários que irá testar a funcionalidade do Modo do Manager Edoc. Com a interface aberta click com o botão direito no Plano de Teste e escolha a opção Adicionar/Threads(Users)/Grupo de Usuários conforme figura 9. Figura 9. Com o grupo de usuários criados podemos visualizar suas propriedades, vamos alterar o nome para Grupo de Usuários Modo. Temos as seguintes propriedades: Número de Usuários Virtuais (threads): indica o número de usuários virtuais que irão utilizar a funcionalidade em questão. Tempo de inicialização (em segundos): indica o intervalo de tempo onde cada usuário vai iniciar o uso da funcionalidade. Contador de Iteração: indica quantas vezes a funcionalidade em questão será disparada. Por exemplo, se deixarmos os valores padrões para as três propriedades conforme Figura 10, estaremos dizendo que: um usuário vai iniciar a cada 1 segundo e irá repetir a operação 1 vez. Figura 10. Caso as configurações sejam trocadas para Threads 10, Tempo inicialização 5 e contador 100, estaremos dizendo que: 10 usuários irão iniciar a cada 5 segundos e irá acontecer 100 repetições da funcionalidade. Caso deixamos o check box Infinito marcado a funcionalidade será executada com 10 usuários iniciando a cada 5 segundos até o testado parar a execução do JMeter pelo botão “Stop” no menu principal. Conforme figura 11. Figura 11. Como grupo de usuários criado click com o botão direito sobre ele e escolha Adicionar/Elemento de Configuração/Gerenciador de Cabeçalhos HTTP conforme figura 12. Na tela de configurações do gerenciador de cabeçalho click no botão adicionar e coloque o nome e valor conform abaixo: Nome = authorization Valor = Basic YWRtaW46MTIzbXVkYXI= Com a autenticação básica do Edoc preenchida click novamente no grupo de usuários com o botão direito e click em Adicionar/Testador/Requisição HTTP conforme figura 13. Figura 13. Com a tela das configurações da requisição HTTP aberta, configure as propriedades conforme 14. Com os seguintes valores: Servidor ou IP: configure com o ip da máquina onde o Edoc está rodando. Número da Porta: configure com o porta configurada no Edoc Método: Será POST ou GET de acordo com a rota da APIWeb do Edoc. No caso será GET para Rota do MODO. Caminho: caminho da rota da APIWebo do Edoc. Valor para rota MODO NFCe: /ManagerAPIWeb/nfce/modo Na Aba Parameters click no botão Adicionar para incluir os parâmetros da requisição de acordo com manual do Manager Edoc. Nesse exemplo vamos alterar a propriedade AtualizaDataHoraEnvio que pode ter os valores ‘0’ e ‘1’. Preencha os parâmetros conforme abaixo Nome Valor AtualizaDataHoraEnvio 1 cnpj 00819201004455 grupo edoc Figura 14. Após a configuração da requisição HTTP vamos adicionar dois Ouvintes ou Listeners para visualizarmos as requisições e suas respostas. Click com o botão direito no grupo de usuário e escolha Adicionar/Ouvintes/Var Árvore de Resultados e depois da mesma forma escolha Adicionar/Ouvintes/Ver Resultados em Tabela conforme Figura 15. Figura 15. Após esses passos teremos o seguinte grupo: Para iniciar os testes basta dar um click no botão Play conforme abaixo. Figura 16. Com o JMeter rodando sempre é possível para os testes com o botão STOP. Quando existem mais de um Grupo do plano de testes todos eles irão disparar ao mesmo quando quando o botão PLAY é acionado. Para rodar um único grupo basta desabilitar os grupos aos quais não se deseja disparar clicanco com o botão direto e escolhando a opção desabilitar. Os botões com a vassoura em destaque na figura 16, servem para limpar o resultado das requisições dos Ouvintes. O primeiro limpa somente o resulta do grupo selecionado, o segundo limpa o resultado de todos os ouvintes de todos os grupos do plano de testes. As imagens abaixo (Figura 17 e 18) mostram duas abas do Ouvinte de resultados em formato de árvore, na Aba Requisição é possível verificar como a requisição foi formada para envio e na Aba Dados da Resposta é possível verificar como foi a resposta da requisição. Figura 17 Figura 18
  5. Tópico originalmente criado por: @Jonathan Santos Regex é uma linguagem formal que permite identificar padrões de caracteres dentro de um texto. E é muito utiliza em editores para encontrar e manipular pedaços de texto, nós podemos utilizar para identificar trechos específicos dentro de um xml, um csv, dados dentro de um formulário e qualquer fonte de texto. Segue abaixo alguns exemplos da forma mais simples até um ponto mais recomendado, você pode testar usando o site rubular.com 3 para acompanhar os exemplos: Dígitos numéricos com Regex : Quando queremos nos referir a dígitos em um pattern, colocamos uma abreviação de dígito = \d Por exemplo, para exigir que um campo de CPF tenha 11 dígitos, colocaria: pattern="\d\d\d\d\d\d\d\d\d\d" Porém, neste padrão acima, ficaria muito custoso manter pelo tanto de repetição e passível de falhas, então para facilitar, pode-se utilizar o recurso de repetição em regex, que é colocar entre chaves o número de repetições desejadas ou limitada: Este mesmo padrão é equivalente ao de cima, muito mais simples de manter e entender. pattern="\d{11}" Para validarmos o caracter if no final do cpf podemos utilizar o operador? que serve para dizer que pode ou não ter este caracter, ficando assim: Aqui teremos três blocos de 3 dígitos, o hífen e o operador? que indica que o hífen é opcional, pode ou não existir. pattern="\d{3}.\d{3}.\d{3}-?\d{2}" Dígitos literais e conjuntos com Regex : Indica que podemos usar qualquer letra do alfabeto no intervalo de a até z. Para letras do alfabeto neste intervalo: pattern="[a-z]" pattern="[A-Z]" Para se utilizar o comum é [a-zA-Z] esse grupo ja indica de forma agrupada todas letras. E para utilizar esse grupo de letras com números, basta colocar o indicador de dígitos que é o \d ficando: pattern="[a-zA-Z\d]" E para funcionar com qualquer palavra utilizamos o operador + que indica que uma ou mais letras deste mesmo grupo ficando. pattern="[a-zA-Z\d]+" Exemplo simples de validação de email: pattern="[a-zA-Z\d]+@[a-zA-Z\d]+\.[a-zA-Z\d]+\.[a-zA-Z\d]+" E para melhorar a forma de validação acima que está muito repetitiva. Usamos o operador \w que é equivalente ao [a-zA-Z\d_] que representa uma “word”. pattern="\w+@\w+\.\w+\.?\w?\w?+" E para melhorar ainda podemos utilizar o caractere especial *, que é o equivalente ao caractere ? e o +. Utilizando o * o caractere antes dele pode ser presente ou não e pode aparecer mais de uma vez ou não também. pattern="\w*@\w*\.\w*\.\w*" Como tratar grupos em regex: exemplo cartão de crédito: 9999-9999-9999-9999 Forma sem agrupamento pattern="\d{4}[ -]\d{4}[ -]\d{4}[ -]\d{4}" Neste grupo acima podemos notar que várias partes se repetem então podemos agrupar utilizar o () entre as partes identificadas exemplo: \d{4} = indica teremos 4 dígitos iniciais ([ -]\d{4}) = indica que este grupo pode se repetir na expressão {3} = e para finalizar nesse pattern, este indica que este grupo pode se repetir 3 vezes. pattern="\d{4}([ -]\d{4}){3}" Este post é apenas o básico desta linguagem formal, que seu uso cresce a cada dia dentre nós desenvolvedores.
  6. Tópico originalmente criado por: @Jonathan Santos Recentemente tivemos um problema sério de compartilhamento na nossa rede interna: As máquinas com Windows XP não conseguiam de forma alguma acessar pastas compartilhadas em uma máquina com Windows 7, retornando o erro abaixo quando tentávamos acessá-la pelo Windows Explorer: \COMPUTADOR\Pasta não está acessível. Talvez você não tenha permissão para usar este recurso de rede. Contate o administrador deste servidor para saber se você tem permissões de acesso. O servidor especificado não pode executar a operação solicitada Quando a máquina com Windows 7 era reiniciada, as máquinas XP ainda conseguiam acessá-la por algum tempo, mas depois perdiam a conexão e o erro retornava. Após muita pesquisa e diversas tentativas de solucionar o problema, finalmente encontramos uma solução definitiva: Configurações de compartilhamento Primeiramente é necessário realizar algumas configurações básicas de compartilhamento: Vá até à Central de Redes e Compartilhamento do Windows 7 e desmarque a opção de “compartilhamento protegido por senha”, nas opções avançadas de compartilhamento. Clique na pasta que foi compartilhada com o botão direito e escolha a opção “Propriedades”. Na aba “Compartilhamento” vá em “Compartilhar” e verifique se a pasta foi compartilhada com “Todos”. Configurações no registro do windows Agora, para o compartilhamento funcionar, é preciso modificar o registro do Windows: Através do RegEdit acesse HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\LargeSystemCache e configure o valor para 1 Ainda no RegEdit encontre HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\Size e configure o valor para 3 Crie o novo parâmetro como DWORD: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\MaxNonpagedMemoryUsage e configure seu valor para 0xFFFFFFFF Estas configurações farão as máquinas Windows XP entenderem que o Windows 7 é um servidor de arquivos e assim conseguirão acessá-lo. A solução final foi encontrada no fórum da Microsoft
  7. Comentário originalmente feito por: "Otavio_Zandonaidi": Poderia demonstrar cursos em português do inicio ao avançado desse ferramenta?
  8. Comentário originalmente feito por: "geovanif": Opa, beleza? Olha, pode ser eu mesmo haha. Pode mandar email pra mim se problemas. ge.jhor@hotmail.com
  9. Comentário originalmente feito por: "jbreis": Olá Geovani. Saberia indicar alguém para ajudar em um projeto com Metabase?
  10. Tópico originalmente criado por: "geovanif" Olá Pessoal, beleza? Quando um negócio começa a crescer e o acesso aos dados começam a ficar cada vez mais importante, ter esses dados em mãos sempre atualizado começa a ficar mais e mais difícil. As planilhas começam a ficar desatualizadas e também é cada vez mais trabalhoso de geri-las, rastrear os dados e até mesmo compartilhar começa a ser problemático. Hoje em dia, ser uma empresa que toma decisões com base em dados já não é um diferencial, e sim um requisito. Quando pesquisamos ferramentas de vizualização de dados, encontramos várias ferramentas incríveis com grande poder para gerar insights, como Tableau, Qlik, Power BI, Superset, etc, mas também geralmente o custo é muito alto ou você vai precisar de um expert na ferramenta. Uma ferramenta que vem ganhando o coração de muitas gestores e equipes de dados e desenvolvimento é o Metabase 47, que além de ser fácil de usar e instalar, é opensource e ainda é bonito! Depois de instalar ele, basta logar, ir na tela de Admin que ele possui, conectar um banco de dados e pronto! Você já pode sair criando Visualizações que você deseja, seja fazendo um SQL na mão ou usando um recurso que ele tem para fazer um consulta sem escrever nada de SQL. Existe até a opção de você pedir pra ele fazer uma análise da sua tabela e gerar alguns insights sozinho! Veja só como se parece um dashboard nele. Vocês pode ajustar o tamanho e posição dos gráficos como bem quiser, de forma bem simples! Com o banco conectado e usuários criandos, qualquer um da sua empresa consegue criar visualizações e compartilhar com todo o time! Sem nem precisar saber escrever SQL! Olha só como é fazer consulta usando o recurso que ele possui de não usar SQL. Você também pode criar várias “coleções”, que são como pastas para organizar onde ficam os dashboard e gráficos. Ele possui controle de permissão, o que possibilita limitar a visualização das suas coleções! É possível fazer dashboard com filtros, de forma que você pode, por exemplo, informar uma data e todos os gráficos do dashboard mudam com esse dado! Outra coisa incrível é a quantidade de fonte de dados que ele conesegue se conectar, e nem precisa ser um banco relacional! E ai, já conhecia o metabase? Bora começar usar ele?Falem que outas ferramentas vocês usam na equipe de vocês!
  11. Tópico originalmente criado por: @Jonathan Santos A autenticação é um ponto importante em qualquer aplicação que tenha sua distribuição baseada em usuários. Pensando nisso, trazemos este tutorial de como criar uma autenticação baseada em tokens para autenticar usuários que acessarem sua API. O módulo que vamos utilizar para trabalhar com os tokens é o jsonwebtoken . O que vamos construir? Vamos construir uma mini API que terá a autenticação baseada em WebTokens, então teremos um registro de usuários (Utilizando o MongoDB para armazenarmos os usuários), as rotas que serão liberadas apenas se o usuário estiver autenticado, e o middleware que fará a verificação do token para nós. Para isso vamos precisar de uma maquina com o NPM, NodeJS instalados e também do aplicativo POSTman , com ele vamos conseguir fazer os testes nas rotas de uma forma mais simples. Para isso vamos precisar da seguinte estrutura de arquivos: - app/ ---- models/ ------------ user.js - config.js - package.json - server.js Mão na massa! No seu arquivo ‘package.json’ informe um nome para sua aplicação e deixe o ‘main’ com o nome de seu arquivo server.js { "name": "api-token", "main": "server.js" } Instalando os pacotes do npm. No seu console digite " npm install express body-parser morgan mongoose jsonwebtoken --save " Dessa forma o npm vai baixar os pacotes e já inserir eles nas dependências do nosso projeto, dentro do package.json express É o pacote mais simples para criarmos as rotas do nosso app. body-parser Com ele conseguimos trabalhar com os dados enviados no body das requisições http que nossas rotas estão recebendo morgan Com ele para cada requisição que nosso app receber, um log é gerado no nosso console. (Usamos para facilitar a visualização do que está sendo feito) mongoose É uma biblioteca do Node para MongoDB usada para para modelar os dados da sua aplicação utilizando esquemas. nodemon Pacote usado para subir sua aplicação com a vantagem de que a cada vez que alterar ou criar um arquivo js ele reinicia automaticamente. jsonwebtoken Este é o pacote responsável pela geração dos tokens de autenticação. Criando o modelo dos dados do usuário que será salvo no banco. No arquivo user.js que fica na pasta /app/models/user.js, faça a seguinte configuração: // Vamos adicionar nosso pacote do mongoose e criar um objeto com schema do nosso usuário que será salvo no banco. var mongoose = require('mongoose') var usuarioSchema = new mongoose.Schema({ name: String, password: String }) // Agora aqui vamos devolver o Schema do usuário para quer acessar este arquivo module.exports = mongoose.model('Usuario', usuarioSchema) Criando o nosso banco utilizando o mLab. Acesse o site do mLab e siga os próximos passos. Clique em Create New ao lado de Create from backup . Depois selecione a opção Single-node , marque o check de Sandbox , de um nome para seu banco e depois clique em Create new MongoDB deployment . Após este passo, selecione o seu banco e adicione um usuário para ele na aba Users clicando no botão Add database user. Note que marquei em vermelho URL do nosso banco, mongodb://< dbuser >:< dbpassword >@ds163377.mlab.com:63377/token-api onde está < dbuser > e < dbpassword > mude para os dados do usuário que você cadastrou. No meu caso ficou da seguinte forma: mongodb://admin:admin@ds163377.mlab.com:63377/token-api Arquivo config.js Agora adicionamos nossa variável ‘secret’ que será usada para a geração do token e também adicionamos a url do nosso banco. module.exports = { 'secret': 'itsasecret', 'url': 'mongodb://admin:admin@ds163377.mlab.com:63377/token-api' // Caso for utilizar o mongoDB localmente // 'url' : 'mongodb://localhost/projeto-api' } Arquivo server.js Nele vamos informar todos os pacotes que vamos utilizar, configurar nossa aplicação com as variáveis importantes, conexão com o banco, criar as rotas básicas como a de criação de um usuário de testes e criar as rotas da API que serão dividas da seguinte forma: - Rota basica - POST - /cadastrar Vamos cadastrar o nome e senha que o usuário nos forneceu. - API - POST - /api/authenticate Vamos verificar o nome e senha no nosso banco e liberar um Token para o usuário utilizar, caso o nome e senha estejam corretos. Esta rota não vai precisar de um Token, pois é nela que o usuário vai conseguir ele. GET - /api Nela vamos mostrar uma mensagem padrão, nessa rota vamos verificar se o usuário requisitou ela usando o Token. GET - /api/users Vamos listar todos os usuários cadastrados, porém apenas se quem requisitar estiver utilizando um Token válido. Como vai ficar o nosso arquivo server.js // Vamos referenciar os pacotes que precisamos var express = require('express') var app = express() var bodyParser = require('body-parser') var morgan = require('morgan') var mongoose = require('mongoose') var jwt = require('jsonwebtoken') var config = require('./config') var User = require('./app/models/user') var port = process.env.PORT || 3000 mongoose.Promise = global.Promise mongoose.connect(config.url) // Conectamos no banco app.set('superSecret', config.secret) // Variável secret app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) // Logs das requisições app.use(morgan('dev')) // Rotas =========== // rota basica app.get('/', (req, res) => { res.send('Olá, a API está em http://localhost:' + port + '/api') }) app.post('/cadastrar', (req, res) => { // Criamos um novo usuário utilizando o schema que montamos na pasta models var novoUsuario = new User({ name: req.body.name, // A instrução req.body nos retorna um objeto com os dados que foram enviados através de uma requisição password: req.body.password }) novoUsuario.save((err) => { if (err) throw err // Se tiver algum erro na hora de salvar, usamos o throw para retornar uma "exception" console.log('Usuário cadastrado com sucesso') res.json({ success: true }) // Se tudo ocorrer bem, retornamos um json dizendo que deu certo }) }) // Rotas da API // Utiliza uma instancia do Router para as rotas da API var apiRoutes = express.Router() // Rota de autenticacao de usuário (POST /api/authenticate) apiRoutes.post('/authenticate', (req, res) => { console.log(req.body) User.findOne({ name: req.body.name }, (err, user) => { // O findOne é como um Select, passando um filtro que é o 'name' if (err) throw err // Verificamos se o usuário existe if (!user) { res.json({ success: false, message: 'A autenticação falhou, o usuário não foi encontrado :C' }) } // Verificamos se a senha é correta if (user.password !== req.body.password) { res.json({ success: false, message: 'A autenticação falhou, a senha está incorreta :C' }) } else { // Se não tiver nenhum erro, então criamos o Token para ele var token = jwt.sign(user, app.get('superSecret'), { expiresIn: '1440m' }) // Aqui dizemos que o Token expira em 1440 minutos (24 hrs) // Retornamos um json dizendo que deu certo junto com o seu Token res.json({ success: true, message: 'Aproveite seu token!', token: token }) } }) }) // middleware para validar o Token apiRoutes.use((req, res, next) => { // Aqui vamos verificar o header da requisição, os parametros e o corpo da requisição, procurando o token var token = req.body.token || req.query.token || req.headers['x-access-token'] // Se o token existir if (token) { // Verificamos se o token está batendo com a nossa Secret jwt.verify(token, app.get('superSecret'), (err, decoded) => { if (err) { return res.json({ success: false, message: 'A autenticação com o token falhou.' }) } else { // Se o token estiver válido, então salvamos ele e liberamos o acesso, fazemos o trabalho do porteiro de um prédio aqui. req.decoded = decoded next() } }) } else { // Se quem requisitou não informou o token, devolvemos um erro para ele. return res.status(403).send({ success: false, message: 'Nenhum token foi informado.' }) } }) // Rota para nos devolver uma mensagem aleatória (GET /api) apiRoutes.get('/', (req, res) => { res.json({ message: 'Bem vindo a API mais dahora no mundo!' }) }) // Rota que retorna todos os usuários cadastrados no banco (GET /api/users) apiRoutes.get('/users', (req, res) => { User.find({}, (err, users) => { // O que fizemos aqui foi basicamente um Select na "tabela" de usuários if (err) { throw err } res.json(users) }) }) // Aqui dizemos que as rotas terão o prefixo /api app.use('/api', apiRoutes) // Inicia o servidor app.listen(port) console.log('Servidor iniciado em http://localhost:' + port) Para executar utilize no console ‘nodemon server.js’ Vamos por partes! ( Rotas da API) Cadastro de usuário app.post('/cadastrar', (req, res) => { // Criamos um novo usuário utilizando o schema que montamos na pasta models var novoUsuario = new User({ name: req.body.name, // A instrução req.body nos retorna um objeto com os dados que foram enviados através de uma requisição password: req.body.password }) novoUsuario.save((err) => { if (err) throw err // Se tiver algum erro na hora de salvar, usamos o throw para retornar uma "exception" console.log('Usuário cadastrado com sucesso') res.json({ success: true }) // Se tudo ocorrer bem, retornamos um json dizendo que deu certo }) }) Teste no POSTman Listagem de usuários // Rota que retorna todos os usuários cadastrados no banco (GET /api/users) apiRoutes.get('/users', (req, res) => { User.find({}, (err, users) => { // O que fizemos aqui foi basicamente um Select na "tabela" de usuários if (err) { throw err } res.json(users) }) }) Teste no POSTman Autenticação do token. // Rota de autenticacao de usuário (POST /api/authenticate) apiRoutes.post('/authenticate', (req, res) => { console.log(req.body) User.findOne({ name: req.body.name }, (err, user) => { // O findOne é como um Select, passando um filtro que é o 'name' if (err) throw err // Verificamos se o usuário existe if (!user) { res.json({ success: false, message: 'A autenticação falhou, o usuário não foi encontrado :C' }) } // Verificamos se a senha é correta if (user.password !== req.body.password) { res.json({ success: false, message: 'A autenticação falhou, a senha está incorreta :C' }) } else { // Se não tiver nenhum erro, então criamos o Token para ele var token = jwt.sign(user, app.get('superSecret'), { expiresIn: '1440m' }) // Aqui dizemos que o Token expira em 1440 minutos (24 hrs) // Retornamos um json dizendo que deu certo junto com o seu Token res.json({ success: true, message: 'Aproveite seu token!', token: token }) } }) }) Testes no POSTman Sucesso Senha inválida Usuário inválido Middleware Neste passo vamos montar a proteção das nossas rotas. // middleware para validar o Token apiRoutes.use((req, res, next) => { // Aqui vamos verificar o header da requisição, os parametros e o corpo da requisição, procurando o token var token = req.body.token || req.query.token || req.headers['x-access-token'] // Se o token existir if (token) { // Verificamos se o token está batendo com a nossa Secret jwt.verify(token, app.get('superSecret'), (err, decoded) => { if (err) { return res.json({ success: false, message: 'A autenticação com o token falhou.' }) } else { // Se o token estiver válido, então salvamos ele e liberamos o acesso, fazemos o trabalho do porteiro de um prédio aqui. req.decoded = decoded next() } }) } else { // Se quem requisitou não informou o token, devolvemos um erro para ele. return res.status(403).send({ success: false, message: 'Nenhum token foi informado.' }) } }) Testes no POSTman Sucesso Erro (Token inválido) Erro (Token vazio) Conclusão Recentemente encontrei este tutorial em um site e resolvi traduzir ele e deixar de uma forma mais simples, ele nos dá uma boa visão de como proteger nossas rotas utilizando o JSON Web Token, caso queira algum tutorial específico nos deixe um comentário, valeu pessoal! Já ia me esquecendo, caso queira verificar o projeto completo baixe o anexo do post, você também pode clonar ele para sua maquina pelo git clone https://github.com/nulldreams/autenticacao-api-jwt.git
  12. Tópico originalmente criado por: @Jonathan Santos O EJS é uma engine de visualização, com ele conseguimos de uma maneira fácil e simples transportar dados do back-end para o front-end, basicamente conseguimos utilizar códigos em javascript no html de nossas páginas. O que vamos construir? Vamos criar uma pequena aplicação que utilizará o EJS para transportarmos dados para o nosso front-end e também vamos ver uma maneira de reaproveitar algumas partes do nosso html. Para isso vamos precisar da seguinte estrutura de arquivos: - public/ ---- css/ ------------ styles.css - views/ ---- layout.ejs ---- pages/ ------------ about.ejs ------------ contact.ejs ------------ home.ejs - package.json - server.js Mão na massa! Instalando os pacotes do npm. No seu console digite " npm i ou install express ejs express-ejs-layouts faker body-parser ndemon --save " Dessa forma o npm vai baixar os pacotes e já inserir eles nas dependências do nosso projeto, dentro do package.json express É o pacote mais simples para criarmos as rotas do nosso app. ejs É o pacote responsável pela engine EJS. express-ejs-layouts Usamos ele para conseguirmos enviar dados para nossas páginas ejs pelo express. faker Usamos ele para gerar algumas informações aleatórias como Nome, email, imagens. (Útil para testes) nodemon Pacote usado para subir sua aplicação com a vantagem de que a cada vez que alterar ou criar um arquivo js ele reinicia automaticamente. Após a instalação dos pacotes seu arquivo package.json ficará da seguinte forma: { "dependencies": { "body-parser": "^1.15.2", "ejs": "^2.5.2", "express": "^4.14.0", "express-ejs-layouts": "^2.2.0", "faker": "^3.1.0" } } Variáveis que vamos utilizar. No início do seu arquivo server.js adicione: var express = require('express') var faker = require('faker') var bodyParser = require('body-parser') var expressLayouts = require('express-ejs-layouts') var app = express() var port = 3000 Configurando o nosso server . Logo após adicionarmos as variáveis, vamos configura-lás. app.set('view engine', 'ejs') // Setamos que nossa engine será o ejs app.use(expressLayouts) // Definimos que vamos utilizar o express-ejs-layouts na nossa aplicação app.use(bodyParser.urlencoded()) // Com essa configuração, vamos conseguir parsear o corpo das requisições Criando as rotas. Vamos utilizar as seguintes rotas GET / app.get('/', (req, res) => { res.render('pages/home') }) Aqui o server recebeu uma requisição do client e devolveu o arquivo home.ejs , com isso o EJS renderiza ele para o client em forma de uma página html. GET /about app.get('/about', (req, res) => { var users = [{ name: faker.name.findName(), email: faker.internet.email(), avatar: 'http://placekitten.com/300/300' }, { name: faker.name.findName(), email: faker.internet.email(), avatar: 'http://placekitten.com/400/300' }, { name: faker.name.findName(), email: faker.internet.email(), avatar: 'http://placekitten.com/500/300' }] res.render('pages/about', { usuarios: users }) }) O que o server faz aqui é praticamente a mesma coisa que foi feita na rota home , porém aqui nós devolvemos para o client além da página about , uma variável chamada usuarios. GET /contact app.get('/contact', (req, res) => { res.render('pages/contact') }) POST /contact app.post('/contact', (req, res) => { res.send('Obrigado por entrar em contato conosco, ' + req.body.name + '! Responderemos em breve!') }) O que o server faz aqui é recepcionar o conteúdo da requisição e devolver uma mensagem para o client aproveitando o nome da pessoa que enviou a mensagem para nós. Essa mensagem que vem no corpo da requisição, só é possível ser manipulada utilizando o pacote body-parser 1. No final o nosso arquivo server.js ficará assim: var express = require('express') var faker = require('faker') var bodyParser = require('body-parser') var expressLayouts = require('express-ejs-layouts') var app = express() var port = 3000 // Definimos que vamos utilizar o ejs app.set('view engine', 'ejs') app.use(expressLayouts) app.use(bodyParser.urlencoded()) // ROTAS app.get('/', (req, res) => { res.render('pages/home') }) app.get('/about', (req, res) => { var users = [{ name: faker.name.findName(), email: faker.internet.email(), avatar: 'http://placekitten.com/300/300' }, { name: faker.name.findName(), email: faker.internet.email(), avatar: 'http://placekitten.com/400/300' }, { name: faker.name.findName(), email: faker.internet.email(), avatar: 'http://placekitten.com/500/300' }] res.render('pages/about', { usuarios: users }) }) app.get('/contact', (req, res) => { res.render('pages/contact') }) app.post('/contact', (req, res) => { res.send('Obrigado por entrar em contato conosco, ' + req.body.name + '! Responderemos em breve!') }) app.use(express.static(__dirname + '/public')) app.listen(port) console.log('Servidor iniciado em http://localhost:' + port) Arquivos ejs Agora vamos ver como vão ficar nossas páginas e também entender como trabalhar com elas. Layout <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Utilizando o EJS</title> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/css/styles.css"> </head> <body> <header> <nav class="navbar navbar-inverse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/contact">Contact</a></li> </ul> </nav> </header> <main> <div class="container"> <%- body %> </div> </main> <footer> EJS </footer> </body> </html> Aparentemente é uma página em html apenas, porém quando iniciamos nosso aplicativo e requisitamos alguma rota que devolve o arquivo ejs , o express-ejs-layouts 3procura o arquivo layout.ejs dentro da pasta views , então onde está o código <%- body %> será carregado o conteúdo de outro arquivo ejs. No próximo passo você vai entender como funciona essa ligação entre os arquivos. Home <%- contentFor('body') %> <div class="jumbotron text-center"> Página Inicial </div> No arquivo layout.ejs vimos que o código <%- body %> seria substituído por outro assim que a página fosse renderizada, agora no arquivo home.ejs temos <%- contentFor(‘body’) %> , é aqui que ocorre a ligação entre os dois arquivos, no lugar de <%- body %> ficará essa div. About <%- contentFor('body') %> <div class="jumbotron text-center"> <h1>O Time!</h1> <div class="row"> <% for (usuario of usuarios){%> <div class="col-sm-4"> <h2><%= usuario.name %> <img class="img-responsive" style="height: 250px" src="<%= usuario.avatar %>"> </div> <% } %> </div> </div> O que fazemos aqui é renderizar para o client todos os nossos usuários, isso é possível pois fizemos um loop com o ejs , para capturarmos o valor de cada usuário que existe na variável usuarios que a rota /about devolveu. Contact <div class="jumbotron text-center"> <div class="row"> <div class="col-sm-6 col-sm-offset-3"> <h2>Entre em contato!</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <form action="/contact" method="POST"> <div class="form-group"> <label>Nome</label> <input type="text" name="name" class="form-control"> </div> <div class="form-group"> <label>Email</label> <input type="text" name="email" class="form-control"> </div> <div class="form-group"> <label>Sua mensagem</label> <input type="text" name="message" class="form-control"> </div> <div class="form-group text-right"> <button type="submit" class="btn btn-primary btn-lg">Enviar</button> </div> </form> </div> </div> </div> Nessa página usamos apenas o html para enviar um POST para a rota /contact . Conclusão Este mini tutorial tem a intenção de mostrar para vocês o básico do que o EJS pode fazer, agora que você já sabe trabalhar com a comunicação entre o back-end e o front-end, por que você não tenta mesclar este tutorial e nosso tutorial anterior Autenticando uma API em NodeJS em um projeto seu? O projeto completo está em anexo no post, e você também pode clonar ele para sua maquina pelo git clone https://github.com/nulldreams/EJS.git Caso queira algum tutorial específico nos deixe um comentário, valeu pessoal! 🤘
  13. Comentário originalmente feito por: "FourPixel_IT": Se precisar de uma API simples e com valores em reais, sugiro Z-API …www.z-api.io
  14. Comentário originalmente feito por: "Joe_Dutra" solução é https://github.com.br/orkestral/venom
  15. Comentário originalmente feito por: "shivamsharma" How can we integrate Whatsapp chat on SSPMIS hindi website?
  16. Tópico originalmente criado por: @Jonathan Santos O SONHO ACABOU! 😔 O suporte ao Chat-API foi encerrado, segue anuncio oficial: https://github.com/mgp25/Chat-API/issues/2116 Uma alternativa seria: https://github.com/tgalal/yowsup Tínhamos um objetivo neste mês que era encontrar uma forma de integrar uma aplicação PHP com o WhatsApp, de cara imaginávamos que não seria simples, pois o WhatsApp não possuí (e nem pretende ter) uma API pública, mas que seria bem divertido de trabalhar com isso. Começamos com a pesquisa no Google e encontramos um repositório no GitHub chamado Chat-API (https://github.com/mgp25/Chat-API 194) que de cara já parecia ser o ideal, porém, antes de continuar precisávamos saber se era legal utiliza-la e o que descobrimos é que sim, poderíamos, só não poderíamos agir como um robô ou gerar spam, veja os termos do WhatsApp (apenas os importantes para o nosso caso): You agree not to use or launch any automated system, … that accesses the Service in a manner that sends more request messages to the WhatsApp servers in a given period of time than a human can reasonably produce in the same period by using a WhatsApp application. Your WhatsApp account can only be verified with one number on one device. If you have a dual SIM phone, please note that you still must choose one number to verify with WhatsApp. There is no option to have a WhatsApp account with two phone numbers. Em tradução livre, isso quer dizer que: Você concorda em não usar ou lançar qualquer sistema automatizado, … que acessa o Serviço de maneira a enviar mais solicitações aos servidores do WhatsApp em um determinado período de tempo do que um ser humano pode responder no mesmo período através de uma aplicação do WhatsApp. Sua conta WhatsApp só pode ser verificada com um número em um único dispositivo. Se você tiver um telefone dual SIM, por favor note que você ainda deve escolher um número para verificar com o WhatsApp. Não há opção de ter uma conta WhatsApp com dois números de telefone. Já que é assim, e a ideia não era mesmo infringir quaisquer termos do WhatsApp, tá tudo ótimo, mãos a obra!
  17. Tópico originalmente criado por: "lucas.gusmao" Olá Desenvolvedor! Você que é cliente do PlugBoleto, fique atento pois teremos uma alteração na interface das notificações enviadas pela API através do Webhook. Atualmente a API envia os campos de valor de maneira despadronizada, ou seja, alguns campos tem o separador decimal como vírgula e outros como ponto, como pode ser visto no exemplo abaixo: Essa correção irá impactar todas as notificações disponíveis, por isso, é necessário preparar o seu sistema para recebê-las da maneira correta. Apesar de ser uma mudança bem simples, as notificações são muito utilizadas pelos clientes! Sendo assim, a alteração estará no ambiente de produção a partir do dia 19/09/2020. Essa alteração consiste em trocar o separador decimal de ponto e colocar todos como vírgula. O tipo de campo (string) será mantido. Qualquer dúvida estamos a disposição, Obrigado!
  18. Tópico originalmente criado por: "guilherme.ganassin" Olá desenvolvedor! Seja bem-vindo à comunidade HUB! A partir de agora passaremos a te apresentar por aqui as principais novidades dos produtos da linha Fintech! Seja bem-vindo a esta nova área e vamos às novidades! PlugBoleto: Ajuste nas regras de validação: Código do Beneficiário da Caixa agora aceita até 7 dígitos, para nos adequarmos à mudança de layout feita pelo banco; Corrigida a validação para o campo TituloCodEmissaoBloqueto do Santander; Personalizar impressão via API: Agora, é possível configurar a impressão personalizada via GUI e também via API! Melhorias no envio via Banco do Brasil por WebService: Efetuamos mudanças na arquitetura da aplicação para que haja um melhor tratamento em casos de erros do webservice bancário e melhoria no tempo de resposta; Criação do campo “Código da Carteira” no cadastro do convênio; Liberado o uso do banco Cresol, CNAB 400; Liberado o envio de webhooks em conjunto com a consulta de boletos automática do Sicredi WS; Correção da mensagem de erro que era apresentada na personalização da impressão (ao usar a "Linha digitável no recibo do pagador); Novo filtro de boletos pela data de atualização (consulta via API); Melhoria no tratamento do valor passado no campo “ConvenioNumeroRemessa” (cadatro/alteração do convênio); Correção na validação de layout para boletos emitidos via Sicredi WS; Caso se utilize a validação, os boletos não ficarão com o processamento travado; Liberação de novos campos no Unicred WS; Atualizamos nossa API de acordo com o manual mais recente do banco, sendo possível agora integrar juros, multa e desconto via WS; Melhoria no tratamento do retorno do Sicredi Implementadas melhorias na API de modo que movimentos que registram tarifas sejam conciliados; Emails via GUI: Agora, via GUI do Cedente é possível enviar emails para múltiplos destinatários Otimização na geração de relatórios: Agora, caso o relatório possua 4 Mb ou mais, é enviado o link para download ao email e o mesmo também é disponibilizado na GUI Melhorias no registro via Santander WS: Campos de endereço passaram a ser truncados para evitar rejeições no processamento do envio pelo banco; API de Pagamentos: Monitoramento da API via Telegram: Configuramos o serviço de monitoramento da API via Telegram para que nossa equipe de infra se antecipe a qualquer problema que possa ocorrer na API de Pagamentos! Ajuste na conciliação de extratos bancários para o Banco do Brasil; Possibilidade de recepcionar extratos .ofx via Transmissão automática com notificações por webhook; Consulta de Crédito: Implementado o retorno em formato json para a Credit Bureau PF Top Score Caso surja qualquer dúvidas sobre os produtos ou os pontos descritos acima, será um prazer ajudar!
  19. Tópico originalmente criado por: "GustavoFiorin" Olá desenvolvedor! Neste post iremos disponibilizar à você algumas informações adicionais referentes a mensagem de erro: “ERRO DE CONSISTENCIA: REGISTRO DE TITULOS ECOMMERCE NAO CONTRATADO (2)”, apresentado pelo WebService do banco Bradesco (237). Este erro será apresentado quando a tentativa de registro via WebService possuir um certificado que não possui o serviço de cobrança contratado, ou seja, não possui liberação do banco para registrar via WebService. Mensagem de erro A mensagem de erro “ERRO DE CONSISTENCIA: REGISTRO DE TITULOS ECOMMERCE NAO CONTRATADO (2)” ocorre quando o certificado utilizado para encaminhar a requisição ao banco possui divergências no cadastro junto ao banco de dados do Bradesco, ou seja, a requisição é encaminhada ao banco, mas como o certificado não foi reconhecido e previamente homologado com o respectivo serviço (cobrança-ecommerce) junto ao banco, esta mensagem é retornada devido ao responsável pela conta não ter realizado a contratação do serviço de cobrança junto ao banco. Como corrigir: Para corrigir o erro acima basta entrar em contato com o banco, e realizar o alinhamento junto ao gerente responsável pela conta para efetuar a contratação do serviço para registro via e-commerce (registro online). Como corrigir nas soluções Tecnospeed: Em nossa plataforma, identifique a conta que foi previamente cadastrada junto ao cedente, e realize o alinhamento junto ao gerente responsável por ela, para que o procedimento de contratação do serviço de cobrança seja iniciado. Após a finalização, cadastre novamente o certificado no ambiente do cedente, verifique se a opção de “registro instantâneo” está selecionada no respectivo convênio do cedente, e dê inicio nas emissões com este novo serviço. Motivos para utilizar o WebService O recurso da transmissão instantânea (WebService) é um método de comunicação direta com as APIs dos bancos, tendo assim uma resposta instantânea sobre a situação de seu boleto, ou seja, já no momento da emissão é feita uma comunicação com os servidores bancários, e os boletos já são autorizados ou rejeitados, permitindo assim que os clientes façam o pagamento logo após a emissão dos títulos, sem precisar aguardar o dia útil padrão de processamento de remessas, pois este serviço não utiliza o arquivo de remessa para o registro do boleto. Caso queira conhecer como fazer a configuração no ambiente da Tecnospeed, clique aqui 1 e conheça nossos produtos! Caso tenha qualquer dúvida sobre o cenário explicado ou se quiser conhecer nossas soluções voltadas a automatização na geração de boletos, estaremos sempre à disposição, será um prazer ajudar!
  20. Tópico originalmente criado por: "Leonardo" Olá desenvolvedor(a), Neste post falaremos sobre uma das rejeições mais comuns quando realizamos o envio de um arquivo de remessa para registro de boletos no site dos bancos, a mensagem: “Arquivo de remessa deve possuir 240 ou 400 posições”. Este erro pode ocorrer por diferentes causas, dentre as principais, podemos destacar: Presença de caracteres inválidos na remessa e, com este caractere o sistema bancário pode converter o arquivo para algum formato que quebre o texto; Limite de caracteres por linha definido pelos manuais dos bancos não foi respeitado, ou seja, linhas com mais ou menos caracteres que o definido pelos manuais; Adição de uma ou mais linhas em branco ao final do arquivo, isto pode causar esta falha no arquivo pois haverão linhas inválidas e ocasionará esta mensagem de rejeição. Para evitar estes problemas, você pode realizar as seguintes análises: Ao emitir um boleto, evite copiar e colar os dados de e-mails ou PDFs sem antes implementar uma rotina de “limpeza” deste texto, pois ao realizar esta cópia junto ao texto podem existir caracteres especiais/ocultos que podem passar despercebidos. Assim que for solicitada a remessa, verifique se em seu sistema o processo de adicionar uma ou mais linhas extras no final do arquivo não esta ocorrendo e se todas as linhas possuem o caractere delimitador de quebra na posição adequada. Como a Tecnospeed lida com este problema? Em nosso sistema possuímos uma validação interna onde verificamos se existem caracteres especiais na remessa gerada e a tratamos para que não haja uma quebra de layout. Também trabalhamos com a possibilidade de envio dos arquivos de remessa automaticamente ao banco, permitindo total automação na transmissão dos arquivos sem a necessidade de encaminha-la através do internet banking, ou seja, sem manipulação de arquivo pelos usuários. Com este modo de envio a possibilidade de ocorrer algum erro por layout diminui drasticamente. Caso queira conhecer nossos produtos voltados à Cobrança Bancária entre em contato conosco! Será um prazer te atender! E restando qualquer dúvida estamos à disposição!
  21. Nesta área você poderá acompanhar os produtos da linha Fintech da Tecnospeed. Por aqui você poderá nos encaminhar perguntas, tirar dúvidas sobre os produtos e acompanhar as principais novidades! Temos algumas regras aqui no ambiente Tecnospeed Fintech: O SLA (tempo máximo de resposta por um especialista da Tecnospeed) é de 5 dias úteis para ter uma resposta da Tecnospeed. Antes disso, seu tópico pode ser respondido por alguém da comunidade. Mas podemos dizer que normalmente buscamos responder antes, mas esse é o prazo máximo. O Hub é um ambiente público, por isso não exponha dados sensíveis do seu Software, da Tecnospeed ou dos seus clientes, como Tokens, senhas, Ips e afins… Caso identificarmos dados sensíveis, vamos excluí-los. Sempre que possível, utilize as tags quando disponíveis na categoria que está postando, para classificar os atendimentos Coloque suas dúvidas, quando envolver produtos da Tecnospeed, na área específica do produto, dentro da sub-categoria “Dúvidas” O Hub também pode ser utilizado por Não Clientes que desejam ajuda com desenvolvimento de software e soluções em geral
  22. Tópico originalmente criado por: @Paulo Olá, desenvolvedor! Como de costume, divulgamos as principais novidades do mês de Julho/20, à partir deste mês, passaremos a centralizar nossa comunicação aqui no HUB, seja bem vindo \o Novidades Infra Ao atualizar via MODO a configuração de VersaoManual, para os documentos NFe, NFCe, MDFe, CTe e CTeOS, os caminhos dos modelos de impressão também são atualizados de acordo. Novidades Plugin NFSe: O padrão IPM agora possui a impressão de NFSe, sendo obtido pelo link pertencente a nota. A impressora utilizada, será a configurada no CNPJ. Homologação do município Piritiba - BA, padrão SAATRI. Homologação do município Antônio Prado - RS, padrão GOVBR20. Homologação do município Peabiru - PR, padrão MAISISS. Homologação do município Carangola - MG, padrão EL20. Re-homologação do município Itajá - GO, mudança de padrão de CENTI para BETHA. Re-homologação do município Araruama - RJ, mudança de padrão de ISSDIGITAL20 para BETHA. Re-homologação do município Castro Alves - BA, mudança de padrão de BETHA para FISCO. Compatibilizando o padrão PubliCenter, nessa versão estará disponível a cidade de Marabá - PA. Para mais informações acesse: Documentação Técnica - Padrão PubliCenter Re-homologação do município Cachoeirinha - RS, mudança de padrão de THEMA para IPM. Implementado motivo de cancelamento DEFAULT para a cidade de Bauru - SP. Caso o motivo não seja informado na requisição, será preenchido automaticamente com “Nota cancelada à pedido do prestador”. Re-homologação do município Itajubá - MG, mudança de padrão de GOVDIGITAL para GINFES. Melhoria para retornos do webservice instável para o padrão COPLAN. Implementando melhoria no fluxo do padrão ISSWEB para quando houver inconsistência no WebService. Re-homologação do município Volta Redonda - RJ, mudança de padrão de SIMPLISS para ISSNETONLINE. Re-homologação do município Cascavel - PR, mudança de padrão de ISSNETONLINE para IPM. Homologação do município Monte Sião - MG, padrão FIORILLI. Re-homologação do município São Miguel do Iguaçu - PR, mudança de padrão de MAISISS para MAISISS20. Re-homologação do município Piraí do Sul - PR, mudança de padrão de MAISISS para MAISISS20. Homologação do município São Jorge D’Oeste - PR, padrão EQUIPLANO. O padrão IPM agora possui a inclusão de múltiplas parcelas. Acesse a documentação do padrão para mais informações: Documentação Técnica - Padrão IPM Implementando melhoria no fluxo com erros no TX2. A partir de agora será priorizado a exception do TX2 ao montar as notas. Re-homologação do município Pouso Alegre - MG, mudança de padrão de GINFES para SIGISS20. Homologação do município Lutécia - SP, padrão FIORILLI. Homologação do município Itaqui - RS, padrão DBSELLER. Homologação do município Bananal - SP, padrão EMBRASUP. Homologação do município Itatinga - CE, padrão INTERSOL. Re-homologação do município Mirassol D’Oeste - MT, mudança de padrão de SATURNO para FIORILLI. Compatibilizando o padrão Futurize com o Manager eDoc, nessa versão estará disponível a cidade de Matias Barbosa - MG. Para maiores informações acesse: Documentação Técnica - Padrão FUTURIZE Implementando tratamento para retornos alternativos do padrão ISSWEB. Implementando cancelamento por substituição para o padrão Fiorilli. Re-homologação do município Itajá - GO, mudança de padrão de BETHA para CENTI. Homologação do município Porto Seguro - BA, padrão ISSINTEL. Homologação do município Acaraú - CE, padrão INTERSOL. Homologação do município Guaçuí - ES, padrão EL. Homologação do município Ibiraçu - ES, padrão EL. Homologação do município Marataízes - ES, padrão EL. Re-homologação do município Carangola - MG, mudança de padrão de EL20 para EL. Implementando melhoria no fluxo do padrão ISSNETONLINE para quando houver inconsistência no WebService. Re-homologação do município Altônia - PR, mudança de padrão de GOVBR para GOVBR20. Implementado preenchimento automático no parâmetro CodigoCancelamento para a cidade de Joinville - SC. Re-homologação do município de Penápolis - SP, mudança de padrão de FGMAISS para ISSONLINE. Re-homologação do município de Americana - SP, mudança de padrão de TIPLAN para SMARAPD. Implementado o fluxo de duplicidade no retorno da consulta de lote para o padrão GovBR20. Homologação do município de São João da Barra - RJ, padrão EL20. Homologação do município de Caarapó - MS, padrão AEG. Re-homologação do município de Marmeleiro - PR, mudança de padrão de GOVBR para GovBr20. Novidades Plugin MDFe: Adicionado o evento de Pagamento de Operação de Transporte no plugin MDF-e na integração por pastas e API. Correções Plugin GNRe: Correção no tratamento da tag QrCodCTe para manter o CDATA. Correções Plugin NFe: Correção no cancelamento de NFe via API utilizando formato XML. Correção na consulta de notas destinadas utilizando o CNPJ do emitente como filtro. Correção para descarte de nota rejeitada quando modo igual a contingência. Correção para gerar exportação PDF de notas destinadas com logotipo padrão. Correções Infra: Correção na numeração automática com envio utilizando CPF. Correções Plugin NFSe: Melhoria para consulta com retorno alternativo da cidade de Goiania. Melhoria no fluxo de envio ao retornar rejeições para Curitiba. Melhoria no fluxo de envio do padrão Tiplan. Agora a nota com retorno “faultstring” (instabilidade do WS) ficará com a situação ENVIADA ao invés de REJEITADA. Ajuste na reutilização do número de RPS para notas com erro na sua geração. Impedimento de geração de notas com o mesmo IdIntegracao para o padrão SigIss e Osasco. Correção no download de XML de NFSe via GUI para o padrão Joinville. Corrigindo a configuração do XML para cada nota de um lote no padrão MaisIss20. Ajustando geração de notas para o padrão Saatri. Não será mais permitido notas com o mesmo idintegracao. Tem alguma dúvida, ou sugestão? Comenta aí 😃
×
×
  • Create New...