Podemos usar el paquete APEX_MAIL para enviar email desde nuestra aplicación en Oracle Application Express.

El paquete APEX_MAIL está construido sobre el paquete UTL_SMTP suministrado por Oracle. Debido a esta dependencia, el paquete UTL_SMTP debe estar instalado y en funcionamiento para usar APEX_MAIL.

Como este paquete esta instalado en la instancia gratuita de APEX en la nube podemos nosotros probarlo.

Para esta demostración vamos a usar la aplicación Demo de Application Express «Sample Database Application». Si no la tenemos instalada en nuestro espacio de trabajo podemos acceder a la galería de aplicaciones y de allí instalarla.

Vamos a enviar un email con la confirmación de la orden a los clientes, el cual ese email esta en la tabla DEMO_CUSTOMERS. El email contendrá el enlace a la Orden realizada en APEX.

Abrimos la pagina 14 de la aplicación y creamos un proceso debajo de Place Order.

El código PL/SQL es el que sigue:

DECLARE

Vbody CLOB;
Vbody_html CLOB;
Vcust_email varchar2(100);
Vcust_name varchar2(100);

BEGIN
  select cust_email into Vcust_email from DEMO_CUSTOMERS 
  where customer_id = :P11_CUSTOMER_ID;
  select CUST_FIRST_NAME into Vcust_name from DEMO_CUSTOMERS 
  where customer_id = :P11_CUSTOMER_ID;
  Vbody := 'Para ver el contenido de este mensaje, utilice un cliente de correo 
  habilitado para HTML.'||utl_tcp.crlf;

  Vbody_html := '<html>
  <head>
  <style type="text/css">
  body{font-family: Arial, Helvetica, sans-serif; font-size:10pt;margin:30px;
  background-color:#ffffff;}
  span.sig{font-size: 20px; font-weight:bold; color:#1C72CE;}
  </style>
  </head>
  <body>'||utl_tcp.crlf;

  Vbody_html := Vbody_html || 'Hola '|| Vcust_name ||','||utl_tcp.crlf||utl_tcp.crlf;
  Vbody_html := Vbody_html ||'<p> Su orden ha sido confirmada 
  al cual puede acceder haciendo clic <a href="'||APEX_UTIL.HOST_URL('SCRIPT')||
  'f?p='||:APP_ID|| ':29'||':0::::P29_ORDER_ID:'||:P14_ORDER_ID ||'"> 
  aquí. </a></p>' ||utl_tcp.crlf;

  Vbody_html := Vbody_html ||'<p> Saludos,</p>'||utl_tcp.crlf;
  Vbody_html := Vbody_html ||' <span class="sig">Sample Demo Team</span><br />'||utl_tcp.crlf;
  apex_mail.send(
     p_to => Vcust_email, 
     p_from => 'miemailvalido@midominio.com', 
     p_body => Vbody,
     p_body_html => Vbody_html,
     p_subj => 'Confirmación de la Orden');
END;

Mensaje de Confirmación: *** El email de confirmación de la Orden fue enviado al cliente.

Mensaje de Error: *** Error! Hay algún problema enviando el email al cliente.

Cuando se presione el Botón: PLACE_ORDER

Como podemos ver en el código PL/SQL tenemos la declaración de algunas variables. Podemos usar el tipo VARCHAR para las variable Vbody y Vbody_html.

Pasar un valor a Vbody, pero no a Vbody_html da como resultado un mensaje de texto sin formato. Pasar un valor a Vbody y a Vbody_html produce un mensaje de varias partes que incluye texto sin formato y contenido HTML. La configuración y las capacidades del cliente de correo electrónico del destinatario determinan lo que se muestra. Aunque la mayoría de los clientes de correo electrónico modernos pueden leer un correo electrónico con formato HTML, recordemos que algunos usuarios deshabilitan esta funcionalidad para solucionar problemas de seguridad. Entonces va a depender del recipiente del email cómo verá el mensaje, si tiene o no activado para ver contenido HTML o solo texto plano.

Con el primer select buscamos la dirección de email de la orden del cliente y el segundo select guardamos el nombre del cliente en una variable.

Es importante recordar que ninguna línea individual puede superar los 1000 caracteres. La especificación SMTP/MIME dicta que ninguna línea individual debe exceder los 1000 caracteres. Para cumplir con esta restricción, debemos agregar un retorno de carro o caracteres de avance de línea para dividir los parámetros Vbody o Vbody_html en fragmentos de 1000 caracteres o menos. De lo contrario, se generan mensajes de correo electrónico erróneos, incluidos mensajes parciales o mensajes con signos de exclamación extraños. Por eso usamos utl_tcp.crlf para este propósito.

Por último se envía el email usando el procedimiento APEX_MAIL.SEND el cual tiene los siguientes parámetros:

p_to:  Dirección de correo electrónico válida a la que se envía el correo electrónico (obligatorio). Para varias direcciones de correo electrónico, usamos una lista separada por comas.

p_from: Dirección de correo electrónico desde la cual se envía el correo electrónico (obligatorio). Esta dirección de correo electrónico debe ser una dirección válida. De lo contrario, el mensaje no se envía.

p_body: Cuerpo del correo electrónico en texto plano, no HTML (requerido). Si se pasa un valor a Vbody_html, este es el único texto que ve el destinatario. Si no se pasa un valor a Vbody_html, este texto solo se muestra para clientes de correo electrónico que no admiten HTML o tienen HTML deshabilitado. Debemos incluir un retorno de carro o avance de línea (CRLF) cada 1000 caracteres.

p_body_html: Cuerpo del correo electrónico en formato HTML. Este debe ser un documento HTML completo que incluya las etiquetas <html> y <body>. Una sola línea no puede superar los 1000 caracteres sin un retorno de carro o avance de línea (CRLF).

p_subj: Asunto del correo electrónico.

p_cc: Direcciones de correo electrónico válidas a las que se copia el correo electrónico. Para varias direcciones de correo electrónico, usamos una lista separada por comas.

p_bcc: Direcciones de correo electrónico válidas a las que se copia en forma oculta el correo electrónico. Para varias direcciones de correo electrónico, usamos una lista separada por comas.

p_replyto: Dirección del encabezado del correo de respuesta. Podemos usar este parámetro de la siguiente manera:

  • Si omitimos el parámetro p_replyto, el encabezado del correo de respuesta se establece en el valor especificado en el parámetro p_from
  • Si incluimos el parámetro p_replyto, pero proporcionamos un valor NULL, el encabezado del correo de respuesta se establece en NULL. Esto da como resultado la supresión de las respuestas automáticas por correo electrónico.
  • Si incluimos el parámetro p_replyto, pero proporcionamos un valor no nulo (por ejemplo, una dirección de correo electrónico válida), envía estos mensajes, pero las respuestas automáticas van al valor especificado (por ejemplo, la dirección de correo electrónico)

Un detalle importante es que nosotros estamos colocando un enlace en nuestro cuerpo del mensaje del correo electrónico para acceder a la página de la Orden.  Cuando el cliente hace clic en el enlace lo lleva a la página 29 de la aplicación, despues de que ingrese sus credenciales de acceso. Necesitamos hacer dos cosas antes de probar el ejemplo.

Accedemos a la página 29 «Order Details» y en propiedades de la página ingresamos a la sección de seguridad, allí configuramos:

  • Page Access Protection: Unrestricted

Luego hacemos clic en el elemento P29_ORDER_ID configurar:

  • Session State Protection: Unrestricted

Por últimos configuramos que la página 29 sea del modo Normal.

Probemos ahora este ejercicio de la siguiente manera:

Accedemos a la lista de clientes y creamos un cliente para colocar nuestro email.

Ahora creamos una Orden.

Después de un momento podemos ver en nuestra bandeja de entrada el email.

Al hacer clic en el enlace nos lleva a la pagina del login y despues de ingresar las credenciales, podemos ver la orden realizada:

Si recibimos un error de que la sesión expiró, cerramos la ventana y recargamos nuestro navegador.

Espero te sirva este ejemplo para poder mejorarlo e implementarlo en tus aplicaciones en APEX.

Aqui puedes acceder a la documentación de la función SEND del paquete APEX_MAIL.

Nota: El código PL/SQL de este ejemplo es parte del libro «Oracle Application Express Pro Hacks» de Riaz Ahmed, el cual lo adapté para esta demostración. Excelente libro de tips para mejorar nuestras aplicaciones en APEX!