The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Email Forward to PHP Script

Discussion in 'E-mail Discussions' started by cmdr_bond, May 15, 2005.

  1. cmdr_bond

    cmdr_bond Registered

    Joined:
    May 15, 2005
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    1
    Hello,

    I was reading on a site (http://gvtulder.f2o.org/articles/incoming-mail/) that it's possible to instead of specify an email address to have your emails forwarded to, you can have cpanel send the email info to a php page.
    I tried whath the site said, put a "|" followed by the path to the file but I think I'm doing something wrong as I'm getting my emails bounced back as undeliverable. How exactly do I do this and what kind of path am I supposed to write?

    Thanks
     
  2. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
    I got stumped by this a bit when I first tried it and it took me a while to figure things out.

    Assuming that the path to the PHP script is correct, what you also need to check is that:

    1. You have #!/usr/local/bin/php as the first line in the PHP file

    2. Check the permissions on the PHP script as it needs to be executable for whatever is piping data to it. Start with perms of 0777 and work down from there if you're not happy with these.

    3. Make sure that the PHP script reads in the email from STDIN. I found that even with the correct setup from steps 1 and 2, the script also needs to read in the email for a bounceback not to occur.

    A good way of troubleshooting is to get the script to email you - an easy way to spot that the script is executing and also a good way of checking the value of variables whilst debugging.

    The PHP function I popped together for reading emails from STDIN is:

    PHP:
    function mailRead($i_klimit "")
    {
      
    // Reads piped mail from STDIN
      // Optional $i_klimit specifies after how many kilobytes the reading should stop
      // Default is 1024k. This is very generous for plain or formatted text.
      // Set to -1 for unlimited (i.e. read entire email)
      // This will prevent the script running into "out of memory" errors when dealing with large mails.

      
    if ($i_klimit == "") {
        
    $i_klimit 1024;
      }
            
      
    $fp fopen("php://stdin""r");
      
    $email "";
            
      if (
    $i_klimit == -1) {
        while (!
    feof($fp)) {
          
    $email .= fread($fp1024);
        }                    
      } else {
        while (!
    feof($fp) && $i_limit $i_klimit) {
          
    $email .= fread($fp1024);
          
    $i_limit++;
        }        
      }
            
      
    fclose($fp);
            
      return 
    $email;
    }
    It may not be perfect but it does the trick and helps prevent"out of memory" errors if reading in huge emails (that was a fun thing to test!)

    Another thing worth noting is that you can pick up a lot of useful info about the piped email through $_SERVER - the values are somewhat different to what you would expect when a script is executed via a browser.

    Good luck!
     
  3. cmdr_bond

    cmdr_bond Registered

    Joined:
    May 15, 2005
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    1
    Works like a charm
    Thanks
     
  4. internetfab

    internetfab Well-Known Member
    PartnerNOC

    Joined:
    Feb 20, 2003
    Messages:
    336
    Likes Received:
    0
    Trophy Points:
    16
    Location:
    Gothenburg, Sweden
    cPanel Access Level:
    DataCenter Provider
    Thanx :) This will come in handy!
     
  5. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
    Good to see this is proving useful.

    I'll actually be putting together a more fully-blown tutorial covering the topic in more detail once I finally get my website in some decent order. Once done I'll post the URL, although don't expect it anytime soon!
     
  6. trigger hippy

    trigger hippy Member

    Joined:
    Dec 2, 2005
    Messages:
    16
    Likes Received:
    0
    Trophy Points:
    1
    Location:
    Bristol, UK
    Trouble piping e-mail to script

    I am trying to pipe e-mail to script.
    I have a file /home/tradein2/bounces/bounces.php both file and dir are CHOWN & CHGRP tradein2 CHMOD 0755 (was 0777, but that didn't work either)


    File has contents as follows:
    <?
    #!/usr/local/bin/php

    function mailRead($i_klimit = "")
    // --- function copied from above post
    }

    $tdebug='Debug script ran at: '.date('r');
    $tdebug.='\n\nThe e-mail was as follows:\n'.mailRead();

    mail('tech@tradeinternet.co.uk', 'debug script', $tdebug);

    ?>




    cPanel has filter as follows:
    $header_to: matches "bounces@tradeinternet.co.uk" | /home/tradein2/bounces/bounces.php

    When I send a mail to bounces@tradeinternet.co.uk, I get delivery failure message back and message is not delivered, and I get no test message from the script.

    Anyone got any ideas?
     
  7. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
    I find permission-based errors to be the most common.

    Try executing the script from the command line as this will reveal any permission issues.
     
  8. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
    You might also want to trim the script down first of all to ensure whilst troubleshooting permission-based issues.

    PHP:
    <?
    #!/usr/local/bin/php

    mail('tech@tradeinternet.co.uk''test subject, 'test message');

    ?>
    Would be about as simple as it could get.

    If the script executes, you will definitely get sent the relevant email. If it doesn't, you won't. When you find it does, add back everything else and check if it still works.

    By the way, the above cut-down script will result in a bounceback message returning to the sender as the message is not being read in from STDIN - worry about this later, get the script executing properly first.

    Out of interest, are you running PHP as an Apache module or in CGI mode (i.e. with phpsuexec enabled)? I've never actually tried piping mail to PHP without phpsuexec enabled, so I can't say if it makes a difference, but you never know.
     
  9. trigger hippy

    trigger hippy Member

    Joined:
    Dec 2, 2005
    Messages:
    16
    Likes Received:
    0
    Trophy Points:
    1
    Location:
    Bristol, UK
    Tried that!....

    I tried running the command from SSH and it worked, I got the message.
    (/usr/local/bin/php /home/tradein2/bounces/bounces.php)

    Still just get a bounce when I send e-mail to bounces@... though :mad:

    (I am running phpsuexec)

    Just a thought... SSH is running as root - is the script running as exim when the script is called, or is it as the user that the e-mail was sent to.
     
    #9 trigger hippy, Feb 25, 2006
    Last edited: Feb 25, 2006
  10. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
    When testing from the command line, you should really be trying

    Code:
    /home/tradein2/bounces/bounces.php
    instead of

    Code:
    /usr/local/bin/php /home/tradein2/bounces/bounces.php
    You already have #!/usr/local/bin/php at the start of the script and so /usr/local/bin/php at the start of the command-line command is both unnecesary and doesn't test things correctly.

    Mail will be being piped directly to '/home/tradein2/bounces/bounces.php' and not to the command '/usr/local/bin/php /home/tradein2/bounces/bounces.php' and so the former is a more accurate way of testing.

    Saying that, if '/usr/local/bin/php /home/tradein2/bounces/bounces.php' works for you from the command line, you might want to adjust your filter so that you have

    Code:
    $header_to: matches "bounces@tradeinternet.co.uk" | /usr/local/bin/php /home/tradein2/bounces/bounces.php 
    instead of

    Code:
    $header_to: matches "bounces@tradeinternet.co.uk" | /home/tradein2/bounces/bounces.php
    I've not tried this myself, but it's worth a shot.
     
  11. trigger hippy

    trigger hippy Member

    Joined:
    Dec 2, 2005
    Messages:
    16
    Likes Received:
    0
    Trophy Points:
    1
    Location:
    Bristol, UK
    Breakthrough

    Yes, changing the filter worked - I now get the script running correctly from sending an e-mail.

    I also tried running the file from SSH and got the following errors which I don't really understand as

    root@ds1 [~]# /home/tradein2/bounces/bounces.php
    /home/tradein2/bounces/bounces.php: line 1: ?: No such file or directory
    /home/tradein2/bounces/bounces.php: line 3: /aquota.user: Text file busy
    /home/tradein2/bounces/bounces.php: line 4: syntax error near unexpected token `
    $i_klimit'
    /home/tradein2/bounces/bounces.php: line 4: `function mailRead($i_klimit = "") '

    from file:

    <? #!/usr/local/bin/php
    /*
    function mailRead($i_klimit = "")
    {
    // Reads piped mail from STDIN
    // Optional $i_klimit specifies after how many kilobytes the reading should stop
    // Default is 1024k. This is very generous for plain or formatted text.
    // Set to -1 for unlimited (i.e. read entire email)
    // This will prevent the script running into "out of memory" errors when dealing with large mails.

    if ($i_klimit == "") {
    $i_klimit = 1024;
    }

    $fp = fopen("php://stdin", "r");
    $email = "";

    if ($i_klimit == -1) {
    while (!feof($fp)) {
    $email .= fread($fp, 1024);
    }
    } else {
    while (!feof($fp) && $i_limit < $i_klimit) {
    $email .= fread($fp, 1024);
    $i_limit++;
    }
    }

    fclose($fp);

    return $email;
    }



    $tdebug='Debug script ran at: '.date('r');
    $tdebug.='\n\nThe e-mail was as follows:\n'.mailRead();

    */
    mail('tech@tradeinternet.co.uk', 'debug script', 'test');

    ?>


    Is the file laid out correctly?
     
  12. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
    Your script should start as:

    Code:
    #!/usr/local/bin/php
    <?
      // php code
    ?>
    i.e. the shebang line should come before all PHP code - this tells the executing program what to handle the script with.

    This was probably the issue all along - with the shebang line in the correct place, you should find that the previous filter works fine and that it will also run from the command line.
     
  13. trigger hippy

    trigger hippy Member

    Joined:
    Dec 2, 2005
    Messages:
    16
    Likes Received:
    0
    Trophy Points:
    1
    Location:
    Bristol, UK
    Well that is another fine mess excaped from...

    :eek: Thanks for your help - that has sorted it all out. At it always the silly little things with me!
     
  14. webignition

    webignition Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    1,880
    Likes Received:
    0
    Trophy Points:
    36
Loading...

Share This Page