Link to home
Start Free TrialLog in
Avatar of rgb192
rgb192Flag for United States of America

asked on

write both the subject and the body of piped email

<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);
date_default_timezone_set('America/Chicago');


// THIS IS THE SORT OF THING THAT MIGHT BE FOUND BY THE EMAIL PIPE
$email = <<<ENDEMAIL
MIME-Version: 1.0
Received: by 10.217.5.194 with HTTP; Tue, 23 Oct 2012 07:02:46 -0700 (PDT)
Date: Tue, 23 Oct 2012 10:02:46 -0400
Delivered-To: ray.paseur@gmail.com
Message-ID: <CALik7L8mmDoneUaWdO+Or1MJFFDQ27YJtEd7Gx_hut9Th_dSww@mail.gmail.com>
Subject: A Sample Message
From: Ray <ray.paseur@gmail.com>
To: Ray <ray.paseur@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Hello World
ENDEMAIL;


// A REGULAR EXPRESSION TO FIND THE FROM-EMAIL ADDRESS
$regex
= '#'         //REGEX DELIMITER
. 'From:'     // LITERAL STRING
. '.*?'       // ANYTHING OR NOTHING
. '\<'        // ESCAPED WICKET
. '(.*?)'     // GROUP OF CHARACTERS WITH EMAIL ADDRESS
. '\>'        // ESCAPED WICKET
. '#'         // REGEX DELIMITER
;

// A DATE PATTERN THAT WILL CREATE ISO-8601 FORMAT
$datep = 'Y_m_d_H_i_s_';

// ISOLATE THE FROM EMAIL ADDRESS
$from = preg_match($regex, $email, $matches);

// REMOVE DOTS
$from = str_replace('.', '_', $matches[1]);

// REMOVE @-SIGN
$from = str_replace('@', '_AT_', $from);

// PREFIX DATETIME AND SUFFIX FILE TYPE
$file = date($datep) . $from . '.txt';

// WRITE THE FILE
file_put_contents($file, $email);
echo "FILE: <b>$file</b> WRITTEN";

Open in new window



email pipe
want to know the subject and the body

subject would be
Subject: A Sample Message
\(*)\space : (*)

but body is not
body: sample body
Avatar of arnold
arnold
Flag of United States of America image

A single empty line (zero length) separates the body from the header of the message.
A line by line search for subject, from would

@emailarray=split(/\r*\n/,$email);
$body=0;
$messagebody='';

foreach $line (@emailarray) {
If ( $body <> 1 ) {
      $messagebody .="$line\n";
}
elseif ( $line =~ /^(From|Subject):(.*)$/i ) {
           $headers{$1}=$2;
}
elseif (length($line)<1 ) {
           $body=1;
}

}

$headers{'From'} will have the from info
Similarly for Subject.

$messagebody will contain th entire message body including any attachments.

If you are passing the data via pipe, yo would replace the foreach with a while <stdin> and line variable would either need to replaced with $_ or assign $_ to $line.

There are modules that help if needed.
The comment on line 33 no longer applies to the date pattern code on line 34.

Here is what I would do.  First, I would not assume that what you have here is actually a valid representation of an incoming email message.  To test, I would set up the email PIPE and send it several email messages.  Send from GMail, Outlook, Hotmail, etc., so you have a representative collection of messages written to files on your server.  Then read those files and look for the common and different patterns.  You may find that the body is separated from the headers by a "blank" line or you may not.  You may find other blank lines in the headers or you may not.  There really are no standards in email, so you would want to prepare the widest possible set of test cases and let those guide your research and the resulting programming.
RFC822, 2821 define email formatting.

If you see an occurrence to which ray_pasteur referenced, this means there is an errand/noncompliant email client or the message was generated as spam/virus.  You can try to make adjustments to compensate for this other non-compliant email.

http://php.net/manual/en/ref.mailparse.php
Avatar of rgb192

ASKER

<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);
date_default_timezone_set('America/Chicago');


// THIS IS THE SORT OF THING THAT MIGHT BE FOUND BY THE EMAIL PIPE
$email = <<<ENDEMAIL
MIME-Version: 1.0
Received: by 10.217.5.194 with HTTP; Tue, 23 Oct 2012 07:02:46 -0700 (PDT)
Date: Tue, 23 Oct 2012 10:02:46 -0400
Delivered-To: ray.paseur@gmail.com
Message-ID: <CALik7L8mmDoneUaWdO+Or1MJFFDQ27YJtEd7Gx_hut9Th_dSww@mail.gmail.com>
Subject: A Sample Message
From: Ray <ray.paseur@gmail.com>
To: Ray <ray.paseur@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Hello World
ENDEMAIL;


