+1

Enviando Emails Autenticados com o Protocolo SMTP

criado por Carlos Sica em 19/08/2005 9:11am
Existem vários verbos ou comandos SMTP, mas vamos explicar somente os comandos necessários para estabelecer uma comunicação de envio de email e as respostas que cada um fornece. Lembre-se que este verbos serão recebidos pelo servidor através do socket, que existe apenas após o estabelecimento de uma conexão.

MAIL
Este verbo requer que o servidor estabeleça um endereço de retorno no envelope, que será utilizado, por exemplo, para enviar mensagens de erro.

MAIL From: sica@exemplo.com.br\r\n

mensagem de aceitação:
250 ok

mensagens de erro:
500 line too long
555 garbage not permitted
501 malformatted address
451 timeout

RCPT
Este verbo solicita ao servidor que escreva um ou mais endereços de destino no envelope.

RCPT To: carlos@exemplo.com.br\r\n

mensagem de aceitação:
250 ok

mensagens de erro:
450 mailbox busy, try again later
452 recipient out of disk space
452 too many recipients
503 need MAIL before RCPT
550 no such recipient here
551 recipient has moved
553 we don't relay mail to remote addresses

DATA
Este verbo estabelece o inicio da composição do email a ser enviado (não requer parâmetros).

DATA\r\n

As próximas linhas enviadas ao servidor devem ser escritas num formato específico, contendo os vários campos necessários para construir um email (veja abaixo). Um ponto estabelece o final do texto.

MIME-Version: 1.0\r\n
Content-Type: text/html; charset=iso-8859-1\r\n
From: Carlos Sica <sica@exemplo.com.br>\r\n
To: Carlos Sica <sica@exemplo.com.br>\r\n
Subject: teste de email\r\n
\r\n
Aqui vem o corpo do email que é um texto composto por linhas de 80 caracteres.\r\n
.\r\n

mensagem de aceitação:
354 go ahead

mensagens de erro:
451 unable to set up internal message buffer
503 need RCPT before DATA
552 sorry, this message is too large
554 too many hops, this message is looping

QUIT
Solicita o encerramento da conexão que esta aberta (não requer parâmetros).

QUIT\r\n

mensagem de aceitação:
221 mail.exemplo.com.br

A validação do login e senha
Os verbos estudados acima são os necessários para compor e enviar um email através do servidor SMTP. Porém, quando o servidor está configurado para enviar apenas emails de usuários cadastrados, é necessário validar o login e a senha desses usuário. Para tanto deve-se utilizar o verbo AUTH. Após esta requisição ser aceita, deve-se enviar o login e senha encriptadas.

AUTH
Solicita autenticação

AUTH LOGIN\r\n

mensagem de aceitação:
334 VXNlcm5hbWU6

Comentários:

Mostrando 1 - 10 de 26 comentários
g disse:
ola eu tenho uma ferramenta administrativa que organiza os destinatarios entao uso uma classe que pega do banco os destinarios o assunto e envia o e-mail mais ele só esta enviando para e-mails com @bizplace.com.br para nenhum outro mais
gostaria que me desse uma luz ai vai o código:






<?
// Instancia os objetos
//require_once $path_classes."PEAR/Mail.php";
//require_once $path_classes."PEAR/Mail/mime.php";

//$mailobj =& Mail::factory($config->mail_opt["driver"], $config->mail_opt);
//$o_sql = new SQL();

// Includes
include("./templates/header.php");
include($path_classes."admin/config/config_tabela.php");
include($path_classes."admin/config/config_form.php");

$o_form = new Form();
$o_form = config_frm( $o_form );
$o_form->descricao = "&raquo; Newsletter &raquo; Enviar";
$o_form->print_desc();
$o_sql = new SQL();
$o_geral = new Geral();

echo $o_form->frm_prefix;

// Envia emails
// ----------------------------------------

