2011-02-18 148 views
5

我正在开发一个PHP应用程序,需要从电子邮件服务器检索任意电子邮件。然后,该消息被完全解析并存储在数据库中。发送邮件从测试目的

当然,我必须做很多测试,因为这个任务对于太阳下的所有不同的邮件格式来说并不是很简单。因此我开始“收集”来自某些客户的不同内容的电子邮件。

我想要一个脚本,以便我可以将这些电子邮件自动发送到我的应用程序来测试邮件处理。

因此,我需要一种发送原始电子邮件的方式 - 以便结构与来自相应客户端的结构完全相同。我有电子邮件存储为.eml文件。

有人知道如何通过提供原始的身体发送电子邮件吗?

编辑: 更具体地说:我正在寻找一种通过使用它们的源代码发送多部分电子邮件的方法。例如,我希望能够使用类似的东西(一个电子邮件与普通和HTML部分,HTML部分有一个内联附件)。

--Apple-Mail-159-396126150 
Content-Transfer-Encoding: quoted-printable 
Content-Type: text/plain; 

The plain text email! 

--=20  

=20 
=20 

--Apple-Mail-159-396126150 
Content-Type: multipart/related; 
    type="text/html"; 
    boundary=Apple-Mail-160-396126150 


--Apple-Mail-160-396126150 
Content-Transfer-Encoding: quoted-printable 
Content-Type: text/html; 
    charset=iso-8859-1 

<html><head> 
    <title>Daisies</title>=20 
</head><body style=3D"background-attachment: initial; background-origin: = 
initial; background-image: = 
url(cid:4BFF075A-09D1-4118-9AE5-2DA8295BDF33/bg_pattern.jpg); = 
background-position: 50% 0px; "> 

[ - snip - the html email content ] 


</body></html>= 

--Apple-Mail-160-396126150 
Content-Transfer-Encoding: base64 
Content-Disposition: inline; 
    filename=bg_pattern.jpg 
Content-Type: image/jpg; 
    x-apple-mail-type=stationery; 
    name="bg_pattern.jpg" 
Content-Id: <4BFF075A-09D1-4118-9AE5-2DA8295BDF33/tbg.jpg> 

/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAASAAA/+IFOElDQ19QUk9GSUxFAAEB 
[ - snip - the image content ] 
nU4IGsoTr47IczxmCMvPypi6XZOWKYz/AB42mcaD/9k= 

--Apple-Mail-159-396126150-- 
+0

你有没有找到解决这个问题的办法? – Johannes 2013-04-30 08:04:55

+0

不,不幸的不是。 – hbit 2013-04-30 22:46:36

+0

我认为你错过了主要部分,与标题标题,并与多部分,所以你的MTA会知道该怎么做。因此你的.eml文件是不完整的。在多部分电子邮件中,根部分(缺少的部分)必须包含这样的内容:“Content-Type:multipart/alternative; boundary =”____ = = _ MCPart_465790590“”。这将指定任何mimeparser至此首先阅读,依此类推。 – 2014-05-21 11:14:27

回答

0

使用PHPMailer,您可以直接设置邮件的正文:

$mail->Body = 'the contents of one of your .eml files here' 

如果您的邮件包含任何MIME附件,这将很可能无法正常工作,因为一些MIME东西都有进入邮件的标题。你不得不按摩的.eml提取那些特定的标题,并将它们添加到PHPMailer的邮件作为customheader

+0

不幸的是,这并没有多大帮助。例如,一个有趣的测试案例是Apple Mail中的附件通常具有“内联”处置,而大多数其他客户端只使用“附件”。因此,我想发送如下内容: - Apple-Mail-4-698704782 内容处置:内联; \t filename =“bla.pdf” .... 我知道某些头文件也需要进入新邮件,但这应该不是一个大问题:只过滤重要的东西(收到的,发件人,...),并再次使用剩余的标题字段。 – hbit 2011-02-18 17:46:38

0

你可以只使用telnet程序来发送这些邮件:

$ telnet <host> <port>     // execute telnet 
HELO my.domain.com      // enter HELO command 
MAIL FROM: [email protected]   // enter MAIL FROM command 
RCPT TO: [email protected]   // enter RCPT TO command 
<past here, without adding a newline> // enter the raw content of the message 
[ctrl]+d        // hit [ctrl] and d simultaneously to end the message 

如果你真的想要在PHP中执行此操作,可以使用fsockopen()stream_socket_client()系列。基本上你做同样的事情:直接与邮件服务器通话。

