How to Run a script when a mail arrives in mail server? (Debian)

28,692

Solution 1

Looks like someone else has already answered this but thought I'd put down a specific answer for you.

I would use procmail and use a recipe in your .procmailrc similar to this:

#turn this off when you're finished testing :)
VERBOSE=on
LOGFILE=/home/user/procmail.log

:0 c #the c means continue on after this recipe is parsed
| /path/to/your/script

You'll also need a default recipe at the bottom to direct the mail into your maildir.

Solution 2

You can use /etc/aliases to pipe email directly to a program to process, so if you wanted to run a script to process all email to [email protected] you would put this line in /etc/aliases (works for postfix, sendmail, etc.):

test:              "|/usr/local/bin/processtestemail.php"

Then run "newaliases" to update the database.

Then make sure you have a working program in /usr/local/bin named processtestemail.php.

It can be written in php, bash, perl, python, whatever you want and whatever you have for an interpeter. You could even launch a compiled binary written in c/c++, etc.

There were suggestions for using procmail above, it is a great product, but honestly what I have presented is the fastest and simplest solution and it works in more versions of *NIX with more mailers than any other.

Too, non of the other answers really tell you how to process the inbound message and so you would, in your script read input from standard "in" (stdin) and then parse that data using whatever algorithms you may have to process it properly as follows:

<?php

$fd = fopen('php://stdin','r');
if ($fd) then
    {
    $email = '';                         // initialize buffer
    while (!feof ($fd))                  // read as long as message
        {
        $rawemail .= fread($fd,1024);    // read up to 1K at a time
        ProcessTheMessageChunk($rawEmail);
        }
    fclose($fd);                         // done so close file handle
    $fd=NULL;                            // clear file handle
    }
else
    {
    print("ERROR:  Could could open stdin...");
    };

/* 
** Now write your code to fill in the function ProcessMessageChunk()
** and then process the data you have collected altogether using
** that function/subroutine.
*/

?>

Solution 3

Here's a good howto on incoming mail processing. The simplese thing to do is to use the .forward mechanism as described, to pipe a message through a script. Create a mode 600 .forward file in the user's home directory and put a pipe to a script in it:

"|$HOME/bin/your.program -and some arguments" 

However, you should look at using procmail instead, as that howto details. Procmail gives you a lot of advantages, such as more sophisticated logging and mail processing. Here's a simple .procmailrc example (again from that same howto):

:0
* !^FROM_DAEMON
* !^FROM_MAILER
* !^X-Loop: [email protected]
| $HOME/bin/my.script 

which has some nice features, like the ability to detect and stop mail loops.

Solution 4

The question was "how do I run a script when mail arrives", not how to use procmail, not a bunch of other things. All the other answers are very helpful, but they require installation of other software such as procmail or are MTA dependent.

The most generic answer that works on all flavors of *NIX no matter what mail transfer agent (MTA) you have (e.g., sendmail, postfix, exim, etc.) is to put a PIPE on an alias to a script in /etc/aliases like so:

mytest:              "|/usr/local/bin/mytestscript -args"

Then, any message that gets sent to "mytest@" will get routed to the script.

Now, I am a huge fan of procmail and other solutions and am not trying ot take away from all the great info presented.

Solution 5

If your server uses Dovecot you could do the following:

  1. create your script (ie. mail_processor.py) in the /usr/lib/dovecot/sieve-execute/ directory:

    #!/usr/bin/python3
    from sys import stdin
    with open('/var/log/mail_processor.log', 'a') as logfile:
        for line in stdin:
            print(line.rstrip(), file=logfile)
    
    • ensure your script and target files have correct permissions:

      $ chmod +rx /usr/lib/dovecot/sieve-execute/mail_processor.py
      $ chmod 0777 /var/log/mail_processor.log
      
  2. enable the sieve_extprograms plugin:

    • modify \etc\dovecot\conf.d\90-sieve.conf's plugin section with the following:

      sieve_extensions = +vnd.dovecot.execute
      sieve_plugins = sieve_extprograms
      sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute
      
    • reload dovecot:

      $ service dovecot restart
      
  3. create sieve filter (ie. in Roundcube goto settings -> filters -> actions -> edit filter set):

    require ["vnd.dovecot.execute"];
    # rule:[mail processing]
    if true
    {
        execute :pipe "mail_processor.py";
    }
    

Now all mail delivered to mailboxes with this sieve filter will be piped through mail_processor.py for action.

Pigeonhole Sieve: Extprograms Plugin documentation for reference

Share:
28,692

Related videos on Youtube

Rahul Prasad
Author by

Rahul Prasad

Updated on September 18, 2022

Comments

  • Rahul Prasad
    Rahul Prasad over 1 year

    I want to parse and insert some information from the mail that just arrived in a mission critical application's mail server.

    I there any way to configure my mail server so that it run a script when mail arrives.

    Although I have a debian system but any generic solution (Linux) will do.

    • Ignacio Vazquez-Abrams
      Ignacio Vazquez-Abrams about 13 years
    • dmourati
      dmourati about 13 years
      nope no duplicate
    • Ignacio Vazquez-Abrams
      Ignacio Vazquez-Abrams about 13 years
      @dmourati: Yes it is.
    • dmourati
      dmourati about 13 years
      What if he's not using postfix or python?
    • Rahul Prasad
      Rahul Prasad about 13 years
      Found my answer @ www.evolt.org/incoming_mail_and_php
    • DevOpsSauce
      DevOpsSauce about 5 years
      "pOSsiBle dUPlicAte oF blAh BlaH bLah" rolls eyes
  • dmourati
    dmourati about 13 years
    +1 procmail Edit your .forward and add to taste. Start here pm-doc.sourceforge.net/doc
  • symcbean
    symcbean about 13 years
    +1 - the right solution, procmail gives a lot more flexibility than calling your script directly via .forward, although I'd recomend configuring postfix to use procmail as the MDA rather than chaining from the bundled MDA - e.g. wiki.kartbuilding.net/index.php/Procmail_-_setup_with_postfi‌​x
  • palswim
    palswim over 5 years
    Though procmail may work, since procmail hasn't had active development since 2001, and the developer has encouraged people to find other solutions, do any alternatives exists which also will run a script on receipt of a new message?
  • dean
    dean over 4 years
    @palswim Did you check this answer: serverfault.com/a/887813/79203 ?