Enviar un mail con archivos adjuntos desde Google Sheets

Enviar un correo con adjunto en Google Sheets

Hoy vamos a aprender como enviar un mail con archivos adjuntos desde Google Sheets

Enviando un correo básico

Ya vimos en otro artículo como enviar un correo desde Sheets, conectándose con Gmail

Es una línea muy sencilla

MailApp.sendEmail(mail,asunto,mensaje)

Aquí un ejemplo real

function enviarCorreoConAdjuntos() {      MailApp.sendEmail("jsguzmanb@gmail.com","Asunto de prueba","Mensaje de prueba");
}

Opciones adicionales para el envío de correos

Hasta ahí todo bien

Sin embargo podemos mejorar nuestros correos con opciones adicionales

Entre estas opciones están:

  • Agregar un mensaje Html
  • Poner un nombre
  • Determinar si no se puede responder este correo
  • Determinar desde que correo enviarlo (si manejamos alias)
  • Incluir correos en copia
  • Incluir correos en copia oculta
  • Incluir archivos adjuntos

Para esto vamos a usar un cuarto argumento de opciones que consiste en un corchete y dentro de los corchetes van las opciones así:

MailApp.sendEmail("jsguzmanb@gmail.com",
"Asunto de prueba",
"Mensaje de prueba",
  {name:"Correo de Prueba",
   cc:"pedritoq@gmail.com",
   bcc:"juanchito@gmail.com",
   htmlBody:"<h1>Hola!</h1>",
   noReply:true,
   replyTo:"info@juansguzman.com",
   attachments:archivo
})

Despues te cuento acerca de las otras opciones (Muchas se explican solas).

Pero hoy me voy a concentrar en el tema de los adjuntos. Entonces hablemos de la opción attachments

MailApp.sendEmail("jsguzmanb@gmail.com",
"Asunto de prueba",
"Mensaje de prueba",
  {
   attachments:[blob]
})

Attachments es un arreglo de archivos

Cada archivo debe ser lo que se conoce como un blob, que no es más que un tipo de archivo específico

Los blobs se pueden crear de cero, o convertir a partir de otros archivos

Podemos crear blobs con cualquier texto con la función Utilities.newBlob()

Esta función tiene 3 argumentos:

  • El texto que va a ir en el archivo
  • El tipo de archivo
  • El título

Aquí creamos un archivo de texto

var blob = Utilities.newBlob("Hola Mundo",MimeType.PLAIN_TEXT,"Mi primer texto Hola Mundo");

Y aquí creamos un PDF

var blob = Utilities.newBlob("Hola Mundo",MimeType.PDF,"Mi primer texto Hola Mundo");

Tambien podemos crear blobs a partir de documentos

Aquí podemos usar dos funciones: getBlob() y getAs();

La primera no tiene mas argumentos, a la segunda hay que incluirle el tipo de archivo

Aquí hacemos un ejemplo con un libro de Sheets

var libro=SpreadsheetApp.getActiveSpreadsheet();
  var blob = libro.getBlob();

Y aquí un ejemplo con un documento de Google Docs

docId="1pBo9yiWGx67675hMx7iQuW76uoKSQLuYrhAx"
const archivoDoc=DriveApp.getFileById(docId);
pdfBlob = archivoDoc.getAs(MimeType.PDF);

Fíjate que en estos casos no tengo que “exportar” el archivo a Drive ni a ningun lado

Todo se crea dentro del codigo y se destruye al momento de enviarse el correo

Resumiendo, primero creamos el archivo en una variable blob, y despues incluimos este blob en la opción attachment del método sendMail()

Adjuntando archivos de Drive

Una segunda opción es traer archivos de Drive y adjuntarlos

Hay varias formas de traer los archivos a nuestro código

La forma más fácil es teniendo el id del archivo con .getFileById()

Una vez traemos el archivo, lo convertimos a blob con la funcion getAs

Aquí un ejemplo:

