Mais Tráfego

Desenvolvimento => Desenvolvimento => PHP => Tópico iniciado por: muiomuio em 24/Mai/2012 13:04

Título: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 24/Mai/2012 13:04
Boas,

Estou a tratar de um formulário simples de envio de email em PHP.
Ocasionalmente ocorre o seguinte erro:

Warning: mail() [function.mail </pt/function.mail> ]:
SMTP server response: 550 5.7.1 Unable to relay for <email removido>
in\\nas41ent\Domains\l\cliente\user\htdocs\common\send-mail.php
<smb://nas41ent/Domains/l/cliente/user/htdocs/common/send-mail.php>  on
line71

Nota: <email removido> e /Domains/l/cliente/user  fui eu que alterei por motivos de confidencialidade.

Aqui está o código do send-mail.php

Código: [Seleccione]
function send_mail($to, $body, $subject, $fromaddress, $fromname, $attachments=false)
{
  $eol="\r\n";
  $mime_boundary=md5(time());

  # Common Headers
  $headers = "From: ".$fromname." <".$fromaddress.">".$eol;
  $headers .= "Reply-To: ".$fromname." <".$fromaddress.">".$eol;
  $headers .= "Return-Path: ".$fromname." <".$fromaddress.">".$eol;    // these two to set reply address
  $headers .= "Message-ID: <".time()."-".$fromaddress.">".$eol;
  $headers .= "X-Mailer: PHP v".phpversion().$eol;          // These two to help avoid spam-filters

  # Boundry for marking the split & Multitype Headers
  $headers .= 'MIME-Version: 1.0'.$eol;
  $headers .= "Content-Type: multipart/mixed; boundary=\"".$mime_boundary."\"".$eol.$eol;

  # Open the first part of the mail
  $msg = "--".$mime_boundary.$eol;
 
  $htmlalt_mime_boundary = $mime_boundary."_htmlalt"; //we must define a different MIME boundary for this section
  # Setup for text OR html -
  $msg .= "Content-Type: multipart/alternative; boundary=\"".$htmlalt_mime_boundary."\"".$eol.$eol;

  # Text Version
  $msg .= "--".$htmlalt_mime_boundary.$eol;
  $msg .= "Content-Type: text/plain; charset=iso-8859-1".$eol;
  $msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
  $msg .= strip_tags(str_replace("<br>", "\n", substr($body, (strpos($body, "<body>")+6)))).$eol.$eol;

  # HTML Version
  $msg .= "--".$htmlalt_mime_boundary.$eol;
  $msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
  $msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
  $msg .= $body.$eol.$eol;

  //close the html/plain text alternate portion
  $msg .= "--".$htmlalt_mime_boundary."--".$eol.$eol;

  if ($attachments !== false)
  {
    for($i=0; $i < count($attachments); $i++)
    {
      if (is_file($attachments[$i]["file"]))
      { 
        # File for Attachment
        $file_name = substr($attachments[$i]["file"], (strrpos($attachments[$i]["file"], "/")+1));
       
        $handle=fopen($attachments[$i]["file"], 'rb');
        $f_contents=fread($handle, filesize($attachments[$i]["file"]));
        $f_contents=chunk_split(base64_encode($f_contents));    //Encode The Data For Transition using base64_encode();
        $f_type=filetype($attachments[$i]["file"]);
        fclose($handle);
       
        # Attachment
        $msg .= "--".$mime_boundary.$eol;
        $msg .= "Content-Type: ".$attachments[$i]["content_type"]."; name=\"".$file_name."\"".$eol;  // sometimes i have to send MS Word, use 'msword' instead of 'pdf'
        $msg .= "Content-Transfer-Encoding: base64".$eol;
        $msg .= "Content-Description: ".$file_name.$eol;
        $msg .= "Content-Disposition: attachment; filename=\"".$file_name."\"".$eol.$eol; // !! This line needs TWO end of lines !! IMPORTANT !!
        $msg .= $f_contents.$eol.$eol;
      }
    }
  }

  # Finished
  $msg .= "--".$mime_boundary."--".$eol.$eol;  // finish with two eol's for better security. see Injection.
 
  # SEND THE EMAIL
  ini_set("sendmail_from",$fromaddress);  // the INI lines are to force the From Address to be used !
  $mail_sent = mail($to, $subject, $msg, $headers);
 
  ini_restore("sendmail_from");
 
  return $mail_sent;
}

