{emayili} Creating Email Threads

R
{emayili}
The ability to specify a message ID in emails sent from the {emayili} package makes it possible to create email threads.
Published

22 Jun 2024 12:00

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.

Thunderbird displaying an email and its reply grouped into a single thread.

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.