function enviarCorreoConAdjuntos() {
  const archivo=DriveApp.getFileById("1tyGGMqcnamrJfzi88r-1PYimOfjqZZlK")
  const blob=archivo.getAs(MimeType.PDF)
  MailApp.sendEmail("jsguzmanb@gmail.com",
    "Asunto de prueba",
    "Mensaje de prueba",
    {
      attachments: [blob]
    });
}

No hay necesidad de crear el blob por aparte, podemos acortar nuestro código así

function enviarCorreoConAdjuntos() {
  const archivo=DriveApp.getFileById("1tyGGMqcnamrJfzi88r-1PYimOfjqZZlK")
  con
  MailApp.sendEmail("jsguzmanb@gmail.com",
    "Asunto de prueba",
    "Mensaje de prueba",
    {
      attachments: archivo.getAs(MimeType.PDF)
    });
}

Adjuntar archivo desde Sheets con el id

Este método anterior funciona muy bien para cuando solo tenemos un archivo y ese es el que siempre vamos a adjuntar, como por ejemplo el brochure de la empresa

Pero en otros casos vamos a querer estar cambiando el id del adjunto en el código, y puede ser desgastante operativamente.

En estos casos sería más fácil poder pegar el id en una celda al frente del email y enviarlo con un botón

El código en este caso sería

function enviarCorreoConAdjuntos() {

//Conexión con Sheets
  const hoja=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Datos")

//Traer email y adjunto
  const email=hoja.getRange('A2').getValue()
  const idArchivo=hoja.getRange('B2').getValue()

//Traer archivo
  const archivo=DriveApp.getFileById(idArchivo)

//Generar blob
  const blob=archivo.getAs(MimeType.PDF)

//Enviar mail
  MailApp.sendEmail(email,
"Asunto de prueba","Mensaje de prueba",  {attachments: [blob]
});
}

Adjuntar archivo desde Sheets con el url

La verdad es que traer este id puede ser desgastante y da para errores.

Podemos extraer este id de la URL con una fórmula de expresión regular así:

=REGEXEXTRACT(B2;”d/(\w+)”)

Así quedaría nuestra base

Y simplemente cambiamos la celda de donde saca el ID en nuestro código

//Traer adjunto
const idArchivo=hoja.getRange('B3').getValue()

Claro que esta operación de extracción también la podemos hacer directamente desde el código así, sin necesidad de tener otra columna

//Traer adjunto 
var idArchivo=hoja.getRange('B2').getValue()
  idArchivo=idArchivo.match(/d\/([0-9A-Za-z_]+)/)[1];

Enviar desde cualquier fila

Ahora imagina que tenemos una tabla con varios correos y varios adjuntos distintos

Quiero enviar al correo de la fila en la que este parado así:

El código sería

function enviarCorreoConAdjuntosDeEstaFila() {
  const hoja=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Datos")
  const rangoActivo=hoja.getActiveRange();
  const filaActiva=rangoActivo.getRow()
  const email=hoja.getRange(filaActiva,1).getValue()
  var idArchivo=hoja.getRange(filaActiva,2).getValue()
  idArchivo=idArchivo.match(/d\/([0-9A-Za-z_]+)/)[1];
   const archivo=DriveApp.getFileById(idArchivo)
  const blob=archivo.getAs(MimeType.PDF)
  MailApp.sendEmail(email,
    "Asunto de prueba",
    "Mensaje de prueba",
    {
      attachments: [blob]
    });
}

Enviar múltiples correos

Ahora quiero enviar correos a todos los de la lista con su respectivo adjunto.

El codigo sería así:

function enviarCorreosMasivosConAdjuntos() {
  const hoja = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Datos")
  const rango = hoja.getDataRange();

  for (i = 2; i <= rango.getLastRow(); i++) {
    const email = hoja.getRange(i, 1).getValue()
    var idArchivo = hoja.getRange(i, 2).getValue()
    idArchivo = idArchivo.match(/d\/([0-9A-Za-z_]+)/)[1];
    const archivo = DriveApp.getFileById(idArchivo)
    const blob = archivo.getAs(MimeType.PDF)
    MailApp.sendEmail(email,
      "Asunto de prueba",
      "Mensaje de prueba",
      {
        attachments: [blob]
      });
  }

}

