Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Paulo de Tarso F. M.

[Resolvido] Enviando e-mail via PHP

Recommended Posts

Fala pessoal!

 

Olha só, já li milhões de artigos sobre como enviar e-mails com PHP. Também já tentei utilizar vários scripts que auxiliam nesse envio. Só que sempre tibe os seguintes problemas:

 

1) O e-mail demora muito para chegar;

2) Só o primeiro e-mail enviado para o mesmo endereço chega ao destinatário;

3) Em alguns serviços, como o BOL, por exemplo, a mensagem é bloqueada.

 

Então, pergunto: quem utiliza esse recurso e poderia me passar um script que funcione?

 

Estou desenvolvendo um sistema, e nele há a opção de recuperação de senha. A hospedagem é na LocaWeb. Nos primeiros testes que fiz, enviei um e-mail para o Yahoo! (recebi a mensagem uma única vez), um para o Hotmail (não recebeu), e um para o BOL. No BOL, recebi a seguinte mensagem:

Undelivered Mail Returned to Sender

 

This is the Postfix program at host selva17.bol.com.br.

 

I'm sorry to have to inform you that your message could not

be delivered to one or more recipients. It's attached below.

 

For further assistance, please send mail to <postmaster>

 

If you do so, please include this problem report. You can

delete your own text from the attached returned message.

 

The Postfix program

 

<pulga.pulga@bol.com.br>: host mfbol.mail.sys.intranet[172.26.14.31] said: 554

Transaction failed (Sua mensagem foi rejeitada pelo sistema devido a

enderecos incorretos) (in reply to end of DATA command)

 

Mensagem anexa:

Recuperação de senha

 

De: ####@hm1510.locaweb.com.br

Para: pulga.pulga@bol.com.br

Cópia:

Assunto: Recuperação de senha

Data: 17/01/2009 17:11

 

Recuperação de Senha...

O engraçado é que nesse caso a mensagem que deveria chegar ficou anexada abaixo da mensagem do erro, como podem ver acima, mas por que houve esse erro exatamente? :mellow:

 

Ah! O script que utilizei quando enviei o e-mail foi esse:

mail($_POST["email"], "Recuperação de Senha", $Msg, $Header)

Depois dessa tentaiva, adicionei o parâmetro que o hinom mostra aqui nesse tópico: Enviar email para hotmail, yahoo, msn, o "-f", mas não mudou em nada.

 

Depois disso, resolvi procurar por "enviar e-mails autenticados em PHP". Aí encontrei o seguinte código nesse endereço:

 

http://www.marceloramos.blog.br/novo/Blog.php?id=37

 

Tentei utilizar (sem sucesso):

include ("smtp.php"); // É a classe que encontrei na internet

$host = "smtp.endereco.com.br"; // Host do servidor SMTP
$smtp = new Smtp($host);
$smtp -> user = "####"; // Usuário do servidor SMTP
$smtp -> pass = "####"; // Senha do usuário do servidor SMTP
$smtp -> debug = true; // Ativar a autenticação SMTP

$from = "Paulo de Tarso <pulga.pulga@bol.com.br>"; // Seu e-mail
$to = $_POST["email"]; // E-mail cadastrado
$subject = "Recuperação de senha";
$smtp -> Send($to, $from, $subject, $Msg);

if($smtp)
{
	header("Location: rec_senha.php?msg_enviada");
	exit;
}
else
{
	header("Location: rec_senha.php?failed");
	exit;
}
Após o envio, ele retornou que a mensagem foi enviada (if), mas a mensagem não chegou... Dessa vez, tentei enviar só para o BOL... Mas das outras vezes, tentei enviar para o Yahoo!, que recebeu a mensagem uma única vez, depois não recebeu mais (utilizando o primeiro script), o Hotmail não recebeu nenhuma vez e o BOL até recebeu, como coloquei acima, mas ele interpretou algum erro...

 