// open connection 
$stream = @stream_socket_client($host . ':' . $port); 

// write HELO command 
fwrite($stream, "HELO my.domain.com\r\n"); 

// read response 
$data = ''; 
while (!feof($stream)) { 
    $data += fgets($stream, 1024); 
} 

// repeat for other steps 
// ... 

// close connection 
fclose($stream); 
0

您可以在PHP函数mail中使用它。 body部分不一定只是文本,它也可以包含混合部分数据。

请记住,这是一个概念证明。 sendEmlFile函数可以使用一些更多的检查,如“文件是否存在”和“是否有边界设置”。正如你所提到的,它是用于测试/开发的,我没有包括它。

<?php 
function sendmail($body,$subject,$to, $boundry='') { 
    define ("CRLF", "\r\n"); 

    //basic settings 
    $from = "Example mail<[email protected]>"; 

    //define headers 
    $sHeaders = "From: ".$from.CRLF; 
    $sHeaders .= "X-Mailer: PHP/".phpversion().CRLF; 
    $sHeaders .= "MIME-Version: 1.0".CRLF; 


    //if you supply a boundry, it will be send with your own data 
    //else it will be send as regular html email 
    if (strlen($boundry)>0) 
     $sHeaders .= "Content-Type: multipart/mixed; boundary=\"".$boundry."\"".CRLF; 
    else 
    { 
     $sHeaders .= "Content-type: text/html;".CRLF."\tcharset=\"iso-8859-1\"".CRLF; 
     $sHeaders .= "Content-Transfer-Encoding: 7bit".CRLF."Content-Disposition: inline"; 
    } 

    mail($to,$subject,$body,$sHeaders); 
} 

function sendEmlFile($subject, $to, $filename) { 
    $body = file_get_contents($filename); 
    //get first line "--Apple-Mail-159-396126150" 
    $boundry = $str = strtok($body, "\n"); 

    sendmail($body,$subject,$to, $boundry); 
} 
?> 

更新:

一些更多的测试后,我发现所有.eml文件是不同的。可能有一个标准,但我有很多选项出口到.eml。我不得不使用一个单独的工具来创建该文件,因为默认情况下使用outlook无法保存到.eml。您可以下载example of the mail script。它包含两个版本。

简单版本有两个文件,一个是index.php文件,它发送test.eml文件。这只是一个文件,我粘贴了您在问题中发布的示例代码。

高级版本使用我创建的实际.eml文件发送电子邮件。它会从它自己的文件中获得所需的标题。请记住,这也会设置ToFrom部分邮件,所以请将其更改为与您自己的/服务器设置相匹配。

先进的代码是这样的:

<?php 
function sendEmlFile($filename) { 
    //define a clear line 
    define ("CRLF", "\r\n"); 

    //eml content to array. 
    $file = file($filename); 

    //var to store the headers 
    $headers = ""; 
    $to = ""; 
    $subject = ""; 

    //loop trough each line 
    //the first part are the headers, until you reach a white line 
    while(true) { 
     //get the first line and remove it from the file 
     $line = array_shift($file); 
     if (strlen(trim($line))==0) { 
      //headers are complete 
      break; 
     } 

     //is it the To header 
     if (substr(strtolower($line), 0,3)=="to:") { 
      $to = trim(substr($line, 3)); 
      continue; 
     } 

     //Is it the subject header 
     if (substr(strtolower($line), 0,8)=="subject:") { 
      $subject = trim(substr($line, 8)); 
      continue; 
     } 

     $headers .= $line . CRLF; 
    } 

    //implode the remaining content into the body and trim it, incase the headers where seperated with multiple white lines 
    $body = trim(implode('', $file)); 

    //echo content for debugging 
    /* 
    echo $headers; 
    echo '<hr>'; 
    echo $to; 
    echo '<hr>'; 
    echo $subject; 
    echo '<hr>'; 
    echo $body; 
    */ 

    //send the email 
    mail($to,$subject,$body,$headers); 
} 


//initiate a test with the test file 
sendEmlFile("Test.eml"); 
?> 
0

只需制作一个快速shell脚本来处理一个目录,并在需要时调用它。使用atcrontab

,因为我在做ls /mydir/cat I | awk .. | sendmail -options

http://www.manpagez.com/man/1/awk/

你也可以只使用脚本来发送emls用模板身体聊到邮件服务器..