Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

write both the subject and the body of piped email

Posted on 2013-01-11
19
Medium Priority
?
360 Views
Last Modified: 2013-01-17
<?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
0
Comment
Question by:rgb192
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 6
  • 2
19 Comments
 
LVL 80

Expert Comment

by:arnold
ID: 38770504
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.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 38770555
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.
0
 
LVL 80

Expert Comment

by:arnold
ID: 38770766
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
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:rgb192
ID: 38770878
<?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)
0
 
LVL 80

Expert Comment

by:arnold
ID: 38770920
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.
0
 
LVL 80

Expert Comment

by:arnold
ID: 38770934
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
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 38770948
@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
0
 
LVL 80

Expert Comment

by:arnold
ID: 38770987
IMHO,the testing for message data is unnecessary.  One should use the presumption that the formatting will be valid Per smtp/ESMTP.
0
 

Author Comment

by:rgb192
ID: 38771041
<?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)
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_27993541.html
0
 
LVL 80

Expert Comment

by:arnold
ID: 38771090
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.
0
 
LVL 80

Expert Comment

by:arnold
ID: 38771095
You need to,provide setup info in your related question, mailserver and its current configuration.
0
 

Author Comment

by:rgb192
ID: 38771142
<?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
0
 
LVL 80

Expert Comment

by:arnold
ID: 38771160
Run php -l <yourphp script>
0
 
LVL 80

Expert Comment

by:arnold
ID: 38771206
What is the goal of your setup?
Are you planning having this data added into a mysql database or something similar?
0
 

Author Comment

by:rgb192
ID: 38772043
>>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
0
 
LVL 80

Accepted Solution

by:
arnold earned 2000 total points
ID: 38772178
You might want to reconsider whether PHP which is geared more to a web based application.
An equivalent resource would be to use a perl script.

The same process outlined earlier.
The example below deals with getting the email message passed on the command line
cat email_message | processemail.pl

#!/usr/bin/perl

use strict;
my %header; # hash of header entries from, subject, body.
my $body=0;# marker to detect beginning of message body.
#begin loop of reading data on standard input

while (<STDIN>) { # each line is assigned to $_
chomp(); #strip crlf if present
if ( $body==1 ) {
           $header{'body'}.="$_\n";
}
elsif ( /^(From|Subject): (.*)$/i ) {
             $header{lc($1)}=$2; # all reference to from and subject hashed reference will be lower case
}
elsif (length($_) <1 ) {
             $body=1;
}

}# close while loop

#the below is just to show the data
foreach $key (keys %header) {
           print "$key: $header{$key}\n------------------------------\n";
}

Open in new window


To incorporated the mysql connection is fairly simple
Look at DBI and DBD::Mysql modules.
0
 

Author Comment

by:rgb192
ID: 38773181
i dont know perl well enough

and I think my hosting only allows php
0
 
LVL 80

Expert Comment

by:arnold
ID: 38773337
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?
0
 

Author Closing Comment

by:rgb192
ID: 38788305
even though this answer is not in php
I think perl would solve the problem

thank you
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses four methods for overlaying images in a container on a web page
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question