9 de julio de 2014

Mas sobre el envio de mensajes de correo electrónico desde Visual FoxPro

Existen muchas herramientas y formas de enviar mensajes de correo electrónico desde Visual FoxPro, y seguramente por ello, existen muchos artículos y códigos escritos sobre este tema. La razón de escribir mas de los mismo, es comentarles sobre mi experiencia y elección personal, de la herramienta que utilizo actualmente, la cual me satisface y cubre todas mis necesidades. Estoy convencido que lo mismo le sucede a muchos desarrolladores y espero que al terminar de leer estas líneas, esto ayude a muchos mas.

The winner is ...

Como indico arriba, esto es "mi experiencia y elección personal", obviamente no digo que sea "la mejor", ni digo tampoco "la peor", por lo tanto no entraré en comparación con otras herramientas, solo hablaré de CDO.

¿Qué es CDO?

CDO (Collaboration Data Objects) es un componente COM (Component Object Model) que simplifica la escritura de código para crear y manipular mensajes de Internet y es parte integrante (Cdosys.dll) de los sistemas operativos Windows 2000 y superiores, siendo esta la primer gran ventaja, ya que no necesitamos descargar, comprar, ni licenciar, ninguna otra herramienta extra. CDO no necesita que tengamos un servidor SMTP local, solo necesita acceso a la Web, a algún servidor SMTP que nos permita enviar los mensajes de correo electrónico.

Usando VFP

Otra ventaja adicional, es que se puede utilizar CDO con lenguajes que soporten COM y Automation, y Visual FoxPro lo soporta. A continuación un sencillo código para enviar un mensaje de correo electrónico con CDO desde VFP. Recuerde configurar correctamente el nombre del servidor SMTP, el puerto SMTP, el nombre de usuario y contraseña.
loCfg = CREATEOBJECT("CDO.Configuration")
WITH loCfg.Fields
  .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.mail.com"
  .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
  .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
  .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "user@mail.com"
  .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
  .Update
ENDWITH

loMsg = CREATEOBJECT ("CDO.Message")
WITH loMsg
  .Configuration = loCfg
  .From = "user@mail.com"
  .To = "user1@mail.com.ar"
  .Subject = "Prueba desde VFP"
  .TextBody = "Este es un mensaje de prueba con CDO desde Visual FoxPro."
  .Send()
ENDWITH

Adjuntando archivos en nuestros mensajes

Para enviar archivos adjuntos en un mensaje de correo electrónico, solo debemos llamar al método AddAttachment() del objeto Message, tantas veces como archivos deseamos adjuntar, con la ruta y el nombre del archivo como parámetros:
WITH loMsg
 .AddAttachment("C:\Imagenes\Foto1.jpg")
 .AddAttachment("C:\Imagenes\Foto2.jpg")
 .AddAttachment("C:\Imagenes\Foto3.jpg")
ENDWITH

Autenficación y cifrado SSL

Algunos servidores SMTP, necesitan autentificación y cifrado SSL para iniciar sesión. Para ello debemos configurar las propiedadades smtpauthenticate y smtpusessl del objeto Configuration con el valor .T..
WITH loCfg.Fields
  .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = .T.
  .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = .T.
ENDWITH

Mensajes a múltiples destinatarios

Para enviar el mensaje de correo a mas de un destinatario, solo debemos separar las direcciones de correos electrónicos, con el caracter "," (coma) en la propiedad To. También podemos agregar una copia para otro destinatario, como así también una copia oculta, configurando las propiedades Cc y Bcc respectivamente.
WITH loMsg
 .To = "user1@mail.com, user2@mail.com"
 .Cc = "user3@mail.com"
 .Bcc = "user4@mail.com"
ENDWITH
Podemos hacer que aparezca el nombre completo del remitente y/o del destinatario, anteponiendo el nombre a la dirección de correo electrónico, y encerrando ésta última entre "<" y ">"
WITH loMsg
 .From = "Jose Fox <jose@fox.org>"
 .To = "Usuario Uno <user1@mail.com>, Usuario Dos <user2@mail.com>"