No formulário estou a passar os seguintes paramentos:

Código: [Seleccione]
ini_set('sendmail_from',$senderEmail);  // the INI lines are to force the From Address to be used !
ini_restore('sendmail_from');

send_mail($dest,$contents,"Mensagem Online (PT)",$senderEmail,$senderName);
   

As variáveis têm todas valores. O erro não ocorre sempre mas provavelmente em 50% das vezes. Já pesquisei no Google mas não consigo intender o motivo concreto disto, talvez pela minha falta de experiência em programação.

As minhas dúvidas são simples:


Agradeço ajuda.

Mário
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 24/Mai/2012 13:12
Estás a enviar os emails através do teu PC ?
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 24/Mai/2012 13:48
Não, é através de outro servidor online.
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 24/Mai/2012 13:53
Eu uso o Swiftmailer para enviar emails "simples" e em massa também.

Mas no teu código não deverias de ter isto
Código: [Seleccione]
ini_set('SMTP', 'mail.o-teu-dominio.com');
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 24/Mai/2012 14:13
Quando coloco isso, com a alteração para o servidor de email do domínio dá outro erro:

Warning: mail() [function.mail]: SMTP server response: 504 <envisage253>: Helo command rejected: need fully-qualified hostname in \\nas41ent\Domains\l\cliente\user\htdocs\common\send-mail.php on line 72
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 24/Mai/2012 14:28
Pois isso acontece porque tens de te autenticar no servidor de email.

Eu prefiro enviar emails por SMTP, mas como disseste que não "pretendes"... o que te posso aconselhar é usar uma class de envio de emails.

O swiftmailer por exemplo podes enviar emails sem ser por SMTP, através do sendmail do php, e pode ser que resolva esse problema..
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 25/Mai/2012 11:33
Bom decidi tentar o SwiftMailer no entanto ainda sem sucesso.

Este é o código que utilizo para utilizar o SwiftMailer:

Código: [Seleccione]
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
$mailer = Swift_Mailer::newInstance($transport);

$message = Swift_Message::newInstance()
->setSubject('Contacto via site (PT)')
->setFrom(array($senderEmail => $senderName))
->setTo(array('umemail@dominio.com' => 'Mario Andrade'))
->setBody($contents)
->setReplyto($senderEmail)
->setContentType('text/html')
;

if($mailer->send($message, $failures)) {
echo "O email foi enviado com sucesso. " . date("H:i:s");
} else {
echo "Ocorreu um erro. O seu email não foi enviado. Tente novamente. \n";
print_r($failures);
}

Nesta situação não ocorrem erros. Aparece a mensagem a dizer "O email foi enviado com sucesso". No entanto com testes efectuados há praticamente 12h atrás ainda não recebi os emails.

Quando troco localhost pelo endereço do mail server fornecido pela empresa de hosting ocorre um erro. Os MX records dizem que a porta 25 é a porta correcta.

Any suggestions?
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 25/Mai/2012 11:36
Já agora, outra situação curiosa.
Tenho 2 contas de Gmail que estou a utilizar para fazer testes. Uma das contas recebe emails através de redireccionamento da outra.

Os emails estão a ir para o SPAM da conta que recebe os redireccionamentos mas não para a conta para onde é enviado o email.
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 25/Mai/2012 11:54
Mas queres enviar por SMTP, pelo sendmail ou pelo mail() do PHP?

É que é diferente.

Um pouco de código de um class que fiz para me auxiliar no envio de emails para um CMS que desenvolvi
Código: [Seleccione]
// Smtp protocol ?
//
if ( $protocol == 'smtp' ):
// Initiate the Swift Smtp Transport.
//
$SwiftTransport = Swift_SmtpTransport::newInstance($smtp_host, $smtp_port)->setUsername($smtp_user)->setPassword($smtp_pass);

// Sendmail protocol ?
//
elseif( $protocol == 'sendmail' ):
// Initiate the Swift Sendmail Transport.
//
$SwiftTransport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');

// PHP mail()
//
else:
// Initiate the Swift Mail Transport.
//
$SwiftTransport = Swift_MailTransport::newInstance();
endif;
// Initiate the Swift Mailer.
//
$this->SwiftMailer = Swift_Mailer::newInstance($SwiftTransport);

