// =================================================== // O ROBÔ QUE SABE PARAR — a Sonda (NÃO SOU PROGRAMADOR, Livro 1) // =================================================== // Varre os rascunhos do Gmail. Só nos que o assunto termina // exatamente em [ENVIAR], anexa o currículo, apaga a marca e envia. // Rascunho sem a marca: o robô não faz nada. De propósito. // Duas linhas para conferir ou trocar (capítulo 4 do livro): // A marca que autoriza o envio. var MARCA = "[ENVIAR]"; // O nome exato do arquivo, dentro da pasta Sonda. var ARQUIVO = "curriculo.pdf"; // Nome da pasta no seu Google Drive. Precisa estar em Meu Drive // (não em Compartilhados comigo) — ver capítulo 3 do livro. var PASTA = "Sonda"; function roboDaSonda() { var rascunhos = GmailApp.getDrafts(); Logger.log(rascunhos.length + " rascunho(s) encontrado(s) no total."); var curriculo = buscarCurriculo_(); if (!curriculo) { Logger.log('curriculo.pdf não encontrado na pasta "' + PASTA + '" — nenhum rascunho marcado será enviado nesta execução.'); } for (var i = 0; i < rascunhos.length; i++) { processarRascunho_(rascunhos[i], curriculo); } } function processarRascunho_(rascunho, curriculo) { var mensagem = rascunho.getMessage(); // O .trim() tira espaço sobrando no fim do assunto. Um espaço depois do // [ENVIAR] é invisível na tela e, sem isso, o robô não reconheceria a marca // e você não teria como descobrir o porquê. var assunto = (mensagem.getSubject() || "").trim(); // A comparação ignora maiúscula e minúscula: [enviar] também vale. var fim = assunto.substring(assunto.length - MARCA.length); var temMarca = assunto.length >= MARCA.length && fim.toUpperCase() === MARCA.toUpperCase(); if (!temMarca) { // Freio de mão: sem a marca no fim do assunto, o robô ignora. Nada é logado // aqui de propósito — rascunho sem marca não é um evento, é o padrão. return; } if (!curriculo) { // Falha segura: sem o anexo, não envia. O rascunho marcado fica intacto, // pronto para ser reprocessado assim que o arquivo existir na pasta. Logger.log('"' + assunto + '": currículo não encontrado — nada foi enviado.'); return; } var novoAssunto = assunto.substring(0, assunto.length - MARCA.length).trim(); // draft.update() SOBRESCREVE o rascunho inteiro — não é um patch. // Por isso lemos e repassamos destinatário, cc, bcc e corpo originais, // além de anexar o currículo aos anexos que já existiam. var destinatario = mensagem.getTo(); var cc = mensagem.getCc(); var bcc = mensagem.getBcc(); var corpoTexto = mensagem.getPlainBody(); var corpoHtml = mensagem.getBody(); var anexos = mensagem.getAttachments().concat([curriculo]); rascunho.update(destinatario, novoAssunto, corpoTexto, { cc: cc, bcc: bcc, htmlBody: corpoHtml, attachments: anexos }); rascunho.send(); Logger.log('enviado: "' + novoAssunto + '" (era: "' + assunto + '")'); } function buscarCurriculo_() { var pastas = DriveApp.getFoldersByName(PASTA); var meuEmail = Session.getActiveUser().getEmail(); while (pastas.hasNext()) { var pasta = pastas.next(); // Só aceita a pasta se ela for sua (Meu Drive). Uma pasta de mesmo nome // em "Compartilhados comigo" tem outro dono e é ignorada — é o que o // capítulo 3 do livro pede para evitar. // Em algumas contas o Apps Script não consegue dizer qual é o seu e-mail // (meuEmail vem vazio). Nesse caso não dá para conferir o dono, e aceitar // a pasta é melhor do que dizer que o currículo não existe com ele lá. var dono = pasta.getOwner(); if (meuEmail && dono && dono.getEmail() !== meuEmail) { continue; } var arquivos = pasta.getFilesByName(ARQUIVO); if (arquivos.hasNext()) { return arquivos.next().getBlob(); } } return null; // Falha segura: sem currículo, robôDaSonda() não envia nada. }