Pular para o conteúdo
  • Este tópico contém 7 respostas, 2 vozes e foi atualizado pela última vez 5 anos, 9 meses atrás por Avatar de José Laurindo ChiappaJosé Laurindo Chiappa.
Visualizando 8 posts - 1 até 8 (de 8 do total)
  • Autor
    Posts
  • #109315
    Avatar de MottaMotta
    Participante

      Alguém já passou por este problema ?

      Prezado(a)s : Ao enviar um email em HTML pelo package SMTP o Oracle coloca um espaço em branco no meio de uma palavra do nada ,

      algo como
      Oracle coloca um espaço
      fica
      Oracle colo ca um espaço

      A rotina do SMTP é basicamente a que a documentação do Oracle indica.

      #109316
      Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
      Moderador

        Blz ? Não, rigorosamente **** NUNCA **** vi o Oracle por conta própria colocar quebra de linha não : pra mim, a minha primeira e mais Provável Suposição é que vc tá montando o HTML dinamicamente e por BUG NA TUA ROTINA, em alguns casos fica alguma TAG html aberta/inválida… Pra DEBUGAR isso uma alternativa EXCELENTE é vc gravar o HTML num arquivo-texto e tentar abrir esse arquivo num editor de HTML….
        A segunda Suposição é que vc NÃO esteja fazendo a conversão pra binário corretamente, confiando na conversão implícita e aí sabe Deus que tipo de resultado se obtém….
        Como exemplo, veja a rotina abaixo que eu uso : ASSUMINDO a limitação de texto HTML menor que 32 Kb, ela funciona perfeitamente – tenta criar ela no teu banco e com ela enviar uma mensagem (TOMANDO O CUIDADO de incluir no texto da mensagem caracteres de carriage return E DE line feed se for Windows o servidor SMTP em questão), que DEVE funcionar okdoc ….
        Segue :

        sistema@sistema-DESENV:SQL>get TESTE_PR_ENVIA_EMAIL.sql
        1 create or replace procedure TESTE_PR_ENVIA_EMAIL (
        2 WREMETENTE varchar2, — Remetente
        3 WDESTINATARIO varchar2, — Destinatário
        4 WDESTINATARIO_CC varchar2, — Com cópia
        5 WASSUNTO varchar2,
        6 WMENSAGEM clob
        7 )
        8 is
        9 WSMTP varchar2(20) := ‘smtp.MINHAEMPRESA.com.br’; — Endereco IP do SMTP
        10 WSMTP_USER varchar2(50) := ‘enviosistema@MINHAEMPRESA.com.br’; — Usuário autenticado no SMTP
        11 WSMTP_USER_PASS varchar2(50) := ‘senhadousuárioSMTP’; — Senha do usuário SMTP
        12 WCONN utl_smtp.connection; — Abre conexão SMTP e HTTP
        13 WHTML varchar2(200) := ‘MIME-Version: 1.0’||utl_tcp.crlf||’Content-type: text/html; charset=iso-8859-1’||utl_tcp.crlf;
        14 WBR varchar2(10) := chr(38)||’nbsp;’;
        15 WRODAPE clob := ‘

        ‘||WBR||WBR||WBR||’Este email foi enviado automaticamente pelos nossos sistemas informatizados.’||WBR||WBR||WBR||’

        ‘;
        16 BEGIN
        17 — Abre conexão com um Servidor SMTP, porta padrão é 587
        18 WCONN := utl_smtp.open_connection(WSMTP,587);
        19 utl_smtp.helo(WCONN,WSMTP);
        20 utl_smtp.command(WCONN,’AUTH LOGIN’);
        21 utl_smtp.command(WCONN,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw((WSMTP_USER)))));
        22 utl_smtp.command(WCONN,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw((WSMTP_USER_PASS)))));
        23 utl_smtp.mail(WCONN,(”));
        24 utl_smtp.rcpt(WCONN,(”));
        25 if WDESTINATARIO_CC is not NULL then
        26 utl_smtp.rcpt(WCONN,(”));
        27 end if;
        28 utl_smtp.open_data(WCONN);
        29 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘From:’ ||WREMETENTE ||utl_tcp.crlf));
        30 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘To:’ ||WDESTINATARIO ||utl_tcp.crlf));
        31 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘Cc:’ ||WDESTINATARIO_CC||utl_tcp.crlf));
        32 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘Subject:’||WASSUNTO ||utl_tcp.crlf));
        33 UTL_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(WHTML));
        34 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘ ‘ ||utl_tcp.crlf));
        35 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(utl_tcp.crlf||WMENSAGEM));
        36 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(utl_tcp.crlf||WRODAPE));
        37 utl_smtp.close_data(WCONN);
        38 utl_smtp.quit(WCONN);
        39 EXCEPTION
        40 when OTHERS then
        41 utl_smtp.quit(WCONN);
        42 raise_application_error(-20011,’Não foi possível enviar o e-mail devido ao seguinte erro: ‘||sqlerrm);
        43* END;
        44 /

        Procedimento criado.

        sistema@sistema-DESENV:SQL>

        []s

        Chiappa

        OBS :

        a) logicamente, aqui usei um banco 10g pro meu exemplo – se fosse um banco 11g ou superior, eu TERIA que incluir também um ACL pra poder acessar servidores externos….

        b) não deixe de checar por eventuais limites NO SERVIDOR DE EMAIL : muito embora em tese um texto html deveria ser capaz de ser exibido com qquer largura de linha, nada impede que teu servidor SMTP por qquer motivo restrinja linesize do html a enviar – NADA A VER com o banco Oracle em si e TUDO A VER com seu servidor SMTP…

        #109317
        Avatar de MottaMotta
        Participante

          Valeu. pela resposta.

          Salvo um html na pasta utl padrão , leio este arquivo e jogo para um CLOB.

          O erro ocorre para o nosso dominio na empresa e também no meu particular (Yahoo).

          Esta SP chama outra que manda o email , esta do email é basicamente a da documentação Oracle , funciona beleza mas estava colocando este espaço antes.

          Pesquisei alguns sites e vi relação com um buffer limitado a 1000 caracteres , não achei nenhum parâmetro para aumentar isto.

          Talvez a solução seja varrer o blob de 1000 em 1000 registros e tratar isto , pegar uma palavra no meio quando na posição 1000.

          Estranho paca.

          Segue a SP de envio

          create or replace PROCEDURE ENVIA_EMAIL_CLOBH (ds_email_origem_w varchar2,
          ds_email_destino_p varchar2,
          ds_assunto varchar2,
          p_attach_clob IN CLOB DEFAULT NULL,
          p_httm in varchar2 default 'S',
          p_log out varchar2,
          p_nome_destino in varchar2 default null) is

          l_step PLS_INTEGER := 900;--12000;-- make sure you set a multiple of 3 not higher than 24573 (doc Oracle)
          ds_smtp_w varchar2(20) := '......';
          /* Abre conex?o SMTP e HTTP */
          CONEXAO UTL_SMTP.CONNECTION;
          -- fixar este envio por segurança
          vs_origem varchar2(100) := ds_email_origem_w;
          --
          vs_para varchar2(100);
          vs_cc varchar2(100);
          --

          PROCEDURE send_header(name IN VARCHAR2, header IN VARCHAR2) AS
          BEGIN
          UTL_SMTP.WRITE_DATA(CONEXAO, name || ': ' || header || UTL_TCP.CRLF);
          END;

          BEGIN
          /* Abre conex?o com um Servidor SMTP(Simple Mail Transfer Protocol), porta padr?o SMTP e 25 */
          CONEXAO := utl_smtp.open_connection (ds_smtp_w,25);
          UTL_SMTP.HELO (CONEXAO, ds_smtp_w); /* Endereco do servidor de SMTP */
          --utl_smtp.command (CONEXAO, 'AUTH LOGIN');
          --utl_smtp.command (CONEXAO, utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw((ds_user_id_w)))));
          --UTL_SMTP.COMMAND (CONEXAO, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW((DS_SENHA_SMTP_W)))));

          UTL_SMTP.MAIL (CONEXAO, ('')); /* E-mail de quem esta mandando */
          -- se estiver em lista separado por ";" manda para o 1º como "para" e para o 2º como CC (copia)
          /* Para quem vou mandar */
          IF INSTR(ds_email_destino_p,';') = 0 THEN
          vs_para := ds_email_destino_p;
          UTL_SMTP.RCPT (CONEXAO, ('')); /* Para quem vou mandar */
          ELSE
          vs_para := SUBSTR(ds_email_destino_p,1,INSTR(ds_email_destino_p,';')-1);
          vs_cc := SUBSTR(ds_email_destino_p,INSTR(ds_email_destino_p,';')+1,length(ds_email_destino_p));
          UTL_SMTP.RCPT (CONEXAO, ('')); /* Para quem vou mandar original */
          UTL_SMTP.RCPT (CONEXAO, ('')); /* Para quem vou mandar copia */
          END IF;
          UTL_SMTP.OPEN_DATA(CONEXAO);

          If upper(p_httm) 'S' Then
          send_header('Subject','=?iso-8859-1?Q?' ||UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(UTL_RAW.CAST_TO_RAW(ds_assunto))));
          Else
          send_header('Subject','=?iso-8859-1?Q?' ||UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(UTL_RAW.CAST_TO_RAW(ds_assunto)))|| '?=');
          end if;

          If upper(p_httm) 'S' Then
          UTL_SMTP.write_data(CONEXAO, 'Content-Type: text/html; charset="UTF-8"' || utl_tcp.CRLF);
          Else
          UTL_SMTP.write_data(CONEXAO, 'Content-Type: text/html; charset="UTF-8"' || utl_tcp.CRLF );
          end if;

          send_header('From',ds_email_origem_w);

          --se denominou o destino formata o envio , senão vai o proprio email
          --tratamento diferente do "from" pois este é em geral dinamico
          --feito pela stored procedure chamadora
          if trim(p_nome_destino) is null then
          send_header('To',vs_para);
          else
          send_header('To','"'||trim(p_nome_destino)||'" ');
          end if;

          If Trim(vs_cc) is not null Then--copia (nao formata o destino)
          send_header('CC',vs_cc);
          end if;

          FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_attach_clob) - 1 )/l_step)
          FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_attach_clob) - 1 )/l_step)
          LOOP
          UTL_SMTP.WRITE_DATA(CONEXAO, DBMS_LOB.substr(p_attach_clob, l_step, i * l_step + 1));
          END LOOP;

          UTL_SMTP.CLOSE_DATA(CONEXAO);
          UTL_SMTP.QUIT (CONEXAO);
          Exception
          when OTHERS then
          utl_smtp.quit (conexao);
          p_log := 'Erro: ' || SQLERRM;
          END ENVIA_EMAIL_CLOBH;

          #109318
          Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
          Moderador

            Acho que entendi o seu ‘problema’ : na verdade não tem *** NADA A VER *** com o database Oracle (NEM DE LONGE é o ‘database Oracle enfiando brancos aleatoriamente, como vc deu a entender) e ** TUDO A VER ** com o protocolo SMTP, okdoc ?? NADA ESTRANHO, longe disso…

            Cfrme https://www.emailonacid.com/blog/article/email-development/line-length-in-html-email/ explica, de acordo com a norma [RFC2821] , esse protocolo de comunicação IMPÕE um limite de 1000 caracteres numa linha aí já inclusos os eventuais caracteres de controle/fluxo de linha como linefeeds/carriage returnos e etc…. No caso eu não tinha caído nisso porque eu mando TEXTOS (ie, cartas, memorandos, avisos, etc) a serem lidos por HUMANOS no corpo do email, e pra esse tipo de uso não faz sentido uma linha tão grande, é ilegível por um humano, não cabe nem em monitor nem em janela de editor de texto normal…. O meu contra-exemplo, usando a minha rotina :

            testenv@SISTEMA:SISTEMA-DESENV:SQL>l
            1 DECLARE
            2 v_str varchar2(4000);
            3 BEGIN
            4 v_str := lpad(‘A’, 500, ‘*’) || lpad(‘B’, 500, ‘!’) || lpad(‘C’, 500, ‘@’) || lpad(‘D’, 499, ‘$’) || ‘Z’;
            5 TESTE_PR_ENVIA_EMAIL(‘financeiro@SISTEMA.com.br’, ‘jlchiappa@gmail.com’, ‘jlchiappa@yahoo.com.br’, ‘Assunto:TESTE’, v_str);
            6* END;
            testenv@SISTEMA:SISTEMA-DESENV:SQL>/

            Procedimento PL/SQL concluído com sucesso.

            ==> O que resultou pra mim no email que recebi :

            *******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************A!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$DZ

            (talvez o Forum aqui enfie umas quebras de linha por conta própria, mas na verdade o que temos aqui é uma só longuíssima linha mas com espaço a cada 1000 caracteres, OBEDECENDO aos ditames pro protocolo SMTP)…

            Já que é algo IMPOSTO por padrões externos ao database Oracle, quais workarounds adotar ?

            => como não faz sentido enviar um texto a ser lido por um humano numa só longuíssima linha, eu SUPONHO que na verdade essa informação são DADOS a serem lidos/interpretados por um sistema informatizado, correto ? Sendo isso, minha Sugestão seria vc enviar esses dados como um ARQUIVO ANEXO ao email : https://oracle-base.com/articles/misc/email-from-oracle-plsql#clob tem um exemplo de como fazer isso via UTL_SMTP, é bem simples a alteração necessária….

            ou

            => se REALMENTE a informação vai ser consumida por um HUMANO, please insira os linebreaks necessários a cada x caracteres, onde x é um número bem inferior a 1000….

            []s

            Chiappa

            #109320
            Avatar de MottaMotta
            Participante

              Mais uma vez grato.

              #109323
              Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
              Moderador

                Ok, espero ter ajudado e desfeito a ‘estranheza’ / explicado a causa do comportamento….

                E reforço a idéia de ANEXAR num arquivo se teus dados realmente PRECISAM estar em linhas tão longas : mesmo usando os caracteres html corretos de quebra de linha, tal como https://github.com/adam-p/markdown-here/issues/130 e https://stackoverflow.com/questions/46979198/how-to-wrap-long-text-in-html-emails (entre vários outros) indicam, clientes de email podem SIM apresentar problemas de exibição com html contendo linhas anormalmente longas …

                []s

                Chiappa

                #109331
                Avatar de MottaMotta
                Participante

                  Vamos pelo mais simples , vamos mandar link de imagem.

                  #109335
                  Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
                  Moderador

                    Ainda melhor, se tem a possibilidade de incluir um link no teu email apontando pro local onde os dados estão, melhor ainda : muitas vezes vc está mandando emails pra usuários externos da Empresa, nem sempre há a chance de se ter um servidor acessível onde os dados residam acessível via link html/url, se vc tem a possibilidade, maravilha…

                    []s

                    Chiappa

                    OBS : só estranhei quando vc disse que o link será ‘de imagem’ : é uma imagem/um arquivo contendo alguma imagem num formato gráfico qquer que vc quer passar no email ? Se sim, se o tamanho do arquivo de imagem não for estrondosamente grande, por que não anexar ele no email ?

                  Visualizando 8 posts - 1 até 8 (de 8 do total)
                  • Você deve fazer login para responder a este tópico.
                  plugins premium WordPress