Ottieni allegati PDF da Gmail come testo

Ho cercato in tutto il web e Stack Overflow ma non ho trovato una soluzione. Quello che cerco di fare è il seguente: Ricevo determinati allegati via mail che vorrei avere come testo (normale) per un’ulteriore elaborazione. Il mio script assomiglia a questo:

function MyFunction() { var threads = GmailApp.search ('label:templabel'); var messages = GmailApp.getMessagesForThreads(threads); for (i = 0; i < messages.length; ++i) { j = messages[i].length; var messageBody = messages[i][0].getBody(); var messageSubject = messages [i][0].getSubject(); var attach = messages [i][0].getAttachments(); var attachcontent = attach.getContentAsString(); GmailApp.sendEmail("mail", messageSubject, "", {htmlBody: attachcontent}); } } 

Sfortunatamente questo non funziona. Qualcuno qui ha un’idea di come posso farlo? È ansible?

Grazie mille in anticipo.

Il migliore, Phil

Modifica: aggiornato per DriveApp, come DocsList deprecato.


Suggerisco di suddividere questo in due problemi. Il primo è come ottenere un allegato pdf da una email, il secondo è come convertire quel pdf in testo.

Come hai scoperto, getContentAsString() non cambia magicamente un allegato pdf in testo normale o html. Dobbiamo fare qualcosa di un po ‘più complicato.

Innanzitutto, otterremo l’allegato come Blob , una class di utilità utilizzata da diversi Servizi per lo scambio di dati.

 var blob = attachments[0].getAs(MimeType.PDF); 

Quindi, con il secondo problema separato, e mantenendo il presupposto che ci interessa solo il primo allegato del primo messaggio di ciascun thread etichettato come templabel , ecco come appare myFunction() :

 /** * Get messages labeled 'templabel', and send myself the text contents of * pdf attachments in new emails. */ function myFunction() { var threads = GmailApp.search('label:templabel'); var threadsMessages = GmailApp.getMessagesForThreads(threads); for (var thread = 0; thread < threadsMessages.length; ++thread) { var message = threadsMessages[thread][0]; var messageBody = message.getBody(); var messageSubject = message.getSubject(); var attachments = message.getAttachments(); var blob = attachments[0].getAs(MimeType.PDF); var filetext = pdfToText( blob, {keepTextfile: false} ); GmailApp.sendEmail(Session.getActiveUser().getEmail(), messageSubject, filetext); } } 

Ci stiamo affidando a una funzione di supporto, pdfToText() , per convertire il nostro blob pdf in testo, che invieremo a noi stessi come email di testo semplice. Questa funzione di aiuto ha una varietà di opzioni; impostando keepTextfile: false , abbiamo scelto di restituire semplicemente il contenuto del testo del file PDF e non lasciare file residui nel nostro Drive.

pdftotext ()

Questa utility è disponibile come sintesi . Qui sono forniti diversi esempi.

Una risposta precedente indicava che era ansible utilizzare il metodo di insert dell'API Drive per eseguire l' OCR , ma non forniva dettagli sul codice. Con l'introduzione di Servizi Google avanzati, l'API di Drive è facilmente accessibile da Google Apps Script. Devi triggersre e abilitare l' Drive API dall'editor, in Resources > Advanced Google Services .

pdfToText() utilizza il servizio Drive per generare un documento Google dal contenuto del file PDF. Sfortunatamente, questo contiene le "immagini" di ogni pagina nel documento - non molto possiamo fare al riguardo. Quindi utilizza il DocumentService regolare per estrarre il corpo del documento come testo normale.

 /** * See gist: https://gist.github.com/mogsdad/e6795e438615d252584f * * Convert pdf file (blob) to a text file on Drive, using built-in OCR. * By default, the text file will be placed in the root folder, with the same * name as source pdf (but extension 'txt'). Options: * keepPdf (boolean, default false) Keep a copy of the original PDF file. * keepGdoc (boolean, default false) Keep a copy of the OCR Google Doc file. * keepTextfile (boolean, default true) Keep a copy of the text file. * path (string, default blank) Folder path to store file(s) in. * ocrLanguage (ISO 639-1 code) Default 'en'. * textResult (boolean, default false) If true and keepTextfile true, return * string of text content. If keepTextfile * is false, text content is returned without * regard to this option. Otherwise, return * id of textfile. * * @param {blob} pdfFile Blob containing pdf file * @param {object} options (Optional) Object specifying handling details * * @returns {string} id of text file (default) or text content */ function pdfToText ( pdfFile, options ) { // Ensure Advanced Drive Service is enabled try { Drive.Files.list(); } catch (e) { throw new Error( "To use pdfToText(), first enable 'Drive API' in Resources > Advanced Google Services." ); } // Set default options options = options || {}; options.keepTextfile = options.hasOwnProperty("keepTextfile") ? options.keepTextfile : true; // Prepare resource object for file creation var parents = []; if (options.path) { parents.push( getDriveFolderFromPath (options.path) ); } var pdfName = pdfFile.getName(); var resource = { title: pdfName, mimeType: pdfFile.getContentType(), parents: parents }; // Save PDF to Drive, if requested if (options.keepPdf) { var file = Drive.Files.insert(resource, pdfFile); } // Save PDF as GDOC resource.title = pdfName.replace(/pdf$/, 'gdoc'); var insertOpts = { ocr: true, ocrLanguage: options.ocrLanguage || 'en' } var gdocFile = Drive.Files.insert(resource, pdfFile, insertOpts); // Get text from GDOC var gdocDoc = DocumentApp.openById(gdocFile.id); var text = gdocDoc.getBody().getText(); // We're done using the Gdoc. Unless requested to keepGdoc, delete it. if (!options.keepGdoc) { Drive.Files.remove(gdocFile.id); } // Save text file, if requested if (options.keepTextfile) { resource.title = pdfName.replace(/pdf$/, 'txt'); resource.mimeType = MimeType.PLAIN_TEXT; var textBlob = Utilities.newBlob(text, MimeType.PLAIN_TEXT, resource.title); var textFile = Drive.Files.insert(resource, textBlob); } // Return result of conversion if (!options.keepTextfile || options.textResult) { return text; } else { return textFile.id } } 

La conversione a DriveApp è supportata da questa utility di Bruce McPherson :

 // From: http://ramblings.mcpher.com/Home/excelquirks/gooscript/driveapppathfolder function getDriveFolderFromPath (path) { return (path || "/").split("/").reduce ( function(prev,current) { if (prev && current) { var fldrs = prev.getFoldersByName(current); return fldrs.hasNext() ? fldrs.next() : null; } else { return current ? null : prev; } },DriveApp.getRootFolder()); }