Automatically convert emails with a Gmail label to PDF and send it to an email address

元气小坏坏 提交于 2021-02-06 13:57:09

问题


I am trying to automatically save the receipts (from Amazon) I receive in GMail to Dropbox. So I have written a script that:

  1. automatically select emails with a certain label
  2. converts the body of the email to html
  3. converts the html to pdf
  4. email the pdf of the body and attachment to IFTTT (which automatically saves the attachments to dropbox)
  5. deletes the temporary files
  6. removes the label

The script works and generates the bodydochtml, but the PDF conversion and email don't work. I am staring at this script for hours. Where is the error in my script?

Thank you!

Function send_Gmail_as_PDF(){

  var gLabel  = "#Receipt";
  var thread = GmailApp.search("label:" + gLabel);
  for (var x=0; x<thread.length; x++) {    
     var messages = thread[x].getMessages();  

     for (var y=0; y<messages.length; y++) {  
       var attach  = messages[y].getAttachments();
       var body    = messages[y].getBody(); 

       // Create an HTML File from the Message Body
       var bodydochtml = DocsList.createFile('body.html', body, "text/html")
       var bodyId=bodydochtml.getId()

       // Convert the HTML to PDF
       var bodydocpdf = bodydochtml.getAs('application/pdf').getBytes();

       // Does the Gmail Message have any attachments?
       if(attach.length>0){

       var file=DocsList.createFile(attach[0]);
       var pdf=file.getAs('application/pdf').getBytes();

       var attach_to_send = {fileName: 'pdftest.pdf',
            content:pdf, mimeType:'application/pdf'};
       var body_to_send = {fileName: 'body.pdf',
           content:bodydocpdf, mimeType:'application/pdf'};

       // Send the PDF to any email address
       MailApp.sendEmail('myemail@gmail.com', 
                         'transfer email as pdf : body & attachment', 
                         'see attachment', {attachments:[attach_to_send,body_to_send]});

     // Trash the temporary PDF and HTML files
     file.setTrashed(true);
     DocsList.getFileById(bodyId).setTrashed(true)
     }
   }
}
   // Message Processed; Remove the Google Drive Label
 GmailApp.getUserLabelByName(gLabel)
         .removeFromThread(thread[x]);
}

回答1:


The error on line 46 is coming up when thread[x] is null. Since you've got that statement outside of the loop that deals with thread[x], you ALWAYS have null. Move the statement into the loop, and this problem is avoided.

Inside your message loop, you check whether the message has any attachments, if(attach.length>0){ and only continue with the message if it DOES. Wouldn't you want to continue to send an email with only the pdf body? If so, we need to do something about the fixed array in {attachments:[attach_to_send,body_to_send]}. Better would be to build an array of attachments as we go, starting with the body_to_send. Add:

      var attachmentList = [];
      attachmentList.push(body_to_send);

Better yet, what if the message has multiple attachments - you'd want them all. To do that, put the attachment handling inside a loop, instead of an if, and make sure to move the temp file tidy-up along with it. (That should have been inside the if anyway, because if there was no attachment, the setTrashed() call would crash.)

      // Process all attachments
      for (var att = 0; att < attach.length; att++) {    
        ...
        attachmentList.push(attach_to_send);

        // Trash the temporary file
        file.setTrashed(true);
      }

Here's your code, with these changes - it works nicely:

function send_Gmail_as_PDF() {

  var gLabel = "#Receipt";
  var thread = GmailApp.search("label:" + gLabel);
  for (var x = 0; x < thread.length; x++) {
    var messages = thread[x].getMessages();

    for (var y = 0; y < messages.length; y++) {
      var attach = messages[y].getAttachments();
      var body = messages[y].getBody();

      // Create an HTML File from the Message Body
      var bodydochtml = DocsList.createFile('body.html', body, "text/html")
      var bodyId = bodydochtml.getId()

      // Convert the HTML to PDF
      var bodydocpdf = bodydochtml.getAs('application/pdf').getBytes();

      var body_to_send = {
        fileName: 'body.pdf',
        content: bodydocpdf,
        mimeType: 'application/pdf'
      };

      var attachmentList = [];
      attachmentList.push(body_to_send);

      // Trash the temporary file
      bodydochtml.setTrashed(true);

      // Process all attachments
      for (var att = 0; att < attach.length; att++) {

        var file = DocsList.createFile(attach[att]);
        var pdf = file.getAs('application/pdf').getBytes();

        var attach_to_send = {
          fileName: 'pdftest.pdf',
          content: pdf,
          mimeType: 'application/pdf'
        };
        attachmentList.push(attach_to_send);

        // Trash the temporary file
        file.setTrashed(true);
      }
    }

    // Send the PDF to any email address
    MailApp.sendEmail('myemail@gmail.com',
      'transfer email as pdf : body & attachment',
      'see attachment', {
        attachments: attachmentList
      });

    // Message Processed; Remove the Google Drive Label
    GmailApp.getUserLabelByName(gLabel)
      .removeFromThread(thread[x]);
  }
}

Code was put through a prettifier.




回答2:


this code I wrote a while ago does the job if the attachement is in a format that can be converted to pdf. It gets the message in the last thread and sends both body and attachment only if an attachment is present. This is a test script.

function getAttachAndBody(){
  var firstThread = GmailApp.getInboxThreads(0,1)[0];
  var message = firstThread.getMessages()[0];
  var attach = message.getAttachments();
  var body = message.getBody();//is a string
  var bodydochtml = DocsList.createFile('body.html', body, "text/html")
  var bodyId=bodydochtml.getId()
  var bodydocpdf = bodydochtml.getAs('application/pdf').getBytes();
  if(attach.length>0){
    var file=DocsList.createFile(attach[0])
    var pdf=file.getAs('application/pdf').getBytes();
    var attach_to_send = {fileName: 'pdftest.pdf',content:pdf, mimeType:'application/pdf'};
    var body_to_send = {fileName: 'body.pdf',content:bodydocpdf, mimeType:'application/pdf'};
//    MailApp.sendEmail('xxxxxxx@gmail.com', 'transfer email as pdf : body ', 'see attachment', {attachments:[body_to_send]});
    MailApp.sendEmail('xxxxxxx@gmail.com', 'transfer email as pdf : body & attachment', 'see attachment', {attachments:[attach_to_send,body_to_send]});
    file.setTrashed(true);
    DocsList.getFileById(bodyId).setTrashed(true)
    }
}


来源:https://stackoverflow.com/questions/16946168/automatically-convert-emails-with-a-gmail-label-to-pdf-and-send-it-to-an-email-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!