Será que alguém pode me ajudar? Indicar um script que funcione? Porque não é possível, como vários serviços na internet o envio de e-mails funciona corretamente e quando tentamos fazer isso não dá certo? Pôxa, vários serviços você se cadastra e não dá nem 1 minuto e você já recebeu a mensagem... Gostaria de construir um sistema que também funcionasse dessa forma (não só eu, lógico...).

 

Então, alguém pode me ajudar? Obrigado desde já!

Compartilhar este post


Link para o post
Compartilhar em outros sites

alguns servidores reconhecem remetentes tipo esse :

De: ####@hm1510.locaweb.com.br
Para: pulga.pulga@bol.com.br
(que sao subdominios numericos)

como sendo possivel spam, por isso eles bloqueiam ou colocam na pasta de spam (ou coisa do tipo, o que importa eh que nao vai pra caixa de entrada, que eh o que queremos)

 

creio que nao exista uma parametro para "passar" por isso, pois se existisse, seria usado por (, sem duvidas,) todos os crackers para enviar spam em massa

 

acho que se tu falasse com a tua hospedagem sobre esse problema do remetente, talvez resolvesse o problema parcialmente (digo parcialmente pq muito provavelmente os servidores de email "olhem" pro cabeçalho do email, o IP de onde ele veio, ou algo do tipo, mas em todo caso...)

 

jah tentou falar com a tua hospedagem sobre isso, ou ateh mesmo falar com os servidores em questao (hotmail, bol, etc)?

 

