An SMTP transaction is valid from MAIL FROM time until RSET or "final-dot".
- transaction.uuid
A unique UUID for this transaction. Is equal to the connection.uuid + '.N' where N increments for each transaction on this connection.
- transaction.mail_from
The value of the MAIL FROM command is an Address
[1] object.
- transaction.rcpt_to
An Array of Address
[1] objects of recipients from the RCPT TO command.
- transaction.message_stream
A node.js Readable Stream object for the message.
You use it like this:
transaction.message_stream.pipe(WritableStream, options)
Where WritableStream is a node.js Writable Stream object such as a net.socket, fs.writableStream, process.stdout/stderr or custom stream.
The options argument should be an object that overrides the following properties:
* line_endings (default: "\r\n")
* dot_stuffing (default: false)
* ending_dot (default: false)
* end (default: true)
* buffer_size (default: 65535)
* clamd_style (default: false)
e.g.
transaction.message_stream.pipe(socket, { dot_stuffing: true, ending_dot: true });
- transaction.data_bytes
The number of bytes in the email after DATA.
- transaction.add_data(line)
Adds a line of data to the email. Note this is RAW email - it isn't useful for adding banners to the email.
- transaction.notes
A safe place to store transaction specific values. See also haraka-results and haraka-notes.
- transaction.add_leading_header(key, value)
Adds a header to the top of the header list. This should only be used in very specific cases. Most cases will use add_header()
instead.
- transaction.add_header(key, value)
Adds a header to the email.
- transaction.remove_header(key)
Deletes a header from the email.
- transaction.header
The header of the email. See Header Object
.
- transaction.parse_body = true|false [default: false]
Set to true
to enable parsing of the mail body. Make sure you set this in hook_data or before. Storing a transaction hook (with transaction.attachment_hooks) will set this to true.
- transaction.body
The body of the email if you set parse_body
above. See Body Object
.
- transaction.attachment_hooks(start)
Sets a callback for when we see an attachment.
The start
event will receive (content_type, filename, body, stream)
as parameters.
The stream is a ReadableStream
If you set stream.connection then the stream will apply backpressure to the connection, allowing you to process attachments before the connection has ended. Here is an example which stores attachments in temporary files using the tmp
library from npm and tells us the size of the file:
exports.hook_data = function (next, connection) {
// enable mail body parsing
connection.transaction.attachment_hooks(
function (ct, fn, body, stream) {
start_att(connection, ct, fn, body, stream)
}
);
next();
}
function start_att (connection, ct, fn, body, stream) {
connection.loginfo(`Got attachment: ${ct}, ${fn} for user id: ${connection.transaction.notes.hubdoc_user.email}`)
connection.transaction.notes.attachment_count++
stream.connection = connection; // Allow backpressure
stream.pause();
require('tmp').file((err, path, fd) => {
connection.loginfo(`Got tempfile: ${path} (${fd})`)
const ws = fs.createWriteStream(path)
stream.pipe(ws);
stream.resume();
ws.on('close', () => {
connection.loginfo("End of stream reached");
fs.fstat(fd, (err, stats) => {
connection.loginfo(`Got data of length: ${stats.size}`);
fs.close(fd, () => {}); // Close the tmp file descriptor
});
});
});
}
- transaction.discard_data = true|false [default: false]
Set this flag to true to discard all data as it arrives and not store in memory or on disk (in the message_stream property). You can still access the attachments and body if you set parse_body to true. This is useful for systems which do not need the full email, just the attachments or mail text.
- transaction.set_banner(text, html)
Sets a banner to be added to the end of the email. If the html part is not given (optional) then the text part will have each line ending replaced with <br/>
when being inserted into HTML parts.
- transaction.add_body_filter(ct_match, filter)
Adds a filter to be applied to body parts in the email. ct_match should be a regular expression to match against the full content-type line, or a string to match at the start, e.g. /^text\/html/
or 'text/plain'
. filter will be called when each body part matching ct_match is complete. It receives three parameters: the content-type line, the encoding name, and a buffer with the full body part. It should return a buffer with the desired contents of the body in the same encoding.
- transaction.results
Store results of processing in a structured format.
[1]: Address
objects are address-rfc2821 objects.