Получите pdf-вложения из Gmail в виде текста

Я искал в Интернете и Stack Overflow, но не нашел решения. Я пытаюсь сделать следующее: я получаю определенные вложения по почте, которые я хотел бы иметь как (обычный) текст для дальнейшей обработки. Мой скрипт выглядит так:

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}); } } 

К сожалению, это не работает. У кого-нибудь есть идея, как я могу это сделать? Возможно ли это?

Заранее большое спасибо.

Лучший, Фил

Изменить: обновлено для DriveApp, поскольку DocsList устарел.


Я предлагаю разбить это на две проблемы. Во-первых, как получить вложение PDF из электронной почты, второе – как преобразовать этот текст в текст.

Как вы узнали, getContentAsString() не волшебным образом меняет вложение в pdf на обычный текст или html. Нам нужно сделать что-то более сложное.

Во-первых, мы получим вложение как Blob , class утилиты, используемый несколькими службами для обмена данными.

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

Таким образом, при templabel второй проблемы и поддержании предположения, что нас интересует только первое вложение первого сообщения каждого streamа с меткой templabel , вот как выглядит 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); } } 

Мы полагаемся на вспомогательную функцию, pdfToText() , чтобы преобразовать наш pdf- blob в текст, который мы затем отправим себе как текстовое электронное письмо. Эта вспомогательная функция имеет множество опций; установив keepTextfile: false , мы решили просто вернуть нам текстовое содержимое PDF-файла и не оставлять остаточные файлы на нашем Диске.

pdfToText ()

Эта утилита доступна как сущность . Там представлено несколько примеров.

В предыдущем ответе было указано, что для выполнения OCR можно использовать метод insert API-интерфейса Drive API, но он не предоставил детали кода. Благодаря внедрению расширенных сервисов Google API Drive легко доступен из Google Apps Script. Вам нужно включить и включить Drive API в редакторе в разделе Resources > Advanced Google Services .

pdfToText() использует службу Drive для создания Google Doc из содержимого файла PDF. К сожалению, это содержит «изображения» каждой страницы документа - мы не можем с этим поделать. Затем он использует обычный DocumentService для извлечения тела документа в виде обычного текста.

 /** * 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 } } 

С помощью этой утилиты от Bruce McPherson помогает преобразование в DriveApp:

 // 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()); } 
Давайте будем гением компьютера.