Managing Threads

The Gmail API uses Thread resources to group email replies with their original message into a single conversation or thread. This allows you to retrieve all messages in a conversation, in order, making it easier to have context for a message or to refine search results.

Like messages, threads may also have labels applied to them. However, unlike messages, threads cannot be created, only deleted. Messages can, however, be inserted into a thread.

Contents

Retrieving threads

Threads provide a simple way of retrieving messages in a conversation in order. By listing a set of threads you can choose to group messages by conversation and provide additional context. You can retrieve a list of threads using the threads.list method, or retrieve a specific thread with threads.get. You can also filter threads using the same query parameters as for the Message resource. If any message in a thread matches the query, that thread is returned in the result.

The code sample below demonstrates how to use both methods in a sample that displays the most chatty threads in your inbox. The threads.list method fetches all thread IDs, then threads.get grabs all messages in each thread. For those with 3 or more replies, we extract the Subject line and display the non-empty ones plus the number of messages in the thread. You'll also find this code sample featured in the corresponding DevByte video.

Python

gmail/snippet/thread/threads.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def show_chatty_threads():
  """Display threads with long conversations(>= 3 messages)
  Return: None

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # create gmail api client
    service = build("gmail", "v1", credentials=creds)

    # pylint: disable=maybe-no-member
    # pylint: disable:R1710
    threads = (
        service.users().threads().list(userId="me").execute().get("threads", [])
    )
    for thread in threads:
      tdata = (
          service.users().threads().get(userId="me", id=thread["id"]).execute()
      )
      nmsgs = len(tdata["messages"])

      # skip if <3 msgs in thread
      if nmsgs > 2:
        msg = tdata["messages"][0]["payload"]
        subject = ""
        for header in msg["headers"]:
          if header["name"] == "Subject":
            subject = header["value"]
            break
        if subject:  # skip if no Subject line
          print(f"- {subject}, {nmsgs}")
    return threads

  except HttpError as error:
    print(f"An error occurred: {error}")


if __name__ == "__main__":
  show_chatty_threads()

Adding drafts and messages to threads

If you are sending or migrating messages that are a response to another email or part of a conversation, your application should add that message to the related thread. This makes it easier for Gmail users who are participating in the conversation to keep the message in context.

A draft can be added to a thread as part of creating, updating, or sending a draft message. You can also add a message to a thread as part of inserting or sending a message.

In order to be part of a thread, a message or draft must meet the following criteria:

  1. The requested threadId must be specified on the Message or Draft.Message you supply with your request.
  2. The References and In-Reply-To headers must be set in compliance with the RFC 2822 standard.
  3. The Subject headers must match.

Take a look at the creating a draft or sending a message examples. In both cases, you would simply add a threadId key paired with a thread ID to a message's metadata, the message object.