none
Bucle para enviar emails RRS feed

  • Pregunta

  • Buenas , tengo un formulario que se abre en el MDI principal que lo que hace es buscar aquellos clientes que se les debe de enviar un email para felicitar su aniversario y lo envía , lo que intento recrear es una especie de COLA que se vayan enviando los emails , todo el código que pongo funciona pero me gustaría saber si es la forma más correcta de hacerlo.

    Creamos una lista del tipo Clientes y por cada registro ejecutamos la acción de enviar un email

                    List<Clientes> mylist = AccionesCRM.ObtenerClientes_AccionAniversario(0, System.DateTime.Now, System.DateTime.Today.AddDays(1));
    
                    foreach (Clientes C in mylist)
                    {
                        if (C.email != "")
                        {
                            string emailDestinatario = C.email;
                            int idCliente = C.id;
                            int tiendaCliente = C.tienda;
                            int añoActual = DateTime.Now.Year;
                            int year = C.FechaNacimiento.Year;
                            int añosCliente = añoActual - year;
                            string nombreCliente = C.Nombre + "" + C.Apellido1 + " " + C.Apellido2;
                            EnvioEmails.enviarCorreoAniversario(0, emailDestinatario, nombreCliente, Convert.ToString(añosCliente), EnvioEmails.obtenerTipoDescuentoAniversario(), idCliente, tiendaCliente);
                        }
                    }
    
    
    


    Método que devuelve la lista con los clientes que se tiene que enviar el email

        public static List<Clientes> ObtenerClientes_AccionAniversario(int contactados,DateTime fechaInicio, DateTime fechaFin)
            {
                String ConnString = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;
                
                List<Clientes> _lista = new List<Clientes>();
                SqlCommand _comando = new SqlCommand();
    
                using (SqlConnection Conn = new SqlConnection(ConnString))
                 {
                    Conn.Open();
                        _comando = new SqlCommand("Select  * from clientes ... ... ...", Conn);
    
    
                    SqlDataReader _reader = _comando.ExecuteReader();
    
                    while (_reader.Read())
                    {
                        Clientes pClientes = new Clientes();
                        pClientes.id = Convert.ToInt32(_reader["id"]);
                        pClientes.tienda = Convert.ToInt32(_reader["tienda"]);
                        pClientes.Nombre = Convert.ToString(_reader["nombreCliente"]);
                        pClientes.email = Convert.ToString(_reader["email"]);
    
                        DateTime? laFecha;
                        pClientes.fechaUltimoContacto =  Convert.ToDateTime(_reader["fecha"]);
                        pClientes.FechaNacimiento = Convert.ToDateTime(_reader["fechaNacimiento"]);
    
                        _lista.Add(pClientes);
                    }
    
                    _reader.Close();
    
                }
                return _lista;
                
            }
    
    
    


    Función que hace el envio del email

    
    
     public static void enviarCorreoAniversario(int mensajes,string emailDestinatario, string nombreCliente, string añosCliente, string descuento, int idCliente, int tiendaCliente)
            {
                Cursor.Current = Cursors.WaitCursor;
    
                //create the mail message
                MailMessage mail = new MailMessage();
    
                String emailUsuario = ConfiguracionBD.obtenerValor("emailUsuario");
                String emailPassword = ConfiguracionBD.obtenerValor("emailPassword");
    
    
                //set the addresses
                mail.From = new MailAddress(emailUsuario);
                mail.To.Add(emailDestinatario);
               
                //set the content
                mail.Subject = "Felicitación de cumpleaños";
    
                // se crea el mensaje
                string nombreTienda = ConfiguracionBD.obtenerValor("emailRemitente");
                string body = "";
    
    
                body = File.ReadAllText("crm\\cartaAniversario.html");
    
                body = body.Replace("[#NOMBRECLIENTE#]", nombreCliente);
                body = body.Replace("[#EDADCLIENTE#]", añosCliente);
                body = body.Replace("[#DESCUENTO#]", descuento);
                body = body.Replace("[#OPTICA#]", nombreTienda);
    
                //first we create the Plain Text part
                AlternateView plainView = AlternateView.CreateAlternateViewFromString(body, null, "text/plain");
    
    
                //then we create the Html part
                //to embed images, we need to use the prefix 'cid' in the img src value
                //the cid value will map to the Content-Id of a Linked resource.
                //thus <img src='cid:companylogo'> will map to a LinkedResource with a ContentId of 'companylogo'
                AlternateView htmlView = AlternateView.CreateAlternateViewFromString("<img src=cid:companylogo>" + body, null, "text/html");
    
                //create the LinkedResource (embedded image)
                LinkedResource logo = new LinkedResource("crm/img/felizcumple.jpg");
                logo.ContentId = "companylogo";
                //add the LinkedResource to the appropriate view
                htmlView.LinkedResources.Add(logo);
    
                //add the views
                mail.AlternateViews.Add(plainView);
                mail.AlternateViews.Add(htmlView);
    
    
                // se define el smtp
                SmtpClient smtp = new SmtpClient()
                {
                    Host = ConfiguracionBD.obtenerValor("emailSMTP"),
                    Port = 587,
                    UseDefaultCredentials = false,
                    Credentials = new NetworkCredential(emailUsuario,emailPassword),
                    EnableSsl = true,
                };
    
    
                try
                {
                    smtp.Send(mail);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    Log.Error("PC_: " + Environment.MachineName + " ERROR  enviarCorreoAniversario ### " + ex.Message);
                    MessageBox.Show("Error enviando el correo , revisa la configuración");
                    return;
                }
    
     
    
                // Set cursor as default arrow
                Cursor.Current = Cursors.Default;
            }

    Al intentar hacer el envío del email hay un try catch por lo que si da error al intentar enviar un email hago uso de la herramienta LOG4NET para que me envié un email con la excepción , pero no se si el procedimiento en global es correcto porque si hay una cola de 30 emails y empieza a fallar del primero al último el bucle seguirá haciéndolo verdad?

    Igual el funcionamiento debería ser si falla solo una vez ya dar una excepción y parar el bucle?

    Gracias

    martes, 6 de septiembre de 2016 10:22