Conclusión

Enviar adjuntos puede ser intimidante al principio, pero como todo, después de practicar y equivocarse algunas veces, cada vez te sentirás más cómodo haciéndolo.

20 comentarios en “Enviar un mail con archivos adjuntos desde Google Sheets”

  1. Hola Juan, suponiendo que mi google sheets tiene multiples hojas (hoja 1 / hoja 2 / etc) pero sólo quiere enviar adjunta la hoja 1, como debería hacer?

    1. Hola!

      Nos tocaría hacer una copia y quitarles las hojas, es la única que veo

      la copia la hacer con DriveApp,getFileById().makeCopy()

      Saludos!

  2. Hola Juan,

    Como puedo guardar un rango de celdas de Google Sheets en los que se encuentra una tabla con formato, en un PDF y enviarlo automáticamente por correo.
    No estoy buscando enviar datos de una tabla, sino que enviar la tabla completa como si fuera una foto.

    Saludos,
    Rodrigo

  3. Hola! yo tengo generado un google doc a partir de una hoja de calculo. Ya pude adjuntar en el mail un pdf de ese google doc, pero también quisiera adjuntar el archivo en .doc editable. Hay manera?
    Gracias

  4. Monica González

    Hola Juan, muchas gracias por esta información. Quisiera preguntarte si es posible adjuntar el mismo archivo Sheets convertido a PDF y enviarlo por correo, ya que se trata de una cotización y lo que va a estar cambiando constantemente son los datos dentro del mismo archivo pero no el id. No sé si sea posible, pero te agradezco de antemano tu atención, muchas gracias.

  5. Buenas Juan,
    una duda. Estoy tratando de enviar como adjunto una hoja de google sheet, pero sin convertir en pdf. Cuando hago el get, trato de cambiar y establecer la siguiente función file.getAs(MimeType.GOOGLE_SHEETS) para que me la deje en ese formato, pero me dice que el var file = DriveApp.getFileById(‘xxxxxxxx’) sólo me deja convertir a pdf…

    ¿Como puedo hacerlo? ando un poco perdido.

    Gracias

    1. Hola Ivan

      Lo que pasa es que los documentos de Google no pueden adjuntarse. Podrías tratar de convertirlo a excel o simplemente enviar el link

      Un gran saludo!

  6. Hola Buenas,

    Quiero usar el codigo que tienes puesto para enviar un correo con un adjunto del Drive, en este caso un google sheet pero en formato excel.

    He copiado y pegado el código y modificado el id y me sale el siguiente error:

    Exception: Unexpected error while getting the method or property getFileById on object DriveApp.

    Me podrías indicar cual es el problema, he mantenido en formato pdf y también he cambiado a xls y no me hace nada.

    Gracias de antemano

    Un saludo

      1. Hola Juan,

        Este es el codigo:

        function enviarCorreoConAdjuntos() {
        const archivo=DriveApp.getFileById(“Idgoogle sheet”)
        const blob=archivo.getAs(MimeType.PDF)
        MailApp.sendEmail(“prueba@hotmail.com”,
        “Asunto de prueba”,
        “Mensaje de prueba”,
        {
        attachments: [blob]
        });
        }

        Lo he copiado igual al tuyo pero lo he adaptado. Si funciona ya pondría todo lo definitivo.
        Se podría poner formato excel?

        Gracias y un saludo
        Armando

  7. Hola Juan, no encuentro en que video lo explicaste.
    Quiero enviar por mail los nuevos datos que se sumaron en una fila y en otro caso
    la fila que se cambio un dato (ejemplo, tengo una columna status, si cambia que mande mail. con toda la fila)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Pin It on Pinterest

Share This