sql >> Base de Datos >  >> RDS >> Oracle

Recuperar mensajes del buzón usando PL/SQL Mail_Client API

Recientemente me dieron la tarea de construir una especie de sistema de cliente de correo en Oracle Apex. El requisito era mostrar los mensajes de la bandeja de entrada de correo en una página para una cuenta en particular para que el usuario pueda ver los mensajes de correo electrónico, los archivos adjuntos y eliminar los mensajes, etc. Pero en Oracle, hay paquetes para enviar correos electrónicos usando UTL_SMPT, UTL_MAIL y APEX_MAIL, y no hay ningún paquete para recuperar los mensajes de correo del buzón. Después de buscar un poco, encontré una API PL/SQL MAIL_CLIENT escrita por Carsten Czarski, con la que puedes recuperar fácilmente los mensajes del buzón. Y en este tutorial, doy ejemplos de MAIL_CLIENT API comandos y procedimientos. Primero, descargue e instale PL/SQL MAIL_CLIENT utilizando el siguiente enlace:

Descargar PL/SQL MAIL_CLIENT API

Ejemplos de la API PL/SQL MAIL_CLIENT

En las siguientes secciones, doy ejemplos paso a paso para conectarse usando el paquete MAIL_CLIENT, luego cómo ver el contenido del buzón, cómo ver un mensaje en particular y sus archivos adjuntos, etc.

Ejemplo-1:Conectar usando MAIL_CLIENT

Para conectarse al servidor de correo, use el siguiente código PL/SQL:

begin
  mail_client.connect_server(
    p_hostname => 'YourMailServer.com',
    p_port     => YourPortIntegerValue,
    p_protocol => mail_client.protocol_IMAP, -- or mail_client.protocol_POP3
    p_userid   => 'YourUserID',
    p_passwd   => 'YourPassword',
    p_ssl      => true -- true or false depends on your mailbox
  );

  mail_client.open_inbox;
  dbms_output.put_line('Mailbox successfully opened.');
  dbms_output.put_line('The INBOX folder contains '||mail_client.get_message_count||' messages.');
end;
/

Cambie el nombre de host, el puerto, el protocolo, la identificación de usuario y la contraseña de acuerdo con la configuración de su buzón. Y después de ejecutar el código anterior, se conectará a su buzón. Ahora definitivamente desea ver el contenido de su bandeja de entrada. Utilice el siguiente comando:

Ejemplo-2:Ver el contenido del buzón

Para ver el contenido del buzón utilizando la API PL/SQL MAIL_CLIENT, ejecute la siguiente instrucción SQL para ver los mensajes más recientes en la parte superior:

select * from table(mail_client.get_mail_headers()) order by msg_number desc;

Obtendrá las siguientes columnas de la consulta anterior:

  • MSG_NUMBER
  • ASUNTO
  • REMITENTE
  • SENDER_EMAIL
  • FECHA DE ENVÍO
  • CONTENT_TYPE
  • ELIMINADO
  • Algunas columnas de banderas más

Ejemplo-3:obtener la estructura del mensaje de correo

La estructura de un mensaje de correo contiene la información, como qué PARTINDEX El número contiene la parte del cuerpo en formato de texto sin formato, la parte del cuerpo en formato HTML y los archivos adjuntos del correo. Suponga que desea obtener el texto sin formato de la parte del cuerpo del correo electrónico, ejecute las siguientes consultas SQL:

select * from table(mail_client.get_message(1).get_structure());

El valor 1 anterior es el MSG_NUMBER de los mensajes Le dará la siguiente información:

  • PARTINDEX
  • ÍNDICE DE PADRES
  • CONTENT_TYPE
  • TALLA, etc.
PARTINDEX ÍNDICE DE PADRES CONTENT_TYPE TALLA
0,0 0 texto/simple 2993
0,1 1 texto/html 94849
1 1 multiparte/informe 39398

Ejemplo 4:recuperar el cuerpo del mensaje

Ahora, por ejemplo, si desea obtener el cuerpo del mensaje en formato de texto sin formato para el mensaje número 1, ejecute la siguiente consulta:

SELECT Mail_Client.Get_Message(1 /* specify message number */).get_bodypart_content_varchar2('0,0')
             FROM Dual;

Nota: El 0,0 anterior es el valor de la columna PARTINDEX para texto/tipo de contenido sin formato.

Para obtener el cuerpo en formato HTML, ejecutaremos la siguiente consulta con el PARTINDEX valor de columna 0,1. Devolverá el cuerpo en CLOB :

SELECT Mail_Client.Get_Message(1 /* specify message number */).get_bodypart_content_clob('0,1')
            FROM Dual;

Ejemplo-5:obtener el archivo adjunto de correo

Del mismo modo, obtenga el archivo adjunto de correo utilizando el PARTINDEX valor 1 como parámetro, como se muestra en la siguiente consulta:

SELECT Mail_Client.Get_Message(1 /* specify message number */).Get_Bodypart_Content_Blob('1')
             FROM Dual;

Ejemplo-6:Eliminar un mensaje de correo

A continuación se muestra el ejemplo de procedimiento almacenado para eliminar el mensaje de correo, utilizando la API MAIL_CLIENT.

Create or Replace PROCEDURE Delete_Mail_Msg(i_Msg_Number IN NUMBER) IS
     
t_Msg Mail_t;

BEGIN