ENDWITH

Mensajes con formato HTML

Con CDO muy fácilmente se puede enviar mensajes de correo electrónico con formato HTML, solamente configurando la propiedad HTMLBody con código HTML válido, en lugar de configurar la propiedad TextBody que es válida para los mensajes con texto sin formato.
WITH loMsg
  .HTMLBody = "<p>Este es un texto HTML con <b>negritas</b> o con <i>cursivas</i>.</p>"
ENDWITH
Esta propiedad la podemos configurar con el contenido de un archivo HTML con la función FILETOSTR() como se muestra a continuación.
WITH loMsg
  .HTMLBody = FILETOSTR("C:\Archivo.htm")
ENDWITH
Mas adelante veremos otra manera de dar formato HTML a un mensaje de correo electrónico, a partir de un archivo HTML ubicado en el disco local o la Web.


Solicitando confirmación de lectura

Podemos configurar nuestros mensajes de correo electrónico para solicitar una confirmación de lectura y recibir ésta confirmación en la dirección predeterminada u otra (siempre y cuando el servidor y/o el programa cliente del destinatario tengan habilitada esta opción). El código para solicitar y recibir la confirmación de lectura en la misma dirección de correo del remitente es el siguiente:
WITH loMsg
  .From = "user@mail.com"
  .Fields("urn:schemas:mailheader:disposition-notification-to") = .From
  .Fields("urn:schemas:mailheader:return-receipt-to") = .From
  .Fields.Update
ENDWITH

Marcar los mensajes con importancia y prioridad

Otra opción que nos brinda CDO es configurar la importancia y prioridad de nuestros mensajes de correo electrónico, marcándolos como Normal (por omision), Alta o Baja. Por ejemplo el código para marcar un mensaje con importancia y prioridad Alta es:
WITH loMsg
  *-- Prioridad
  && -1=Low, 0=Normal, 1=High
  .Fields("urn:schemas:httpmail:priority") = 1
  .Fields("urn:schemas:mailheader:X-Priority") = 1
  *-- Importancia
  && 0=Low, 1=Normal, 2=High
  .Fields("urn:schemas:httpmail:importance") = 2
  .Fields.Update
ENDWITH

Mensajes con imágenes

Bueno, hasta aquí todo marcha bien sin mayores complicaciones; ahora solo nos faltaría saber como añadir imágenes a nuestros mensajes de correo con formato HTML.

Una opción simple, es que en el código HTML hagamos referencia a una URL de un sitio donde este almacenada la imagen, de esta forma se mostrará, siempre y cuando, se tenga acceso a internet. Esta opción tiene a favor que el mensaje enviado tiene un tamaño pequeño, ya que las imágenes estan almacenadas en algún lugar de la Web.
WITH loMsg
  .HTMLBody = "<p><img src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGieyVDxXhjI_M8hUaScl4xnww-NanlrybU3TKA2dttmhsqjwqmqHi6JLs6rasgRcRAe221GsMfw3mDs56IMAAubfTNOxd05snzhVDqgp1I2TPqwQWpM5hA9i2KHeT-0XE_of3g-Bo2VuC/s873/logo_cvfpe.png'></p>" + ;
    "<p>La imagen de arriba esta ubicada en el sitio de la ComunidadVFP.</p>"
ENDWITH
Otra opción es embebiendo las imágenes en el mensaje de correo. Para ello tenemos direrentes maneras de hacerlo.

Una forma es reemplazando el contenido: SRC='c:\Imagenes\Imagen10.gif' en la etiqueta IMG, por un ID de Contenido, como por ejemplo: SRC='cid:imagen10-gif'. La ruta y nombre del archivo de imagen, como el ID de Contenido, lo pasamos como parámetro al método AddRelatedBodyPart() que agregará un objeto imagen al cuerpo del mensaje.
WITH loMsg
  .HTMLBody = "<p><img src='cid:id_imagen10'></p>" + ;
    "<p>La imagen de arriba esta embebida en el mensaje.</p>"
  loBP = .AddRelatedBodyPart("c:\Imagenes\Imagen10.gif", "id_imagen10", 1)
  WITH loBP.Fields
    .Item("urn:schemas:mailheader:Content-ID") = "id_imagen10"
    .Update
  ENDWITH
