[英]Fix PL/SQL program that sends e-mail
以下 PL/SQL 程序发送 email,它使用基本身份验证向 sendgrid 进行身份验证,直到昨天才运行。
create or replace PROCEDURE ENVIA_EMAIL( p_remetente IN VARCHAR2
,p_destinatario IN VARCHAR2
,p_titulo_email IN VARCHAR2
,p_mensagem IN VARCHAR2
,p_dsc_arquivo_atachado1 IN VARCHAR2 DEFAULT NULL
,p_tipo_arquivo1 IN VARCHAR2 DEFAULT 'TEXT'
,p_dsc_arquivo_atachado2 IN VARCHAR2 DEFAULT NULL
,p_tipo_arquivo2 IN VARCHAR2 DEFAULT 'TEXT'
,p_dsc_arquivo_atachado3 IN VARCHAR2 DEFAULT NULL
,p_tipo_arquivo3 IN VARCHAR2 DEFAULT 'TEXT'
,p_username IN VARCHAR2
,p_password IN VARCHAR2) IS
--
-- Declaracao de variaveis
w_usuario NUMBER(10);
w_smtp_ip VARCHAR2(30) := 'smtp.sendgrid.net';
w_smtp_porta NUMBER := 587;
boundary CONSTANT VARCHAR2(256) := 'CES.Boundary.DACA587499938897';
w_conexao UTL_SMTP.CONNECTION;
w_mensagem VARCHAR2(30000);
w_nova_linha VARCHAR(2) := chr(13)||chr(10);
wrk_local NUMBER;
w_destinatario VARCHAR2(500);
w_destinatario_todo VARCHAR2(500);
w_destin_todo_fixo VARCHAR2(500);
TYPE varchar2_table IS TABLE OF VARCHAR2(256) INDEX BY BINARY_INTEGER;
w_contador BINARY_INTEGER;
function subject_encode(s_string varchar2) return varchar2 is
temp_subject varchar2(6000);
lengthsubject pls_integer:= 40;
w_nova_linha VARCHAR(2) := chr(13)||chr(10);
count_length pls_integer;
begin
count_length:=CEIL(LENGTH(s_string)/lengthsubject);
temp_subject:='=?iso-8859-1?B?' ||
utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(substr(s_string,1,lengthsubject ))))|| '?=';
for i in 2..count_length loop
temp_subject:=temp_subject||'=?iso-8859-1?B?'||
utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw( SUBSTR(s_string,1+(lengthsubject*(i-1)) ,lengthsubject ))))|| '?=';
end loop;
return temp_subject;
end;
BEGIN
w_destinatario_todo := p_destinatario||';';
w_destin_todo_fixo := p_destinatario;
LOOP
w_destinatario := substr(w_destinatario_todo,1,(instr(w_destinatario_todo,';')) - 1);
w_destinatario_todo := substr(w_destinatario_todo,(instr(w_destinatario_todo,';') + 1));
IF w_destinatario IS NOT NULL THEN
-- Abrindo Conexao SMTP e HTTP
w_conexao := utl_smtp.open_connection(w_smtp_ip,w_smtp_porta);
-- Comunicando SMTP
utl_smtp.helo(w_conexao, w_smtp_ip);
-- Autenticacao INICIO
utl_smtp.command(w_conexao,'AUTH LOGIN');
utl_smtp.command(w_conexao,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(('username')))));
utl_smtp.command(w_conexao,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(('password')))));
utl_smtp.mail(w_conexao,('<'||'myusername@myhost.com.br'||'>'));
utl_smtp.rcpt(w_conexao,('<'||w_destinatario||'>'));
utl_smtp.open_data (w_conexao);
-- Criando Cabeca do E-mail
w_mensagem := 'Date: '||TO_CHAR(SYSDATE,'dd Mon yy hh24:mi:ss')||w_nova_linha||
'From: '||p_remetente||w_nova_linha||
'To: '||w_destin_todo_fixo||w_nova_linha||
'Subject: '||subject_encode(p_titulo_email)||w_nova_linha;
--- 'To: '||w_destin_todo_fixo||w_nova_linha;
-- w_mensagem := w_mensagem || 'Mime-Version: 1.0' || w_nova_linha ||
-- 'Content-Type: multipart/mixed; boundary="' || boundary || '"' || w_nova_linha || w_nova_linha; --||
utl_smtp.write_data(w_conexao,w_mensagem);
--
IF p_mensagem IS not NULL THEN
w_mensagem := '--' || boundary || w_nova_linha ||
'Content-Type: text/html; charset=iso-8859-1' || w_nova_linha ||
'Content-Transfer-Encoding: base64' || w_nova_linha || w_nova_linha;
utl_smtp.write_data(w_conexao,w_mensagem);
utl_smtp.write_data(w_conexao,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(p_mensagem)))|| w_nova_linha);
END IF;
-- Append the final boundary line
-- w_mensagem := w_nova_linha || '--' || boundary || '--' || w_nova_linha;
-- utl_smtp.write_data(w_conexao,w_mensagem);
-- Fechando conexao SMTP
utl_smtp.close_data(w_conexao);
utl_smtp.quit(w_conexao);
-- Insere um registro de emails.
BEGIN
w_usuario := substr(USER,2,50);
EXCEPTION
WHEN OTHERS THEN
w_usuario := 0;
END;
END IF;
IF w_destinatario_todo IS NULL THEN
EXIT;
END IF;
END LOOP;
END;
昨天 sendgrid 停止支持基本身份验证。 现在 sendgrid 要求使用 api 密钥进行身份验证。
我按照 sendgrid 的说明通过 UI 门户创建了 api 密钥。 另外,我根据 sendgrid 文档将电子邮件程序中的用户名和密码替换为“apikey”(用户名)和“actualKey”(密码)的值,如下图所示。
utl_smtp.command(w_conexao,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(('apikey')))));
utl_smtp.command(w_conexao,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(('Sdyg.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')))));
但是,我在尝试发送电子邮件时收到以下错误。
“提供的授权授权无效、过期或撤销”
关于如何解决这个问题的任何建议?
问题是执行以下命令时添加了换行符
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(('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')))) from dual;
output 是
U0cuNkU5TExrMHNUamZ0YzZxbG04ZXpnUS5raXhJd2RTSWV0RGE4d0ZUYnNNZHFf
Z1hWeVgxM3dtSHhGdlU5SHZmOTlv
为了删除该换行符,我将该语句修改为如下所示
select replace(replace(replace(utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(('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')))),chr(10),' '),chr(13),' '),' ','') from dual;
output 是
U0cuNkU5TExrMHNUamZ0YzZxbG04ZXpnUS5raXhJd2RTSWV0RGE4d0ZUYnNNZHFfZ1hWeVgxM3dtSHhGdlU5SHZmOTlv
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.