No teu código estas a tentar enviar por SMTP
Código: [Seleccione]
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
Talvez assim:
Código: [Seleccione]
$transport = Swift_MailTransport::newInstance();
Eu como prefiro usar SMTP sei que o meu código funciona bem, por acaso nunca experimentei com outro "protocolo".

Edit:

Os emails irem para a pasta SPAM, isso já me aconteceu, algumas vezes era dos headers que enviava, outras do próprio assunto do email, pois sei que no hotmail não ia para o spam mas no gmail ia...
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 25/Mai/2012 13:10
Eu tentei utilizar o método para enviar por sendmail e por mail mas esses davam-me sempre erro.

No caso do MailTransport mostrava:

Código: [Seleccione]
Array ( [0] => omeuemail@gmail.com )
No caso do Sendmailtransport
Código: [Seleccione]
Notice: Undefined variable: pipes in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 296

Warning: proc_open() has been disabled for security reasons in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 296

Notice: Undefined variable: pipes in \\nas41ent\Domains\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 297

Warning: stream_set_blocking(): supplied argument is not a valid stream resource in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 297

Notice: Undefined variable: pipes in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 298

Warning: stream_get_contents() expects parameter 1 to be resource, null given in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 298

Fatal error: Uncaught exception 'Swift_TransportException' with message 'Expected response code 220 but got code "", with message ""' in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php:422 Stack trace: #0 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php(315): Swift_Transport_AbstractSmtpTransport->_assertResponseCode('', Array) #1 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php(123): Swift_Transport_AbstractSmtpTransport->_readGreeting() #2 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\SendmailTransport.php(57): Swift_Transport_AbstractSmtpTransport->start() #3 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Mailer.php(79): Swift_Transport_SendmailTransport->start() #4 \\nas41ent\Domains\l\cliente\user\htdocs\pt\inc\contact.inc. in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php on line 422
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: muiomuio em 28/Mai/2012 10:59
Alguém já passou pelo mesmo problema? Como posso resolver isto?

Já solicitei um user e password ao cliente mas até ele me enviar o formulário não vai funcionar correctamente.
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 28/Mai/2012 14:01
Alguém já passou pelo mesmo problema? Como posso resolver isto?

Já solicitei um user e password ao cliente mas até ele me enviar o formulário não vai funcionar correctamente.

Desculpa, não tinha reparado que tinhas respondido..

Eu mais logo vou fazer uns tens a enviar email sem ser por smtp e já te digo algo..
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: ricardomoreira em 28/Mai/2012 14:35
O SwiftMailer é um componente, acaba sempre por enviar por smtp o email (nem é possível enviar emails de outra forma).

O servidor não permite relay(o que é normal), portanto ou usas autenticação, ou te permitem relay através do ip.
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 28/Mai/2012 14:56
O SwiftMailer é um componente, acaba sempre por enviar por smtp o email (nem é possível enviar emails de outra forma).

Não, ao usar o Swift_MailTransport ele usa a função mail(), não sendo necessário nenhum servidor SMTP, não é tão viável como o SMTP, dai eu ter dito que é preferível usar SMTP, sempre.
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: ricardomoreira em 28/Mai/2012 16:00
Não, ao usar o Swift_MailTransport ele usa a função mail(), não sendo necessário nenhum servidor SMTP, não é tão viável como o SMTP, dai eu ter dito que é preferível usar SMTP, sempre.

E a função mail() não usa o SMTP server? Então como é que envia o email?
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: kaydara em 28/Mai/2012 16:58
por magia :)
Título: Re: SMTP server response: 550 5.7.1 Unable to relay
Enviado por: Bruno Gaspar em 28/Mai/2012 17:07
E a função mail() não usa o SMTP server? Então como é que envia o email?

Sim usa SMTP, mas usa o servidor que está no PHP.ini e sendo assim não precisas de ser tu a definir um, era isso que eu queria dizer, mas pelos vistos não me consegui explicar bem, whatever...

Agora se o servidor onde o site/script, está instalado não estiver configurado correctamente os emails não são enviados.

Em windows até bastava ( não sei se ainda funciona ) ter localhost como SMTP que os emails geralmente eram enviados.

O problema aqui é que ele não quer definir nenhum servidor SMTP, e sim usar o "default", mas pelos vistos não está a ter sucesso..

Mas um aparte, já que percebes tanto do assunto, e que percebes dessas linguagens todas de programação, és um "webmaster", podes sempre dar umas ajudas.. não sei digo eu..

por magia :)
Também é possível..