esofitec. CoreDocs

esofitec. CoreDocs

Addons estándar / Módulo de envío de mailings / Instalación y soporte

Modelo de datos

El diccionario DSIT_FEDMAILING crea una única tabla, SIT_FED_MAIL_LOG, que es a la vez la cola de envíos pendientes y el histórico de lo enviado. No hay procedimientos almacenados, vistas ni disparadores: todo el trabajo lo hacen los dos ejecutables.

La tabla es auxiliar, y eso importa#

SIT_FED_MAIL_LOG está declarada como tabla auxiliar en el diccionario, con SIT_FED_SUBJECT como columna descriptiva. La consecuencia práctica es que a3ERP la expone en Ficheros > Otros > Adicionales de gestión con el nombre Mailings, sin necesidad de ninguna pantalla propia del módulo.

Para soporte es la vía más rápida y muchas veces suficiente: permite consultar la cola y el histórico, y actuar sobre las filas, sin acceso a SQL Server ni al servidor. Antes de pedir credenciales de base de datos o abrir una sesión remota, merece la pena mirar ahí, y es también donde se puede indicar al usuario que compruebe las cosas por su cuenta. Está explicado desde el punto de vista de operativa en consultar la cola después de procesar.

Las columnas se presentan en esa pantalla con sus descripciones del diccionario —Fecha envío, Asunto, Destinatario(s), Directorio de adjuntos, Mensaje, Mensaje (Html) y Operación posterior—, así que al hablar con un usuario conviene usar esos nombres y no los de las columnas físicas.

El diccionario define qué se puede tocar y qué no: solo son editables Destinatario(s) y las dos columnas de mensaje; el resto, incluida Fecha envío, están como solo ver. Eso tiene dos consecuencias directas para soporte:

  • Se puede rescatar una fila atascada corrigiendo su dirección de destino, sin tener que eliminarla ni volver a procesar el envío desde la pantalla del módulo.
  • No se puede frenar un envío pendiente marcándolo como enviado, porque la fecha no se deja escribir. La única forma de que un correo encolado no salga es eliminar la fila, y solo mientras siga pendiente.

Que se pueda editar el cuerpo no significa que convenga

Lo que se guarde en las columnas de mensaje es literalmente lo que se enviará. Vale para un apaño puntual en una fila concreta, pero no para corregir el contenido de un envío masivo: para eso se corrige la plantilla y se vuelve a procesar.

La tabla SIT_FED_MAIL_LOG#

Columna Tipo Nulos En Adicionales de gestión Contenido
SIT_FED_ID_MAIL_LOG int identidad No Solo ver Clave primaria, agrupada
SIT_FED_SUBJECT varchar(100) No Solo ver Asunto, que es el nombre de la plantilla sin extensión
SIT_FED_TO varchar(500) No Editar Destinatarios, separables por comas o puntos y comas
SIT_FED_BODY text Sí Editar Cuerpo en HTML, con los marcadores ya sustituidos
SIT_FED_BODY_PLAIN text Sí Editar Cuerpo en texto plano
SIT_FED_ATTACHMENTS varchar(150) Sí Solo ver Ruta del directorio de adjuntos, no de un fichero
SIT_FED_SENT_TIME datetime Sí Solo ver Fecha y hora del envío. NULL significa pendiente
SIT_FED_POST_OPERATION varchar(8000) Sí Solo ver JSON para aplicaciones externas al módulo

Ciclo de vida de un registro#

Solo hay dos estados y los distingue una única columna:

  1. La extensión inserta la fila con SIT_FED_SENT_TIME a NULL al pulsar Procesar. El cuerpo ya viaja compuesto: los marcadores se sustituyen en el momento de encolar, no al enviar. Cambiar la plantilla después no afecta a lo que ya está en cola.
  2. El servicio de envío coge las filas con SIT_FED_SENT_TIME IS NULL, envía y actualiza esa columna con la fecha del envío.

Un fallo de envío no deja rastro en la tabla: la fila sigue pendiente y se reintenta en la siguiente pasada. Dentro de una misma ejecución sí se descarta, para no entrar en bucle con un envío que falla siempre. Esto tiene una lectura importante para soporte: la tabla no dice si algo ha fallado, solo si se ha enviado. El motivo del fallo está en el log del servicio y en el correo de resumen.

Consultas útiles para soporte#

Todo lo de este apartado se puede hacer también desde Adicionales de gestión; las consultas son para cuando hay que revisar volumen, cruzar datos o actuar sobre muchas filas a la vez.

Cola pendiente, lo primero que hay que mirar cuando alguien dice que no llegan los correos:

SELECT COUNT(*) AS Pendientes, MIN(SIT_FED_ID_MAIL_LOG) AS PrimeroEnCola
FROM SIT_FED_MAIL_LOG
WHERE SIT_FED_SENT_TIME IS NULL;

Últimos envíos realizados, para confirmar que el servicio está trabajando y con qué ritmo:

SELECT TOP 50 SIT_FED_ID_MAIL_LOG, SIT_FED_SUBJECT, SIT_FED_TO, SIT_FED_SENT_TIME
FROM SIT_FED_MAIL_LOG
WHERE SIT_FED_SENT_TIME IS NOT NULL
ORDER BY SIT_FED_SENT_TIME DESC;

Anular un envío que el usuario ha programado por error, solo mientras siga pendiente:

DELETE FROM SIT_FED_MAIL_LOG
WHERE SIT_FED_SENT_TIME IS NULL
  AND SIT_FED_SUBJECT = 'Asunto de la plantilla';

