docs: add installation and configuration guide for email automation with Mem0 open source (#4567)

This commit is contained in:
Kartik
2026-03-28 21:12:31 +05:30
committed by GitHub
parent 41abb571a2
commit 4b7f51d194
+240 -11
View File
@@ -18,11 +18,36 @@ Email overload is a common challenge for many professionals. By leveraging Mem0'
## Setup
<Tabs>
<Tab title="Platform">
Before you begin, ensure you have the required dependencies installed:
```bash
pip install mem0ai openai
```
</Tab>
<Tab title="Open Source">
Here we use **Mem0 open source** (`Memory`): all local, no API keys needed for memory. Vectors in **Qdrant**, LLM and embeddings via **Ollama**.
### Installation
Install the required dependencies:
```bash
pip install mem0ai qdrant-client openai ollama
```
Then start Qdrant and pull the Ollama models:
```bash
docker run -d -p 6333:6333 qdrant/qdrant
ollama pull llama3.1:latest
ollama pull nomic-embed-text:latest
```
<Note>You can swap `nomic-embed-text` for any Ollama-supported embedding model (e.g., `snowflake-arctic-embed`, `mxbai-embed-large`). Just update the `model` in the `embedder` config and set `embedding_model_dims` in the Qdrant config to match the model's output dimensions (768 for `nomic-embed-text`).</Note>
</Tab>
</Tabs>
## Implementation
@@ -30,6 +55,8 @@ pip install mem0ai openai
The following example shows how to create a basic email processing system with Mem0:
<Tabs>
<Tab title="Platform">
```python
import os
from mem0 import MemoryClient
@@ -45,11 +72,11 @@ class EmailProcessor:
def __init__(self):
"""Initialize the Email Processor with Mem0 memory client"""
self.client = client
def process_email(self, email_content, user_id):
"""
Process an email and store it in Mem0 memory
Args:
email_content (str): Raw email content
user_id (str): User identifier for memory association
@@ -57,20 +84,20 @@ class EmailProcessor:
# Parse email
parser = Parser()
email = parser.parsestr(email_content)
# Extract email details
sender = email['from']
recipient = email['to']
subject = email['subject']
date = email['date']
body = self._get_email_body(email)
# Create message object for Mem0
message = {
"role": "user",
"content": f"Email from {sender}: {subject}\n\n{body}"
}
# Create metadata for better retrieval
metadata = {
"email_type": "incoming",
@@ -79,18 +106,18 @@ class EmailProcessor:
"subject": subject,
"date": date
}
# Store in Mem0 with appropriate categories
response = self.client.add(
messages=[message],
user_id=user_id,
metadata=metadata,
categories=["email", "correspondence"],
)
return response
def _get_email_body(self, email):
"""Extract the body content from an email"""
# Simplified extraction - in real-world, handle multipart emails
@@ -100,7 +127,7 @@ class EmailProcessor:
return part.get_payload(decode=True).decode()
else:
return email.get_payload(decode=True).decode()
def search_emails(self, query, user_id, sender=None):
"""
Search through stored emails
@@ -132,7 +159,7 @@ class EmailProcessor:
results = self.client.search(query=query, filters=filters)
return results
def get_email_thread(self, subject, user_id):
"""
Retrieve all emails in a thread based on subject
@@ -182,6 +209,208 @@ processor.process_email(sample_email, user_id)
meeting_emails = processor.search_emails("meeting schedule", user_id)
print(f"Found {len(meeting_emails['results'])} relevant emails")
```
</Tab>
<Tab title="Open Source">
```python
from mem0 import Memory
from email.parser import Parser
OLLAMA_URL = "http://localhost:11434"
# Set up Mem0 with local providers
memory = Memory.from_config({
"vector_store": {
"provider": "qdrant",
"config": {
"collection_name": "email_intelligence",
"host": "localhost",
"port": 6333,
"embedding_model_dims": 768,
},
},
"llm": {
"provider": "ollama",
"config": {
"model": "llama3.1:latest",
"temperature": 0,
"max_tokens": 2000,
"ollama_base_url": OLLAMA_URL,
},
},
"embedder": {
"provider": "ollama",
"config": {
"model": "nomic-embed-text:latest",
"ollama_base_url": OLLAMA_URL,
},
},
})
class EmailProcessor:
def __init__(self):
"""Initialize the Email Processor with Mem0 memory"""
self.memory = memory
def process_email(self, email_content, user_id):
"""
Process an email and store it in Mem0 memory
Args:
email_content (str): Raw email content
user_id (str): User identifier for memory association
"""
# Parse email
parser = Parser()
email = parser.parsestr(email_content)
# Extract email details
sender = email["from"]
recipient = email["to"]
subject = email["subject"]
date = email["date"]
body = self._get_email_body(email)
# Create message object for Mem0
message = {
"role": "user",
"content": f"Email from {sender}: {subject}\n\n{body}",
}
# Create metadata for better retrieval
# In OSS, categories are modeled as metadata fields
metadata = {
"email_type": "incoming",
"memory_category": "email",
"sender": sender,
"recipient": recipient,
"subject": subject,
"date": date,
}
# Store in Mem0
response = self.memory.add(
message,
user_id=user_id,
metadata=metadata,
)
return response
def _get_email_body(self, email):
"""Extract the body content from an email"""
if email.is_multipart():
for part in email.walk():
if part.get_content_type() == "text/plain":
return part.get_payload(decode=True).decode()
else:
return email.get_payload(decode=True).decode()
def search_emails(self, query, user_id, sender=None):
"""
Search through stored emails
Args:
query (str): Search query
user_id (str): User identifier
sender (str, optional): Filter by sender email address
"""
# In OSS, user_id is an explicit parameter (not inside filters)
if not sender:
results = self.memory.search(
query=query,
user_id=user_id,
filters={"memory_category": "email"},
)
else:
results = self.memory.search(
query=query,
user_id=user_id,
filters={
"AND": [
{"memory_category": "email"},
{"sender": sender},
]
},
)
return results
def get_email_thread(self, subject, user_id):
"""
Retrieve all emails in a thread based on subject
Args:
subject (str): Email subject to match
user_id (str): User identifier
"""
# In OSS, user_id is an explicit parameter
thread = self.memory.get_all(
user_id=user_id,
filters={
"AND": [
{"memory_category": "email"},
{"subject": {"icontains": subject}},
]
},
)
return thread
# Initialize the processor
processor = EmailProcessor()
# Example raw email
sample_email = """From: alice@example.com
To: bob@example.com
Subject: Meeting Schedule Update
Date: Mon, 15 Jul 2024 14:22:05 -0700
Hi Bob,
I wanted to update you on the schedule for our upcoming project meeting.
We'll be meeting this Thursday at 2pm instead of Friday.
Could you please prepare your section of the presentation?
Thanks,
Alice
"""
# Process and store the email
user_id = "bob@example.com"
processor.process_email(sample_email, user_id)
# Later, search for emails about meetings
meeting_emails = processor.search_emails("meeting schedule", user_id)
print(f"Found {len(meeting_emails['results'])} relevant emails")
```
<Note>
**Categories vs Metadata:** The Platform version uses `categories=["email"]` which are AI-assigned by Mem0. In open source, categories are modeled as `metadata` fields (e.g., `memory_category`) that you set on each `add` call and filter on during search.
</Note>
</Tab>
</Tabs>
### Fetching Memories
You can fetch all the memories at any point in time using the following code:
<Tabs>
<Tab title="Platform">
```python
meeting_emails = processor.search_emails("meeting schedule", user_id)
for m in meeting_emails['results']:
print(m['memory'])
```
</Tab>
<Tab title="Open Source">
```python
meeting_emails = processor.search_emails("meeting schedule", user_id)
for m in meeting_emails["results"]:
print(m["memory"])
```
</Tab>
</Tabs>
## Key Features and Benefits