Respuestas

  • hola

    Pero no necesitas enviar uno por uno los mails, salvo que el mensaje sea personalizado para cada persona

    quizas armar un mail generico sin personalizacion asi podrias armar una lista de mail y asignar el BCC

    MailMessage.Bcc Property

    o sea defines la lista de destinatarios que se envia con copia oculta

    De esta forma armas la lista y realizas un unico envio de mail, sera el servidor SMTP quien se encargue que llegue a cada destinatarios

    Nota: sino quieres ocultar a quien se envia el mail podrias usar simplemente el CC

    >>porque si hay una cola de 30 emails y empieza a fallar del primero al último el bucle seguirá haciéndolo verdad?

    en este caso como tienes el codigo solo atrapara si falla el Send() del mail, pro si hay algun otro fallo no lo contemplas

    aconsejaria que el control de errores sea algo mas abarcativo

    foreach (Clientes C in mylist)
    {
    	if (C.email == "")
    		continue;
    		
    	string emailDestinatario = C.email;
    	int idCliente = C.id;
    	int tiendaCliente = C.tienda;
    	int añoActual = DateTime.Now.Year;
    	int year = C.FechaNacimiento.Year;
    	int añosCliente = añoActual - year;
    	string nombreCliente = C.Nombre + "" + C.Apellido1 + " " + C.Apellido2;
    	
    	try
    	{
    		EnvioEmails.enviarCorreoAniversario(0, emailDestinatario, nombreCliente, Convert.ToString(añosCliente), EnvioEmails.obtenerTipoDescuentoAniversario(), idCliente, tiendaCliente);
    	}
    	catch(..)
    	{
    		//aqui aplicas el log
    	}
    }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    Gracias , se me olvidó mencionar que el cuerpo del email es personalizado para cada cliente, ya que dentro del email se le saluda con un "hola $nombre"

    Gracias por las sugerencias.

    • Marcado como respuesta golfgti6 lunes, 26 de septiembre de 2016 16:38
    martes, 6 de septiembre de 2016 15:17

