One component when teaching is needing to send e-mails to students that contain announcements or provide feedback. Announcements serve as important reminders and a means to ensure resources are surfaced to students in a condensed way without interacting with a learning management system (LMS) that isn’t streamlined. Meanwhile, feedback is geared to provide insight on how the student is progressing on learning. Specifically, the feedback that is most troublesome to distribute is that with group-related projects.
With this being said, communications to students need to come from an official university e-mail account. Alas, setting up means to send e-mails outside of approved applications is problematic. Furthermore, R doesn’t offer many packages for working within the Exchange/Office365 oriented world.
Overview of E-mail Generation Packages for R
Unfortunately, that means that gmailr
by Jim Hester – which connects only to Google’s GMail service – is out.
If we go further down the rabbit’s nest, we would find mailR
and sendmailR
. As I work mainly on a Mac, the first part of new package adoption is checking to see if there is a dependency on rJava
. The rJava
package is a headache to properly configure and, unlike C++, must be present for the CRAN package binary to work. If I even try to use the mailR
package, I would get:
library("mailR")
# Error: package or namespace load failed for 'mailR':
# .onLoad failed in loadNamespace() for 'rJava', details:
# call: dyn.load(file, DLLpath = DLLpath, ...)
# error: unable to load shared object
# '/Library/Frameworks/R.framework/Versions/3.6/Resources/library/rJava/libs/rJava.so':
# dlopen(/Library/Frameworks/R.framework/Versions/3.6/Resources/library/rJava/libs/rJava.so, 6): Library not loaded:
# /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/lib/server/libjvm.dylib
# Referenced from: /Library/Frameworks/R.framework/Versions/3.6/Resources/library/rJava/libs/rJava.so
# Reason: image not found
Then, we’re left with sendmailR
. Alas, this just isn’t that powerful of a package.
Having said this, there is one more entrant: blastula
by Richard Iannone. If you’ve ever tried to send automated e-mail before, this package revolutionizes the concept. Once you’ve used it, there is no going back.
Setup Credentials for Bastula
One of the first steps with bastula
is to setup an SMTP credential. These credentials will allow for e-mail to be sent from R easily. Moreover, the overarching process is painless.
For UIUC, the approach taken is:
install.packages(c("blastula", "keyring"))
# Run once to generate credentials
::create_smtp_creds_key(
blastulaid = "UIUCExchange", # Name the Credential
user = "netid@illinois.edu", # User E-mail Address
provider = "office365", # Provider
use_ssl = TRUE # Ensure SSL is used
)
Sample e-mail meta data
When sending e-mails to groups of students, the e-mail sent to each group will have a similar structure with only slight changes related to specific feedback. Approaching e-mail construction in this manner provides a way for automatically composing and sending uniform e-mails. Moreover, the feedback is no longer codified in a single LMS system and can easily be reference or added onto to future assignments.
For generating group e-mails, the most important part is the meta-data for each group alongside of a message. Metadata in this case is:
What is the group identifier? What is the group name? Who belongs to the group?
In practice, this can be structured like so:
# Randomly generate some data
= 5
n
= data.frame(
email_group_df group_id = seq_len(n),
group_shortname = replicate(n, paste0(sample(letters, 10), collapse = "")),
group_emails = replicate(n, paste0("netid",sample(10, 2), "@illinois.edu", collapse = ";")),
group_msg = replicate(n, paste0("- name, netid",sample(10, 2), "@illinois.edu", collapse = "\n\n"))
)
email_group_df
group_id | group_shortname | group_emails | group_msg |
---|---|---|---|
1 | iqdhjngeut | netid2@illinois.edu;netid3@illinois.edu | - name, netid2@illinois.edu;- name, netid1@illinois.edu |
2 | lomsjetihu | netid10@illinois.edu;netid2@illinois.edu | - name, netid3@illinois.edu;- name, netid4@illinois.edu |
3 | qzbiutxosf | netid4@illinois.edu;netid3@illinois.edu | - name, netid1@illinois.edu;- name, netid9@illinois.edu |
4 | ulogyhbtms | netid5@illinois.edu;netid8@illinois.edu | - name, netid4@illinois.edu;- name, netid10@illinois.edu |
5 | otdqhvxurm | netid6@illinois.edu;netid3@illinois.edu | - name, netid5@illinois.edu;- name, netid9@illinois.edu |
Templating and Sending E-mail
With the group data in hand and formatted nicely, the next step is to write an e-mail template. There are three ways to structure the template with: text, using markdown via blastula::md()
, or using block-based HTML via blastula::blocks()
. I haven’t explored yet the
For simplicity, I’ve opted to create a function that covers the template.
library(blastula)
library(glue)
= function(group_data) {
group_email_template
# Customize e-mail title
= group_data %>%
title glue_data("[STAT 430 - FDL] {group_id} {group_shortname} Roster")
# Construct the e-mail for the Team.
= group_data %>%
email glue_data(
"Team **{group_shortname}**,\n\n\n\n",
"Hope all is well! In this e-mail, we details of your team assignment. \n\n\n\n",
"**Team ID**: {group_id} \n\n\n\n",
"The following students are part of your team:\n\n\n\n",
"{group_msg} \n\n\n\n"
%>%
) md() %>%
compose_email(title = title)
= list("email" = email, "title" = title)
out
return(out)
}
Next, let’s construct and send the e-mail for each team.
for (i in seq_len(nrow(email_group_df))) {
# Retrieve current team
= email_group_df[i, ]
group_data
# Construct the e-mail using our custom template.
# Returns a list with `email` and `title`
= group_email_template(group_data)
email_contents
# Generate a to-field
= strsplit(group_data$group_emails, ";")[[1]]
to
# Send e-mail
$email %>%
email_contentssmtp_send(
from = "netid@illinois.edu",
to = to,
subject = email_contents$title,
credentials = creds_key(id = "UIUCExchange")
) }
Fin
Voila! All the groups now have an e-mail with the same fundamental structure but specific content. This process was done seamlessly as blastula
handled the difficulties with authentication and e-mail formatting.