lunes, 3 de febrero de 2025

Enviar correo electrónico (Email) SMTP desde Visual FoxPro

 

Hola a tod@s, he estado fuera desde hace mucho tiempo, pero ya  estoy volviendo, reconstruyéndome desde mis cenizas cual Ave Fenix.

Hace unos días un cliente que está llevando el procedimiento de cambiar de facturación tradicional (osea en papel) a facturación electrónica, solicitó el envío de correos desde una app de Visual Fox, caso que ya he cubierto antes, pero en esta ocasión el requerimiento fue un poco más específico, por alguna razón el cliente no desea ningún archivo adjunto, más bien lo que necesita es que los datos estén embebidos dentro del cuerpo del Email, además debe salir de un correo institucional con parámetros específicos y debe poder incluir imágenes como logotipo y dar formato de tabla tipo HTML.

En resumidas cuentas debería el destinatario del correo electrónico recibir algo como la siguiente imagen:




Luego de plantear dichos requerimientos, me dí cuenta que hay 3 problemas por resolver, los que detallo a continuación:

a)      Hacer la recolección de datos y preparar un cursor con los mismos para luego ir a la segunda parte.

b)      Poder enviar un correo desde una cuenta institucional, ya que la mayoría de ejemplos en la red son de cuentas gratuitas tipo Gmail, Hotmail, etc.

c)       Dar formato tipo HTML.

Luego de buscar por la web encontré 2 soluciones que explicaré a continuación:

1)     1) Para envío desde correos que no fueran los clásicos Gmail, Hotmail, Yahoo, etc. Encontré una librería que me sirvió mucho y que se llama FoxyDB que puede encontrarse en https://foxydb.wordpress.com/csfoxysmtp-ejemplos/ del compañero Antonio Meza Pérez programador Mexicano y que en su blog escribe sobre su librería lo siguiente “es totalmente gratis (OpenSource) que les permitirá crear una Capa de acceso a Datos, con varios Servidores de Bases de Datos, en especial con MySql, MariaDB y FireBird, en un futuro con ayuda de alguien que use Sql Server y PostgreSql se pueden agregar, al igual que otros mas.”.

2)      Para abordar lo de usar código HTML para embeber los datos encontré una librería que muchos desconocen, Visual FoxPro desde hace ya varias versiones anteriores trae una herramienta para poder convertir tablas, formularios, informes, etiquetas y menús a formato HTML. La herramienta se llama GenHtml.prg y se encuentra en la carpeta donde está instalado VFP. La ruta y nombre de este programa está almacenado en la variable del sistema _GENHTML.

Comprobamos que la variable del sistema este correctamente configurada con:

? _GENHTML

Esta variable del sistema la podemos configurar desde el menú de VFP, en Herramientas, Opciones, en la solapa Archivos, y buscamos en la lista "Generador de HTML".

El programa GenHtml.prg

GenHtml.prg utiliza la librería de clases visuales _Html.vcx que son parte de las FoxPro Foundation Classes (FFC) que vienen con Visual FoxPro y se encuentran en la carpeta \ffc\ del directorio de instalación de VFP.