ENDWITH
Esta forma de embeber las imágenes en los mensajes de correo electrónico, se utiliza cuando generamos programáticamente toda la cadena HTML y las imágenes son muy pocas. Cuando la cantidad de imágenes aumenta, este método resulta un poco engorroso.

La otra manera es directamente tomar un archivo HTML, ya sea desde la Web o del disco local, con el método CreateMHTMLBody(), y éste convierte automáticamente los enlaces de las imágenes en un ID de Contenido. A continuación vemos la forma de lograr esto con un ejemplo con la opción de si el archivo está almacenado en la Web o en el disco local:
WITH THIS.oMsg
  IF llFileLocal 
    *-- Si el archivo está en el disco local
    .CreateMHTMLBody("file://c:\documentos\archivo.htm", 0)
  ELSE
    *-- Si el archivo está en la Web
    .CreateMHTMLBody("http://comunidadvfp.blogspot.com/p/acerca-de.html", 0) 
  ENDIF
ENDWITH
Este método es válido, aun si el archivo HTML no contiene imágenes, con lo que lo podemos usar para reemplazar:
WITH loMsg
  .HTMLBody = FILETOSTR("C:\Archivo.htm")
ENDWITH
con:
WITH loMsg
  .CreateMHTMLBody("file://C:\Archivo.htm")
ENDWITH
como indicamos mas arriba.

El ejemplo final

Para terminar veremos un ejemplo completo y funcional de como enviar un mensaje de correo electrónico desde Visual FoxPro, con varias de las opciones que mostramos. Vamos a usar una cuenta de Gmail (el servidor SMTP de Gmail requiere autenticación y utiliza cifrado SSL), y enviaremos un mensaje de correo a Usuario Uno, con copia a Usuario Dos, con confirmación de lectura y con formato HTML, tomado de la Web y con imágenes embebidas, y un archivo adjunto que seleccionaremos de nuestro disco.
LOCAL loCfg, loMsg, lcFile, loErr
TRY
  loCfg = CREATEOBJECT("CDO.Configuration")
  WITH loCfg.Fields
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465 && ó 587
    .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = .T.
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = .T.
    .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "josefox@gmail.com"
    .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
    .Update
  ENDWITH
  loMsg = CREATEOBJECT ("CDO.Message")
  WITH loMsg
    .Configuration = loCfg
    *-- Remitenete y destinatarios
    .From = "Jose Fox <josefox@gmail.com>"
    .To = "Usuario Uno <user1@gmail.com>"
    .Cc = "Usuario Dos <user2@gmail.com>"
    *- Notificación de lectura
    .Fields("urn:schemas:mailheader:disposition-notification-to") = .From
    .Fields("urn:schemas:mailheader:return-receipt-to") = .From
    .Fields.Update
    *-- Tema
    .Subject = "Ejemplo del " + TTOC(DATETIME())
    *-- Formato HTML desde la Web
    .CreateMHTMLBody("http://comunidadvfp.blogspot.com/p/acerca-de.html", 0)
    *-- Archivo adjunto
    lcFile = GETFILE()
    IF NOT EMPTY(lcFile)
      .AddAttachment(lcFile)
    ENDIF
    *-- Envio el mensaje
    .Send()
  ENDWITH
CATCH TO loErr 
  MESSAGEBOX("No se pudo enviar el mensaje" + CHR(13) + ;
    "Error: " + TRANSFORM(loErr.ErrorNo) + CHR(13) + ;
    "Mensaje: " + loErr.Message , 16, "Error")
FINALLY
  loMsg = NULL
  loCfg = NULL
ENDTRY

Otros enlaces relacionados al uso de CDO con VFP
Notas finales

