validation - hippo - verify email list
Correo electrónico validador SMTP (7)
La validación de correo electrónico Real (TM) está intentando enviar algo a la dirección y ver si se rechaza / rebota. Por lo tanto, solo tendrá que enviarlos y eliminar las direcciones que fallan de su lista de correo.
Necesito enviar cientos de boletines informativos, pero me gustaría verificar primero si existe correo electrónico en el servidor. Se llama validación SMTP , al menos eso creo, basado en mi investigación en Internet.
Hay varias bibliotecas que pueden hacer eso, y también una página con código de fuente abierta en ASP Classic ( http://www.coveryourasp.com/ValidateEmail.asp#Result3 ), pero me cuesta leer ASP Classic, y parece que usa una biblioteca de terceros ...
¿Hay algún código para la validación de SMTP en C # y / o una explicación general de cómo funciona?
No tome esto de la manera equivocada, pero el envío de boletines a más de un puñado de personas en estos días es un asunto bastante serio. Sí, necesita supervisar los rebotes (correos electrónicos rechazados) que pueden ocurrir de forma síncrona durante el envío SMTP (normalmente si el servidor SMTP al que está conectado tiene autoridad), o de forma asíncrona como un mensaje de correo electrónico generado por el sistema que ocurre una cierta cantidad de tiempo después el envío SMTP tuvo éxito.
También tenga presente la ley CAN-SPAM y respete la ley al enviar estos correos electrónicos; debe proporcionar un enlace unsub así como una dirección de calle física (para identificarlo a usted y para permitir a los usuarios enviar solicitudes unsub por correo postal si lo desean).
Si no hace estas cosas, su IP podría enrutarse de manera nula en el mejor de los casos y, en el peor, demandaría.
SMTP es un protocolo basado en texto transportado a través de TCP / IP.
Su programa de validación debe abrir una conexión TCP / IP al puerto 25 del servidor (SMTP), escribir en pocas líneas y leer la respuesta. La validación se realiza (pero no siempre) en la línea "RCTP TO" y en la línea "VFRY".
El SMTP RFC describe cómo funciona esto (ver [email protected] a continuación, S son líneas enviadas por el cliente, R son líneas recibidas del servidor):
Example of the SMTP Procedure This SMTP example shows mail sent by Smith at host Alpha.ARPA, to Jones, Green, and Brown at host Beta.ARPA. Here we assume that host Alpha contacts host Beta directly. S: MAIL FROM: R: 250 OK S: RCPT TO: R: 250 OK S: RCPT TO: R: 550 No such user here
Tenga en cuenta que la mayoría de los MTA (Agente de transferencia de correo) tendrán desactivado el comando VRFY por razones de protección contra correo no deseado, probablemente incluso lo bloquearán si prueba varios RCPT TO en una fila (consulte http://www.spamresource.com/ 2007/01 / whatever-happened-to-vrfy.html ). Entonces, incluso si encuentra una biblioteca para hacer esa verificación, no valdrá mucho. Ishmaeel tiene razón, la única forma de averiguarlo realmente es enviar un correo electrónico y ver si rebota o no.
@Hrvoje: Sí, sugiero que controle los correos rechazados. PERO: no todos los correos electrónicos devueltos deben terminar automáticamente en su lista "no existe", también debe diferenciar entre los errores temporales (por ejemplo, el buzón lleno) y los permanentes.
Si bien es cierto que muchos dominios devolverán falsos positivos debido a abusos, todavía hay algunos componentes geniales que realizarán varios niveles de validación más allá de la validación de SMTP. Por ejemplo, vale la pena verificar primero para ver si al menos existe el dominio. Estoy en el proceso de compilar mi propia lista de recursos relacionados con esta pregunta que puede seguir aquí:
http://delicious.com/dworthley/email.validation
Para aquellos que quieran agregar a esta lista, también incluiré lo que tengo aquí:
- aspNetMX
- Biblioteca de clases de .NET Email Validation Wizard
- Correo electrónico de MONOProg Validator.Net
Para una forma a prueba de balas y una gran experiencia de usuario, es útil validar tantos aspectos de la dirección de correo electrónico como sea posible. Puedo ver desde el validador aspNetMX que verifican:
- la sintaxis
- el correo electrónico contra una lista de malas direcciones de correo electrónico
- el dominio contra una lista de dominios defectuosos
- una lista de dominios de buzones
- si el dominio existe o no
- si hay registros MX para el dominio
- y finalmente a través de SMTP si existe o no un buzón
Es este último paso el que pueden eludir los administradores devolviendo fiel a básicamente todas las solicitudes de verificación de cuenta, pero en la mayoría de los casos, si el usuario ha ingresado intencionadamente una dirección incorrecta, ya ha sido interceptada. Y si fue un error del usuario en la parte del dominio de la dirección, eso también se detectará.
Por supuesto, una mejor práctica para usar este tipo de servicio para una pantalla de registro o formulario sería combinar este tipo de validación con un proceso de verificación para garantizar que la dirección de correo electrónico sea válida. Lo mejor de usar un validador de correo electrónico frente a un proceso de verificación es que mejorará la experiencia general del usuario.
Es posible que necesite este componente Validador de correo electrónico para .NET
Aquí está el ejemplo del código:
// Create a new instance of the EmailValidator class.
EmailValidator em = new EmailValidator();
em.MessageLogging += em_MessageLogging;
em.EmailValidated += em_EmailValidationCompleted;
try
{
string[] list = new string[3] { "[email protected]", "[email protected]", "[email protected]" };
em.ValidateEmails(list);
}
catch (EmailValidatorException exc2)
{
Console.WriteLine("EmailValidatorException: " + exc2.Message);
}
Puedes probar el siguiente código, funciona bien para mí:
public class EmailTest {
private static int hear(BufferedReader in) throws IOException {
String line = null;
int res = 0;
while ((line = in.readLine()) != null) {
String pfx = line.substring(0, 3);
try {
res = Integer.parseInt(pfx);
} catch (Exception ex) {
res = -1;
}
if (line.charAt(3) != ''-'')
break;
}
return res;
}
private static void say(BufferedWriter wr, String text) throws IOException {
wr.write(text + "/r/n");
wr.flush();
return;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static ArrayList getMX(String hostName) throws NamingException {
// Perform a DNS lookup for MX records in the domain
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext(env);
Attributes attrs = ictx.getAttributes(hostName, new String[] { "MX" });
Attribute attr = attrs.get("MX");
// if we don''t have an MX record, try the machine itself
if ((attr == null) || (attr.size() == 0)) {
attrs = ictx.getAttributes(hostName, new String[] { "A" });
attr = attrs.get("A");
if (attr == null)
throw new NamingException("No match for name ''" + hostName + "''");
}
/*
Huzzah! we have machines to try. Return them as an array list
NOTE: We SHOULD take the preference into account to be absolutely
correct. This is left as an exercise for anyone who cares.
*/
ArrayList res = new ArrayList();
NamingEnumeration en = attr.getAll();
while (en.hasMore()) {
String mailhost;
String x = (String) en.next();
String f[] = x.split(" ");
// THE fix *************
if (f.length == 1)
mailhost = f[0];
else if (f[1].endsWith("."))
mailhost = f[1].substring(0, (f[1].length() - 1));
else
mailhost = f[1];
// THE fix *************
res.add(mailhost);
}
return res;
}
@SuppressWarnings("rawtypes")
public static boolean isAddressValid(String address) {
// Find the separator for the domain name
int pos = address.indexOf(''@'');
// If the address does not contain an ''@'', it''s not valid
if (pos == -1)
return false;
// Isolate the domain/machine name and get a list of mail exchangers
String domain = address.substring(++pos);
ArrayList mxList = null;
try {
mxList = getMX(domain);
} catch (NamingException ex) {
return false;
}
/*
Just because we can send mail to the domain, doesn''t mean that the
address is valid, but if we can''t, it''s a sure sign that it isn''t
*/
if (mxList.size() == 0)
return false;
/*
Now, do the SMTP validation, try each mail exchanger until we get
a positive acceptance. It *MAY* be possible for one MX to allow
a message [store and forwarder for example] and another [like
the actual mail server] to reject it. This is why we REALLY ought
to take the preference into account.
*/
for (int mx = 0; mx < mxList.size(); mx++) {
boolean valid = false;
try {
int res;
//
Socket skt = new Socket((String) mxList.get(mx), 25);
BufferedReader rdr = new BufferedReader(new InputStreamReader(skt.getInputStream()));
BufferedWriter wtr = new BufferedWriter(new OutputStreamWriter(skt.getOutputStream()));
res = hear(rdr);
if (res != 220)
throw new Exception("Invalid header");
say(wtr, "EHLO rgagnon.com");
res = hear(rdr);
if (res != 250)
throw new Exception("Not ESMTP");
// validate the sender address
say(wtr, "MAIL FROM: <[email protected]>");
res = hear(rdr);
if (res != 250)
throw new Exception("Sender rejected");
say(wtr, "RCPT TO: <" + address + ">");
res = hear(rdr);
// be polite
say(wtr, "RSET");
hear(rdr);
say(wtr, "QUIT");
hear(rdr);
if (res != 250)
throw new Exception("Address is not valid!");
valid = true;
rdr.close();
wtr.close();
skt.close();
} catch (Exception ex) {
// Do nothing but try next host
ex.printStackTrace();
} finally {
if (valid)
return true;
}
}
return false;
}
public static void main(String args[]) {
String testData[] = { "[email protected]", "[email protected]", "[email protected]",
"[email protected]" };
System.out.println(testData.length);
for (int ctr = 0; ctr < testData.length; ctr++) {
System.out.println(testData[ctr] + " is valid? " + isAddressValid(testData[ctr]));
}
return;
}
}
Gracias y Saludos Rahul Saraswat