Did you ever think about how an email group works behind the screen? You send an email to an email address(a unique email address dedicated to an email group). It is being saved and shown on the email group’s web page and also sent out to all email addresses of members of this group. So, you will need to process the email contents to save them to DB, publish them on the webpage and send emails to others.
How PHP Email Piping Works:
In this tutorial, I will try to demonstrate the main part of a similar application as follows:
- How we can send an email’s content/information to a PHP handler on a Linux server
- How can we parse the email contents into necessary parts like sender/subject/content?
So, in order to achieve these above goals, in this pipe email to the PHP tutorial, we are going to implement the following two requirements:
- Forward an email to a PHP script.
- Retrieve the necessary contents by PHP.
Forward an email to a PHP script:
This part is pretty straightforward and doesn’t involve any coding. However, your hosting may or may not support this feature, so make sure first and contact support if it doesn’t find out whether there is any way to do so(maybe by upgrading the hosting package, etc.).
Firstly, log in to your hosting “cpanel”(Screenshots here are from host-gator).
Then, find the main section, where you should see an option named ‘Forwarder’ or similar. Enter this section, and then click on the ‘Add forwarder’ button.
This section provides you with the option to take several actions whenever an email reaches the address it handles. We will be using the “Pipe to a program” option, which is the only option to forward it to a PHP script (Just to mention, you can use other languages too, not necessarily PHP, as long as that language is supported in your server). On this option, you will have to enter the path to the PHP handler file. Here, carefully remember three things:
- If you enter the PHP script’s URL here, it won’t work. You have to provide the local path location (like “public_html/handlers/email_handler.php” or something similar).
- You should specify the PHP compiler path at the beginning (e.g., “/usr/bin/php”).
- You must ensure that the handler file has ‘execute’ permission. Otherwise, this command will not be executed.
So basically, your command string here will be like a terminal command. One example is as follows:
/usr/local/bin/php -q /home/yourdomain/public_html/handlers/mail_to_group.php
Retrieve necessary contents from email by PHP:
First, we need to get the contents. To do so, on your handler PHP file, please add the following directive at the very top of the page(it may vary for you; refer to the previous section; need the path of the PHP compiler correctly):
#!/usr/local/bin/php -q
Code language: JavaScript (javascript)
This will not be under the PHP tag; it will be outside. The PHP tag should start after it.
Now, the following code snippet will retrieve the entire content received:
$fd = fopen("php://stdin", "r");
$email_content = "";
while (!feof($fd)) {
$email_content .= fread($fd, 1024);
}
fclose($fd);
Code language: PHP (php)
After executing the code snippet, we will receive the full content in the “$email_content” variable.
Ok, so as we are now ready to get the contents from email, we can move ahead and parse it as you will receive the contents in some wired manner, not every piece differently. Wanna see what it looks like? Here is an example 🙂 :
Return-path: <senderemail@domain.com>
Received: from mail-wy0-f179.google.com ([74.125.82.179]:53218)
by gator526.hostgator.com with esmtps (TLSv1:RC4-SHA:128)
(Exim 4.69)
(envelope-from <senderemail@domain.com>)
id 1Qetnx-00061q-E5
for recieveremail@domain.org; Thu, 07 Jul 2011 14:00:05 -0500
Received: by wyh21 with SMTP id 21so939158wyh.38
for <recieveremail@domain.org>; Thu, 07 Jul 2011 12:00:06 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=mime-version:date:message-id:subject:from:to:content-type;
bh=aVvn1hmmUfdWAswRt69lpHB1V8XJtvcueoBNWIIKkV8=;
b=o1jHeVKd8ollKyXuUlTpCG+DIS8eY1qoueyTaSYTyEqIFgiynuoX1NXTKzT9+l8SU/
LCqUoNYxofOtjNhkhJ7wS5mOQvoZVEnMyONTwRrx024PJE4/Do5VLltwNjPRzqMrFPux
otJCyqSddue/SGlTPxbBXiFsD7Gzl3TcTTdz8=
MIME-Version: 1.0
Received: by 10.216.237.131 with SMTP id y3mr7444080weq.87.1310065206713; Thu,
07 Jul 2011 12:00:06 -0700 (PDT)
Received: by 10.216.237.170 with HTTP; Thu, 7 Jul 2011 12:00:06 -0700 (PDT)
Date: Fri, 8 Jul 2011 01:00:06 +0600
Message-ID: <CAAxg_qAWbasvps0Q-2FAjXZ73zWzMErztqp5U_aUYUTCsxP6LQ@mail.domain.com>
Subject: [Demo - Test Group] Test topic 6
From: "Sender Full Name" <senderemail@domain.com>
To: Email Group <recieveremail@domain.org>
Content-Type: multipart/alternative; boundary=0015175cfc46475cbc04a77f53d6
--0015175cfc46475cbc04a77f53d6
Content-Type: text/plain; charset=ISO-8859-1
another new test topic.
--
Regards
Rana
--0015175cfc46475cbc04a77f53d6
Content-Type: text/html; charset=ISO-8859-1
<br clear="all">another new test topic.<br>-- <br>Regards<br><br>Rana<br>
--0015175cfc46475cbc04a77f53d6--
Code language: HTML, XML (xml)
So, how is it? Do you like it? I hope not; I didn’t like it at all :D. So, what we need now is to parse it. Well, though you can do it yourself by spending some time, here is some ready-made code you can reuse all the time. Here we go:
//split the string into array of strings, each of the string represents a single line, received
$lines = explode("\n", $email_content);
// 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;
}
}
Code language: PHP (php)
So, after this, in the end, you should get from, to, subject, and message information in their corresponding variables.
Final Words:
Remember, your message body structure will differ slightly from one email client to another. So, you must take care of the client you are using. If you want to support most clients (Yahoo/Google/Hotmail), you may have to apply several parsing rules to the message to get the text and/or HTML version.
To debug how it’s working, you can’t do it on the browser as the contents will go from email, so you should use logging on an external text file and write a log about each step and error to get full details.
Hopefully, this pipe email to PHP tutorial will help you understand how the process works. Those are just the fundamental yet most essential parts of the way to build an email group. Let me know if you have any questions. Happy coding 🙂
sunil kumar says
Thanks for your good solution.
Rob Chadwick says
Thanks! This was very useful.
Stewart says
Very good, thanks.
I added an insert statement to drop the data from the email message including email address etc into a MySQL DB – but I get a bunch of unwanted stuff in the database appearing in the ‘message’ column which looks like headers of the email like this:
“This is a multi-part message in MIME format.
——=_NextPart_000_0101_01CEAA6E.6A79E160
Content-Type: text/plain;
charset=”iso-8859-1”
Content-Transfer-Encoding: quoted-printable
I also see quotes appearing in the other columns – how to get rid of any unwanted characters?
Md Ali Ahsan Rana says
You will need to filter them with regular expression as far I can suggest. Don’t see any other way around atm, email contents usually do have such lots of unnecessary characters for formatting probably, which differs from client to client(yahoo/gmail/outlook etc).
I have my text in spanish but when I answer the mail with outlook, I get unwanted characters where I use spanish accents á ú í é ó and in the line breack I get =20, can you give me a hint on how can I replace this charaters with the vocals and with the accent again ?
thanks for your help
NICE OWRK
Hello! I know this post is a little bit cold… but I wonder if you might help? I have implemented this code, and it works with one exception… each time a mail is successfully parsed i get 7 mails.
The processing i have programmed is supposed to identify the subject, and then add that as the body of a mail to my office email address.
only I get 7 identical emails!
Any thoughts or direction would be much appreciated!
cheers
LAex
Hi ,
Thanks for the post. It’s realy useful. I have implement this functionality and It’s working fine.
Regards,
Ashok Singh
Hi,
How can I use this to also retrieve attachments from the email?
Regards,
How can add forwaders path to capanel in framework codeigniter
You can put something like “/path/to/domain/index.php/controller/method” easily to get it working. Just imagine, .htaccess won’t have any effect as this is not going through Apache server, rather direct access.
I have implemented the script and it is working fine. The only issue is that I am trying to send an email back to the sender with an output text file of the parsed info as an attachment. The output text file looks good, however the sender is receiving the email without the attachment.
Is it possible to send an attachment email from the script itself since the sending email part with attachment works when executed separately ?
how to get attachments files??
Is it possible to pipe emails of a gmail account?
Thank you
first of all forword gmail to privet email where forword command existed then you will get, if you want dirctilly its log procedure
How to get exact messages and images? let me know..
How can I pipe to Laravel Controller? Please, help.
It did not work for me
What did not work for you? Need something more verbose to assist…
Thank you for this. It worked great for me except I can’t figure out why I can’t write any of the details to a file. I’m guessing that maybe there’s something unexpected with the file path? My script is in public_html/my_folder/pipescript.php and I’m trying to write in to a text file in public_html/my_folder/files/
so I have a code like this:
$File = “files/text-file.txt”;
$Open = fopen($File, “a+”);
fwrite($Open, “$message”);
fclose($Open);
I send a test email, I get the message back in the body as expected, but nothing writes to the file.
Any suggestions?
Hello, It resolved my problem.
Thanks