Email to Script
From DreamHost
This article shows how to have all email sent to a shell user piped to a script in a language such as Bash, Perl, PHP and Java for processing. Software packages that are designed to react to incoming email (such as Mailman) will need this setup.
Contents |
Setting up an email and a shell account
First of all, you'll need set up a shell user and associate an email to it, because the step 2 works only with email accounts that have shell access. More specifically the email address should be associated with a USER that has shell access.
To create a new user and an email address associated to him:
- Go to DreamHost control panel.
- Open "Users => Manage Users".
- Click on "Add New User".
- Select the option "Shell account - allows FTP plus ssh/telnet shell access."
- Click on "Add User".
- In the next screen, you'll be asked to associate an email address to this user.
- Select an email address and that's it.
To create a new email address and associate it to an existing user:
- Go to DreamHost control panel.
- Open "Mail => Manage Mail".
- Click on "Create a new email address".
- Be sure to check "Deliver to this mailbox".
- Select the user in "Mailbox Login:".
- Don't worry about the other configuration, as (except explicit configuration) no email will be actually stored in your mail box.
- Click on "Create Address" and that's it.
Creating your .forward.postfix
Now, you have to create a file named .forward.postfix in your home directory. If you have ever worked with a dedicated server, you'll see that this file has the same syntax of /etc/aliases.
It's quite easy. First of all, create a file with just a line (see below what you have to write in it) that will pipe the email to your script. Then, name it .forward.postfix save it in your home directory.
By the way, do you know where's your home directory? It is /home/yourusername. For instance, if the username you just created is "john.smith", save your file as /home/john.smith/.forward.postfix. Please note that if you're logging with ftp (and not sftp), the home is just the upper directory. The same is valid if you are logged with ssh.
Piping your email
What must you write in your .forward.postfix? A line like that (quotes inclusive):
"| /home/username/scripts/myscript"
On Dreamhost you have a file server included in home directory paths. Do not include the file server name. So, if your username is mark and if your file is located here: /home/.diplodocus/mark/storedb.php, your path will be just /home/mark/storedb.php.
The | means that the email will be available in the script's standard input. What you have instead of scripts/myscript may vary. For instance:
If you want to run a Bash script, just do this:
"| /home/username/sh/myscript.sh"
If you want to run a Perl script, it's quite the same:
"| /home/username/perl/myscript"
If you want to run a PHP4 script, you need to call the php interpreter, first:
"| /usr/local/bin/php /home/username/php/myscript.php"
If you want to run a PHP5 script, you need to call the php interpreter, first:
"| /usr/local/php5/bin/php /home/username/php/myscript.php"
If you want to run a Java program, you need to call JVM first:
"| /usr/bin/java /home/username/java/myscript.class"
By the way, if don't you know where your interpreter/virtual machine, find it by typing "which php", "which java" or whatever.
Reading the standard input from your script
Now, you just have to read the standard input and do something with your mail. Here you have some lines of code that do that.
Bash
#!/bin/bash mailfile=`mktemp` cat - > $mailfile # Now you have your email on the temporary file # pointed by $mailfile and can do whatever you want. # Just don't forget to end the program with: rm $mailfile
PHP
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
//Now your mail is in $email and you can save it
//to a database or POST it to somewhere.
You can also forward all incoming mails to another mailbox using 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(trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
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";
}
}
mail("recipient@example.com", $subject, $message, "From: $from\r\n");
Java
try {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String email = "";
String str = "";
while (str != null) {
System.out.print("> prompt ");
str = in.readLine();
email = email + "\n" + str;
}
} catch (IOException e) {
}
//Now your mail is in email and you can save it
//to a database or do something else
Ruby
open("/home/#{username}/mailrecv.txt", "a") do |f|
f.puts "=" * 50
f.puts "#{Time.now.to_s}"
$stdin.each_line do |line|
f.puts line
end
f.puts
f.puts
end
Handling multiple addresses
The easiest way to handle mail received at multiple addresses through a single shell user is to forward to plus extensions of the shell user, for example:
- alice@domain -> shelluser+alice@webserver.dreamhost.com
- bob@domain -> shelluser+bob@webserver.dreamhost.com
Then the mail delivery system will pass your script an environment variable EXTENSION containing the part of the address between the + and @ signs. You can test that variable to pass the mail on to the right place.
If your application is capable of generating a Postfix-style aliases file specifying what to do for each address @domain at which it wants to receive mail (e.g., Mailman can do this), your script can use the /usr/sbin/postalias -q "$EXTENSION" /path/to/aliases command to look up the arrived mail in that file. You might also wish to write a script to translate the aliases file to a form that you can copy and paste into the "Bulk-Edit Forwarding-Only Addresses" box on the Web panel.