IF ($tipo=="testar")
{
// Pega o destinatário (email do user logado)
$tupla = $o_sql->select("SELECT distinct(usu_e_mail) FROM usuario WHERE usu_codigo='".$_SESSION["dados"]["usu_codigo"]."'");
}
ELSE
{
// Pega os destinatários
$in = "";
for ( $ind=0; $ind<sizeof($gru_cod); $ind++)
{
$in .= $gru_cod[$ind];
IF ($ind<sizeof($gru_cod)-1)
$in .= ",";
}
if ($reman==1)
$and = " AND usu_enviad='0'";

if ($filtro!="")
{
$o_sql->execSql("update usuario set usu_enviad = '0' WHERE gru_codigo IN ($in) ".$filtro);
$tupla = $o_sql->select("SELECT distinct(usu_e_mail)
FROM usuario
WHERE gru_codigo IN ($in) "
.$filto.$and );
}
else
{
$o_sql->execSql("update usuario set usu_enviad = '0' WHERE gru_codigo IN ($in) AND usu_newsle='1'");
$tupla = $o_sql->select("SELECT distinct(usu_e_mail)
FROM usuario
WHERE gru_codigo IN ($in)
AND usu_newsle='1' ".$and );
}


}

if ($assunto=="")
{
list($ntx_codigo) = $_GET['ntx_codigo'];
// Pega o assunto da mensagem
$tupla2 = $o_sql->select("SELECT new_descri FROM newsletter WHERE new_codigo=$new_codigo");
$assunto = $tupla2[0]["new_descri"];
//echo "SELECT ntx_conteu FROM news_texto WHERE ntx_codigo=$ntx_codigo";
$vet = $o_sql->select("SELECT ntx_conteu FROM news_texto WHERE ntx_codigo='$ntx_codigo'");
$conteudo = $vet[0]["ntx_conteu"];
}

/*$mime =& new Mail_mime();
$mime->setHTMLBody($message);
$body = $mime->get();
*/$body = $message;
$headers = array();

//$headers['From'] = $config->nome_resp." <".$config->email_resp.">";
// $headers['To'] = "dud@bizplace.com.br";
$headers['Subject'] = $assunto;

$c1=0;
$sto=$msg="";

for ( $ind=0; $ind<sizeof($tupla); $ind++)
{
$sto.=$tupla[$ind]["usu_e_mail"];

if((sizeof($tupla)-1)>$ind) $sto.=",";

#if ($c1==$config->mail_fila_qtd)
$c1 = true;
if ($c1)
{
$to = $sto;
$tto = $to;

$bcc = "Bcc:".$tto;
// Envia Mensagem
#$retorno = $mailobj->send($to, $headers, $body);
echo "<pre>";
//print_r($bcc);
echo "</pre>";
#$eMail = mail("adler@bizplace.com.br,adlerdesigner@hotmail.com,","mensagem teste","MENSAGEM TESTE");
#if($eMail) { echo "enviado"; } else { echo "nao enviado"; }
#echo "headers:::::: <pre>";
#print_r($headers);
#echo "</pre>";
#$headers[MIME-Version] . $headers[Content-Type] .
#$headers[Content-Transfer-Encoding] . $headers[From] . $headers[Subject];
#echo "<br>";
$subject = $headers[Subject];
#echo "<br>";
$from = "Goedert <goedert@bizplace.com.br>";
#echo "<br>";
// Cabeçalhos que definem o e-mail como sendo em formato HTML
$cabeca = "MIME-Version: 1.0\n";
$cabeca .= "Content-type: text/html; charset=iso-8859-1\n";
#$cabeca .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$cabeca .= "From: ".$from."\n";
$cabeca .= "Return-Path: Goedert <goedert@bizplace.com.br>\n";
#$cabeca .= "Bcc: ".$tto."\n";
#$cabeca .= "To: <$tto>\n";

#$headers = "From: ".$email."\r\n" .
#"MIME-Version: 1.0\r\n" .
#"Content-Type: text/html; charset=windows-1252\r\n" .
#"Content-Transfer-Encoding: 8bit\r\n\r\n";

$corpo = $conteudo;
$corpo .= "<center><a href='http://goedert.bizwork.com.br/news_cancelar.php?email={$tupla[$ind]['usu_e_mail']}'><img src='http://goedert.bizwork.com.br/imagens/b_cancelar.jpg&#039; border=0></a></center>";
//echo $corpo;
//$retorno = mail("adler@bizplace.com.br,adlerdesigner@hotmail.com,adlerdesigner@gmail.com", "TESTE", $corpo, $cabeca); // retorna todos os emails
//echo $o_geral->alert();
$retorno = mail($tto, $subject, $corpo, $cabeca);

//$retorno = mail($emails, $subject, $corpo, $cabeca);


//$retorno = $mailobj->send($tto, $headers, $body);
//$retorno = TRUE;
IF ($retorno!==TRUE)
{
$msg = "<div align='left' valign='top' class='{$o_form->desc_class}'>Erro ao enviar e-mail!<br></div><br><br>";
break;
}
$c1 = 0;
$sto="";
}
$o_sql->execSql("update usuario set usu_enviad = '1' where usu_e_mail = '".$tupla[$ind]["usu_e_mail"]."'");
$c1++;
}

if ($sto<>"")
{
// Envia Mensagem
$sto.=$tupla[$ind]["usu_e_mail"].",";
if ($c1==$config->mail_fila_qtd)
{
$to = $sto;
$tto = $to;
$bcc = "Bcc:".$tto;
// Envia Mensagem
$subject = $headers[Subject];
$from = "Goedert <goedert@bizplace.com.br>";
// Cabeçalhos que definem o e-mail como sendo em formato HTML
$cabeca = "MIME-Version: 1.0\n";
$cabeca .= "Content-type: text/html; charset=iso-8859-1\n";
#$cabeca .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$cabeca .= "From: ".$from."\n";
$cabeca .= "Return-Path: Goedert <goedert@bizplace.com.br>\n";
//$cabeca .= "Bcc: ".$tto."\n";
#$cabeca .= "To: <$tto>\n";

#$headers = "From: ".$email."\r\n" .
#"MIME-Version: 1.0\r\n" .
#"Content-Type: text/html; charset=windows-1252\r\n" .
#"Content-Transfer-Encoding: 8bit\r\n\r\n";
$corpo = $conteudo;
$corpo .= "<center><a href='http://goedert.bizwork.com.br/news_cancelar.php?email={$tupla[$ind]['usu_e_mail']}'><img src='http://goedert.bizwork.com.br/imagens/b_cancelar.jpg&#039; border=0></a> </center>";

//echo $to;

$retorno = mail($to, $subject, $corpo, $cabeca);
//echo $cabeca;
//$retorno = TRUE;
IF ($retorno!==TRUE)
{
$msg = "<div align='left' valign='top' class='{$o_form->desc_class}'>Erro ao enviar e-mail!<br></div><br><br>";
break;
}
$c1 = 0;
$sto="";
}
$o_sql->execSql("update usuario set usu_enviad = '1' where usu_e_mail = '".$tupla[$ind]["usu_e_mail"]."'");
$c1++;

}

// Mensagem de OK...
IF ( $msg!=="" )
$ind = $ind-$config->mail_fila_qtd;

// Mensagem de OK...
echo "<div align='left' valign='top' class='{$o_form->desc_class}'>&nbsp;{$ind}&nbsp;Mensagens Enviadas&nbsp;</div><br><br>";
IF ( $msg!=="" )
echo $msg;
echo "<a href='news_enviar.php' class='titulo4'&laquo;>&laquo; Voltar</a>";

echo $o_form->frm_sufix;

include("./templates/footer.php");
?>
05/05/2010 12:04pm (~8 anos atrás)

Diego Campos disse:
esse script aki dah Connection refused mas tenho certeza do servidor e da porta pois a mesma configuração no outlook conecta no smtp e envia ok
Já tentei com mais de um servidor diferente SMTP o local, alguns pagos outros grátis, sempre da Connection refused
alguém sabe pq?
16/08/2008 7:32pm (~9 anos atrás)

pela disse:
ERRATA: O TÍTULO SERIA:

"Máquina trava e a página >>NÃO<< é exibida"

Até mais!
10/05/2007 2:13pm (~11 anos atrás)

pela disse:
Máquina trava e a página é exibida

SOLUÇÃO:
substituir da linha 41 à 44 por:

//modificado ----------------
$i=0;
do
{
$i++;
$buffer=fgets($conexao, 512);
print($i." - loop: ".$buffer."<br>");
if(substr($buffer , 4, 8)=='8BITMIME')
break;
}
while ($buffer);
// fim -------------- modificado

Até mais!
10/05/2007 2:11pm (~11 anos atrás)

Bem pessoal...
o meu fica assim:
conectou com: Resource id #1
conexão:
loop:
loop:
loop:
loop:
loop:
loop:
loop:
Loop infinitamente :S

alguem poderia me ajudar?
obrigado!
19/04/2007 1:44pm (~11 anos atrás)

Carlos, ótimo artigo!
Meus parabéns mesmo, muito didático e funcional.
Junto à observação do Flavio Vargas eis um script muito bom.

Abraço,

Líbene Fernandes
27/09/2006 6:54am (~11 anos atrás)

Carlos estou escrevendo para elogiar seu script e tb a sua iniciativa de compartilhar com os amigos do forum esse script senssacional !!!
27/06/2006 9:21pm (~12 anos atrás)

Aproveitando que você criou esse artigo super interessante você poderia também fazer alguns comentarios a respeito de segurança que envolve esse método, etc.
Até mais!
18/04/2006 8:30am (~12 anos atrás)

Meu velho, estou tendo problemas com esse código, não funciona comigo, aparece isso pra mim!

conectou com: Resource id #1
conexão: 220 mail1.salvador.ba.gov.br ESMTP
loop: 250-mail1.salvador.ba.gov.br
loop: 250-PIPELINING
loop: 250-SIZE 10000000
loop: 250-DATAZ
loop: 250-STARTTLS
loop: 250-AUTH LOGIN PLAIN
loop: 250 8BITMIME

Fatal error: Maximum execution time of 30 seconds exceeded in c:\inetpub

Já mudei o tempo do timeout e nada.

O que tá errado?
Abraços!
Anderson
24/03/2006 7:56am (~12 anos atrás)

Tiago Felipe disse:
Olá, você esqueceu de publicar para a galera como que envia vários emails ao mesmo tempo em uma única conexão...
14/02/2006 1:55pm (~12 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)