Como Limpar sua Lista de Emails

Depois que o sujeito aprende a usar o potencial que uma lista de emails tem para impulsionar seus sites, alavancar vendas, ou apenas para entregar conteúdo para seu público qualificado (gente que, num mundo perfeito, pediu para receber suas mensagens) é normal que, depois de configurar um sistema de envio de newsletters bacana a pessoa queira inserir nele todos os contatos que tem, não importando muito de onde venham: comentários antigos, listas antigas, ou outras fontes menos nobres — não sou ninguém para julgar.

Tudo muito bem, exceto por um pequeno detalhe: estas listas costumam ser muito “sujas,” no sentido que emails deixam de funcionar, os próprios usuários informam emails falsos ou mal escritos, etc.

Se a sua lista for pequena, poucas centenas de contatos, você não vai se preocupar tanto com os endereços inválidos, porque os custos para volumes baixos são menores. Entretanto, todos os serviços de envio de email se baseiam ou em quantidade de mensagens enviadas (como a Amazon SES) ou em quantidade de contatos cadastrados.

Em ambos os casos, quanto menos contatos inválidos melhor, para não inchar custos. Mas também por outro motivo, ainda mais importante: listas sujas vão gerar uma alta taxa de retornos por erro — bounce rate – e fazer com que o remetente seja marcado como spammer,o que pode ser bem prejudicial aos negócios.

Existem várias maneiras de limpar uma lista de email, mas vou ensinar exatamente a mesma técnica que uso para limpar as minhas listas.

Você vai precisar de:

  • uma conta SSH num servidor configurado para enviar e-mails corretamente (com DNS reverso e portas liberadas);
  • um arquivo contendo os emails que quer testar, em formato texto, um email por linha;
  • conhecimento mínimo para executar scripts PHP via linha de comando.

Antes do código, a explicação para os itens acima.

  • Você precisará de um servidor bem configurado, não pode ser o seu PC, porque o script fará uma conexão com o servidor de email do seu contato fingindo que vai enviar uma mensagem; se houver qualquer problema com o IP, qualquer coisinha, você será considerado um spammer e o teste falhará com um falso positivo para email inválido.
  • Por motivos de limitações na quantidade de emails que uma conta pode enviar por hora, você provavelmente não vai poder usar essa solução em uma conta de hospedagem compartilhada, necessitando no mínimo de um VPS (e eu sei quem tem os melhores servidores e VPSs pra te indicar).
  • Você precisará rodar o script via linha de comando, e não via web, porque o tempo de execução do script pode ser, literalmente, de horas; a maioria dos webservers aborta a execução de qualquer script que demore mais do que 30s.

Como eu disse acima, o script que uso para limpar emails faz uma conexão SMTP e inicia o protocolo para o envio de uma mensagem para o endereço do contato; se o resultado da operação (que é abortada antes que qualquer email seja enviado de verdade) for diferente do esperado para um envio bem sucedido, então o script “sabe” que se trata de um email ruim.

Eu normalmente separo um diretório no servidor e coloco nele três arquivos: a lista de emails, que vou chamar de entrada.txt; o arquivo SMTPValidate.php que contém a lógica para validar um único endereço de email; e o verifica.php, que contém a lógica para abrir o arquivo de entrada, passar linha por linha validando-a como email válido, e exibir na saída padrão cada email que passar pelo teste.

Para gerar um arquivo de saída (como saida.txt) é só usar o operador de redirecionamento do Bash (deve funcionar também no Windows, sei que funciona no Cygwin):

$> php verifica.php > saida.txt

Seguem os códigos.

SMTPValidate.php