El compañero Luis María Guayán, de origen español nos cuenta en una entrada que tuvo la necesidad de crear una clase más elemental y sencilla, que solo convierte tablas y cursores a formato HTML. Aquí (https://comunidadvfp.blogspot.com/2005/10/convertir-tablas-formato-html.html) la exponge para que ustedes la utilicen en sus aplicaciones y quizás necesiten modificarla para agregarle más datos al archivo HTML o para cambiar la apariencia de visualización.

Utilizando Foxydb.

El problema de la recolección de datos dependerá de lo que cada quién desee poner en sus correos y dado que no es el tema central lo dejaré como descontado asumiendo que si lees esto eres programador y sabrás como lidiar con ello, entonces el segundo problema es como configurar la librería, lo primero que hice fue ponerme en contacto con el proveedor de correos quienes me dieron la siguiente información, pero que asumiremos que tienen un dominio llamado “repuestosparamotocicletas.com”, es claro que los datos a continuación son ficticios.

Correo saliente tipo :SMTP

   mail.repuestosparamotocicletas.com

puerto de entrada : 645

sin seguridad SSL

cuenta de correo saliente : facturación@repuestosparamotocicletas.com

contraseña:   Tu_c0ntraseni@

 ** Creamos una variable para las pruebas llamada oSmtp, puede ser cualquier nombre.

Public oSmtp

** Creamos el objeto de la librería,** 32 Bit

oSmtp = CreateObject("CsFoxySmtp")

 

** 64 Bit

*oSmtp = CreateObject("CsFoxySmtp64")

 

** Configuramos las propiedades del Servidor para enviar correos desde una cuenta de correo.

 

oSmtp.server = " mail.repuestosparamotocicletas.com "

oSmtp.port = 645

oSmtp.ssl = .F.

oSmtp.user = "facturacion@repuestosparamotocicletas.com "

oSmtp.password = " Tu_c0ntraseni@"

** Configuramos los datos para el correo, la priority por default es normal, para el ejemplo la cambio a Alta.

oSmtp.from = "No responder < facturacion@repuestosparamotocicletas.com >"

oSmtp.subjet = "Informe de documentos no enviados al MH del día "+DTOC(DATE())

 

lcBody = TEXTMERGE(lcFile)

*!*   * Incrustar imágenes

oSmtp.body = lcBody

oSmtp.EmbedImage("imágenes\Logo.jpg", "imagen1")

oSmtp.priority = 1

** Agregamos las direcciones de correo, es decir los Destinatarios.

oSmtp.AddTo("logistica@tuempresa.com")

*oSmtp.AddTo(“correoDos@dominio.com”)

*oSmtp.AddTo(“correoTres@dominio.com”)

 

*** Agregamos las direcciones de los Destinatarios que irán en Copia

oSmtp.AddCc("asistenciaporoperadora@gmail.com")

oSmtp.AddCc("gerencia.general@lacruz-ada.com")

 

** Agregamos las direcciones de los Destinatarios que irán en Copia Oculta

*oSmtp.AddBcc(“correoOcultoUno@dominio.com”)

*oSmtp.AddBcc(“correoOcultoDos@dominio.com”)

 

** Agregamos los archivos Adjuntos al correo, dado que no quieren adjuntos se ** van como comentarios pero lo dejo por si te sirve

*oSmtp.AddAttachments(“c:\carpeta\archivoUno.pdf”)

*oSmtp.AddAttachments(“d:\foto\imagen.jpg”)

*oSmtp.AddAttachments(“c:\doc\listado.xls”)

 

** Finalmente enviamos el correo y validamos si se envió correctamente

IF oSmtp.Smtp() = .t.

      wait windows "Correo Enviado" NOWAIT

ELSE

      gError = .T.

      gMsg = oSmtp.Error

      RETURN -1

ENDIF

RETURN 1

Es claro que el TEXTMERGE debe ser creado previamente, esto es lo que yo tengo en mi código, la función AgregarListaResumen() se mostrará luego en esta entrada.

SET TEXTMERGE OFF

TEXT TO lcFile NOSHOW

<p><i> Informe automático <br>

<b> De Fecha: <<DTOC(DATE())>>, Generado a las <<TIME()>></b><br>

</i></p>

<hr>

<p>A continuación el listado de los Documentos de fecha <<ldFecha2>> no enviados al MH:</p>

<<AgregarListaResumen()>>

<p>La cantidad total de documentos es <b><<TotalRegistros()>></b>.</p>

<p>Sin más por el momento, atentamente</p>

<p><u><i>Factura Fácil</i></u></p>

       <body style="background-color: blank">

             <h2>Apuntando al éxito</h2>

             <img src='cid:imagen1' alt="no se muestra" width="250" height="150" align="left" />

             <br>

ENDTEXT

 

Y pues las otras funciones son :

PROCEDURE TotalRegistros()

 LOCAL lcHtml

 *-- Total de Ordenes por Empleado

 SELECT Dos

  COUNT to Tot_Regis

 lcHtml = TRANSFORM(Tot_Regis)

 RETURN lcHtml

 USE IN Dos

ENDPROC

 

PROCEDURE AgregarListaResumen()

 LOCAL lcHtml, loHtml

 *-- Listado de documentos no enviados a MH

 loHtml = CREATEOBJECT("ClaseHtml")

 lcHtml = loHtml.AgregarTabla('Dos') + CHR(13) + CHR(10)

 RELEASE loHtml

 RETURN lcHtml

ENDPROC

Y finalmente la clase “ClaseHtml” es la misma que te mencioné antes de Luis María Guayán.

Espero les sirva de ayuda u orientación por si tienen algún reto parecido, sin más por el momento me despido no sin antes enviar mi más sentido pésame a mi prima Laura Trejo por la irreparable pérdida de su madre, mi tía Laura Trejo, si se llaman igual.


Mr. Moon. 

La vida es un 10% como viene y un 90% como la tomamos.

Pensar es gratis.