En este video te mostrare como puedes enviar correos electrónicos a través de un servidor SMTP (en este caso utilizo gmail); haremos uso de la clase PHPMailer.
Código
require "PHPMailer/Exception.php";
require "PHPMailer/PHPMailer.php";
require "PHPMailer/SMTP.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$oMail= new PHPMailer();
$oMail->isSMTP();
$oMail->Host="smtp.gmail.com";
$oMail->Port=587;
$oMail->SMTPSecure="tls";
$oMail->SMTPAuth=true;
$oMail->Username="[email protected]";
$oMail->Password="tupassword";
$oMail->setFrom("[email protected]","Pepito el que pica papas");
$oMail->addAddress("[email protected]","Pepito2");
$oMail->Subject="Hola pepe el que pica";
$oMail->msgHTML("Hola soy un mensaje");
if(!$oMail->send())
echo $oMail->ErrorInfo;
Para enviar un email desde .Net, lo podemos hacer muy fácil, ya que .Net ya nos proporciona lo necesario para realizarlo rápidamente.
A continuación plasmo el código de una clase improvisada que sirve para enviar el mail y a su vez tiene comentarios que van explicando parte por parte:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
namespace EnviaMail
{
class Mail
{
string From = ""; //de quien procede, puede ser un alias
string To; //a quien vamos a enviar el mail
string Message; //mensaje
string Subject; //asunto
List<string> Archivo = new List<string>(); //lista de archivos a enviar
string DE = "[email protected]"; //nuestro usuario de smtp
string PASS = "tupass"; //nuestro password de smtp
System.Net.Mail.MailMessage Email;
public string error = "";
/// <summary>
/// constructor
/// </summary>
/// <param name="FROM">Procedencia</param>
/// <param name="Para">Mail al cual se enviara</param>
/// <param name="Mensaje">Mensaje del mail</param>
/// <param name="Asunto">Asunto del mail</param>
/// <param name="ArchivoPedido_">Archivo a adjuntar, no es obligatorio</param>
public Mail(string FROM, string Para, string Mensaje, string Asunto, List<string> ArchivoPedido_ = null)
{
From = FROM;
To = Para;
Message = Mensaje;
Subject = Asunto;
Archivo = ArchivoPedido_;
}
/// <summary>
/// metodo que envia el mail
/// </summary>
/// <returns></returns>
public bool enviaMail()
{
//una validación básica
if (To.Trim().Equals("") || Message.Trim().Equals("") || Subject.Trim().Equals(""))
{
error = "El mail, el asunto y el mensaje son obligatorios";
return false;
}
//aqui comenzamos el proceso
//comienza-------------------------------------------------------------------------
try
{
//creamos un objeto tipo MailMessage
//este objeto recibe el sujeto o persona que envia el mail,
//la direccion de procedencia, el asunto y el mensaje
Email = new System.Net.Mail.MailMessage(From, To, Subject, Message);
//si viene archivo a adjuntar
//realizamos un recorrido por todos los adjuntos enviados en la lista
//la lista se llena con direcciones fisicas, por ejemplo: c:/pato.txt
if (Archivo != null)
{
//agregado de archivo
foreach (string archivo in Archivo)
{
//comprobamos si existe el archivo y lo agregamos a los adjuntos
if (System.IO.File.Exists(@archivo))
Email.Attachments.Add(new Attachment(@archivo));
}
}
Email.IsBodyHtml = true; //definimos si el contenido sera html
Email.From = new MailAddress(From); //definimos la direccion de procedencia
//aqui creamos un objeto tipo SmtpClient el cual recibe el servidor que utilizaremos como smtp
//en este caso me colgare de gmail
System.Net.Mail.SmtpClient smtpMail = new System.Net.Mail.SmtpClient("smtp.gmail.com");
smtpMail.EnableSsl = false;//le definimos si es conexión ssl
smtpMail.UseDefaultCredentials = false; //le decimos que no utilice la credencial por defecto
smtpMail.Host = "smtp.gmail.com"; //agregamos el servidor smtp
smtpMail.Port = 465; //le asignamos el puerto, en este caso gmail utiliza el 465
smtpMail.Credentials = new System.Net.NetworkCredential(DE, PASS); //agregamos nuestro usuario y pass de gmail
//enviamos el mail
smtpMail.Send(Email);
//eliminamos el objeto
smtpMail.Dispose();
//regresamos true
return true;
}
catch (Exception ex)
{
//si ocurre un error regresamos false y el error
error = "Ocurrio un error: " + ex.Message;
return false;
}
return false;
}
}
}
Para utilizar la clase anterior lo podemos hacer de la siguiente manera:
//creamos nuestra lista de archivos a enviar
List<string> lstArchivos = new List<string>();
lstArchivos.Add("c:/archivo1.txt");
lstArchivos.Add("c:/archivo2.txt");
//creamos nuestro objeto de la clase que hicimos
Mail oMail = new Mail("[email protected]", "[email protected]",
"hola", "un mensaje bien chevere",lstArchivos);
//y enviamos
if (oMail.enviaMail())
{
Console.Write("se envio el mail");
}
else
{
Console.Write("no se envio el mail: "+oMail.error);
}
Nota: si utilizan una cuenta Gmail, a veces va a tardar en conectarse, esto es porque Gmail tiene muchas restricciones de conexiones anónimas, en cambio sí utilizan una conexión smtp propia, no debe darles problema.
En php existe un módulo llamado imap dedicado a las conexiones a correos, este módulo contiene un conjunto de funciones que nos ayudan a realizar esta tarea fácilmente.
Pero antes tenemos que cambiar la siguiente configuración en nuestra cuenta de Gmail para permitir a una aplicación externa conectarse.
Primero(con sesión creada en gmail para hacer estos cambios claro) debemos activar la opción de permitir conexiones de aplicaciones externas en la siguiente liga:
Seleccionamos Activar y Guardar.
La segunda configuración es para que Gmail nos permita conectarnos por el protocolo IMAP. Basta con que vayamos a la configuración de Gmail y seleccionemos la siguiente opción y demos guardar.
En el siguiente código, realizo la conexión a una cuenta de Gmail por medio del protocolo imap y a la vez obtengo los asuntos de los correos.
Clase
class ObtieneMails{
//usuario de gmail, email a donde deseamos conectarnos
var $user="[email protected]";
//password de nuestro email
var $password="tuPasswordDeGmail";
//inforrmación necesaria para conectarnos al INBOX de gmail,
//incluye el servidor, el puerto 993 que es para imap, e indicamos que no valide con ssl
var $mailbox="{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX";
var $fecha="01-MAR-2015"; //desde que fecha sincronizara
//metodo que realiza todo el trabajo
function obtenerAsuntosDelMails(){
//realizamos la conexión por medio de nuestras credenciales
$inbox = imap_open($this->mailbox,$this->user,$this->password) or die('Cannot connect to Gmail: ' . imap_last_error());
//con la instrucción SINCE mas la fecha entre apostrofes ('')
//indicamos que deseamos los mails desde una fecha en especifico
//imap_search sirve para realizar un filtrado de los mails.
$emails=imap_search($inbox,'SINCE "'.$this->fecha.'"');
//comprbamos si existen mails con el la busqueda otorgada
if($emails) {
//ahora recorremos los mails
foreach($emails as $email_number)
{
//leemos las cabeceras de mail por mail enviando el inbox de nuestra conexión
//enviando el identificdor del mail
$overview=imap_fetch_overview($inbox,$email_number);
//ahora recorremos las cabeceras para obtener el asunto
foreach($overview as $over){
//comprobamos que exista el asunto (subject) en la cabecera
//y si es asi continuamos
if(isset($over->subject)){
//aqui pasa algo curioso
//el asunto vendra con caracteres raros
//para ello anexo una función que lo limpia y lo muestra ya legible
//en lenguaje mortal
$asunto=$this->fix_text_subject($over->subject);
//y aqui simplemente hacemos un echo para mostrar el asunto
echo utf8_decode($asunto)."n";
}
}
}
}
}
//arregla texto de asunto
function fix_text_subject($str)
{
$subject = '';
$subject_array = imap_mime_header_decode($str);
foreach ($subject_array AS $obj)
$subject .= utf8_encode(rtrim($obj->text, "t"));
return $subject;
}
}
Ejecución
//creamos el objeto
$oObtieneMails= new ObtieneMails();
//ejecutamos el metodo
$oObtieneMails->obtenerAsuntosDelMails();
la función imap_search contiene muchísimas variantes para realizar filtrados en los correos y todos los pueden ver dando clic aquí.
En esta entrada tratare el tema de realizar una conexión por el protocolo Pop3 para poder leer nuestro correo electrónico, en este caso utilizare una cuenta de Gmail y obtendré los correos de la bandeja de entrada de la misma.
Para poder conectarnos haremos uso de una librería llamada OpenPop.Net que ya realiza la conexión de una manera rápida. La podemos descargar desde su página, o directamente de Nuget en visual studio buscándola por su nombre.
Es importante que realicemos en nuestra cuenta de Gmail los siguientes cambios, ya que Gmail cuenta con restricciones a clientes externos para leer los mails.
Primero(con sesión creada en gmail para hacer estos cambios claro) debemos activar la opción de permitir conexiones de aplicaciones externas en la siguiente liga:
Seleccionamos Activar y Guardar.
La segunda configuración es opcional y es para que Gmailnos permita descargar varias veces los mensajes aunque sea ya leído o ya descargado, basta con que vallamos a la configuración de Gmail y seleccionemos la siguiente opción y demos guardar.
Una vez tengamos la librería y la configuración en Gmail podemos hacer uso de la siguiente clase que he escrito y comentado pasó por paso:
using OpenPop.Mime;
using OpenPop.Pop3;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace Sincronizador_SMTP.Business.Connect
{
/// <summary>
/// clase que se conecta por smtp
/// </summary>
class ConnectPop3
{
//usuario/mail de gmail
private string username = "[email protected]";
//password
private string password = "tupassword";
//el puerto para pop de gmail es el 995
private int port = 995;
//el host de pop de gmail es pop.gmail.com
private string hostname = "pop.gmail.com";
//esta opción debe ir en true
private bool useSsl = true;
public List<Message> getMensajes()
{
try
{
// El cliente se desconecta al terminar el using
using (Pop3Client client = new Pop3Client())
{
// conectamos al servidor
client.Connect(hostname, port, useSsl);
// Autentificación
client.Authenticate(username, password);
// Obtenemos los Uids mensajes
List<string> uids = client.GetMessageUids();
// creamos instancia de mensajes
List<Message> lstMessages = new List<Message>();
// Recorremos para comparar
for (int i = 0; i < uids.Count; i++)
{
//obtenemos el uid actual, es él id del mensaje
string currentUidOnServer = uids[i];
//por medio del uid obtenemos el mensaje con el siguiente metodo
Message oMessage = client.GetMessage(i + 1);
//agregamos el mensaje a la lista que regresa el metodo
lstMessages.Add(oMessage);
}
// regresamos la lista
return lstMessages;
}
}
catch(Exception ex){
//si ocurre una excepción regresamos null, es importante que cachen las excepciones, yo
//lo hice general por modo de ejemplo
return null;
}
}
}
Y de esta manera utilizamos la clase y recorremos los mensajes, y a su vez mostramos el asunto para probar que si corresponde a lo que tenemos en nuestra cuenta de Gmail.
//creamos el objeto
ConnectPop3 oCP3 = new ConnectPop3();
//invocamos el metodo para obtener mensajes
List<OpenPop.Mime.Message> lstMensajes = oCP3.getMensajes();
//recorremos y mostramos el asunto
foreach(OpenPop.Mime.Message oMensaje in lstMensajes){
Console.WriteLine(oMensaje.Headers.Subject);
}
Nota: Pop3 al igual que IMAP es un protocolo para leer mails, si deseamos enviar mails debemos conectarnos con el protocolo SMTP.