Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用节点imap读取和保存附件_Javascript_Node.js_Base64_Imap - Fatal编程技术网

Javascript 如何使用节点imap读取和保存附件

Javascript 如何使用节点imap读取和保存附件,javascript,node.js,base64,imap,Javascript,Node.js,Base64,Imap,我正在使用,但我找不到一个简单的代码示例,说明如何使用fs将电子邮件中的附件保存到磁盘 我已经把文档读了好几遍了。在我看来,我应该做另一个获取,引用消息的特定部分作为附件。我从一个基本的例子开始: var Imap = require('imap'), inspect = require('util').inspect; var imap = new Imap({ user: 'mygmailname@gmail.com', password: 'mygmailpassword

我正在使用,但我找不到一个简单的代码示例,说明如何使用fs将电子邮件中的附件保存到磁盘

我已经把文档读了好几遍了。在我看来,我应该做另一个获取,引用消息的特定部分作为附件。我从一个基本的例子开始:

var Imap = require('imap'),
    inspect = require('util').inspect;

var imap = new Imap({
  user: 'mygmailname@gmail.com',
  password: 'mygmailpassword',
  host: 'imap.gmail.com',
  port: 993,
  tls: true
});

function openInbox(cb) {
  imap.openBox('INBOX', true, cb);
}

imap.once('ready', function() {
  openInbox(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', inspect(Imap.parseHeader(buffer)));
        });
      });
      msg.once('attributes', function(attrs) {
        console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));

        //Here's were I imagine to need to do another fetch for the content of the message part...

      });
      msg.once('end', function() {
        console.log(prefix + 'Finished');
      });
    });
    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();
这个例子很有效。这是附件部件的输出:

 [ { partID: '2',
     type: 'application',
     subtype: 'octet-stream',
     params: { name: 'my-file.txt' },
     id: null,
     description: null,
     encoding: 'BASE64',
     size: 44952,
     md5: null,
     disposition:
      { type: 'ATTACHMENT',
        params: { filename: 'my-file.txt' } },
     language: null } ],

如何使用node的fs模块读取该文件并将其保存到磁盘?

多亏了@arnt和的帮助,我才明白了这一点。下面是一个完整的工作脚本,它将所有附件作为文件流式传输到磁盘,同时base64将动态解码它们。在内存使用方面具有很好的可扩展性