<?php  
    /**
     * @file SMTPValidate.php
     * Attempt to validate an email address using a combination of MX lookup and
     * an old fashioned SMTP test message.
     *
     * @return void
     * @author Jimmy K. <jimmy@ghazlawl.com>
     */

    class SMTPValidate {
        public $fromDomain = 'mydomain.com';
        public $fromEmail = 'sample@mydomain.com';
        public $debug = false;

        /**
         * Attempt to validate an email address.
         *
         * @param string $email The email address to validate.
         * @return boolean
         * @author Jimmy K. <jimmy@ghazlawl.com>
         */

        public function validate($email)
        {
            // Assume the email address is valid by default.
            $valid = true;

            // Split the email into two parts, user and domain.
            $emailParts = explode('@', $email);
            list($user, $domain) = $emailParts;

            // Attempt to validate using MX records.
            getmxrr($domain, $matches);

            if (sizeof($matches) == 0) {
                // No MX records were found for the domain.
                echo $this->debug ? 'No MX records found for the specified email. ' . $domain : '';
                return false;
            }

            foreach ($matches as $match) {
                if ($valid && !isset($responseCode)) {
                    // Open the connection.
                    $connection = @fsockopen($match, 25, $errno, $errstr, 30);
                    $response = @fgets($connection);

                    if ($connection) {
                        // So far so good.
                        $log['Connection'] = "SUCCESS";
                        $log['ConnectionResponse'] = $errstr;
                    } else {
                        // Unable to connect.
                        $log['Connection'] = "ERROR";
                        $log['ConnectionResponse'] = $errstr;
                        if ($this->debug) print_r($log);
                        return false;
                    }

                    // Say hello to the nice robots.
                    fputs($connection, "HELO $this->fromDomain\r\n");
                    $response = fgets($connection);
                    $log['HELO'] = $response;

                    // Send the email "from" value.
                    fputs($connection, "MAIL FROM: <$this->fromEmail>\r\n");
                    $response = fgets($connection);
                    $log['MailFromResponse'] = $response;

                    // Send the email "to" value.
                    fputs($connection, "RCPT TO: <$email>\r\n");
                    $response = fgets($connection);
                    $log['MailToResponse'] = $response;

                    // Get the response code.
                    $responseCode = substr($log['MailToResponse'], 0, 3);
                    $responseCodeBase = substr($responseCode, 0, 1);

                    // Wave goodbye to the nice robots.
                    fputs($connection, "QUIT\r\n");
                    $response = fgets($connection);

                    // Get the quit response and quit code.
                    $log['QuitResponse'] = $response;
                    $log['QuitCode'] = substr($response, 0, 3);

                    if ($responseCodeBase == "5") {
                        // Server responded that the message is undeliverable.
                        $valid = false;
                    }

                    // close the connection.
                    @fclose($connection);
                }
            }

            if ($debug) {
                // Output the log for debugging.
                print_r($log);
            }
            return $valid;
        }
    }
?>

verifica.php

<?php  
require("SMTPValidate.php");

$validator = new SMTPValidate();
$validator->fromDomain = 'seudominio.com';
$validator->fromEmail = 'noreply@seudominio.com';
$validator->debug = false;

$handle = fopen("entrada.txt", "r");
if ($handle) {  
    while (($line = fgets($handle)) !== false) {
        // Tenta validar o endereço.
         $line = trim($line);
          $valid = $validator->validate($line);

          if ($valid) echo "$line\n";
    }
}
fclose($handle);  
?>

Você terá que adaptar o script verifica.php para a sua realidade: é necessário configurar o domínio de onde será iniciada a conexão para validação do email, o endereço de email que será usado na conexão de teste, e logo abaixo no argumento da função fopen() o nome do arquivo de entrada ("entrada.txt" no meu caso).

Por fim, é necessário ressaltar que:

  • você vai conseguir eliminar das suas listas um bom percentual de emails inválidos, porém só mesmo no momento que você fizer o envio das mensagens é que será possível ter uma validação 100% eficiente dos contatos;
  • se o seu servidor contar com limitações quanto à quantidade de emails enviados por hora (ou por minuto, ou por dia) o script pode não funcionar adequadamente;
  • é normal que demore uma cara para validar uma lista (quanto mais contatos, mais vai demorar): é natural; certifique-se de que o script não vai ser interrompido por motivos bobos, o que obrigaria a reiniciar o processamento do zero (dica pra vida: pesquise no Google por um programa chamado SCREEN no Linux — de nada).

Limpeza de Listas Profissional

Agora, caso você queira validar suas listas sem gastar muito dinheiro (normalmente este é um serviço bastante caro), com alguém em quem você pode confiar plenamente quanto à privacidade, honestidade e competência, sem ter que se preocupar com detalhes técnicos,conheça meu serviço de limpeza de listas de email, e faça contato por lá.

Newsletter

Gostou deste conteúdo? Informe seu email e receba gratuitamente todos os novos posts na sua caixa de entrada (será necessário confirmar a inscrição em seguida, verifique sua caixa postal).

Deixe seu comentário

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.