I am trying to write a script which will be used to get emails piped to it and then forwarded to another email address with a different "From" field
#!/usr/local/bin/php56 -q
<?php
$fd = fopen("php://stdin", "r");
$message = "";
while (!feof($fd)) {
$message .= fread($fd, 1024);
}
fclose($fd);
//split the string into array of strings, each of the string represents a single line, received
$lines = explode("\n", $message);
// initialize variable which will assigned later on
$from = emailFrom#example.com;
$subject = "";
$headers = "";
$message = "";
$is_header= true;
//loop through each line
for ($i=0; $i < count($lines); $i++) {
if ($is_header) {
// hear information. instead of main message body, all other information are here.
$headers .= $lines[$i]."\n";
// Split out the subject portion
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
//Split out the sender information portion
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
} else {
// content/main message body information
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$is_header = false;
}
}
mail( "emailTo#example.com", $subject,$message, $from );
?>
this script is getting us bounced emails with delivery failure message "local delivery failed".
What am I doing wrong?
You need to verify that it's parsing the incoming messages properly. Add this line following your mail() command to verify the script's output:
echo "Subject:".$subject."\nFrom:".$from."\nMessage:".$message;
Then pass the script a test email from the command line and watch the screen. Something probably isn't getting parsed correctly.
Related
I am trying to forward all emails from support#example.com to PHP script to be inserted into MySql.
My script works, but I have two issues.
The from email address shows the name of the sender, not the email address.
The email body content shows for eg.
--00000000000095430105a9347fe3
Content-Type: text/plain; charset="UTF-8"
This is a test email
--00000000000095430105a9347fe3
Content-Type: text/html; charset="UTF-8"
This is a test email
--00000000000095430105a9347fe3--
Instead of just the body of the email This is a test email
This is my code:
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
// content/main message body information
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
I have tried
$message = imap_fetchbody($mbox,1,'1');
$message = strip_tags(quoted_printable_decode(imap_fetchbody($mbox,1,"1")));
$message = strip_tags($message, '<body>');
$message = explode(">", $message);
$message = explode("<", $message[1]);
$message = str_replace(" ", "", $message[0]);
$message = html_entity_decode($message);
$message = trim($message);
And I tried this but could not figure out how to make it work:
$emailnumberPattern = "--[0]{12}";
$replacement = " ";
preg_replace($emailnumberPattern, $replacement, $string);
$message .= $lines[$i]."\n";
Any help would be welcome to show the sender email as well as remove unwanted content from the email body.
Parsing emails is no easy task that can be solved with a couple of regexes. You should definitely use a dedicated extension or program. Also, you shold avoid loading the entire message into a single string (or array).
This one is just a single composer command away: composer require zbateson/mail-mime-parser.
require __DIR__ . '/vendor/autoload.php';
$handle = fopen('php://stdin', 'r');
$message = \ZBateson\MailMimeParser\Message::from($handle);
fclose($handle);
$from = $message->getHeaderValue('from');
$body = $message->getTextContent();
That said, you can obtain some results with your code, which I've modified as little as possible:
$lines = explode("\n", $email);
// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
if (preg_match('/Content-Type: text\/plain; charset=/', $lines[$i])) {
$m = true;
continue;
}
if (preg_match('/Content-Type:/', $lines[$i])) {
$m = false;
}
if ($m) {
$message .= $lines[$i]."\n";
}
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
if (preg_match('/ <(.*)>/', $from, $matches)){
$from = $matches[1];
}
Those results are not guaranteed, and highly dependent on the input format. For a robust solution, please use a well-tested parser.
I am trying to email piping with cpanel and PHP script. Its working fine. I am looking for get From Address, Subject and Message from received email. My script is like below
#!/usr/bin/php -q
<?php
/*$fd = fopen( "php://stdin", "r" );
$message = "";
while ( !feof( $fd ) )
{
$message .= fread( $fd, 1024 );
}
fclose( $fd );*/
$fd = fopen("php://stdin", "r");
$message = "";
while (!feof($fd)) {
$message .= fread($fd, 1024);
}
fclose($fd);
//split the string into array of strings, each of the string represents a single line, received
$lines = explode("\n", $message);
// initialize variable which will assigned later on
$from = "";
$subject = "";
$headers = "";
$message = "";
$is_header= true;
//loop through each line
for ($i=0; $i < count($lines); $i++) {
if ($is_header) {
// hear information. instead of main message body, all other information are here.
$headers .= $lines[$i]."\n";
// Split out the subject portion
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
//Split out the sender information portion
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
} else {
// content/main message body information
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$is_header = false;
}
}
$to = 'myemail#gmail.com';
$subject = 'the subject';
$message1 = "You have new message from :".$from. "and message is" .$message;
$headers = 'From: webmaster#mydomain.com' . "\r\n" .
'Reply-To: webmaster#mydomain.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message1, $headers);
?>
I am getting result in my email like below
You have new message from :FirstName LastName <senderemail#gmail.com>and message is--00000000000045a1e5059ef97af8
Content-Type: text/plain; charset="UTF-8"
This is Body text Message
--00000000000045a1e5059ef97af8
Content-Type: text/html; charset="UTF-8"
<div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif;font-size:large">This is text<br></div></div>
--00000000000045a1e5059ef97af8--
However its contain unnecessary words in it. I want plain output like below
You have new message from :senderemail#gmail.com and message is This is Body text Message
Sorry I am new in PHP and does not able to solve the issue. Let me know if anyone can help me for extract and get output like this.
Thanks!
I am writing a PHP script to get email piped to the script and save it to the database.. I have succeeded in get coming emails.. But i am still struggling with how to get rid of raw contents that comes with the email.. What technique can i use to get only the message either the text version or the html version
This is the example of email i receive currently
Content preview: Mine Mine [...]
Content analysis details: (-0.1 points, 5.0 required)
pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(techservice4real[at]gmail.com)
0.0 HTML_MESSAGE BODY: HTML included in message
-0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's
domain
0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid
-0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
-0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2)
[209.85.222.182 listed in wl.mailspike.net]
X-Spam-Flag: NO
--000000000000c1a52105822cd389
Content-Type: text/plain; charset='UTF-8'
Mine
--000000000000c1a52105822cd389
Content-Type: text/html; charset='UTF-8'
<div dir='ltr'>Mine<br></div>
--000000000000c1a52105822cd389--
This is currently the code i am using to get the email
#!/usr/local/bin/php -q
<?php
require_once('inc/init.php');
//chdir(dirname(__FILE__));
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
// if(strlen($email)<1) {
// die();
// }
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$to="";
$subject = "";
$headers = "";
$message = "";
$bodyContent = "";
$myBody = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
$data = explode("\n", $message);
mail("boomztechs#gmail.com", "You Have One new Email Piped", "A New Mail Message just Piped to you) ".$message);
Your response is highly appreciated thanks..
I'm using email piping to save data sent by an end user through email; however, one requirement is that the user sends a text file with additional information.
Therefore, I need the email piping script to get the attachment, and read it. It's a simple text (.txt) document, base64 encoding, example:
Content-Type: text/plain; charset=UTF-8
Content-ID: <text_doc>
Content-Location: text_doc.txt
Content-Transfer-Encoding: BASE64
This is my Email Piping script. The email passes through fine, I just need to get the attachment.
<?php
chdir(dirname(__FILE__));
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
if(strlen($email)<1) {
die();
}
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$to="";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
Im trying to setup a program that will accept an incoming email and then break down the "sender" and "message" into php variables that i can then manipulate as needed, but im unsure where to start.
I already have the email address piped to the php file in question (via cpanel)
Start with:
$lines = explode("\n",$message_data);
$headers = array();
$body = '';
$in_body = false;
foreach($lines as $line)
{
if($in_body)
{
$body .= $line;
}
elseif($line == '')
{
$in_body = true;
}
else
{
list($header_name,$header_value) = explode(':',$line,2);
$headers[$header_name] = $header_body;
}
}
// now $headers is an array of all headers and you could get the from address via $headers['From']
// $body contains just the body
I just wrote that off the top of my head; haven't tested for syntax or errors. Just a starting point.
Have a look at the eZ Components ezcMailParser class. You'll need to implement an interface - ezcMailParserSet - to use it.
Here is working solution
#!/usr/bin/php -q
<?php
// read from stdin
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
echo $from;
echo $subject;
echo $headers;
echo $message;
?>
Works like a charm.