var inspect = require('util').inspect;
var fs      = require('fs');
var base64  = require('base64-stream');
var Imap    = require('imap');
var imap    = new Imap({
  user: 'mygmailname@gmail.com',
  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) {
  attachments = 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();
var-inspect=require('util')。inspect;
var fs=需要('fs');
var base64=require('base64-stream');
var Imap=require('Imap');
var imap=新的imap({
用户:'mygmailname@gmail.com',
密码:“MygMail密码”,
主持人:“imap.gmail.com”,
港口:993,
tls:对
//,debug:function(msg){console.log('imap:',msg);}
});
函数toUpper(thing){返回thing&&thing.toUpperCase?thing.toUpperCase():thing;}
函数findAttachmentParts(结构、附件){
附件=附件| |[];
对于(变量i=0,len=struct.length,r;i-1){
附件.推送(结构[i]);
}
}
}
归还附件;
}
函数buildAttMessageFunction(附件){
var filename=attachment.params.name;
var编码=附件.encoding;
返回函数(消息,序号){
变量前缀='(#'+序号+)';
msg.on('body',函数(流,信息){
//创建一个写流,这样我们就可以将附件流到文件中;
log(前缀+‘将此附件流式处理到文件’、文件名、信息);
var writeStream=fs.createWriteStream(文件名);
writeStream.on('finish',function(){
console.log(前缀+‘已写入文件%s’,文件名);
});
//stream.pipe(writeStream);这会将base64数据写入文件。
//所以我们在流媒体中使用
如果(toUpper(编码)=='BASE64'){
//流是base64编码的,因此在这里,流是动态解码的,并通过管道传输到写入流(文件)
stream.pipe(base64.decode()).pipe(writeStream);
}否则{
//在这里,我们没有或一些其他解码流直接到文件,这使得它可能无用
stream.pipe(writeStream);
}
});
msg.once('end',function(){
console.log(前缀+‘已完成的附件%s’,文件名);
});
};
}
imap.once('ready',function(){
imap.openBox('INBOX',true,函数(err,box){
如果(错误)抛出错误;
变量f=imap.seq.fetch('1:3'{
正文:[“HEADER.FIELDS(从主题日期到主题日期)”,
结构:对
});
f、 on('message',函数(msg,seqno){
console.log('Message#%d',seqno);
变量前缀='(#'+序号+)';
msg.on('body',函数(流,信息){
var缓冲区=“”;
stream.on('data',函数(块){
buffer+=chunk.toString('utf8');
});
stream.once('end',function(){
console.log(前缀+'Parsed header:%s',Imap.parseHeader(缓冲区));
});
});
msg.once('attributes',函数(attrs){
var attachments=findAttachmentParts(attrs.struct);
console.log(前缀+'包含附件:%d',附件.length);
对于(变量i=0,len=attachments.length;i
基于克里斯蒂安·韦斯特比克

更改:1。use=>,forEach;2.第二次获取不需要“struct”

问题:

在某些情况下,附件的文件名应为attachment.disposition.params['filename*']。请参阅“RFC2231 MIME参数值和编码字扩展名”&


你也可以用它来为我工作

const IMAP = require("imap");
const MailParser = require("mailparser").MailParser;
const moment = require('moment');
var fs = require('fs'), fileStream;
module.exports.imapEmailDownload = function () {
return new Promise(async (resolve, reject) => {
    try {
        const imapConfig = {
            user: 'XXX126@gmail.com',
            password: 'XXX@126',
            host: 'imap.gmail.com',
            port: '993',
            tls: true,
            tlsOptions: {
                secureProtocol: 'TLSv1_method'
            }
        }
        const imap = IMAP(imapConfig);

        imap.once("ready", execute);
        imap.once("error", function (err) {
            console.error("Connection error: " + err.stack);
        });

        imap.connect();

        function execute() {
            imap.openBox("INBOX", false, function (err, mailBox) {
                if (err) {
                    console.error(err);
                    return;
                }
                imap.search([["ON", moment().format('YYYY-MM-DD')]], function (err, results) {
                    if (!results || !results.length) { console.log("No unread mails"); imap.end(); return; }
                    /* mark as seen
                    imap.setFlags(results, ['\\Seen'], function(err) {
                        if (!err) {
                            console.log("marked as read");
                        } else {
                            console.log(JSON.stringify(err, null, 2));
                        }
                    });*/
                    var f = imap.fetch(results, { bodies: "" });
                    f.on("message", processMessage);
                    f.once("error", function (err) {
                        return Promise.reject(err);
                    });
                    f.once("end", function () {
                        imap.end();
                    });
                });
            });
        }

        function processMessage(msg, seqno) {
          
            var parser = new MailParser({ streamAttachments: true });
            parser.on("headers", function (headers) {
            });

            parser.on('data', data => {
                if (data.type === 'text') {
                    console.log(seqno);
                    console.log(data.text);  /* data.html*/
                }

            });
            let data = ""
            msg.on("body", function (stream) {
                stream.on("data", function (chunk) {
                    data = data + chunk.toString("utf8");
                    parser.write(chunk.toString("utf8"));
                });
                stream.on("end", (chunk) => {
                })
            });

            parser.on('attachment', async function (attachment, mail) {
                let filepath = './download/';
                let output = fs.createWriteStream(filepath + attachment.fileName);
                
                attachment.stream.pipe(output).on("end", function () {
                    console.log("All the data in the file has been read");
                }).on("close", function (err) {
                    console.log("Stream has been cloesd.");
                });

            });

            msg.once("end", function () {
                // console.log("Finished msg #" + seqno);
                parser.end();
            });
        }
        resolve();
    } catch (error) {
        console.log("error", error);
        reject(error);
    }
});};

您看到的partID(示例中的2)是零件号。您想发出UID FETCH 1234 BINARY.PEEK[2](如果服务器支持二进制扩展)或BODY.PEEK[2]。BINARY.PEEK为您提供原始数据,BODY.PEEK必须根据您的编码字段进行解码。此时,RAM中有一个字符串,我希望您能找到一种方法,使用node.js将该字符串写入文件。@arnt谢谢。
imap.seq.fetch
的第一个参数如何使其执行
UID fetch 1234 BINAR
const IMAP = require("imap");
const MailParser = require("mailparser").MailParser;
const moment = require('moment');
var fs = require('fs'), fileStream;
module.exports.imapEmailDownload = function () {
return new Promise(async (resolve, reject) => {
    try {
        const imapConfig = {
            user: 'XXX126@gmail.com',
            password: 'XXX@126',
            host: 'imap.gmail.com',
            port: '993',
            tls: true,
            tlsOptions: {
                secureProtocol: 'TLSv1_method'
            }
        }
        const imap = IMAP(imapConfig);

        imap.once("ready", execute);
        imap.once("error", function (err) {
            console.error("Connection error: " + err.stack);
        });

        imap.connect();

        function execute() {
            imap.openBox("INBOX", false, function (err, mailBox) {
                if (err) {
                    console.error(err);
                    return;
                }
                imap.search([["ON", moment().format('YYYY-MM-DD')]], function (err, results) {
                    if (!results || !results.length) { console.log("No unread mails"); imap.end(); return; }
                    /* mark as seen
                    imap.setFlags(results, ['\\Seen'], function(err) {
                        if (!err) {
                            console.log("marked as read");
                        } else {
                            console.log(JSON.stringify(err, null, 2));
                        }
                    });*/
                    var f = imap.fetch(results, { bodies: "" });
                    f.on("message", processMessage);
                    f.once("error", function (err) {
                        return Promise.reject(err);
                    });
                    f.once("end", function () {
                        imap.end();
                    });
                });
            });
        }

        function processMessage(msg, seqno) {
          
            var parser = new MailParser({ streamAttachments: true });
            parser.on("headers", function (headers) {
            });

            parser.on('data', data => {
                if (data.type === 'text') {
                    console.log(seqno);
                    console.log(data.text);  /* data.html*/
                }

            });
            let data = ""
            msg.on("body", function (stream) {
                stream.on("data", function (chunk) {
                    data = data + chunk.toString("utf8");
                    parser.write(chunk.toString("utf8"));
                });
                stream.on("end", (chunk) => {
                })
            });

            parser.on('attachment', async function (attachment, mail) {
                let filepath = './download/';
                let output = fs.createWriteStream(filepath + attachment.fileName);
                
                attachment.stream.pipe(output).on("end", function () {
                    console.log("All the data in the file has been read");
                }).on("close", function (err) {
                    console.log("Stream has been cloesd.");
                });

            });

            msg.once("end", function () {
                // console.log("Finished msg #" + seqno);
                parser.end();
            });
        }
        resolve();
    } catch (error) {
        console.log("error", error);
        reject(error);
    }
});};