How to send bulk email to your students using R
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
mailR
, which proved to be the right tool for this task.A brief outline of the educational process at the UNA
On the necessity of creating a better communicational platform
Why do I employ R with the mailR package for bulk emailing instead of other tools?
sendmailR
, mailR
and gmailr
. The latter package looks interesting and on the author’s GitHub site7, there is a tutorial of sorts on how to set it up for sending bulk emails from a Gmail account, coincidentally with an online course application example such as the one I’m discussing in this post. However, I had tried this package before and for some reason, could not get it to work. In deciding between sendmailR
and mailR
, I considered that mailR
‘s send.mail
function has an option for sending pure text or HTML mails, whereare the equivalent sendmailR
function had text mail only hardcoded within (this is a bug that they apparently fixed now8). Being able to end HTML was important to me, as I wanted to be able to send nicely formatted emails like this one:UNIVERSIDAD NACIONAL ABIERTA CENTRO LOCAL ANZOATEGUI UA EL TIGRE |
Hola PEDRO:
Ante todo quiero desearte éxito en este semestre 2016-1 y particularmente en la primera prueba parcial de la asignatura XXX (código xxx) que presentarás este sábado. El propósito de este mensaje es presentarme: mi nombre es José Romero, soy egresado en la Licenciatura de Matemáticas de la UNA y actualmente, soy el asesor del área de matemáticas en la unidad de apoyo de El Tigre.
Estoy contactando por correo a todos los estudiantes de la asignatura XXX (xxx) de la UNA a nivel nacional para invitarlos a que visiten mi blog.
Huelga decir que en caso de cualquier duda, no dudes en consultarme por el buzón de mensajes del blog o a través de mi correo: [email protected]. (NOTA: No respondas a este correo ya que es una cuenta para envios automatizados solamente). Estoy a tus ordenes,
Atentamente,
José Romero
Materials needed for this experiment
mailR
package, you will need a file with the data of your students: their email addresses, their names, and any other relevant information you wish to convey to them, such as grades, personal feedback for each student, etc. The file needs to be a csv file, which is essentially a text file in which each line is a row of the data table and the fields or columns in each line are separated by a special character such as a comma, a semicolon, or a tab9. If you have your data in a spreadsheet, you can easily convert this to a csv file by using “Save As” and then choosing the “Text/CSV” file type. Indicate the separation character- that will be the same character you indicate when you read in the csv file from R. Your csv file could contain something like this:id lastname firstname gender c_code una_location email_address 12345678 PEREZ PEDRO M 126 02-01 [email protected] 87654321 PEREZ JOSEFINA F 126 02-01 [email protected] : : : : : : : : : : : : : :
Error in ls(envir = envir, all.names = private) : invalid 'envir' parameter
R script for batch emailing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #Batch email sending script #The following function crafts the message for each student, #represented by the x parameter message_text <- function(x) { tmp <- paste(c( '<!DOCTYPE html>', '<html xml:lang="es" lang="es">', '<head>', '<meta http-equiv="content-type" content="text/html;charset=utf-8" />', '<meta name="author" content="José Loreto Romero Palma" />', '<STYLE type="text/css">', 'h1 { text-align: center; font-family: Helvetica, FreeSans; font-size: 40px;', 'font-variant: small-caps }', 'h2 { text-align: center; font-family: Helvetica, FreeSans; font-size: 32px;}', 'h3 { text-align: center; font-family: Helvetica, FreeSans; font-size: 28px;}', 'p { text-align: justify; font-family: Helvetica, FreeSans; font-size: 16px;', 'width: 640px}', 'ul { text-align: justify; font-family: Helvetica, FreeSans; font-size: 16px}', 'td { font-family : Helvetica, FreeSans; font-size: 12px}', '</STYLE>','</head>','<body>', paste(c( paste0("<table><tbody><tr><td width='60px'>", "<IMG SRC='https://lh3.googleusercontent.com/hgDApmnzAf2TrP9lzTUc3U9ZG9", "EBaUn9s9OM4DWD4BXtO6j51GCfgLyfyjTdHJ5G8CfXD6_XeipYaQ=w1366-h768-no' ", "NAME='logo_UNA' ALIGN='LEFT' WIDTH='51' HEIGHT='51' BORDER='0'>", "</td><td width='580px'>UNIVERSIDAD NACIONAL ABIERTA<br/>", "CENTRO LOCAL ANZOATEGUI<br/>UA EL TIGRE</td></tr></tbody></table>"), paste0("<br/>"), paste0("<p>Hola ",x$firstname," ",x$lastname,":</p>"), paste0("<p>", "Ante todo quiero desearte éxito en este semestre 2016-1 y ", "particularmente en la primera prueba parcial de la asignatura ", "XXX (código xxx) que presentarás ", "este sábado. El propósito de este mensaje es ", "presentarme: mi nombre es <b>José Romero</b>, soy egresado en la ", "Licenciatura de Matemáticas de la UNA y actualmente, soy el ", "asesor del área de matemáticas en la unidad de apoyo de El Tigre.</p>"), paste0("<p>", "Estoy contactando por correo a todos los estudiantes de la asignatura ", "XXX (xxx) de la UNA a nivel nacional para invitarlos a que ", "visiten mi <a href='http://unamatematicaseltigre.blogspot.com'", " target='_blank'>blog</a>.</p>", "<p>Huelga decir que en caso de cualquier duda, no dudes en ", "consultarme por el buzón de mensajes del blog o a través de mi ", "correo: <a href=\"mailto:[email protected]\">[email protected]</a>.", " (NOTA: No respondas a este correo ya que es una cuenta para envios ", "automatizados solamente). Estoy a tus ordenes,</p>"),"","", "<p>Atentamente,</p>","<br />","<p>José Romero</p>")), '</body>','</html>'), collapse="") return(tmp) } library(mailR) #note: turn on/off less secure apps access for gmail (?) #note: the daily quota is 100 emails #read in the mailing list in the csv mail_list <- read.csv2("roster.csv",as.is=TRUE) file_h <- file('test.html',open="w") writeLines(message_text(mail_list[1,]),file_h) close(file_h) ext_f <- file("mail.out",open="w") close(ext_f) for (recipient in 1:nrow(mail_list)) { email <- message_text(mail_list[recipient,]) send.mail(from="[email protected]", to=as.character(lista_correos[recipient,]$email_address), subject="Invitation to the unamatematicaseltigre blog", body=email, html=TRUE, authenticate=TRUE, smtp = list(host.name = "smtp.gmail.com", user.name = "mygmail", passwd = "mypasswd", ssl = TRUE), encoding = "utf-8",send=TRUE) print(mail_list[recipient,]) Sys.sleep(runif(n=1,min=3,max=6)) #write each recipient to a file ext_f <- file("mail.out",open="a") writeLines(text=paste0("[",recipient,"] ", paste0(as.character(mail_list[recipient,]),collapse="\t")), sep="\n",con=ext_f) close(ext_f) } |
message_text
that builds the HTML message body for a given recipient. This script produces a message body such as the one shown in the example above. Notice the meta tags in the header defining the CSS to give format to your message and the ability to include images like the UNA logo in line 23-25.mail_list
variable. The read.csv2
function assumes your separation character is a semicolon (;) and the decimal point is the , (this is so in spanish speaking countries). However, you can configure other settings by using the read.table
or read.csv
functions. Lines 59-61 simply write a test message to an HTML file. I usually run the script up to these lines first to ensure that the message text comes out like I want it before starting the batch sending processs. The for
loop in lines 64-83 is responsible for batch emailing to all the students in the roster data frame.recipient
of the for
loop (line 64) is an integer going from 1 to the number of rows in the roster data frame. Bear in mind that the daily quota is 100 emails a day if you are emailing from a free email account like gmail or yahoo. Therefore, if your roster file consists of more than 100 students, you will want to split this up into groups of 100 students, batch sending for each group on different days. Besides, there may be problems while emailing to a particular address that cause the script to stop with an error (the Error in ls(envir = ...
mentioned earlier). Therefore, you need some way of keeping track of the emails that you send.send.mail
function of the mailR
package in lines 66-74. In this example, I'm sending from a fake gmail account: [email protected]. The user name before the ad sign of your gmail address is the one you will pass to the user.name
parameter in line 73. In the same line of code, you also have to indicate the password you use to login to your email account as parameter to passwd
. The host name for gmail addresses is smtp.gmail.com
, but if you use yahoo or some other free email provider, you have to find what the smtp host name is for that provider and indicate it in the host.name
parameter at line 72. A Google lookup should suffice.send.mail
function. This is so my gmail client won't suspect I'm sending emails in "automatic pilot mode" and my account won't be temporarily suspended. For me, random delays between 3 and 6 seconds worked fairly well, but you may want to experiment with higher delay values to be safe.Notes
- See McIsaac and Gunawardena (2002) for an account on the history and theoretical constructs behind distance education.
- See What Is Google+? (An African Perspective), an interesting post by Rotimi Orimoloye for his blog Digital Africa. In it, he argues that Nigerians, who also use Facebook more often than any other social network, should transition into Google+, the latter being more suitable for getting to know who the experts in a particular field are and to engage in learning about these fields.
- See the statistics in the FAQ section of Specific Feeds: https://www.specificfeeds.com/page/faq-email-publishers.
- Michael Hyatt, author of a book titled "Platform: Get Noticed in a Noisy World", is a expert in this subject. I strongly reccomend visiting his blog https://michaelhyatt.com.
- While there are experts on the subject of platforms like Michael Hyatt and the others I have mentioned, I think that out of necessity, I'm on my way to becoming an expert myself on the subject of building a platform with free or freely available tools. I believe that while technology is in some cases widening the gap between the rich and the poor, free and open source technology holds enormous potential as empowering tools for people who, like myself, live in countries with failed economies.
- See Premraj, 2014.
- Hence the acronym CSV: Comma Separated Values. The separation character can be any character you choose. For this example, we will assume the semicolon (;) is the separation character.
Bibliography
- McIsaac, M. S. and Gunawardena, C. N. (2002). Distance Education. [Retrieved November 26 , 2016 from http://www.aect.org/edtech/ed1/pdf/13.pdf.
- WTFPL. (10/18/2016). In Wikipedia, The Free Encyclopedia. [Retrieved 11/15/2016 from: https://en.wikipedia.org/wiki/WTFPL].
- R DEVELOPMENT CORE TEAM (2009). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. ISBN 3-900051-07-0. http://www.R-project.org.
- Premraj, R. (2014). How to send HTML email using R. [Question on Stackoverlow available at: http://stackoverflow.com/questions/19844762/how-to-send-html-email-using-r]..
- YETESOFT.COM. (2015). Email Sending Limit and Send Rate - Gmail, Hotmail, Yahoo! Mail, AOL. [Available at: http://www.yetesoft.com/free-email-marketing-resources/email-sending-limit/].
If you found this post interesting or useful, please share it on Google+, Facebook or Twitter so that others may find it too.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.