Reenviar algo ya enviado, poniendo la fila de nuevo en cola:

UPDATE SIT_FED_MAIL_LOG
SET SIT_FED_SENT_TIME = NULL
WHERE SIT_FED_ID_MAIL_LOG = 123;

Reencolar no recompone el correo

Al reenviar se manda el cuerpo tal y como está guardado y se adjuntan los ficheros del directorio de SIT_FED_ATTACHMENTS, que puede haberse borrado si era una carpeta temporal. Si lo que se quiere es enviar la versión nueva de una plantilla, hay que volver a procesar desde a3ERP, no reencolar.

Límites que hay que tener presentes#

Las longitudes de la tabla son las que provocan los errores de truncado, y hay una que salta más de lo que parece.

El asunto tiene 100 caracteres, y como el asunto es el nombre del fichero de la plantilla, una plantilla con un nombre muy descriptivo puede pasarse.

El directorio de adjuntos tiene 150 caracteres y ahí no cabe cualquier ruta. Cuando un correo lleva adjuntos, la extensión crea una carpeta por destinatario dentro del directorio temporal del usuario, con el nombre de la plantilla y un identificador único: algo del estilo C:\Users\usuario\AppData\Local\Temp\SitMailerAttachments\<asunto>_<guid>. Del límite, la carpeta SitMailerAttachments y el identificador consumen 58 caracteres fijos, y el resto se lo reparten el temporal del usuario y el nombre de la plantilla.

Cuánto queda para el nombre depende por tanto de la longitud del perfil de Windows del usuario que genera el envío, que varía mucho entre instalaciones:

Temporal del usuario Caracteres disponibles para el nombre de la plantilla
C:\Users\usuario\AppData\Local\Temp\ (36) 56
C:\Users\nombre.apellido000.0000MAQUINA.001\AppData\Local\Temp\ (63) 29

El segundo caso no es raro: los perfiles de dominio y los perfiles recreados generan nombres de carpeta largos. La misma plantilla que funciona en un puesto puede fallar en otro por este motivo. La salida rápida es acortar el nombre de la plantilla.

Desde la App 2.3.2.0 la columna solo se rellena si el correo lleva algún adjunto, así que los envíos sin adjuntos ya no pueden fallar por esta longitud. En versiones anteriores se guardaba la ruta siempre, y el error afectaba a todos los envíos.

La operación posterior tiene 8.000 caracteres, el máximo de un varchar que no sea max. Parece mucho, pero el JSON lleva un elemento por registro afectado, no uno por correo: una consulta que resuma todo lo pendiente de un cliente mete un objeto por vencimiento, y con el texto habitual eso son unos 136 caracteres cada uno, así que el techo real ronda los cincuenta y ocho registros por correo. Y ojo con esta longitud: está declarada dos veces, en el diccionario y en el atributo StringLength de la entidad. Entity Framework valida antes de hablar con SQL Server, así que si las dos no coinciden manda la más corta, y ampliar solo una no sirve de nada.

Los campos son varchar y text, no Unicode. Los acentos y la eñe entran sin problema con las colaciones habituales en España, pero caracteres fuera de esa página de códigos —emojis en el asunto, alfabetos no latinos— se pierden o se sustituyen. Conviene descartarlo pronto si alguien reporta caracteres extraños en un asunto.

Crecimiento de la tabla#

La tabla no se purga: cada correo enviado se queda con su cuerpo HTML completo en SIT_FED_BODY y su versión en texto plano en SIT_FED_BODY_PLAIN. En un cliente que hace envíos masivos con plantillas de Word —que generan HTML muy verboso— crece bastante más rápido de lo que se espera de una tabla de log.

Además, el único índice es el de la clave primaria: no hay índice sobre SIT_FED_SENT_TIME, y el servicio consulta las filas pendientes una y otra vez a lo largo de cada pasada. Mientras la tabla es pequeña da igual, pero con cientos de miles de filas históricas el envío se vuelve notablemente más lento.

En instalaciones con volumen conviene por tanto acordar con el cliente un archivado o purga periódica de los envíos antiguos, valorando primero si necesita conservar el cuerpo de los correos como prueba de la comunicación. Una alternativa habitual es vaciar solo los cuerpos de los registros antiguos y conservar asunto, destinatario y fecha.

Ficheros en disco#

La tabla solo guarda la ruta del directorio de adjuntos: los ficheros están fuera de la base de datos, y de ahí vienen los problemas de adjuntos que faltan.

  • Los adjuntos propios de la plantilla salen de la carpeta <nombre de la plantilla>_archivos, junto al .htm, en la carpeta de plantillas. Se copian siempre que esa carpeta exista y tenga ficheros, sin depender de la casilla.
  • La casilla de adjuntar documentos añade a esa misma carpeta temporal los ficheros vinculados a los documentos de a3ERP. La carpeta se crea al copiar el primer fichero, venga de donde venga, y es la que se guarda en la tabla. Si no hay ningún fichero de ninguno de los dos orígenes, no se crea nada y la columna se queda vacía.
  • Las rutas de los ficheros vinculados las resuelve la propia consulta de la vista, normalmente desde VINCULOS, y la extensión las copia al procesar. El detalle está en Adjuntar los documentos vinculados.

Las carpetas temporales no se limpian solas. Si el envío se retrasa y alguien vacía el temporal del usuario por el medio, los correos saldrán sin adjuntos.