The ability to specify a message ID in emails sent from the {emayili}
package makes it possible to create email threads.
Create a Server
First set up the SMTP server details. Credentials are stored in environment variables.
library(emayili)
GMAIL_USERNAME = Sys.getenv("GMAIL_USERNAME")
GMAIL_PASSWORD = Sys.getenv("GMAIL_PASSWORD")
smtp <- gmail(
username = GMAIL_USERNAME,
password = GMAIL_PASSWORD
)
Create a Message ID
Create a suitably unique message ID.
id <- c(letters, 0:9) %>%
sample(size = 24, replace = TRUE) %>%
paste0(collapse = "") %>%
paste0("@mx.google.com")
print(paste("Message ID:", id))
xxvgylax7olu8skv3fzi7h53@mx.google.com
Send a Message with an ID
Now create a message specifying that message ID. Set the sender and receiver to the same email address so that we’ll be able to see the thread in a single inbox.
msg <- envelope(
to = GMAIL_USERNAME %>% address(display = "Receiver"),
from = GMAIL_USERNAME %>% address(display = "Sender"),
subject = "Hello!",
id = id,
# importance = "high",
priority = "urgent"
) %>%
return_path(GMAIL_USERNAME %>% address(display = "Sender"))
Send the message.
smtp(msg, verbose = TRUE)
This is what the message source looks like in my email client:
X-Google-Original-Date: Mon, 24 Jun 2024 06:07:26 GMT
X-Mailer: {emayili}-0.8.0
MIME-Version: 1.0
To: Receiver
From: Sender
Subject: Hello!
Message-ID: <xxvgylax7olu8skv3fzi7h53@mx.google.com>
Priority: urgent
Return-Path: Sender <andrew@fathomdata.dev>
Notice that the specified message ID is included as the Message-ID
header.
Reply on Same Thread
Next we’ll respond to that message. Again we’ll provide a message ID, but this time using the message_id()
utility function. In order to create the thread we specify the message ID from the original message in the In-Reply-To
and References
header fields via the inreplyto()
and references()
methods.
(another_id <- message_id("github.com"))
[1] "a98f51c6-6a97-4639-a91f-328499dee08b@github.com"
msg <- envelope(
to = GMAIL_USERNAME %>% address(display = "Sender"),
from = GMAIL_USERNAME %>% address(display = "Receiver"),
subject = "Hello! (reply)",
id = another_id
) %>%
inreplyto(id) %>%
references(id)
Send the reply.
smtp(msg, verbose = TRUE)
This is the source for the reply in my email client:
Date: Mon, 23 Jun 2024 23:08:28 -0700 (PDT)
X-Google-Original-Date: Mon, 24 Jun 2024 06:08:27 GMT
X-Mailer: {emayili}-0.8.0
MIME-Version: 1.0
To: Sender
From: Receiver
Subject: Re: Re: Hello! (reply)
Message-ID: <a98f51c6-6a97-4639-a91f-328499dee08b@github.com>
In-Reply-To: <xxvgylax7olu8skv3fzi7h53@mx.google.com>
References: <xxvgylax7olu8skv3fzi7h53@mx.google.com>
Notice the generated message ID but that the ID of the original message is included in both the In-Reply-To
and References
header fields.
Thread in Email Client
Finally, check that the thread is recognised by email client.
Yes indeed, Thunderbird recognises that the original message and reply are related and renders them as a thread.
One More Message
Let’s take this one step further, adding a third message to the thread. You could specify the message ID again, but since we won’t be proceeding any further with this thread we’ll just let the SMTP server generate a message ID.
msg <- envelope(
to = GMAIL_USERNAME %>% address(display = "Receiver"),
from = GMAIL_USERNAME %>% address(display = "Sender"),
subject = "Hello! (reply-to-reply)"
) %>%
inreplyto(id) %>%
references(c(id, another_id))
To ensure that all of the messages are linked together specify both the IDs for both of the previous messages in the References
field using the references()
function.
Message-ID: <66792d3d.050a0220.a7692.a572@mx.google.com>
Date: Mon, 23 Jun 2024 23:09:29 -0700 (PDT)
X-Google-Original-Date: Mon, 24 Jun 2024 06:09:28 GMT
X-Mailer: {emayili}-0.8.0
MIME-Version: 1.0
To: Receiver
From: Sender
Subject: Re: Re: Hello! (reply-to-reply)
In-Reply-To: <xxvgylax7olu8skv3fzi7h53@mx.google.com>
References: <xxvgylax7olu8skv3fzi7h53@mx.google.com>
<a98f51c6-6a97-4639-a91f-328499dee08b@github.com>
Message ID Utility
The utility function for generating message IDs has a default domain.
# Using default domain.
message_id()
[1] "8f21fb03-c81a-45ff-abfb-d54e6ea595a5@mail.gmail.com"
You can also provide a specific domain.
# Specific domain.
message_id("github.com")
[1] "326cf080-614b-45a8-870c-4897d21827ff@github.com"
This is the first iteration of this function. Its API will likely evolve as its used and I receive feedback.