sobre a demora, isso depende, tanto do servidor que esta enviando como do servidor que esta recebendo (pense : vai que naquela hora em que tu resolveu enviar o email tanto o teu server quanto o de destino nao estavam sobrecarregados, pode acontecer http://forum.imasters.com.br/public/style_emoticons/default/pinch.gif )

 

flw xD/

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quanto à demora, é muito estranho, pois no Yahoo! sempre que fiz testes de envio de e-mails via PHP, somente uma, no máximo duas mensagens chegam... Nos outros serviços, nem chega sinal nenhum.

 

Nesse caso do BOL, pelo menos a mensagem chegou, mesmo que anexada a uma mensagem de erro, mas já é um grande avanço, digamos.

 

Quanto à hospedagem, entrarei em contato com o pessoal da LocaWeb então, para saber o que eles podem orientar em relação a isso, se há algumas medidas a serem tomadas, etc.

 

Agora, de que adianta então enviar e-mails supostamente autenticados? :mellow: Se não funcionam, então isso é propaganda enganosa... http://forum.imasters.com.br/public/style_emoticons/default/closedeyes.gif

 

Compreendo perfeitamente que se isso fosse liberado, obviamente que nossos e-mails não existiriam mais, pois seria tanto lixo, mas tanto lixo, que não teríamos mais condições de identificar se um e-mail é pessoal ou não...

 

Mas deve haver algum jeito que, pelo menos estes e-mails enviados com o intuito de recurepar a senha de acesso ao sistema sejam permitidos!

 

O que estou fazendo de errado?

 

Eu fiz testes enviando assim:

$from = "Paulo de Tarso <pulga.pulga@bol.com.br>"
Observe que o e-mail que enviou é o mesmo que recebeu... Será que o problema está aqui? Será que eu tenho que utilizar um e-mail do próprio domínio para enviar e-mails com o SMTP do próprio domínio? :mellow:

Compartilhar este post


Link para o post
Compartilhar em outros sites

teste usando esse script simplificado.

o email é enviado autenticado usando socket

 

 

 

<?php
define( 'MAIL_LIB_SMTP_AUTH',  true );			   // true: codifica em base64, false: envia como texto
define( 'MAIL_LIB_SMTP_HOST',  'smtp.bol.com.br' );  // endereço smtp
define( 'MAIL_LIB_SMTP_PORT',  25 );				 // porta smtp
define( 'MAIL_LIB_SMTP_USER',  'user' );			 // nome de usuario
define( 'MAIL_LIB_SMTP_PASS',  'pass' );			  // senha
define( 'MAIL_LIB_SMTP_BITS',  256 );				// quantidade limite de bits para fputs
define( 'MAIL_LIB_SMTP_HNAME',  'meusite.com' );	 // nome ou endereço dns do seu site (de preferencia o nome de dominio...)
define( 'SMTP_Mail_Chunk', 60 );					 // nao ultrapasse 79 caracteres. por segurança, defina abaixo do limite.


$mail['subject']	  = 'teste';			 // assunto do email
$mail['body']		 = 'OK' . time();	   // conteúdo do email

$mail['fromName']	 = 'meu site';		  // nome do remetente
$mail['fromEmail']	= 'email@meusite.com'; // email do remetente
$mail['toName']	   = 'fulano da silva';   // nome do destinatário
$mail['toEmail']	  = 'email@foo.bar';	 // email do destinatário
$mail['Reply-To']	 = $mail['fromEmail'];  // e-mail de retorno, caso o destinatário queira responder
$mail['Return-Path']  = $mail['Reply-To'];   // alternativa para Reply-to, alguns servers não reconhecem Return-Path mas reconhecem Reply-To, ou vice-versa.


$mail['MIME-Version']			  = '1.0';	 // versão mime do padrão utilizado no email (1.0 é o padrão estável e recomendado)
$mail['Content-Transfer-Encoding'] = 'base64';  // codificação dos dados.
$mail['Content-Type']			  = 'text/plain';
$mail['charset']				   = 'utf-8';




$p = 'fromName';  $mail[$p] != $mail['fromEmail'] ? $mail[$p] = StrCharset( $mail['charset'], $mail[$p] ):'';
$p = 'toName';	$mail[$p] != $mail['toEmail']   ? $mail[$p] = StrCharset( $mail['charset'], $mail[$p] ):'';
$p = 'Content-Transfer-Encoding';
$mail[$p] == 'base64' ? $mail['body'] = chunk_split( base64_encode( $mail['body'] ), SMTP_Mail_Chunk ):'';


$mail['headers']	  = 'From: ' . $mail['fromName'] . '<' . $mail['fromEmail'] . '>';
$mail['headers']	 .= PHP_EOL . 'To: ' . $mail['toName'] . '<' . $mail['toEmail'] . '>';
$mail['headers']	 .= PHP_EOL . 'Subject: ' . $mail['subject'];
$mail['headers']	 .= PHP_EOL . 'Reply-To: ' . $mail['Reply-To'];
$mail['headers']	 .= PHP_EOL . 'Return-Path: ' . $mail['Return-Path'];
$mail['headers']	 .= PHP_EOL . 'MIME-Version: ' . $mail['MIME-Version'];
$mail['headers']	 .= PHP_EOL . 'Content-Type: ' . $mail['Content-Type'] . ';  charset=' . $mail['charset'];
$mail['headers']	 .= PHP_EOL . 'Content-Transfer-Encoding: ' . $mail['Content-Transfer-Encoding'];



$rs = auth( $mail );
print_r( $rs );







	function StrCharset( $charset, $str )
	{
		return '=?' . $charset . '?B?' . base64_encode( $str ) . '?=';
	}

	function auth( $mail )
	{

		$talk		= false;
		$rs['talk']  = false;
		$rs['error'] = false;
	
		$user	 = MAIL_LIB_SMTP_USER;
		$pass	 = MAIL_LIB_SMTP_PASS;
	
		$bitsLen  = MAIL_LIB_SMTP_BITS;

		if( $sock = fsockopen( MAIL_LIB_SMTP_HOST, MAIL_LIB_SMTP_PORT ) )
		{

			fputs( $sock, 'HELO ' . MAIL_LIB_SMTP_HNAME . PHP_EOL );
			$ret = fgets( $sock, $bitsLen );

			if( $user )
			{
	
				if( MAIL_LIB_SMTP_AUTH )
				{
	
					fputs( $sock, 'auth login' . PHP_EOL );
					$ret .= fgets( $sock, $bitsLen );
	
					fputs( $sock, base64_encode($user) . PHP_EOL );
					list( $uc, $us ) = explode( ' ', fgets( $sock, $bitsLen ) );
					$ret .= $uc .' ' . base64_decode( $us ) . PHP_EOL;
	
					fputs( $sock, base64_encode( $pass ) . PHP_EOL );
					list( $pc, $ps ) = explode( ' ', fgets( $sock, $bitsLen ) );
					$ret .= $pc . ' ' . base64_decode( $ps ) . PHP_EOL;
	
				}else{

					// plain

					fputs( $sock, 'auth plain' . PHP_EOL );
					$ret .= fgets( $sock, $bitsLen );

					fputs( $sock, base64_encode( '^@' . $user .'^@'. $pass ) );
					$ret .= fgets( $sock, $bitsLen );
	
				}
	
			}
	
			fputs( $sock, 'MAIL FROM: <' . $mail['fromEmail'] . '>' . PHP_EOL );
			$ret .= fgets( $sock, $bitsLen );
	
			fputs( $sock, 'RCPT TO: <' . $mail['toEmail'] . '>' . PHP_EOL );
			$ret .= fgets( $sock, $bitsLen );
	
			fputs( $sock, 'DATA' . PHP_EOL );
			$ret .= fgets( $sock, $bitsLen );
	
			fputs( $sock, $mail['headers'] . PHP_EOL . $mail['body'] . PHP_EOL . '.' . PHP_EOL );
			$r	= fgets( $sock, $bitsLen );
			$ret .= $r;
	
			fputs( $sock, 'QUIT' . PHP_EOL );
			$ret .= fgets( $sock, $bitsLen );
	
			fclose( $sock );

			$rs['talk'] = $ret;

		}else{
	
			if( $talk )
			{
				$rs['error'] = 1; // 'Could not connect to host'
			}else{
				$rs['error'] = $php_errormsg;
			}

		}

		return $rs;
	
	}

?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá hinom!

 

Obrigado pelo script, fiz alguns testes e funcionou com a seguinte alteração: estranhamente, com a função StrCharset() ali onde está não funcionou, informou que a função não existia (o erro ocorreu nessa linha abaixo)

$p = 'fromName';  $mail[$p] != $mail['fromEmail'] ? $mail[$p] = StrCharset( $mail['charset'], $mail[$p] ):'';
Então eu coloquei a função antes dessa linha e funcionou... http://forum.imasters.com.br/public/style_emoticons/default/assobiando.gif

 

Agora, pode me explicar que usuário e senha são essas que tenho que colocar (e para quê)?

define('MAIL_LIB_SMTP_USER', 'user'); // nome de usuario
define('MAIL_LIB_SMTP_PASS', 'pass'); // senha
Eu deixei vazio (entre aspas apenas), e não retornou erro.

 

Agora, veja o retorno:

Array
(
	[talk] => 220 hm1089.cl01.mobimail.com ESMTP CommuniGate Pro 5.2.9
250 hm1089.cl01.mobimail.com is pleased to meet you
250 contato@cesarcruz.com.br sender accepted
250 email@cesarcruz.com.br will leave the Internet
354 Enter mail, end with "." on a line by itself
250 4903098 message accepted for delivery

	[error] => 
)
Pode me explicar o que significam estas linhas? Assim, o que elas realmente querem dizer? :mellow:

 

Bom, estes testes deram certo só quando enviei para o e-mail do próprio domínio. Ao tentar enviar para meu e-mail do Yahoo!, apareceu o seguinte:

Array
(
	[talk] => 220 hm1089.cl01.mobimail.com ESMTP CommuniGate Pro 5.2.9
250 hm1089.cl01.mobimail.com is pleased to meet you
250 contato@cesarcruz.com.br sender accepted
473 x_ptfm@yahoo.com.br relaying prohibited. You should authenticate first
554 no valid RCPT address specified
501 Unknown command

	[error] => 
)
Aí, tentei enviar para o BOL, e apareceu o seguinte:

Array
(
	[talk] => 476 connections from your host are denied

	[error] => 
)
O que tenho que fazer então para que os e-mails enviados para os serviços gratuitos sejam entregues?

Compartilhar este post


Link para o post
Compartilhar em outros sites

a funcao auth retorna um array com dois indices

 

"talk" e "error"

primeiramente verifique o valor de "error", é booleano ( true ou false )

se for true, um erro ocorreu

se for false a script funcionou normalmente.

 

mas verifique o valor de talk, é a resposta que o servidor do destinatário retorna.

 

Array
(
	[talk] => 
	[error] => 
)

 

 

 

define('MAIL_LIB_SMTP_USER', 'user'); // nome de usuario
define('MAIL_LIB_SMTP_PASS', 'pass'); // senha

para enviar email autenticado precisa de uma conta de email válida..

quando você enviou para o email do yahoo, foi recusado. Veja que a resposta do server do yahoo diz que não aceita emails enviados sem autenticação.

 

no lugar de "user" coloque o nome de usuario da sua conta de email

em "pass" coloque a senha da sua conta.

 

 

 

quanto às funções, coloque-as sempre antes de fazer uma chamada.

por isso ocorreu o erro ali com o StrCharset.

 

coloquei aí em baixo porque fiz sem testar. só fui digitando.

 

 

coloque aí o user e senha e faça o teste que com cerveja vai funcionar.

 

falow

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas em todos os casos de tentativa, não retornou erro nenhum... Observe os códigos que colei no post anterior, o "error" está em branco. Eu só acessei o código fonte, copiei e colei...

 

Mas quanto ao usuário e senha: o usuário deve ser o e-mail completo? Exemplo: paulo@dominio.com.br? Porque eu tentei colocar só o usuário, sem o "@" e o domínio, na primeira tentativa, e ele informou que o usuário e senha estavam incorretos... Mas mesmo assim, como enviei para um e-mail do próprio domínio, a mensagem chegou.

 

E aquela mensagem quando tentei enviar para o BOL?

[talk] => 476 connections from your host are denied

Outra coisinha: quando eu conseguir fazer funcionar, posso substituir a parte que imprime esse array (com o print_r) por uma verificação se o e-mail foi enviado ou não, redirecionando para uma página específica onde exibirei uma mensagem para o usuário, do tipo "Mensagem enviada!" ou "Falha no envio, tente novamente."? Se puder, que variável devo verificar para efetuar o rdirecionamento? Algo do tipo?

if($emailEnviado) { header("Location: pagina.php?msgEnviada"); } else { header("Location: pagina.php?erro"); }
Qual a variável devo verificar?

 

Valeu!

 

(Obs.: Não poderei testar agora, só à noite...)

Compartilhar este post


Link para o post
Compartilhar em outros sites

o indice "error" controla apenas se os parâmetros estão sendo passados corretamente

 

não retorna o status de resposta do servidor que recebe o email

 

 

usuário e senha...

é o nome de usuario da conta de email

 

Se você usa conta do gmail por exemplo, e sua conta é fulano@gmail.com o nome de usuario é "fulano"

Se usa hotmail, o nome de usuário é fulano@hotmail.com

Enfim, cada serviço tem um regra. veja qual a regra do servidor pop do seu host.

Já configurou uma conta de email no outlook express ? é a mesma coisa.

 

 

Mas mesmo assim, como enviei para um e-mail do próprio domínio, a mensagem chegou.
se enviar para o mesmo dominio, nao precisa autenticar, ele envia sem autenticação, por isso o email chegou.. quer dizer.. nem foi, pois nem saiu do lugar.

 

476 connections from your host are denied
São filtros anti-spam. O seu servidor está na lista de spammers do BOL. Os seus testes ultrapassaram a quota de conexões negadas dos servidores do BOL.

Seria melhor consultar o suporte técnico e explicar o motivo para liberarem, senão podem continuar bloqueando mesmo se enviar autenticado. Isso pode ter certeza, é dor de cabeça...

Compartilhar este post


Link para o post
Compartilhar em outros sites

esqueci de explicar

 

 

print_r é somente para testar..

$rs = auth( $mail );
print_r( $rs );

use assim:

 

 

$rs = auth( $mail );
if( $rs['error'] )
{
	// algum erro ocorreu
}else{
   // aparentemente nenhum erro
   // por precaução, verifique o valor de $rs['talk']
}

quando envia com sucesso, o servidor que recebe responde alguma resposta

 

veja uma tabela de codigos de resposta SMTP

http://www.xequte.com/support/maillistking/smtperrors.html

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fala hinom!

 

Olha só, fiz algumas alterações e agora está funcionando direitinho! http://forum.imasters.com.br/public/style_emoticons/default/joia.gif

 

Fiz algumas alterações, veja abaixo o que fiz e as mensagens retornadas:

 

1) Na função auth(), temos o seguinte:

