arul selvan
arul selvan

Reputation: 624

Save Email as PDF

I am trying to save the emails received as PDF in a Drive folder. It is working all right when I run it once. When I run the function once more, the mail PDF (with the same name=subject of the email) is created again. I wan the old PDF to be deleted before saving the new PDF (as it may have some new emails in the same thread)

      var tempFile = DriveApp.createFile("temp.html", html, "text/html");
      if (spfolder.getFilesByName(subject + ".pdf").hasNext()) {
          var ofile=spfolder.getFilesByName(subject + ".pdf");
          ofile[0].setTrashed(true);
          spfolder.createFile(tempFile.getAs("application/pdf").setName(subject + ".pdf"));
          tempFile.setTrashed(true);
      } else {      
        spfolder.createFile(tempFile.getAs("application/pdf").setName(subject + ".pdf"));
        tempFile.setTrashed(true);
      }

It gives an error "TypeError: Cannot read property 'setTrashed' of undefined" when running for the second time.

Upvotes: 0

Views: 281

Answers (1)

iansedano
iansedano

Reputation: 6481

How to save a thread as a PDF

/**
 * @param {string} subject - the subject of the thread
 */
function saveEmailAsPdf(subject) {
  // first searches for the subject thread
  const threads = GmailApp.search(`subject:${subject}`)

  if (threads.length != 1) throw "either no message found or too many threads found"

  // gets the HTML
  const html = threads[0].getMessages().reduce((html,message)=>{
    html += message.getBody()
    html += "\n"
    return html
  },"")

  // creates the temp HTML
  const tempFile = DriveApp.createFile("temp.html", html, "text/html");
  
  // Deletes the old file if it exists
  const existingFileQuery = DriveApp.searchFiles(`title contains "${subject}.pdf"`)

  if (existingFileQuery.hasNext()) {
    existingFile = existingFileQuery.next()
    existingFile.setTrashed(true)
    if (existingFileQuery.hasNext()) throw "more than one file found"
  }

  // creates new pdf version and trashes the temp file.
  const pdf = DriveApp.createFile(tempFile.getAs('application/pdf')).setName(`${subject}.pdf`)
  tempFile.setTrashed(true)
}

// This is how I tested it with an email with subject `0000123`
function test(){
  saveEmailAsPdf("0000123")
}

The order of operations is very important, and I suspect this is what was making your code only work the first time.

  1. Get the email and build the HTML string.
  2. Create the temporary HTML file.
  3. Check if the PDF has already been created during a previous execution of the function, if so, trash it.
  4. Create the new PDF from the HTML file.
  5. Trash the temporary file.

If you are having issues with DriveApp then you might try to reauthorize it. Or is your Apps Script project linked to a GCP project?

References

Upvotes: 1

Related Questions