Mr. Programmer
Mr. Programmer

Reputation: 3093

How to parse email on Haraka?

Ive been exploring the haraka (http://haraka.github.io ) and Ive successfully install it on my linux machine. I'm wondering if there is a good tutorial on parsing an email meta headers and content body using haraka. Ive check on their manual but I couldnt find it. Any ideas/suggestions on how to do that would greatly appreciated. Thanks.

Here is my script to retrieve the email body:

var winston = require('winston');
exports.hook_data = function (next, connection) {
    winston.log('info', '----------------------------------------');
    winston.log('info', 'hook_data');
    // enable mail body parsing
    connection.transaction.parse_body = true;
    winston.log('info', "body="+connection.transaction.body);
    winston.log('info', "mail_from="+connection.transaction.mail_from);
    next();
}

The output:

{"level":"info","message":"----------------------------------------","timestamp":"2015-01-12T07:16:28.216Z"}
{"level":"info","message":"hook_data","timestamp":"2015-01-12T07:16:28.217Z"}
{"level":"info","message":"body=null","timestamp":"2015-01-12T07:16:28.218Z"}
{"level":"info","message":"[email protected]","timestamp":"2015-01-12T07:16:28.218Z"}

As you can see the body contains a null value.

Upvotes: 2

Views: 1709

Answers (4)

Nedry
Nedry

Reputation: 11

The previous answers were missing some important details. I've demonstrated how to fetch various headers in the data hook.

The email body can have multiple children.

Each hook needs to call the callback (next) to proceed with the next stage in the pipeline of processing the email.

    exports.hook_data = function (next, connection) {
        // enable mail body parsing - should be enabled in hook_data
        connection.transaction.parse_body = true;
    
        // get a decoded copy of a header, e.g. From
        const from_header = connection.transaction.header.get_decoded('From');
        connection.loginfo(this, `From: ${from_header}`);
        
        // get a header that doesn't need to be decoded:
        const msg_id = connection.transaction.header.get('Message-ID');
        
        // get multiple headers, e.g. Received:
        const received = connection.transaction.header.get_all('received');

        next();
    }

    exports.hook_data_post = function (next, connection) {
        // confirm body has text
        if(connection.transaction.body.bodytext) {
            this.examine_body(connection.transaction.body.bodytext);
        }

        next();
    }

    exports.examine_body = function (body) {
        if (!body.bodytext) return;
    
        this.loginfo(body.bodytext);

        // recursively get all of the children
        if (body.children?.length) {
            for (const child of body.children) {
                this.examine_body(child);
            }
        }
    }

Upvotes: 0

ajai007
ajai007

Reputation: 31

For me this worked

connection.transaction.body.children[1].bodytext
exports.hook_data = function (next, connection) {
    connection.transaction.parse_body = true;
    this.loginfo("connection.transaction.parse_body");
    next();
}

exports.hook_data_post = function (next, connection) {
    this.loginfo("connection.transaction.body.bodytext");
    this.loginfo(connection.transaction.body.children[1].bodytext);
    next();
}

Upvotes: 3

Moby Duck
Moby Duck

Reputation: 2090

It seems transaction.parse_body needs to be set before the data has arrived - so do that in the 'data' hook (called at the DATA command), or earlier:

exports.hook_data = function (next, connection) {
    connection.transaction.parse_body = true;
    next();
}

Then you can read the body from the 'data_post' (called at the end-of-data marker) hook:

exports.hook_data_post = function (next, connection) {
    this.loginfo(connection.transaction.body.bodytext);
    next();
}

Upvotes: 2

Sham
Sham

Reputation: 114

You can retrieve email body using below code

connection.transaction.body.body_text_encoded
connection.transaction.body.bodytext

It's code is easy to understand. You can read it and do according to you.

Upvotes: 1

Related Questions