Set Up an Email Triage System with Home Assistant and a Local LLM

Featured Image

Leveraging Home Assistant for Email Triage with a Local LLM

Home Assistant is an incredibly powerful platform that goes beyond just connecting hardware from different vendors into a single dashboard. It can integrate a wide range of tools and services, including software running on your PC or even games like Counter-Strike. One particularly useful integration is the IMAP integration, which allows you to link your email account to Home Assistant. This feature enables you to process every incoming email in a way that suits your needs.

I’ve taken this functionality and created a personal email triage system using Home Assistant and a local large language model (LLM). The system processes each incoming email, categorizes it, and provides a summary, making it easier to manage my inbox.

Why Build an Email Triage System?

Emails can quickly become overwhelming, especially when they’re filled with newsletters, work-related messages, and other types of communication. While I try to unsubscribe from unnecessary emails, some are still important, even if not always. I wanted a way to make this process more efficient, so I turned to a local LLM to help summarize and categorize incoming emails.

Home Assistant’s IMAP integration allows it to pull every email from a designated server, including the content. However, parsing this content can be challenging due to varying HTML structures. A local LLM offers a more flexible solution by recognizing patterns in the text, generating summaries, and assigning categories.

Using a local LLM also ensures privacy, as no data is sent to external servers. This approach doesn’t replace manual inbox checks but significantly reduces the frequency with which I need to review my emails. Additionally, it provides insights into the types of emails I receive, helping me better understand my communication patterns.

Setting Up the LLM Triage REST Command

To implement this system, I built two components: a REST command that sends emails to the LLM and an automation that processes the response. Here's the configuration for the REST command:

rest_command:
  llm_email_triage:
    url: "http://192.168.1.81:11434/api/chat"
    method: POST
    headers:
      Content-Type: "application/json"
    payload: >
      {{
        {
          "model": "dolphin-llama3",
          "stream": false,
          "keep_alive": "24h",
          "messages": [
            {
              "role": "system",
              "content": "You are an email-triage assistant. Read the email JSON, then return ONLY JSON matching the schema."
            },
            {
              "role": "user",
              "content": (email_payload if email_payload is string else (email_payload | to_json))
            }
          ],
          "format": {
            "type": "object",
            "properties": {
              "priority": {"type": "string", "enum": ["P0", "P1", "P2", "P3"]},
              "category": {"type": "string", "enum": ["personal", "transaction", "calendar", "newsletter", "promo", "alert", "receipt", "support", "unknown"]},
              "summary": {"type": "string"},
              "actions": {
                "type": "object",
                "properties": {
                  "archive": {"type": "boolean"},
                  "move_to_folder": {"type": "string"},
                  "snooze_until": {"type": "string"},
                  "create_task": {
                    "type": "object",
                    "properties": {
                      "title": {"type": "string"},
                      "due": {"type": "string"}
                    },
                    "required": ["title"]
                  }
                },
                "additionalProperties": false
              },
              "confidence": {"type": "number"}
            },
            "required": ["priority", "category", "summary", "actions", "confidence"],
            "additionalProperties": false
          },
          "options": {
            "temperature": 0,
            "num_ctx": 32768
          }
        } | to_json
      }}

This REST command sends an email to the LLM, which returns structured data including priority, category, summary, actions, and confidence. The LLM uses a context window of 32,768 tokens, allowing it to handle complex emails effectively.

Setting Up Automation to Summarize Emails

The next step is to set up automation that processes the LLM’s response. When an email arrives, the automation fetches the message, extracts relevant details, and calls the REST command. It then processes the response, updates counters based on the category, and sends a notification to a device.

The automation includes variables such as mail, email_payload, and triage. It also increments counters for each category, such as counter.emails_personal or counter.emails_transaction. These counters help track the types of emails received over time.

Once an email is processed, a summary is sent to the phone, along with the subject line and priority. Additional actions, like snoozing or archiving, can be implemented based on the LLM’s recommendations.

Expanding the Possibilities

Home Assistant is a versatile platform that can integrate many different tools and services. For example, I’ve connected my GoXLR audio interface to control lights and linked Uptime Kuma to monitor office lights for service outages.

There are countless ways to customize Home Assistant to suit individual needs, and this email triage system is just one example. The GitHub repository for this project also demonstrates how tasks can be automatically added to a to-do list in Home Assistant, showcasing the platform’s flexibility.

Comments