He tomado la elección de usar CDO para el envío de los mensajes de correo electrónico en mis aplicaciones hace aproximadamente 20 meses. Desde entonces he creado una una clase que encapsula al objeto CDO, y a medida que aparecieron nuevas necesidades, agregaba nuevos métodos y/o propiedades a la definición de la clase, con lo que logre que los cambios no tengan efectos no deseados en mis aplicaciones anteriores. Es por ello que aconsejo a ustedes a que también hagan su propia clase para el envio de mensajes de correo electrónico, con todas sus necesidades, tomándolas de cada ejemplo de este artículo.

[07/04/2015] ACTUALIZACIÓN:

Quizás no puedas enviar correos electrónicos con el código de este artículo dado que Gmail (Google) puede bloquear intentos de inicio de sesión de aplicaciones que no utilicen los últimos estándares de seguridad. Para solucionar este inconveniente, se debe habilitar en nuestra cuenta de Google el acceso a aplicaciones menos seguras. Esto lo haces desde el enlace: https://www.google.com/settings/security/lesssecureapps

Hasta la próxima,


Luis María

73 comentarios :

  1. Gracias por tu aporte, estoy haciendo las pruebas y no envia el mail, simplemente me aparece como si me lo enviara a mi.
    me puedes ayudar ?

    ResponderBorrar
  2. No sé si el comentario anterior se borró, pero quiero agradecerte Luis María por el esfuerzo que te tomas en publicar estos artículos tan explicativos, te comentaba que a mi me han servido mucho a través de los años como desarrollador y te estoy muy agradecido, saludos desde Honduras.

    ResponderBorrar
  3. Gracias, buenos días. Estoy usando este ejemplo y me cancela el proceso en el SEND. El error que saca es OLE IDispatch Exeception code 0? Teh message could not be send to the SMTP server. The transpor t error code was 0x80040217 . The server response was not available. Gracias por la aytuda. Muy amable

    ResponderBorrar
  4. Hola yo tenia ese mismo mensaje al tratar de enviar un correo por medio de Gmail también me aparecia otro mensaje que no preciso ahora, en mi caso no era problema con los parámetros del programa sino con el correo, en Gmail tuve que habilitar una opción que se llama "acceso de aplicaciones menos seguras " y una vez habilitado deje de tener problemas para el envío, ojala les sirva de algo.

    ResponderBorrar
  5. Funciona perfecto muchas gracias....!!!, Como le puedo hacer para que en la bandeja de enviados de mi cuenta de correo aparezca estos mensaje que envió desde el sistema que quede un historial de envio.

    Gracias.

    ResponderBorrar
  6. Como puedo hacer para que me aparezcan aquellos correos que son enviados desde el sistema en la bandeja de enviados?

    ResponderBorrar
  7. Podeis echarme una mano con la configuracion de correo de gmail?

    Gracias

    ResponderBorrar
    Respuestas
    1. Exactamente que necesitas configurar el smtp,el puerto la capa de conexion o un error en especial?

      Borrar
  8. .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465 && ó


    Cambio el servidor y el puerto por variables publicas, que contienen el servidor y el puerto que están en una tabla pero me muestra error pero lo dejo como esta en el ejemplo y funciona que puede ser

    ResponderBorrar
    Respuestas
    1. El valor de la variable Puerto SMTP es un entero número entero = 465 (u otro como 587 ó 25)

      Borrar
  9. buenos dias

    Compañero yo utilizo esta forma de enviar correo hace mucho tiempo y todo perfecto, hasta ahora que debo enviar archivos de tipo
    PDF, el proceso se hace todo correcto, pero el correo que llega al destinatario tiene el archivo adjunto dañado
    no lo deja abrir , esto me sucede con archivos pdf, jpgm doc, los archivos txt llegan sin problemas.

    agredezco cualquier alguna ayuda que me puedan brindar .

    gracias

    ResponderBorrar
    Respuestas
    1. Se me presentó el mismo problema y no encontré una solución. Si se ejecuta el ejemplo original, colocando por supuesto los datos apropiados, y se adjunta un archivo de cualquier tipo llega sin problemas (junto con con el resto de la información del ejemplo). Así que analizando mi adaptación Vs el original y la diferencia era la sección de agregar la sección de HTML. Así que agregue esta sección y !voala! funciona perfectamente, Lo que agregue como sección HTML es:
      *-- Formato HTML desde la Web

      .HTMLBody = " Esta Sección la Agrego, para Solventar los Archivos Anexos. Gracias a la Comunidad VFP. etiqueta"

      la palabra etiqueta la agregue por error al publicar
      Espero le sirva también.

      Borrar
  10. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  11. Buenas noches

    Al ejecutar este codigo me sale el error de "el protocolo especificado es desconocido"

    ResponderBorrar
  12. Sencillo y de lo mejor, muchas gracias

    ResponderBorrar
  13. Luis María,

    Muchas gracias por tus aportes.

    Yo probé y todo bien.

    ¿Hay alguna posibilidad de que quede en gmail como borrador?

    Es porque así controlo, antes de enviar, de que esté todo bien.

    Muchas gracias.

    Un gran abrazo desde Uruguay,


    Washington

    ResponderBorrar
  14. Buenas tardes queridos colegas, me gustaria saber por favor si es posible accesar al articulo " Lo nuevo del Generador de Informes en VFP 9.0 Parte 2", Mil gracias por su atencion

    ResponderBorrar
  15. Hola que tal? se me presento el siguiente caso referente a lo que es envio de mail, tengo un sistema que envia correo con un adjunto que lo utilizan varios dispositivos que usan la misma cuenta de correo para hacer el envio, el problema que se me presento que algunos casos el catch no toma ningun error pero el correo no sale o no llega, desde ya gracias por cualquier sugerencia

    ResponderBorrar
  16. Se pueden enviar correos masivos mediante esta técnica? necesito enviar un mail a 5,000 cuentas de correo, gracias Luis Maria si puedes orientarme

    ResponderBorrar
  17. Esto está excelente. Me quita varios dolores de cabeza.Gracias por su publicación.

    ResponderBorrar
  18. Gracias por todos los aportes que realizaste a lo largo de los años, un fuerte abrazo.

    ResponderBorrar
  19. Excelente artículo, muchas gracias por tu aporte.

    ResponderBorrar
  20. Saludos, excelente aportación, lo he utilizado por varios años, sin embargo estoy intentado utilizarlo, en un servidor dedicado, pero tengo el problema con el puerto smpt no me acepta , i el 465, ni el 9025, ni el 587, hay alguna solución ?

    ResponderBorrar
  21. Los mensajes enviados con CDO tienen el inconveniente de que no se quedan guardados en ninguna parte. Pero se pueden almacenar como ficheros EML, que después podrán abrirse con cualquier gestor de correo, con todas las opciones propias del mismo: reenviar, contestar, etc.
    La forma de hacerlo es la siguiente:

    WITH loMsg
    lcStr = .getstream
    ENDWITH
    lcArch = && Ruta y Nombre de archivo .EML en el que queremos guardarlo
    lcStr.SaveToFile(lcArch,1)

    ResponderBorrar
  22. Buen dia, estoy tratando de usar este proceso pero me sale un error al enviarlo "El servidor rechazo la direccion del remitente. Respuesta de servidor 550 5.1.0", coloque todos los parametros pero nada, que puede estar mal o que debo hacer. saludos

    ResponderBorrar
    Respuestas
    1. debes de poner una dirección de correo que esté registrado en el servidor de correo que utilizas.

      Borrar
  23. Hola, gracias como leo los mail de la bandeja de entrada ??

    ResponderBorrar
  24. hola gracias , necesito saber como leer mails de gmail, desde la bandeja de entrada

    ResponderBorrar
  25. Como puedo evitar que se envíen archivos adjuntos nomame.*

    ResponderBorrar
  26. Me resulto excelente el aporte de este tema en Visual Fox, muchas gracias.

    ResponderBorrar
  27. Estimado Luis María: Estoy utilizando VFP9 SP2 en una estacion de trabajo con Windows 10 Pro. Al intentar realizar un envío de correo mediante el instructivo del blog, obtengo el siguiente mensaje de error "OLE IDispatch exception code 0 from CDO.Message.1:Error de transporte en la conexión al servidor".

    He intentado las diferentes variantes de SSL y siempre obtuve el mismo mensaje

    Tampoco es una cuestion de incluir o no archivos adjuntos.

    Serías tan amable de darme alguna pista? Gracias

    ResponderBorrar
    Respuestas
    1. puede ser que estes usando variables diferente, prueba de esta manera.
      m.ObjetoMail.Configuration.Fields.Item(m.cadena + "smtpauthenticate").Value = .T.
      m.ObjetoMail.Configuration.Fields.Item(m.cadena + "smtpusessl").Value = .T.

      Borrar
  28. Hola, ya habitualmente automatizo los correos con outlook, pero ahora estoy probando el ejemplo de Luis Maria, con distintos servidores smtp, diferentes puertos, y siempre choco con el error 1429, el mismo que comenta Alberto, "error de transporte en la conexión al servidor"
    Estoy probando con el ejemplo básico publicado por Luis Maria.
    Ya le indiqué a Gmail que permita el acceso a aplicaciones menos seguras con el link https://www.google.com/settings/security/lesssecureapps pero sigue igual.
    Si alguien me puede tirar letra de comohacerlo

    ResponderBorrar
  29. Hola buenas noches,
    gracias por el aporte me ha servido de mucho....
    ahora te pregunto :

    si lo que tengo es una variales, o un campo con la direccion de correo, como seria la sintaxis para realizar el envio en esta instrucción:
    .To = "user1@mail.com.ar"
    porque aqui se la envio a user1@gmail.com.ar pero si es el contenido de una variable o campo como seria la sintaxis?

    gracias de anticipadas

    Antonio

    ResponderBorrar
    Respuestas
    1. Yo lo probé con
      .To=chr(34)+alltrim(socios.mail)+chr(34)
      donde "chr(34)" es el ASCII de las comillas dobles. socios.mail es el campo "mail" de la tabla "socios" donde se guarda la dirección de mail de destino. Y anduvo.
      Espero te ayude.

      Borrar
    2. Gracias amigo, y si es una variable la que contiene el valor del email como quedaria la instruccion .to= ?

      Borrar
  30. Gracias por el aporte. Si lo uso con mi cuenta de gmail, funciona de maravillas, pero si cambio a una cuenta con servidor SMTP propio no funciona. Los parámetros de la cuenta fallida son:
    Nombre del servidor: mail.xxxxx.com.ar
    Puerto: 587
    Nombre de usuario: yyyyy@xxxxx.com.ar
    Método de identificación: Contraseña cifrada
    Seguridad de conexión: Ninguna
    Creo que el problema radica en los dos últimos ítems de la configuración ¿De qué manera puedo traducir eso en el código?
    Desde ya, muchas gracias.

    ResponderBorrar
  31. Y si es una variable que contiene el email, como quedaria la instruccion .To= ?

    gracias de antemano

    ResponderBorrar
  32. Y si es una variable que contiene el email, como quedaria la instruccion .To= ?
    Quedaria asi:
    .TO = lcVariable

    ResponderBorrar
  33. Buenas tardes amigos. he estado intentando enviar correos con CDO, tal como lo muestran en su ejemplo, pero no tengo suerte. Siempre me da error 1429. A qué se debe??? Habrá que configurar algo en VFP??? o en Windows???
    Gracias su gentil ayuda!!

    ResponderBorrar
  34. Hola! Excelente ejemplo. Lo tengo funcionando de forma perfecta! Solo una cosa, me he dado cuenta que indica a veces destinatarios como cuentas no existentes cuando si existen. Como se puede hacer para que no haga esta verificación y los envíe todos y que ya luego me llegue por el Outlook los típicos "Mail delivery failed....."

    ResponderBorrar
  35. Excelente ayuda, gracias !

    ResponderBorrar
  36. Very very nice job Luis Maria! Thank you to share your know-how with us! Five stars ***** Cheers!

    ResponderBorrar
  37. Buenas tardes. Estoy presentando el error cuando trato de enviar mail con outlook de 64 bits. si es de 32 no genera error, pero al tener instalado uno de 64 si genera error "OLE IDispatch exception code 0 from CDO.Message.1:Error de transporte en la conexión al servidor".

    ResponderBorrar
  38. Buena tarde. cuando intento enviar correo por outlook de 64 bit me genera este error."OLE IDispatch exception code 0 from CDO.Message.1:Error de transporte en la conexión al servidor". Si lo hago desde outlook 32bit, funciona bien. Espero me pueda ayudar. Muchas gracias

    ResponderBorrar
  39. Gracias…!! Eres un crack…!! Genio…!!

    ResponderBorrar
  40. Buenas noches, he usado tambien esta modalidad de envio de correos, hasta que mis clientes tuvieron office 2013 funciono sin problemas, pero una vez obtuvieron office 365 no logro que funcione siempre me presenta el error de ."OLE IDispatch exception code 0 from CDO.Message.1:Error de transporte en la conexión al servidor". favor si me pueden indicar alguna configuracion adicional. gracias por los aportes muy buenos.

    ResponderBorrar
  41. Ejecuto el programa en VFP 6 para enviar por correo y sale el mensaje:

    Codigo de excepción OLE IDispatch 0 de ?: No se pudo enviar el mensaje al servidor SMTP. El codigo de error de transporte fue 0x80040217. La respuesta del servidor fue not available.

    ResponderBorrar
  42. Buenas noche Luis María, un saludo cordial.
    De antemano Mil Gracias por este Blog, y por los conocimientos, y me imagino de largas horas en estudio has tenido,
    y que tu a bien has querido compartir por acá.
    Te quería consultar con respecto al envio de Email con CDO -y te digo funciona muy bien-, que habrá sucedido con el
    envío de email a través de la plataforma Hotmail? He probado de diferentes maneras y no he podido de nuevo utilizarla
    para el envío de correos electrónicos usando CDO.
    De nuevo Luis, Mil Gracias.
    Gilberto.

    ResponderBorrar
  43. Estoy haciendolo con una cuenta de office 365 y me funciona pero con una cuenta en especifico y la misma configuración me genera un error, "The message could not be sent to the SMTP server. The transport error code was 0x80040217. The server response was not available"

    ResponderBorrar
    Respuestas
    1. si quitas ésta linea y usas el puerto 587 funciona bien
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = .T.

      esa línea funcionaba para gmail ... ahora no me funciona con gmail pero con los dominios propios sí

      Borrar
  44. Muchas gracias por el aporte...me funciona OK, solo una consulta...si quiero hacer que el mail enviado quede en la bandeja de salida de la cuneta..como hago? gracias y saludos,

    ResponderBorrar
  45. me sale mensaje el programa no puede iniciarse porque falta INETCOMM.DLL

    ResponderBorrar
    Respuestas
    1. la solución fue actualizar Windows7 que tenia a una versión con service pack. Lo tenia con Windows Ultimate y lo pase a Windows pro service pack 1 y todas las ultimas actualizaciones. Con windows 10 no presenta problema alguno.
      Gracias Grupo!!!

      Borrar
  46. No logro que funcione siempre me presenta el error de ."OLE IDispatch exception code 0 from CDO.Message.1:Error de transporte en la conexión al servidor". favor si me pueden indicar alguna configuracion. Gracias, Omar

    ResponderBorrar
    Respuestas
    1. Hola. No era problemas de antivirus. la solución fue ir jugando con los distintos puertos de SMTP (25,465,487) y con las opciones siguientes colocando verdadero o falso, hay que ir probandolas
      m.ObjetoMail.Configuration.Fields.Item(m.cadena + "smtpauthenticate").Value = .T.
      m.ObjetoMail.Configuration.Fields.Item(m.cadena + "smtpusessl").Value = .T.

      funciona perfecto tanto para gmail como para los que tienen dominios propios.

      Dió trabajo pero funciona excelente.

      Buen aporte!!!

      Borrar
  47. Quiero enviar un correo con ajuntos xml y no permite. Gracias por su ayuda

    ResponderBorrar
  48. Me pasa algo muy curioso, al enviar un PDF adjunto que fue generado con FoxyPreviewer, version 2013, al abrir el pdf recibido me sale ne blanco. Ahora si lo envio con un correo gmail desde el el gmail propiamente tal el archivo recibido llega sin problemas. Al comparar ambos archivos tienen tamaños diferentes, el original 9.860 byte y el erroneo 10.084 byte.

    Gracias de antemano

    ResponderBorrar
  49. hola amigos ya CDO funciona perfectamente y sin problema en win7 con win10 ya no funciona.

    maestro luis seria bueno revisar para actualizar este articulo para que funcione con win10

    ResponderBorrar
  50. Richard, yo lo tengo funcionando con Windows 10 PRO y con cuantas de Gmail particular y Gmail de empresa. Lo que sí hay que permitir aplicaciones menos seguras en Gmail.

    ResponderBorrar
  51. Maestro gracias por contestar lo estoy utilizando hace varios años y su función era perfecta pero desde el año pasado ya no funciona en win10 aun que le habilite aplicaciones menos seguras, para que funcione hay que tener Gmail de empresa o dominios con Gmail con win7 si funciona por eso es que muchas personas estan buscando alternativas como la dll de antonio mesa

    ResponderBorrar
    Respuestas
    1. Intenta la con librería CsFoxySmtp de Antonio Meza que funciona muy bien.

      -- CsFoxySmtp --
      https://foxydb.wordpress.com/csfoxysmtp/

      Vamos a tener que ir cambiando ya que varios servicios de correos se hacen mas estrictos en el tema de seguridad.


      Borrar
  52. Buenos Días, gracias maestro Luis María por sus aportes y seguro nuevamente se va a poner en actualidad este post ya que solo hasta el día 30 mayo del 2022 se va poder acceder con "aplicaciones menos seguras" luego de ello según el propio google se va a aplicar las nuevas normas. Yo estuve trabajando los últimos años con su ejemplo y me ha ido muy bien hasta que se bloqueo y tuve que activar "aplicaciones menos seguras" pero como le comente esto va solo hasta el 30 de mayo, como se haría con los nuevos requerimientos en adelante y se podría aplicar en nuestro querido VFP a nivel de programación?. GRACIAS POR SU RESPUESTA.

    ResponderBorrar
    Respuestas
    1. parece que nadie tiene idea de como solucionar este problema de seguridad de google que inicia el 30.mayo.2022,,,

      Borrar
    2. La única es que autentifique con celular la cuenta con 2 claves (o doble seguridad) y luego se te abre una entrada mas (justo debajo de doble seguridad, en la cual pides una clave especial para tu programa) y con esa nueva clave para aplicaciones menos seguras, si te comunicas, en algunos gmails no he tenido problemas, ahora tengo uno nuevo que no me deja entrar ni con el metodo que te indico pero en varios clientes si me funciono, es una clave muy larga que te da la cuenta google

      Borrar
  53. Luis Maria, muchas gracias por los ejemplos , como me salvaste !!!! gracias

    ResponderBorrar
  54. Hola Luis Maria, Me da error 1429 Código de excepción OLE IDispach 0 de CDO.Message.1 Error de transporte en la conexión al Servidor. Me ayudas? Gracias

    ResponderBorrar
  55. Buen día, desde haceun par de días no funciona csFoxySmtp version 1.0.7 w32, dá el error "Código de excepción OLE IDispach 0 de CDO.Message.1 Error de transporte en la conexión al Servidor", alguna alternativa

    ResponderBorrar

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.