Oracle incluye un paquete para el manejo de envío de correo directamente desde la base de datos. Desde que me tocó realizar una función para enviar notificaciones a clientes, he trabajado a la par con dicha librería, todas las pruebas fueron correctas, desde cambio de formato a html, múltiples recipientes de correo separados por coma, sin embargo al visualizar los correos no había notado algo importante, aunque llegaba a la bandeja de entrada de primero en outlook, tenían la fecha errada y si tienes ordenado los correos por fecha, no se encontrarían en la fecha de hoy.
Este problema se debe a que hay que especificar un formato de fecha correcto que acepta la librería smtp de oracle en su encabezado. El encabezado es obligatorio y no hay forma automática de que obtenga la fecha actual, uno debe especificarla manualmente.
Inicialmente utilizábamos un formato simple en ANSI el cual es lo común para estos sistemas:
‘Date: ‘ || to_char(sysdate, ‘YYYY-MM-DD HH24:MI:SS’)
Luego al leer la documentación oficial, se debe utilizar el estándar de RFC1123 el cual indica que podemos usarla de esta manera
Dy, DD Mon YYYY HH24:MI:SS
Que aunque no es común indicar texto entre fechas, usualmente es solo números, es un estándar adecuado para oracle. Esto nos imprimiría:
SELECT TO_CHAR(SYSTIMESTAMP, Dy, DD Mon YYYY HH24:MI:SS) FROM DUAL;
«Fri, 09 Aug 2019 14:09:21»
Que es un formato correcto, sin embargo al cambiarnos de servidor de pruebas a producción, notamos que dejó de funcionar y la fecha llegaba errada tanto para las horas como los meses, mostraba la fecha 5 meses atrás.
Entonces al verificar, en producción mostraba «Vie 09 Ago», porque estaba configurado en español y el texto en español no es un estándar para la cabecera, siempre debe ser en inglés, entonces se tuvo que modificar. También para ser mas preciso las horas, se puede agregar la zona horaria «TZH:TZM» quedando de esta manera:
‘Date: ‘ || TO_CHAR(SYSTIMESTAMP, ‘Dy, DD Mon YYYY HH24:MI:SS TZH:TZM’,’NLS_DATE_LANGUAGE=ENGLISH’)
Aunque se discute si se le puede agregar una coma o utilizar el doble puntos, esto depende completamente del servidor smtp, puede o no puede reconocer «Dy, DD mon» con coma, o incluso el doble puntos «HH24:MI:SS», así que basta con probar y comprobar.
Nuestra función final quedó de la siguiente manera:
1 2 3 4 5 6 7 8 9 10 |
UTL_SMTP.DATA(v_conex, 'Date: ' || TO_CHAR(SYSTIMESTAMP, 'Dy, DD Mon YYYY HH24:MI:SS TZH:TZM','NLS_DATE_LANGUAGE=ENGLISH') || CRLF || 'From: ' || v_desde || CRLF || 'Subject: '|| v_titulo || CRLF || 'To: ' || v_email || CRLF || 'MIME-Version: 1.0'|| CRLF || 'Content-Type: text/html;charset=UTF-8'|| CRLF || CRLF || CONVERT_SPECIAL_CHAR(v_mensaje)|| CRLF ); |
Utilizando el Date correcto, cambiando el correo en html y convertimos los caracteres especiales a html con una función propia. Esto es importante, que sea en html para evitar problemas con acentos y caracteres utf8.