It's actually quite simple: I want to pass all incoming emails to a PHP-script, but only as a copy, the original email shall still be delivered to the mailbox as usual.

I just can't seem to get it working. I've tried the following

(1) Created a catchall-alias (mysql):

@mydomain.tld   pipe@mydomain.tld

(2) Created a regex-transport mapping in /etc/postfix/mailpipe.cf (basically means: apply to all emails of mydomain.tld)

/.*@mydomain\.tld/   mailpipe:

(3) integrated it all in /etc/postfix/main.cf:

transport_maps = ... regexp:/etc/postfix/mailpipe.cf
virtual_alias_maps = proxy:mysql:/etc/postfix/....

(4) Added the transport to /etc/postfix/master.cf:

mailpipe   unix  -       n       n       -       -       pipe
  flags=FR user=localuser argv=/path/to/my/script.php
  ${nexthop} ${user}

The script:

#!/usr/bin/php -q
  $file = '/home/localuser/pipe/log.log';
  $input = file_get_contents('php://input');
  file_put_contents($file, $input, FILE_APPEND | LOCK_EX);

So the setup seems to work, the script is hit on incoming emails, but the $input is empty (works with any other string though). The email is being processed and then removed/discarded. So here are my 2 questions:

  1. How can I access the contents of the email from the script?

  2. How can I prevent the email from being discarded after processing? Is there a way to pass one copy to the inbox as usual and another one to the script for processing?

  • Does it help if you don't omit the closing PHP tag in your script? It is currently missing. – gparent Sep 5 '13 at 14:54
  • @gparent Nope, still the same result... But thanks! – Quasdunk Sep 5 '13 at 15:00
  • Fixed the previous problem with the syntax errors and edited my post accordingly (seems like some php binaries were messed up), but then there's a new one... :) – Quasdunk Sep 5 '13 at 15:53
  • I still see a missing PHP tag. Perhaps it doesn't solve your problem, but unless you're 100% certain it's unnecessary I'd include it in order not to confuse people in the future. Unless I'm grossly misunderstanding what you're doing and they shouldn't be there. – gparent Sep 5 '13 at 19:23
  • @gparent Adding a closing PHP tag is NOT necessary, and for a file that only contains PHP code, it's a best practice to leave it off. See stackoverflow.com/questions/3219383/… for more info if desired. – Brian Showalter Sep 5 '13 at 19:51

This can be accomplished by using recipient_bcc_maps to BCC all emails to a local-only address that is configured to route to your script.

Add the following line to /etc/postfix/recipient_bcc. Run "postmap /etc/postfix/recipient_bcc" after editing is done. This tells Postfix to BCC all emails where the domain matches "@yourdomain.tld" to the "robotscript@localhost" address.

@yourdomain.tld  robotscript@localhost

Add the following line to /etc/postfix/transport. Run "postmap /etc/postfix/transport" after editing is done. This tells Postfix that emails destined for the "robotscript@localhost" address are to be delivered directly on this server, and not relayed elsewhere.

robotscript@localhost :

Add the following lines to /etc/postfix/main.cf so that Postfix will use the configurations entered above.

recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
transport_maps = hash:/etc/postfix/transport

Make sure that the "mydestination" parameter in /etc/postfix/main.cf includes the "localhost" value.

Add the following line to /etc/aliases. Run "postalias /etc/aliases" after editing is done. This is what actually passes emails destined for "robotscript@localhost" to your PHP script. Your script should be set up to read the contents of the email from STDIN.

robotscript: "|/path/to/your/php_script.php"

Restart Postfix, and all your emails should then be copied to your script as well as delivered to the original recipient address.

| improve this answer | |
  • Thank you so much! This is exactly what I was looking for! You really made my day :) But there still seem to be some issues with reading the contents of the email. I'm reading it with php://stdin now and it works fine from the command line: > echo "test" | php -q /home/localuser/pipe/pipe.php writes "test" to the file. But on receiving mail, nothing happens, even though the mail.log tells me, that the email has been passed to the script and it passed with no errors. But I guess I will figure that out somehow, too, I'm probably just missing something stupid... :) Anyway: Thank you! – Quasdunk Sep 5 '13 at 20:07
  • Glad to help. :) As for the script, I noticed you used the "php" command to run your script in your comment above. If that script doesn't contain a shebang on the first line as the script in your initial question did, then perhaps one needs to be added? That, or set the line in /etc/aliases to "|/usr/bin/php -q /path/to/your/php_script.php". – Brian Showalter Sep 5 '13 at 20:37
  • Nope, that was not it either. Found the solution here: stackoverflow.com/questions/7855091/… - the postfix default user "nobody" was not privileged to run the script... Why the heck did this fail so silently?! Anyway, now it's working like a charm :) Thanks again for your effort! – Quasdunk Sep 6 '13 at 11:08
  • Ah! That makes sense. Glad you were able to find a solution. – Brian Showalter Sep 6 '13 at 12:26
  • This doesn't work for me. I have my configuration saved in Postgresql. Is there any way to test the config? – T.Coutlakis Aug 15 '16 at 0:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.