$talk = false;
$rs['talk'] = false;
$rs['error'] = false;
Eu alterei as duas últimas linhas para true

 

2) Lá no nome do usuário e senha, eu coloquei o nome do usuário completo, com domínio:

define('MAIL_LIB_SMTP_USER', 'contato@cesarcruz.com.br'); // nome de usuario
3) Após a primeira alteração, o código exibido após o envio do e-mail passou a mostrar o seguinte na última linha:

[error] => 1
Lembra que antes não aparecia nada? :mellow: Esse erro "1" na verdade é um erro mesmo? Porque todos os e-mails que enviei, apareceu esse "1", mas eu recebi todos os e-mails enviados (enviei para o Yahoo!, para o BOL, para o Hotmail e para um e-mail do próprio domínio).

 

Bom, é isso. Só não testei ainda substituir a parte do print_r pelo header com o redirecionamento... Mas depois eu vejo isso.

 

Muito obrigado hinom! Esse material pode ajudar muita gente, além de mim, que queiram enviar e-mails autenticados via PHP.

 

Um grande abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

hinom, meu amigo, olha eu de volta!

 

Bom, muito estranho, o envio do e-mail está sendo feito normalmente, mas ele sempre retorna o erro "1"! Ou seja, não consigo utilizar uma verificação do tipo "se o e-mail foi enviado, retorne o aviso informando que foi enviado, senão, informe que não foi enviado". Retornar ele até retorna, mas ele sempre retorna erro porém envia o maledeto do e-mail! :angry:

 

Eu já não sei mais o que mudar para ver se funciona isso, já removi trechos de códigos, e nada! Enfim, já não sei mais no que mexer!

 

Até tentei estudar o script que me passou, mas meus conhecimentos básicos não me permitem ir tão longe assim... http://forum.imasters.com.br/public/style_emoticons/default/closedeyes.gif Não existe nenhuma documentação que fala sobre esse script? Ou algum tutorial que explica as funções utilizadas, sei lá, alguma coisa que possa me ajudar a decifrar esse enigma?!

Compartilhar este post


Link para o post
Compartilhar em outros sites

é por causa da alteração que você fez..

 

você trocou os valores de dos arrays e nao precisava pois servem para o funcionamento do script

 

Eu alterei as duas últimas linhas para true

coloque:

$rs['talk'] = false;
$rs['error'] = false;

Compartilhar este post


Link para o post
Compartilhar em outros sites

lembrando que o script está num formato bruto

 

precisa checar os retornos e no controle de fluxo de repostas fazer tratamento de possíveis erros também.

 

 

a partir de um script simples como esse é possível entender melhor o funcionamento, por isso, prefiri não passar um script mais avançado como o phpMailer, por exemplo

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.