Cuando necesitamos enviar correos desde Oracle APEX, tenemos la posibilidad de usar el paquete APEX_MAIL o el paquete UTL_MAIL de la base de datos para la creación del proceso de envío de correos, sin embargo, al momento de llamar una función para enviar correos usando APEX_MAIL desde un job o una sesión fuera de las sesiones de Oracle APEX, tendremos el siguiente error: ORA-20001: This procedure must be invoked from within an application session.

¿Porqué se da el error?

El paquete APEX_MAIL debe ser llamado utilizando una sesión de Oracle APEX, es por ello que si lo llamamos usando PL/SQL fuera de una sesión de APEX o desde un job de base de datos, la función no se ejecutará.

Nota: Si desea aprender a configurar un servidor de correos en Oracle APEX, puede seguir la siguiente documentación:
https://oracle-max.com/configurando-un-servidor-de-correos-en-una-instancia-oracle-apex-19-usando-postfix/

Solución:

Para llamar el proceso y usarlo desde un job o PL/SQL, basta con decirle a la función desde cuál workspace se deberá ejecutar, para ello debemos añadirle al proceso de envío de correo las siguientes líneas:

l_workspace_id := apex_util.find_security_group_id (p_workspace => p_id_workspace);
apex_util.set_security_group_id  (p_security_group_id => l_workspace_id);

De esta manera nuestro proceso para enviar correos se verá de la siguiente manera, se añadieron las líneas 11, 15 y 16:

create or replace FUNCTION "ENVIO_CORREO" 
(
     p_to IN VARCHAR2,
     p_subj IN NVARCHAR2,
     p_body IN NVARCHAR2,
     p_id_workspace IN VARCHAR2
)
return VARCHAR2
is
respuesta varchar2(20);
l_workspace_id    number := null;
pragma autonomous_transaction;
BEGIN

l_workspace_id := apex_util.find_security_group_id (p_workspace => p_id_workspace);
apex_util.set_security_group_id  (p_security_group_id => l_workspace_id);

apex_mail.send(
    p_from => 'oracle.max.consultor@gmail.com',
    p_to => p_to,
    p_subj => p_subj,
    p_body => p_body,
    p_body_html => p_body
);
    APEX_MAIL.PUSH_QUEUE('localhost',25); --Libera la cola de correos de Apex
    respuesta := 'Correo Enviado';
return respuesta;
END;

¿Cómo conseguimos el id de nuestros workspaces?:

Para saber cuál id tiene cada workspace, se debe ejecutar el siguiente select:

select WORKSPACE_ID, WORKSPACE from apex_workspaces;

Ahora solo debemos elegir el id del workspace que queramos usar para el envío de correos y enviarle ese id por parámetro al proceso, en mi caso el id es: 2300461183311886

ENVIO_CORREO('oracle.max.consultor@gmail.com','Correo de prueba','Prueba de envío','2300461183311886');

De esta manera podemos llamar la función de envío de correos sin la necesidad de estar en una sesión de Oracle APEX.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *