Usar el correo electrónico desde R para enviar calificaciones (o cualquier cosa...)

Me he vuelto a encontrar en esta última temporada de exámenes con un problema que no es nuevo: cómo hacer llegar a los alumnos sus calificaciones a la vez que se respetan los requisitos de privacidad. Aunque hay otras soluciones, una posibilidad pasa por enviar a cada alumno un correo electrónico con su calificación (opcionalmente con el examen corregido como adjunto, etc.)

En el pasado he probado varias librerías de R que abordan el problema de enviar correos electrónicos. Algunos escollos con los que me he topado en esos intentos eran los requisitos de esas librerías, la compatibilidad con distintas plataformas de correo o la disponibilidad de la librería para distintos sistemas operativos. En este post del blog de Mailtrap se describen algunas de esas librerías y la forma de usarlas en distintos escenarios. Pero aquí me quiero centrar en el uso de una cuenta de correo de plataformas como Gmail, Outlook o similar para enviar unas pocas decenas de correos, como sucede típicamente con los resultados de los exámenes de una asignatura. Alternativamente, el post de Mailtrap explica como usar algunas de esas librerías si, por ejemplo, se dispone de un servidor SMTP propio o se deben gestionar un volumen mayor de correo.

Ese post de Mailtrap me llevó a descubrir la librería emayili de Andrew Collier (datawookie), que no conocía. Se puede leer algo más sobre esa librería en este post.

Para instalar la librería si somos usuarios de Rstudio podemos usar el mecanismo habitual a través del panel Packages. O en cualquier caso ejecutando:

install.packages("emayili") 

La documentación de emayili describe también como instalar la última versión desde su repositorio en GitHub.

Vamos a suponer que tenemos las notas de nuestros alumnos en un fichero. Si se trata de un fichero csv es muy fácil leerlo desde R, así que me voy a centrar en el caso de ficheros Excel porque es una situación bastante común. Supongamos que tenemos un fichero con una estructura básica parecida a la de la siguiente tabla, que contiene en sus columnas la información de nuestros alumnos: nombre, apellidos, direcciones de correo y notas.

Apellido    Nombre    Correo                Nota
Ap1         N1        N1_Ap1@correoAlumno.com   10
Ap2         N2        N2_Ap2@correoAlumno.com   10
Ap3         N3        N3_Ap3@correoAlumno.com   10

Aquí tienes esos datos en un fichero Excel de ejemplo llamado notas.xlsx por si quieres ejecutar el código en tu máquina.

Empezamos cargando las librerías necesarias:

library(emayili)
library(readxl) 
library(getPass)
library(svDialogs)

Aparte de emayili vamos a usar readxl para leer el fichero Excel y las librerías svDialogs y getPass para que R nos solicite el usuario y password de nuestro servidor de correo sin necesidad de almacenarlo en el fichero de código de R (¡muy desaconsejable!).

Esos datos, nuestro nombre de usuario y password, se leerán con este código:

usuario = dlg_input("Intropduce tu dirección de correo o nombre de usuario en el servidor")$res
mailPass = getPass(msg = "Escribe ahora el password de tu cuenta de correo:")

Al ejecutarlo se abren sendos cuadros de diálogo y los datos necesarios se almacenan en esas variables. Además vamos a definir el nombre del examen o asignatura:

asignatura = "Chorlitografía cuantitativa"

Para poder enviar correo es imprescindible disponer de un par de datos sobre nuestro servidor. Lo normal, si no los conoces ya, es que los servicios informáticos de tu centro te proporcionen esa información para que puedas configurar un cliente de correo electrónico. Necesitas una pareja de valores como estos:

servidorSMTP = "outlook.office365.com"
puerto = 587

Puedes mirar esta página de Microsoft para hacerte un idea de cuáles son los valores típicos.

El siguiente paso es leer el fichero Excel que contiene las notas. En este ejemplo el código asume que el directorio de trabajo de R contiene ese fichero Excel. Si no es así hay que modificar el código para indicar la ubicación del fichero. Además el código asume también que la estructura del fichero de notas es tan sencilla como la del fichero de ejemplo que he incluido. Es decir, que no contiene filas de cabecera o columnas extra con otros datos, etc. En muchos casos el fichero del que dispones no te lo pondrá tan fácil. Puedes optar entre “limpiar” previamente los datos para preparar un fichero de Excel sencillo o usar las opciones que ofrece read_excel para seleccionar la parte relevante del fichero Excel. A modo de ejemplo he incluido una línea de código comentada en la que se indica como seleccionar una parte del fichero Excel eligiendo la hoja y las filas y columnas.

notas = read_excel("notas.xlsx")
# notas = read_excel("notas.xlsx", range = "B11:F60", sheet = 4)

Para situaciones más complejas me remito a la documentación de readxl.

Una vez leídos los datos si fuera necesario podríamos proceder a una segunda etapa de limpieza y procesado dentro de R. En este ejemplo tan básico no es necesario pero, dado que lo más fácil es usar readxl para leer porciones rectangulares de filas y columnas contiguas, típicamente habrá que eliminar algunas columnas extra, filtrar alumnos (por grupos, convocatoria, etc.) antes de seguir adelante.

Ahora usaremos emayili para enviar su calificación a cada alumno. Por razones de claridad lo vamos a hacer mediante un sencillo bucle for que irá recorriendo las filas de nuestro conjunto de datos y enviando por turno cada una de las calificaciones. El mensaje tendrá formato HTML para ampliar las posibilidades de incluir formatos, figuras, etcétera si se desea, aunque para este ejemplo vamos a obtener unos mensajes muy básicos. El código es este, explicado mediante comentarios intercalados:

# El valor de i indica en que fila/alumno de la tabla estamos.
for(i in 1:nrow(notas)){
  # Leemos el nombre de cada alumno.
  nombreAlumno = notas$Nombre[i]
  # La variable html_msg se va modificando para añadir el código HTML del mensaje.
  html_msg = "<html><body>"
  
  # Aquí los datos de la tabla se insertan en el texto del mensaje.
  html_msg = paste0(html_msg, "<p>Hola, ",nombreAlumno,".</p>
                     <p>Tu nota en la asignatura ", asignatura," es: " )
  html_msg = paste0(html_msg, notas$Nota[i])
  
  html_msg = paste0(html_msg, "</p>
                    <p>Gracias por tu trabajo en la asignatura y saludos.</p>
                    </body></html>")
  
  # Formateo final del mensaje.
  html_msg = sprintf(html_msg)
  
  # Leemos la dirección de ese alumno en la tabla.
  emailAlumno = notas$Correo[i]
  
  # Ahora creamos el mensaje con la función envelope de emayili
  email = envelope() %>%
    from(usuario) %>%
    to(emailAlumno) %>%
    # Descomenta la siguiente línea para incluir una dirección de copia oculta bcc.
    # bcc("alguien@algunSitio.com") %>% 
    subject(paste0("Nota de la asignatura ", asignatura)) %>% 
    # Aquí se añade el código HTML del mensaje.
    html(html_msg) 
  
  # Creamos una conexión al servidor de correo con sus datos.
  smtp = server(host = servidorSMTP,
                 port = puerto,
                 username = usuario,
                 password = mailPass)
  # Y lo enviamos así. 
  # La opción verbose muestra detalles del envío en la consola de R.
  smtp(email, verbose = TRUE)  
  }

Y eso es todo para este ejemplo tan sencillo. Con algunos conocimientos básicos de R y HTML es muy fácil adaptar ese ejemplo para crear mensajes mucho más expresivos, tanto en formato como en contenido. Entre otras muchas cosas que se nos pueden ocurrir, mensajes que incluyan adjuntos, de manera que cada alumno reciba su examen corregido o la solución del examen, etc. La documentación de emayili es un buen punto de partida para seguir descubriendo todas sus posibilidades.

Fernando San Segundo
Fernando San Segundo
Profesor Colaborador Asociado - Doctor

My research interests include Applied Mathematics, Data Analysis, Scientific Computation and Mathematical Modelling.

Related