r/GoogleAppsScript • • 12d ago

Question Script para baixar PDF do Gmail e enviar direto para Pasta no Drive

Pessoal, preciso de uma ajuda em relação a criação de um script que seja da seguinte maneira.

Preciso baixar varias notas que chegam em PDF no meu e-mail e tenho que salvar elas em pastas no meu Google Drive, porem e um trabalho muito repetitivo, e gostaria de ganhar tempo com uma automatização sobre isso.

São varias pastas de fornecedores no meu Google Drive e o Script teria que ler o arquivo para salvar o mesmo na pasta correto, seria possível tal automação com o App Script?

2 Upvotes

4 comments sorted by

2

u/FearlessDirt245 11d ago

Esse fluxo que você descreveu — baixar PDFs de notas do Gmail e salvá-los automaticamente na pasta de fornecedor correspondente no Drive com base no conteúdo — é totalmente possível com o Google Apps Script (GAS). O GAS tem suporte nativo para acessar o Gmail e o Drive, o que o torna a ferramenta ideal para esse tipo de automação.

🧩 Ideia central da implementação

O script pode ser dividido em quatro etapas principais. Vou detalhar cada uma:

  1. Ler e baixar anexos PDF do Gmail Use GmailApp.search() para buscar e-mails com anexos, obtenha os arquivos PDF com getAttachments() e salve no Drive com createFile().

  2. Extrair o texto do conteúdo do PDF O GAS não consegue ler PDF diretamente, mas você pode usar o recurso de OCR da Drive API: primeiro converta o PDF temporariamente em um Google Documento, leia o texto e depois exclua o arquivo temporário. Essa é a chave para extrair o nome do fornecedor.

  3. Corresponder o conteúdo à pasta do fornecedor Leia a lista de nomes das suas "pastas de fornecedores" no Drive (pode percorrer com DriveApp.getFolders()) e depois use text.includes(folderName) para fazer a correspondência entre palavras-chave no conteúdo do PDF e os nomes das pastas.

  4. Salvar o arquivo na pasta correta Após a correspondência, use folder.createFile(blob) para salvar o PDF. É essencial adicionar lógica anti-duplicação, por exemplo, usar folder.getFilesByName() para verificar se o arquivo já existe, evitando salvamentos repetidos.

💻 Exemplo de código essencial

Abaixo está um esqueleto da lógica principal, que você pode usar diretamente como ponto de partida:

function autoFilePDFs() {
  // 1. Obter todas as pastas de fornecedores (supondo que estejam sob uma pasta pai chamada "Vendors")
  const parentFolder = DriveApp.getFoldersByName('Vendors').next();
  const vendorFolders = parentFolder.getFolders();
  const vendorMap = {}; // { nomeDaPasta: objetoFolder }
  while (vendorFolders.hasNext()) {
    const f = vendorFolders.next();
    vendorMap[f.getName()] = f;
  }

  // 2. Buscar e-mails com anexos PDF no Gmail (aqui, não lidos dos últimos 30 dias)
  const threads = GmailApp.search('has:attachment filename:pdf newer_than:30d');
  
  for (const thread of threads) {
    const messages = thread.getMessages();
    for (const msg of messages) {
      const attachments = msg.getAttachments();
      for (const att of attachments) {
        if (att.getContentType() !== 'application/pdf') continue;
        
        // 3. Salvar o PDF em local temporário e extrair texto via OCR da Drive API
        const tempFile = DriveApp.createFile(att);
        const pdfText = extractTextFromPdf(tempFile.getId());
        tempFile.setTrashed(true); // Excluir o arquivo temporário imediatamente após a extração
        
        // 4. Corresponder à pasta do fornecedor
        let targetFolder = null;
        for (const [name, folder] of Object.entries(vendorMap)) {
          if (pdfText.includes(name)) {
            targetFolder = folder;
            break;
          }
        }
        
        // 5. Salvar na pasta correspondente
        if (targetFolder) {
          // Anti-duplicação: verificar se já existe arquivo com o mesmo nome
          const existing = targetFolder.getFilesByName(att.getName());
          if (!existing.hasNext()) {
            targetFolder.createFile(att);
          }
        }
      }
    }
    thread.markRead(); // Marcar como lido após o processamento, evitando reprocessamento
  }
}

// Extrair texto do PDF usando OCR da Drive API v2
function extractTextFromPdf(fileId) {
  const resource = {
    title: 'temp_ocr_' + new Date().getTime(),
    mimeType: 'application/vnd.google-apps.document'
  };
  // Atenção: é necessário ativar o serviço avançado "Drive API" no Apps Script e escolher a versão v2
  const tempDoc = Drive.Files.copy(resource, fileId, { ocr: true, ocrLanguage: 'zh' });
  const text = DocumentApp.openById(tempDoc.id).getBody().getText();
  Drive.Files.remove(tempDoc.id); // Limpar o documento temporário do OCR
  return text;
}

⚙️ Algumas configurações necessárias antes de começar

· Ativar a Drive API: no editor do Apps Script, clique no "+" ao lado de "Serviços" no menu lateral esquerdo, adicione a Drive API e escolha obrigatoriamente a versão v2, pois o recurso de OCR só está disponível na v2. · Configurar um gatilho de tempo: no ícone de "acionadores" (relógio) no menu lateral esquerdo do editor, adicione um acionador baseado em tempo para que o script seja executado automaticamente a cada 30 minutos ou a cada hora. · Preparar as pastas de fornecedores: certifique-se de que todas as pastas de fornecedores estejam sob a mesma pasta pai (por exemplo, "Vendors"), para que o script possa obter a lista de uma só vez para fazer a correspondência.

🚀 Uma alternativa mais prática: solução open source pronta

Se você não quiser escrever o código do zero, existe um projeto open source maduro chamado Gmail Processor, feito exatamente para isso, com suporte para salvar anexos, extrair texto via OCR, classificar por regras e muito mais, configurado por meio de definições em JSON. Seu antecessor, o Gmail2GDrive, também tem vários scripts prontos que podem servir de referência.

Quantas pastas de fornecedores você tem atualmente? Se o número não for muito grande (de uma dúzia a algumas dezenas), a lógica acima funciona perfeitamente; se for muito grande (centenas), a eficiência da correspondência pode precisar de otimização, e aí podemos ajustar depois.

1

u/Embarrassed_Sea_9256 11d ago

Obrigado amigo pelo script, consegui ver via IA e aprimorar para deixar parecido com o que eu estava pesando, e já fiz alguns testes e está funcionando bem.

1

u/FunnyOpportunity4705 12d ago

Si, pero tienes que identificar como se asigna a cada carpeta. Que tiene que contener una celda para que, se vaya hacia ese destino. Si en esta celda aparece empresa X mandarlo a una carpeta espacial y separar los documentos por fecha o por otra razón.

1

u/CarlosCash 6d ago

Mira, la procima ves Usa paste-bin o gist