todos - Obtenga archivos adjuntos en formato PDF de Gmail como texto
no puedo descargar archivos adjuntos desde mi celular (1)
Busqué por la web y Stack Overflow pero no encontré una solución. Lo que trato de hacer es lo siguiente: obtengo ciertos archivos adjuntos por correo que me gustaría tener como texto (normal) para su posterior procesamiento. Mi script se ve así:
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});
}
}
Lamentablemente, esto no funciona. ¿Alguien aquí tiene una idea de cómo puedo hacer esto? ¿Es posible?
Muchas gracias por adelantado.
Mejor, Phil
Editar: actualizado para DriveApp, ya que DocsList está en desuso.
Sugiero dividir esto en dos problemas. El primero es cómo obtener un archivo adjunto en PDF de un correo electrónico; el segundo es cómo convertir ese archivo PDF a texto.
Como ha descubierto, getContentAsString()
no cambia mágicamente un archivo adjunto en PDF a texto sin formato o html. Necesitamos hacer algo un poco más complicado.
Primero, obtendremos el archivo adjunto como un Blob
, una clase de utilidad utilizada por varios Servicios para intercambiar datos.
var blob = attachments[0].getAs(MimeType.PDF);
Así que con el segundo problema separado, y manteniendo la suposición de que estamos interesados en solo el primer archivo adjunto del primer mensaje de cada hilo etiquetado como templabel
, así es como se 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);
}
}
Estamos confiando en una función auxiliar, pdfToText()
, para convertir nuestro blob
pdf en texto, que luego nos enviaremos a nosotros mismos como un correo electrónico de texto plano. Esta función de ayuda tiene una variedad de opciones; al establecer keepTextfile: false
, keepTextfile: false
nos devuelva el contenido de texto del archivo PDF y no deje archivos residuales en nuestra unidad.
pdfToText ()
Esta utilidad está disponible como una esencia . Varios ejemplos se proporcionan allí.
Una respuesta anterior indicaba que era posible utilizar el método de insert
la API Drive para realizar OCR , pero no proporcionaba detalles del código. Con la introducción de los servicios avanzados de Google, la API Drive es fácilmente accesible desde Google Apps Script. Debe activar y habilitar Drive API
desde el editor, en Resources > Advanced Google Services
.
pdfToText()
usa el servicio de Drive para generar un Google Doc desde el contenido del archivo PDF. Lamentablemente, contiene las "imágenes" de cada página del documento, no hay mucho que podamos hacer al respecto. A continuación, utiliza DocumentService
normal para extraer el cuerpo del documento como texto sin formato.
/**
* 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 conversión a DriveApp es ayudada con esta utilidad de 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());
}