1
votes

I need to be able to collect multipple attachments in any email body. My testcase is based on multipart/mixed formatted email. I was able to get the filename correctly for a single attachment. The problem can easily be seen when including a console.log('Filename' + part.filename) inside the callback. It will always remain empty. It seems like the array - parts is always "stuck" on the last in the index, which in my case will give me an empty part.filename and a wrong part.mimeType.

I have tried all sorts of workarounds including pushing and pop'ing the correct filename but this does not work because the attachments are returned in a random sequence..

I belive this is an error, and I hope this can be recognized as an Error as I really need to have this fixed.

EDIT: Additional information after some more investigation: 1. The request.execute(function( attachment).. is only runnning once - after the for..loop has finished, even if there is multipple attachments. BUT It will return the correct attachments - also multipple, in a random sequence.

  1. The attachment object returned from request.execute(function( attachment) will NEVER contain an attachmentId, only the raw data and size.

  2. The size returned from attachment object request.execute(function( attachment) is not the same size as reported by var parts = message.payload.parts; which makes it impossible to be used for correlating.

  3. The request.execute(function(attachment) will only use the last data from the var parts = message.payload.parts; which is not related to the attachment.

function getAttachments(userId, message, callback) { var parts = message.payload.parts;

for (var i = 0; i < parts.length; i++) {
part = parts[i];
if (part.filename && part.filename.length > 0){
    var attachId = part.body.attachmentId;
    myfilename.push( part.filename )
    var request = gapi.client.gmail.users.messages.attachments.get({
    'id': attachId,
    'messageId': message.id,
    'userId': userId
    }); 

request.execute(function( attachment) {

// PROBLEM: part.filename and part.mimeType is empty or wrong.            
callback( **part.filename**, part.mimeType, attachment );
});
}
}

}

function callback( name, mime, att ) {
// PROBLEM: empty name, and wrong mime 
console.log( 'Filnavn: ' + name );
if (name == '') {
 name = myfilename.pop();
}
2

2 Answers

0
votes

You need to save the file context so that when callback is made, it knows the original filename and mimetype as follows:

function getAttachments(userId, message, callback) {
  var parts = message.payload.parts;
  var attachments = [];//The attachments cache
  for (var i = 0; i < parts.length; i++) {
    part = parts[i];
    if (part.filename && part.filename.length > 0) {
        var attachId = part.body.attachmentId;
        myfilename.push(part.filename);
        console.log('attachId=' + attachId);
        console.log('MessageID=' + message.id);
        console.log('UserID=' + userId);
        var request = gapi.client.gmail.users.messages.attachments.get({
            'id': attachId,
            'messageId': message.id,
            'userId': userId
        });
        attachments[attachId] = {filename: part.filename, mimeType:part.mimeType};
        request.execute(function (attachment) {
        // PROBLEM: part.filename and part.mimeType is empty or wrong.            
            var file = attachments[attachment.attachmentId];
            callback(file.filename, file.mimeType, attachment);
        });
    }
  }
}
0
votes

not sure if you have this problem solved. I am facing the same issue. While I look at the Google ApI Gmail Attachment Play ground Even though I have those fields:attachmentId,data,size. The response just doesn't give the attachmentId. I guess we probably shouldn't use the bathQuery approach.