Lo primero que se necesita son algunas enumeraciones. Una es para obtener un estatus de éxito o error cuando se realiza el envío. Y la otra es para elegir entre un correo de texto plano y uno con contenido HTML.
Public Enum Estatus_Email As Byte
EXITO = 0
[ERROR] = 1
End Enum
Public Enum EnumTipoMensaje
TextoPlano
HTML
End Enum
Public Class Excepcion_Email
Inherits Exception
Sub New(ByVal mensaje As String)
MyBase.New(mensaje)
End Sub
Sub New()
End Sub
End Class
Aun es necesario otro objeto más. Este será para cuando se necesite adjuntar un archivo.
Public Class ArchivoAdjunto
Public archivo As String = "" ' Ruta y nombre del archivo
Public stream As IO.Stream = Nothing ' Un stream con los bytes.
Public tipoMime As String
' cid para incrustar imágenes. Ejemplo: <img src="cid:Logo"/>
Public cid As String
End Class
Los datos que almacena este objeto son los siguientes:
archivo. Aquí va el nombre del archivo que se va a adjuntar. Por ejemplo: "c:\imagen.png"
stream. Este se usa cuando el archivo se encuentra en un stream.
tipoMIME. Aquí se pone el tipo MIME del archivo. Por ejemplo: "image/png"
cid. Cuando se trata de una imagen que estará incrustada como parte del cuerpo del mensaje, se necesita el dato cid. Se trata de una simple referencia a la imagen, por ejemplo: "logo"
Este objeto lleva dos constructores, uno para cuando se adjunta el archivo con una ruta del disco, y el otro para cuando se adjunta un stream. Lo único que hacen los constructores es poner los datos dentro de los campos del objeto.
Public Class ArchivoAdjunto
Public archivo As String = ""
Public stream As IO.Stream = Nothing
Public tipoMime As String
Public cid As String
Sub New(ByVal archivo As String, ByVal tipoMime As String,
Optional ByVal cid As String = "")
Me.archivo = archivo
Me.tipoMime = tipoMime
Me.cid = cid
End
Sub
Sub New(ByRef stream As IO.Stream, ByVal tipoMime As String,
Optional ByVal cid As String = "")
Me.stream = stream
Me.tipoMime = tipoMime
Me.cid = cid
End Sub
End Class
Y ahora si, lo que sigue es tener un objeto que sea el encargado de enviar el correo.
Public Class Email
End Class
Esta clase también necesita algunos campos que usará para poder realizar el envío. Yo uso los siguientes:
Public Class Email
Public Shared HabilitarEnvio As Boolean = True
End Class
Public Class Email
End Class
Public Class Email
Public Shared HabilitarEnvio As Boolean = True
Public Shared Host, Port As String
Public Shared UserName, Pwd, Domain As String
Private smtp As SmtpClient
Private adjuntos As New Collection
Public errorDesc As String = ""
Public hayError As Boolean = FalseEnd Class
El campo HabilitarEnvio lo tengo porque hay veces que necesitas probar y depurar, pero sin que ocurra realmente un envío.
Los campos Host, Port, UserName, Pwd y Domain son los parámetros de configuración que las librerías de .NET necesita para poder hacer el envío del correo.
Después tengo un par de objetos. Uno es el objeto SmtpClient de .NET que es el que hace los envíos. El otro es una colección donde se almacenan los archivos adjuntos que tendrá el correo.
Los campos Host, Port, UserName, Pwd y Domain son los parámetros de configuración que las librerías de .NET necesita para poder hacer el envío del correo.
Después tengo un par de objetos. Uno es el objeto SmtpClient de .NET que es el que hace los envíos. El otro es una colección donde se almacenan los archivos adjuntos que tendrá el correo.
Por último, tengo dos campos que inicialmente están en blanco. En ellos se almacena la información de cualquier error que haya ocurrido durante el proceso.
También es necesario un constructor del objeto, precisamente para recibir los parámetros. Se aprovecha también el constructor para ajustar el objeto SmtpClient, por ejemplo, para pasarle las credenciales, o para habilitar el SSL:
Public Class Email
Sub New()
' Prepara el obteto
smtp
smtp = New SmtpClient(Host, Port)
smtp.DeliveryMethod = SmtpDeliveryMethod.Network
smtp.Credentials = New
System.Net.NetworkCredential(UserName, Pwd)
smtp.EnableSsl = True
smtp.Timeout = 30000 ' 30 segundos
End Sub
Bien. Dentro de esta clase es donde tengo la opción de agregar archivos adjuntos. Para eso tengo dos funciones, una para agregar un archivo adjunto directo desde una ruta de disco, y el otro para agregarlo desde un stream. En ambas funciones, lo único que se hace es generar un nuevo objeto de tipo ArchivoAdjunto, y se agrega a la colección de adjuntos:
Public Class Email
Public Sub AgregarAttachment(ByVal archivo As String,
ByVal tipoMime As String,
ByVal tipoMime As String,
Optional ByVal cid As String = "")
adjuntos.Add(New ArchivoAdjunto(archivo,
tipoMime, cid))
End Sub
Public Sub AgregarAttachment(ByRef stream As IO.Stream,
ByVal tipoMime As String,
ByVal tipoMime As String,
Optional ByVal cid As String = "")
adjuntos.Add(New ArchivoAdjunto(stream,
tipoMime, cid))
End Sub
También será necesario, en algún momento, después de haber realizado el envío, dejar en blanco la colección, para que otros envíos subsecuentes de otros correos no lleven esos archivos adjuntados. Para eso utilizo la siguiente rutina. En realidad, solo libera la memoria utilizada por los streams, en caso de haber alguno.
Public Class Email
Public Sub ClearAdjuntos()
For Each aa As ArchivoAdjunto In adjuntos
If
aa.stream IsNot Nothing Then
If aa.stream.GetType().Name = "IO.MemoryStream" Then
aa.stream.Dispose()
End If
End
If
Next
adjuntos.Clear()
End Sub
End Class
Y por último, solo falta la rutina que realiza los envíos. Esta recibe los destinatarios separados por comas, la cuenta de envío, el asunto, el cuerpo del mensaje, el tipo de mensaje (texto plano o HTML), las cuentas para hacer copia o copia oculta, cuenta de "respuesta para", y nombre del remitente. Todo esto lo acomoda dentro de un objeto MailMessage.
Además, considera todos los archivos adjuntos, ya sea por medio de un stream o por medio de una ruta de disco, y los agrega al mensaje.
Después, en caso de que los envíos estén habilitados, realiza el envío. Tiene un bloque Try-Catch para atrapar cualquier error que pueda ocurrir, y en caso de haberlo se puede registrar en un archivo de Log.
Al terminar, utiliza la rutina ClearAdjuntos para que, como se mencionó antes, los archivos adjuntos no vayan incluidos en otros envíos.
Aquí está la rutina:
Public Class Email
' Envia un eMail con
imagenes incrustadas, puede tener attachments con streams
Public Function Enviar(ByVal de As String, ByVal para As String,
ByVal asunto As String,
ByVal asunto As String,
ByVal mensaje As String, tipo As EnumTipoMensaje,
Optional ByVal nombre_remitente As String = "",
Optional ByVal copia_para As String = "",
Optional ByVal copia_oculta_para As String = "",
Optional ByVal respuesta_para As String = "")
As Estatus_Email
As Estatus_Email
Dim _para(), _copia_para(), _copia_oculta_para() As String
Dim msg As New MailMessage
Enviar = Estatus_Email.EXITO
hayError = False
errorDesc = ""
Try
' Prepara los destinatarios
If
Not para = "" Then
_para = para.Split(",")
For i As Integer = 0 To _para.Length - 1
If _para(i).Trim <> "" Then
msg.To.Add(_para(i).Trim)
End If
Next
End
If
If
Not copia_para = "" Then
_copia_para = copia_para.Split(",")
For i As Integer = 0 To _copia_para.Length - 1
If _copia_para(i).Trim <>
"" Then
msg.CC.Add(_copia_para(i).Trim)
End If
Next
End
If
If
Not copia_oculta_para = "" Then
_copia_oculta_para =
copia_oculta_para.Split(",")
For i As Integer = 0 To _copia_oculta_para.Length -
1
If _copia_oculta_para(i).Trim
<> "" Then
msg.CC.Add(_copia_oculta_para(i).Trim)
End If
Next
End
If
' Prepara el remitente
If
Not respuesta_para = "" Then
_respuesta_para =
respuesta_para.Split(",")
For i As Integer = 0 To _respuesta_para.Length - 1
If _respuesta_para(i).Trim
<> "" Then
msg.ReplyToList.Add(_respuesta_para(i).Trim)
End If
Next
End
If
If
Not de = "" Then
If nombre_remitente = "" Then
msg.From = New MailAddress(de)
Else
msg.From = New MailAddress(de,
nombre_remitente)
End If
msg.Sender = New MailAddress(de)
End
If
' Titulo y cuerpo del mensaje
msg.Subject = asunto
msg.SubjectEncoding = Encoding.UTF8
If
tipo = EnumTipoMensaje.HTML Then
msg.IsBodyHtml = True
msg.AlternateViews.Add(
AlternateView.CreateAlternateViewFromString(
mensaje, Encoding.UTF8, "text/html"))
AlternateView.CreateAlternateViewFromString(
mensaje, Encoding.UTF8, "text/html"))
Else
msg.IsBodyHtml = False
msg.Body = mensaje
End
If
' Attachments
If
adjuntos.Count > 0 Then
Dim lnk As LinkedResource
For Each aa As ArchivoAdjunto In adjuntos
If aa.cid = "" Then
' Es un archivo adjunto
If aa.archivo <> "" Then
msg.Attachments.Add(New
Attachment(
aa.archivo, aa.tipoMime))
aa.archivo, aa.tipoMime))
Else
msg.Attachments.Add(New
Attachment(
aa.stream, aa.tipoMime))
aa.stream, aa.tipoMime))
End If
Else
' Es una imagen incrustada
If aa.archivo <> "" Then
lnk = New LinkedResource(aa.archivo,
aa.tipoMime)
lnk.ContentId =
aa.cid
msg.AlternateViews(0).LinkedResources.Add(lnk)
Else
lnk = New LinkedResource(aa.stream,
aa.tipoMime)
lnk.ContentId =
aa.cid
msg.AlternateViews(0).LinkedResources.Add(lnk)
End If
End If
Next
End
If
' Manda el correo
If
HabilitarEnvio Then
smtp.Send(msg)
End
If
Catch ex As Exception
hayError = True
errorDesc = ex.Message
Enviar = Estatus_Email.ERROR
Finally
ClearAdjuntos()
End Try
End Function
End Class
No olvides que necesitarás también importar algunos espacios de nombres. Yo tengo los siguientes:
Imports System.Net.Mail
Imports Microsoft.VisualBasic
Imports System.Configuration.ConfigurationSettings
Imports System.Text
Imports System.Net.Security
Bien, ahora veamos como funciona. Verás que es fácil. Primero que nada, en cualquier lugar donde se puedan inicializar variables, se necesita lo siguiente:
Email.Host = "smtp.live.com"
Email.Port = 587
Email.UserName = "micorreo@hotmail.com"
Email.Pwd = "xxxxxxxx"
Dim objCorreo As New Email
objCorreo.AgregarAttachment("E:\Media\PAISAJES\prado.jpg", "images/jpg")
objCorreo.AgregarAttachment("e:\ciencia\tangram\tangram.pdf", "application/pdf")
objCorreo.Enviar("micuenta@hotmail.com", "cuentadestino@yahoo.com", "Hola mundo", "Mensaje de
prueba.",
EnumTipoMensaje.TextoPlano)
objCorreo.Enviar("micuenta@hotmail.com", "otracuentadestino@yahoo.com", "Hola mundo", "Mensaje de <strong>prueba</strong>.", EnumTipoMensaje.HTML)
objCorreo.AgregarAttachment("E:\Media\Gif Animados\roses.gif", "images/gif", "roses")
objCorreo.Enviar("micuenta@hotmail.com", "otracuentadestino@yahoo.com", "Hola mundo", "Mensaje de
prueba. <img src='cid:roses'/>", EnumTipoMensaje.HTML)
No hay comentarios:
Publicar un comentario