// A REGULAR EXPRESSION TO FIND THE FROM-EMAIL ADDRESS
$regex
= '#'         //REGEX DELIMITER
. 'From:'     // LITERAL STRING
. '.*?'       // ANYTHING OR NOTHING
. '\<'        // ESCAPED WICKET
. '(.*?)'     // GROUP OF CHARACTERS WITH EMAIL ADDRESS
. '\>'        // ESCAPED WICKET
. '#'         // REGEX DELIMITER
;

// A DATE PATTERN THAT WILL CREATE ISO-8601 FORMAT
$datep = 'Y_m_d_H_i_s_';

// ISOLATE THE FROM EMAIL ADDRESS
$from = preg_match($regex, $email, $matches);

// REMOVE DOTS
$from = str_replace('.', '_', $matches[1]);

// REMOVE @-SIGN
$from = str_replace('@', '_AT_', $from);

// PREFIX DATETIME AND SUFFIX FILE TYPE
$file = date($datep) . $from . '.txt';




@emailarray=split(/\r*\n/,$email);
$body=0;
$messagebody='';

foreach $line (@emailarray) {
If ( $body <> 1 ) {
      $messagebody .="$line\n";
}
else if ( $line =~ /^(From|Subject):(.*)$/i ) {
           $headers{$1}=$2;
}
else if (length($line)<1 ) {
           $body=1;
}

}











// WRITE THE FILE
file_put_contents($file, $email);
echo "FILE: <b>$file</b> WRITTEN";

Open in new window



line 51,60,62 have errors

I want to forward all my received email from gmail to the pipe email address (which gets parsed by this pipe script)
So would this make all the email in the same format (because it is gmail)
You seem to be set on attempting to reprocess the data over and over and over and over depending on how many data points you would like to extract.  Using the mailparse to extract the data or use the read in nd process the input buffer one line at a time.  A better and simpler approach depending on your mail server and whether it is passing the incoming mail through an LDA dovcot, procmail. The from and the body can be extracted and presented to your php with the from and subject as arguments to your script and the body of the message as input on stdin.
On the split error,you have to use "\r*\n" as the pattern.

Or try "\n" on which to split the line.

The hash assignment which is whatn 61 and 62 may have to be changed to an array
$headers[$1]=$2;
http://stackoverflow.com/questions/3134296/hash-tables-vs-associative-arrays-php
@arnold: I am complimented by your reference to me as ray_pasteur since that might imply a relationship to the great chemist!

@rgb192: Your success in this will be somewhat dependent on your patience and willingness to test many messages.  If your script reads from stdin here is a strategy that might be useful.

Set ob_start(), then set a counter to zero.  When your script reads a line from stdin, echo the counter and the line that was just read.  Increment the counter.  When your script detects EOF on stdin, use ob_get_clean() to capture the output buffer.  Use PHP mail() to send the output buffer to yourself.  Examine it carefully, looking for the nearly invisible \r\n character combinations.  

This is not really a question with any "answer" so much as a requirement for step-by-step programming and debugging.  We've done the best we can to equip you with the tools and process, so I'll sign off for now.  Best of luck with it, ~Ray
IMHO,the testing for message data is unnecessary.  One should use the presumption that the formatting will be valid Per smtp/ESMTP.
Avatar of rgb192

ASKER

<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);
date_default_timezone_set('America/Chicago');


// THIS IS THE SORT OF THING THAT MIGHT BE FOUND BY THE EMAIL PIPE
$email = <<<ENDEMAIL
MIME-Version: 1.0
Received: by 10.217.5.194 with HTTP; Tue, 23 Oct 2012 07:02:46 -0700 (PDT)
Date: Tue, 23 Oct 2012 10:02:46 -0400
Delivered-To: ray.paseur@gmail.com
Message-ID: <CALik7L8mmDoneUaWdO+Or1MJFFDQ27YJtEd7Gx_hut9Th_dSww@mail.gmail.com>
Subject: A Sample Message
From: Ray <ray.paseur@gmail.com>
To: Ray <ray.paseur@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Hello World
ENDEMAIL;


// A REGULAR EXPRESSION TO FIND THE FROM-EMAIL ADDRESS
$regex
= '#'         //REGEX DELIMITER
. 'From:'     // LITERAL STRING
. '.*?'       // ANYTHING OR NOTHING
. '\<'        // ESCAPED WICKET
. '(.*?)'     // GROUP OF CHARACTERS WITH EMAIL ADDRESS
. '\>'        // ESCAPED WICKET
. '#'         // REGEX DELIMITER
;

// A DATE PATTERN THAT WILL CREATE ISO-8601 FORMAT
$datep = 'Y_m_d_H_i_s_';

