Ten en cuenta que en las ciencias un error casi siempre tiene diferentes soluciones, no obstante nosotros aquí te mostramos lo más óptimo y mejor.
Solución:
Lo descubrí gracias a la ayuda de @arnt y mscdex. Aquí hay un script completo y en funcionamiento que transmite todos los archivos adjuntos como archivos al disco mientras los decodifica en base64 sobre la marcha. Bastante escalable en términos de uso de memoria.
var inspect = require('util').inspect;
var fs = require('fs');
var base64 = require('base64-stream');
var Imap = require('imap');
var imap = new Imap(
user: '[email protected]',
password: 'mygmailpassword',
host: 'imap.gmail.com',
port: 993,
tls: true
//,debug: function(msg)console.log('imap:', msg);
);
function toUpper(thing) return thing && thing.toUpperCase ? thing.toUpperCase() : thing;
function findAttachmentParts(struct, attachments) [];
for (var i = 0, len = struct.length, r; i < len; ++i)
if (Array.isArray(struct[i]))
findAttachmentParts(struct[i], attachments);
else
if (struct[i].disposition && ['INLINE', 'ATTACHMENT'].indexOf(toUpper(struct[i].disposition.type)) > -1)
attachments.push(struct[i]);
return attachments;
function buildAttMessageFunction(attachment)
var filename = attachment.params.name;
var encoding = attachment.encoding;
return function (msg, seqno)
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info)
//Create a write stream so that we can stream the attachment to file;
console.log(prefix + 'Streaming this attachment to file', filename, info);
var writeStream = fs.createWriteStream(filename);
writeStream.on('finish', function()
console.log(prefix + 'Done writing to file %s', filename);
);
//stream.pipe(writeStream); this would write base64 data to the file.
//so we decode during streaming using
if (toUpper(encoding) === 'BASE64')
//the stream is base64 encoded, so here the stream is decode on the fly and piped to the write stream (file)
stream.pipe(base64.decode()).pipe(writeStream);
else
//here we have none or some other decoding streamed directly to the file which renders it useless probably
stream.pipe(writeStream);
);
msg.once('end', function()
console.log(prefix + 'Finished attachment %s', filename);
);
;
imap.once('ready', function()
imap.openBox('INBOX', true, function(err, box)
if (err) throw err;
var f = imap.seq.fetch('1:3',
bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE)'],
struct: true
);
f.on('message', function (msg, seqno)
console.log('Message #%d', seqno);
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info)
var buffer = '';
stream.on('data', function(chunk)
buffer += chunk.toString('utf8');
);
stream.once('end', function()
console.log(prefix + 'Parsed header: %s', Imap.parseHeader(buffer));
);
);
msg.once('attributes', function(attrs)
var attachments = findAttachmentParts(attrs.struct);
console.log(prefix + 'Has attachments: %d', attachments.length);
for (var i = 0, len=attachments.length ; i < len; ++i)
var attachment = attachments[i];
/*This is how each attachment looks like
partID: '2',
type: 'application',
subtype: 'octet-stream',
params: name: 'file-name.ext' ,
id: null,
description: null,
encoding: 'BASE64',
size: 44952,
md5: null,
disposition: type: 'ATTACHMENT', params: filename: 'file-name.ext' ,
language: null
*/
console.log(prefix + 'Fetching attachment %s', attachment.params.name);
var f = imap.fetch(attrs.uid , //do not use imap.seq.fetch here
bodies: [attachment.partID],
struct: true
);
//build function to process attachment message
f.on('message', buildAttMessageFunction(attachment));
);
msg.once('end', function()
console.log(prefix + 'Finished email');
);
);
f.once('error', function(err)
console.log('Fetch error: ' + err);
);
f.once('end', function()
console.log('Done fetching all messages!');
imap.end();
);
);
);
imap.once('error', function(err)
console.log(err);
);
imap.once('end', function()
console.log('Connection ended');
);
imap.connect();
Si te gusta la programación, puedes dejar una sección acerca de qué le añadirías a esta división.
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)