Mail_Client.Connect_Server(p_Hostname => 'YourMailServer',
                           p_Port     => MailServerPort,
                           p_Protocol => Mail_Client.Protocol_Imap,
                           p_Userid   => 'username',
                           p_Passwd   => 'password',
                           p_Ssl      => TRUE);

Mail_Client.Open_Inbox;

t_Msg := Mail_Client.Get_Message(i_Msg_Number);
t_Msg.Mark_Deleted();

Mail_Client.Expunge_Folder;
Mail_Client.Close_Folder;
Mail_Client.Disconnect_Server;

EXCEPTION
     WHEN OTHERS THEN
       IF Mail_Client.Is_Connected() = 1 THEN
         Mail_Client.Close_Folder;
         Mail_Client.Disconnect_Server;
       END IF;
       Raise;
   END Delete_Mail_Msg;

Ahora simplemente llame al procedimiento anterior para eliminar un mensaje de correo específico, pasado como parámetro. A continuación se muestra el ejemplo:

Begin
   Delete_Mail_Msg(3);
End;

La llamada anterior al procedimiento DELETE_MAIL_MSG eliminará el mensaje de correo electrónico número 3 del servidor.

Además, brinde el siguiente ejemplo para almacenar todos los mensajes de la bandeja de entrada en una tabla con el cuerpo del correo y los archivos adjuntos. Sigue estos pasos:

Paso 1:Crear una tabla.

CREATE TABLE MAIL_INBOX (
MSG_NUMBER INTEGER,
SUBJECT VARCHAR2(4000),
SENT_DATE DATE,
SENDER_EMAIL,
BODY_TEXT CLOB,
MAIL_ATTACHMENT BLOB)
/

Paso 2:Cree un procedimiento almacenado de Oracle PL/SQL

CREATE OR REPLACE PROCEDURE LOAD_EMAILS IS

CURSOR c_Inbox IS
SELECT Msg_Number,
Subject,
Sender,
Sender_Email,
Sent_Date,
Content_Type
FROM TABLE(Mail_Client.Get_Mail_Headers())
ORDER BY Msg_Number DESC;

c_Clob CLOB;
b_blob BLOB;

t_Msg Mail_t;

v_Partindex VARCHAR2(100);
BEGIN

Mail_Client.Connect_Server(p_Hostname => 'YOURMAILSERVER',
p_Port => YOURPORT,
p_Protocol => Mail_Client.Protocol_Imap,
p_Userid => 'USERID',
p_Passwd => 'PASSWORD',
p_Ssl => TRUE);

Mail_Client.Open_Inbox;

FOR c IN c_Inbox LOOP

Dbms_Lob.Createtemporary(Lob_Loc => c_Clob,
Cache => TRUE,
Dur => Dbms_Lob.Call);

Dbms_Lob.Createtemporary(Lob_Loc => b_blob,
Cache => TRUE,
Dur => Dbms_Lob.Call);

IF Substr(c.Content_Type,
1,
9) = 'multipart' THEN
v_Partindex := NULL;
BEGIN
SELECT Partindex
INTO v_Partindex
FROM TABLE(Mail_Client.Get_Message(c.Msg_Number).Get_Structure())
WHERE Substr(Content_Type,
1,
9) = 'text/html';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;

IF v_Partindex IS NOT NULL THEN

BEGIN
SELECT Mail_Client.Get_Message(c.Msg_Number).Get_Bodypart_Content_Clob(v_Partindex)
INTO c_Clob
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;

BEGIN
SELECT Mail_Client.Get_Message(c.Msg_Number).Get_Bodypart_Content_BLOB('1')
INTO b_blob
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;

END IF;
INSERT INTO mail_inbox
(Msg_Number,
Subject,
Sent_Date,
Sender_email,
Body_Text,
mail_attachment)
VALUES
(c.Msg_Number,
c.Subject,
c.Sent_Date,
c.Sender_Email,
c_Clob,
b_blob);
ELSIF Substr(c.Content_Type,
1,
9) = 'text/html' THEN

BEGIN
SELECT Mail_Client.Get_Message(c.Msg_Number).Get_Content_Clob()
INTO c_Clob
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;

INSERT INTO mail_inbox
(Msg_Number,
Subject,
Sent_Date,
Sender_email,
Body_Text)
VALUES
(c.Msg_Number,
c.Subject,
c.Sent_Date,
c.Sender_Email
c_Clob);

END IF;
END LOOP;
COMMIT;
Mail_Client.Close_Folder;
Mail_Client.Disconnect_Server;

EXCEPTION
WHEN OTHERS THEN
ROLLBACK;

IF Mail_Client.Is_Connected() = 1 THEN
Mail_Client.Close_Folder;
Mail_Client.Disconnect_Server;
END IF;
RAISE;

END LOAD_EMAILS;

Ejecute el procedimiento anterior para llenar la tabla con mensajes de correo electrónico de la siguiente manera:

Begin
Load_Emails;
End;

Ahora puede consultar la tabla MAIL_INBOX para ver los mensajes de correo electrónico.

Select * from mail_inbox;
Descarga este proyecto de GitHub

Tutoriales relacionados:

  • ¿Cómo obtener BLOB de un archivo en PL/SQL?
  • Oracle UTL_SMTP:Enviar correo con ejemplo de archivo adjunto mediante la autenticación de Oracle Wallet