// ISOLATE THE FROM EMAIL ADDRESS
$from = preg_match($regex, $email, $matches);

// REMOVE DOTS
$from = str_replace('.', '_', $matches[1]);

// REMOVE @-SIGN
$from = str_replace('@', '_AT_', $from);

// PREFIX DATETIME AND SUFFIX FILE TYPE
$file = date($datep) . $from . '.txt';




@emailarray=split("\n",$email);
$body=0;
$messagebody='';

foreach $line (@emailarray) {
If ( $body <> 1 ) {
      $messagebody .="$line\n";
}
else if ( $line =~ /^(From|Subject):(.*)$/i ) {
           $headers[$1]=$2;
}
else if (length($line)<1 ) {
           $body=1;
}

}











// WRITE THE FILE
file_put_contents($file, $email);
echo "FILE: <b>$file</b> WRITTEN";

Open in new window



line 51,60,62 have still have errors





and based upon a comment,  I have a related question

parse email with php (LDA dovcot, procmail)
https://www.experts-exchange.com/questions/27993541/parse-email-with-php-LDA-dovcot-procmail.html
Sorry, strlen should be used instead of length on line 62.
51 might be an issue depending on the php version.
str_split.

Need to try to read data from stdin.
You need to,provide setup info in your related question, mailserver and its current configuration.
Avatar of rgb192

ASKER

<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);
date_default_timezone_set('America/Chicago');


// THIS IS THE SORT OF THING THAT MIGHT BE FOUND BY THE EMAIL PIPE
$email = <<<ENDEMAIL
MIME-Version: 1.0
Received: by 10.217.5.194 with HTTP; Tue, 23 Oct 2012 07:02:46 -0700 (PDT)
Date: Tue, 23 Oct 2012 10:02:46 -0400
Delivered-To: ray.paseur@gmail.com
Message-ID: <CALik7L8mmDoneUaWdO+Or1MJFFDQ27YJtEd7Gx_hut9Th_dSww@mail.gmail.com>
Subject: A Sample Message
From: Ray <ray.paseur@gmail.com>
To: Ray <ray.paseur@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Hello World
ENDEMAIL;


// A REGULAR EXPRESSION TO FIND THE FROM-EMAIL ADDRESS
$regex
= '#'         //REGEX DELIMITER
. 'From:'     // LITERAL STRING
. '.*?'       // ANYTHING OR NOTHING
. '\<'        // ESCAPED WICKET
. '(.*?)'     // GROUP OF CHARACTERS WITH EMAIL ADDRESS
. '\>'        // ESCAPED WICKET
. '#'         // REGEX DELIMITER
;

// A DATE PATTERN THAT WILL CREATE ISO-8601 FORMAT
$datep = 'Y_m_d_H_i_s_';

// ISOLATE THE FROM EMAIL ADDRESS
$from = preg_match($regex, $email, $matches);

// REMOVE DOTS
$from = str_replace('.', '_', $matches[1]);

// REMOVE @-SIGN
$from = str_replace('@', '_AT_', $from);

// PREFIX DATETIME AND SUFFIX FILE TYPE
$file = date($datep) . $from . '.txt';




@emailarray=str_split("\n",$email);
$body=0;
$messagebody='';

foreach $line (@emailarray) {
If ( $body <> 1 ) {
      $messagebody .="$line\n";
}
else if ( $line =~ /^(From|Subject):(.*)$/i ) {
           $headers[$1]=$2;
}
else if (strlen($line)<1 ) {
           $body=1;
}

}











// WRITE THE FILE
file_put_contents($file, $email);
echo "FILE: <b>$file</b> WRITTEN";

Open in new window


line 51,60,62
still same error in my code editor for
PHP Version 5.2.17
Run php -l <yourphp script>
What is the goal of your setup?
Are you planning having this data added into a mysql database or something similar?
Avatar of rgb192

ASKER

>>Run php -l <yourphp script>
I am using hostgator shared and I cant do command line


>>What is the goal of your setup?
Are you planning having this data added into a mysql database or something similar?

store subject and body in mysql
ASKER CERTIFIED SOLUTION
Avatar of arnold
arnold
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rgb192

ASKER

i dont know perl well enough

and I think my hosting only allows php
Within the shell which is where the script will run, perl is often ubiquitous. Php is built on several used languages including perl.

Hashes %variablename in perl is not included in PHP.

Depending on the mailserver and how the email is handled routed within the hosted platform is something you have to determine what you will use.

The process is straight forward, a text is being passed on standard input.  You o line by line looking for the entry you want until an single empty line which separates the header portion from the body of the message.

Do you have shell access from this hosting provider?
Avatar of rgb192

ASKER

even though this answer is not in php
I think perl would solve the problem

thank you