Creating Email Threads

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.