Todas las respuestas

  • hola

    Pero no necesitas enviar uno por uno los mails, salvo que el mensaje sea personalizado para cada persona

    quizas armar un mail generico sin personalizacion asi podrias armar una lista de mail y asignar el BCC

    MailMessage.Bcc Property

    o sea defines la lista de destinatarios que se envia con copia oculta

    De esta forma armas la lista y realizas un unico envio de mail, sera el servidor SMTP quien se encargue que llegue a cada destinatarios

    Nota: sino quieres ocultar a quien se envia el mail podrias usar simplemente el CC

    >>porque si hay una cola de 30 emails y empieza a fallar del primero al último el bucle seguirá haciéndolo verdad?

    en este caso como tienes el codigo solo atrapara si falla el Send() del mail, pro si hay algun otro fallo no lo contemplas

    aconsejaria que el control de errores sea algo mas abarcativo

    foreach (Clientes C in mylist)
    {
    	if (C.email == "")
    		continue;
    		
    	string emailDestinatario = C.email;
    	int idCliente = C.id;
    	int tiendaCliente = C.tienda;
    	int añoActual = DateTime.Now.Year;
    	int year = C.FechaNacimiento.Year;
    	int añosCliente = añoActual - year;
    	string nombreCliente = C.Nombre + "" + C.Apellido1 + " " + C.Apellido2;
    	
    	try
    	{
    		EnvioEmails.enviarCorreoAniversario(0, emailDestinatario, nombreCliente, Convert.ToString(añosCliente), EnvioEmails.obtenerTipoDescuentoAniversario(), idCliente, tiendaCliente);
    	}
    	catch(..)
    	{
    		//aqui aplicas el log
    	}
    }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 6 de septiembre de 2016 12:46
  • hola

    Pero no necesitas enviar uno por uno los mails, salvo que el mensaje sea personalizado para cada persona

    quizas armar un mail generico sin personalizacion asi podrias armar una lista de mail y asignar el BCC

    MailMessage.Bcc Property

    o sea defines la lista de destinatarios que se envia con copia oculta

    De esta forma armas la lista y realizas un unico envio de mail, sera el servidor SMTP quien se encargue que llegue a cada destinatarios

    Nota: sino quieres ocultar a quien se envia el mail podrias usar simplemente el CC

    >>porque si hay una cola de 30 emails y empieza a fallar del primero al último el bucle seguirá haciéndolo verdad?

    en este caso como tienes el codigo solo atrapara si falla el Send() del mail, pro si hay algun otro fallo no lo contemplas

    aconsejaria que el control de errores sea algo mas abarcativo

    foreach (Clientes C in mylist)
    {
    	if (C.email == "")
    		continue;
    		
    	string emailDestinatario = C.email;
    	int idCliente = C.id;
    	int tiendaCliente = C.tienda;
    	int añoActual = DateTime.Now.Year;
    	int year = C.FechaNacimiento.Year;
    	int añosCliente = añoActual - year;
    	string nombreCliente = C.Nombre + "" + C.Apellido1 + " " + C.Apellido2;
    	
    	try
    	{
    		EnvioEmails.enviarCorreoAniversario(0, emailDestinatario, nombreCliente, Convert.ToString(añosCliente), EnvioEmails.obtenerTipoDescuentoAniversario(), idCliente, tiendaCliente);
    	}
    	catch(..)
    	{
    		//aqui aplicas el log
    	}
    }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    Gracias , se me olvidó mencionar que el cuerpo del email es personalizado para cada cliente, ya que dentro del email se le saluda con un "hola $nombre"

    Gracias por las sugerencias.

    • Marcado como respuesta golfgti6 lunes, 26 de septiembre de 2016 16:38
    martes, 6 de septiembre de 2016 15:17