tags:

views:

38

answers:

2

Before I probably reinvent the wheel, can anyone tell me if there exists a FOSS code library to check email on a regular basis (or driven by a cron job), to parse the title and body and to perform certain functions (mainly sending other emails).

I was thinking PHP as it is server side and good at string handling, but I would be happy enough with C or C++.

Hmmm, why am I even thinking server side? I suppose that it could just as well run on my PC (add Delphi, C++ Builder and maybe C# or even VB) as possibilities (sorry & no offence intended; I know that it is well suited for string processing, but I don't know PERL and don't rally have time to learn).


Edit: I'm think of some common code which allows to define "triggers" and register callback functions. So, a trigger might say that sender = XXX, title contains, To address is, etc (or combinations thereof) and I can register a callback function which I code which will do the appropriate processing when the condition(s) is met.


Edit: found on SourceForge "ETODB is a free PHP class which allows to parse and extract data from emails to integrate with other php applications. You can automatically parse email messages and convert email to database records, save attachments to specific folders, browse log." http://sourceforge.net/projects/etodb/

+1  A: 

Here's a quickly cobbled together script I was using for processing attachments of a special email account:

(some steps and code redacted, for example parts that remember already processed messages and remove messages from the server after a number of days)

#!/usr/local/bin/php5
<?php

error_reporting(E_ALL);

date_default_timezone_set('Asia/Tokyo');

define('TYPE_TEXT', 0);
define('TYPE_MULTIPART', 1);
define('TYPE_MESSAGE', 2);
define('TYPE_APPLICATION', 3);
define('TYPE_AUDIO', 4);
define('TYPE_IMAGE', 5);
define('TYPE_VIDEO', 6);
define('TYPE_OTHER', 7);

define('ENCODING_7BIT', 0);
define('ENCODING_8BIT', 1);
define('ENCODING_BINARY', 2);
define('ENCODING_BASE64', 3);
define('ENCODING_QUOTEDPRINTABLE', 4);
define('ENCODING_OTHER', 5);

$server = 'example.com:110';
$user = 'foo';
$password = 'bar';

echo "\nLogging in to $server with user $user...\n";

$mbox = imap_open('{' . $server . '/pop3}INBOX', $user, $password);

if (!$mbox) {
    die("Couldn't establish a connection.\n" . join("\n", imap_errors()));
}

$numMessages = imap_num_msg($mbox);

echo "Found $numMessages messages in inbox.\n";

for ($i = 1; $i <= $numMessages; $i++) {

    echo "\nProcessing message $i...\n";

    $header = imap_headerinfo($mbox, $i);

    if (!$header) {
        die("An error occurred while processing message $i.\n" . join("\n", imap_errors()));
    }

    echo "Message id: {$header->message_id}\n";

    $structure = imap_fetchstructure($mbox, $i);

    if (!$structure) {
        die("An error occurred while processing the structure of message $i.\n" . join("\n", imap_errors()));
    }

    if ($structure->type !== TYPE_MULTIPART || empty($structure->parts)) {
        echo "Couldn't find any attachments to process, moving on...\n";
        continue;
    }

    echo "Message has " . count($structure->parts) . " parts, beginning processing of individual parts...\n";

    foreach ($structure->parts as $index => $part) {
        $index++;

        echo "Processing part $index with type of {$part->type}...\n";

        if ($part->type === TYPE_TEXT) {
            echo "Part is plain text, moving on...\n";
            continue;
        }

        $bodypart = imap_fetchbody($mbox, $i, $index);

        echo "Fetched part with length of " . strlen($bodypart) . " bytes, encoded in {$part->encoding}.\n";

        switch ($part->encoding) {
            case ENCODING_BASE64 :
                echo "Decoding attachment from BASE64.\n";
                $bodypart = imap_base64($bodypart);
                break;
            case ENCODING_QUOTEDPRINTABLE :
                echo "Decoding attachment from Quoted-Printable.\n";
                $bodypart = imap_qprint($bodypart);
                break;
        }

        $filename = $header->message_id . '_part_' . $index;
        if (!empty($part->parameters)) {
            foreach ($part->parameters as $param) {
                if ($param->attribute == 'NAME') {
                    $filename = $param->value;
                    echo "Using original filename '$filename'.\n";
                    break;
                }
            }
        }

        // file processing here...
    }

    echo "Done processing message $i.\n";
}

imap_close($mbox);

echo "\nDone.\n";

Hope this serves as a starting point for you. Unless you can provide a more specific purpose of what you're looking for, it's probably just easy to come up with a script yourself.

deceze
+1 Thanks. I agree that it might be best to code my own (unless there is some all singing, all dancing code already available (I will update the question slightly)).
Mawg
+1  A: 

The imap lib comes as standard with PHP - rolling your own code around this is trivial.

However polling the email is a very inneficient way to solve the problem - a far better approach is to route the email (or a copy thereof) direct to your script - but you don't say what Operating system you are running on nor which MTA your are using. Assuming it all sits on a Unix box running sendmail or similar, most local delivery agents allow ~/.forward to reference a script. My personal preference is for procmail (which is efectively a programming language for delivery mail, making copies, auto-responses etc).

symcbean
+1 and, yes, my server runs Linux, has standard CPanel and it has the option to route mail to a script (do you happen to knwo it it stays on the mail server, or is deleted when passed to the script?) I need to heck if I have IMAP or just POP, but maybe the IMAP library handles POP too; I will look into it. Thanks again
Mawg