Skip to main content
Glama
email.ts4.38 kB
export interface EmailData { subject: string; body: string; sender: string; recipients?: string[]; date?: string; company?: string; messageId?: string; inReplyTo?: string; } export interface EmailRecord extends EmailData { id: string; userId: string; memoryId: string; created_at: string; } function extractCompanyFromEmail(email: string): string | undefined { const match = email.match(/@([^>]+)>?$/); if (!match) return undefined; const domain = match[1].toLowerCase(); const parts = domain.split('.'); if (parts.length > 2) parts.shift(); return parts[0]; } import { storeMemory, searchMemories } from './vectorize'; import { storeMemoryInD1 } from './db'; import { v4 as uuidv4 } from 'uuid'; export async function storeEmailMemory( email: EmailData, userId: string, env: Env ): Promise<string> { const memoryId = uuidv4(); const company = email.company || extractCompanyFromEmail(email.sender); const recipients = email.recipients?.join(',') ?? ''; const text = `${email.subject}\n${email.body}\nFrom: ${email.sender}\nTo: ${recipients}`; await storeMemoryInD1(text, userId, env, memoryId); await storeMemory( text, userId, env, { subject: email.subject, sender: email.sender, recipients, date: email.date ?? '', company: company ?? '', messageId: email.messageId ?? '', inReplyTo: email.inReplyTo ?? '', }, memoryId, ); const stmt = env.DB.prepare( 'INSERT INTO emails (id, userId, memoryId, sender, recipients, subject, date, company, messageId, inReplyTo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' ); await stmt .bind( memoryId, userId, memoryId, email.sender, recipients, email.subject, email.date ?? '', company ?? '', email.messageId ?? '', email.inReplyTo ?? '', ) .run(); return memoryId; } export async function getEmailMetadata( memoryId: string, userId: string, env: Env ): Promise<EmailRecord | null> { const res = await env.DB.prepare( 'SELECT * FROM emails WHERE memoryId = ? AND userId = ?' ) .bind(memoryId, userId) .first(); return res as EmailRecord | null; } export async function getEmailsMetadata( memoryIds: string[], userId: string, env: Env, ): Promise<Record<string, EmailRecord>> { if (memoryIds.length === 0) return {}; const placeholders = memoryIds.map(() => '?').join(','); const query = `SELECT * FROM emails WHERE memoryId IN (${placeholders}) AND userId = ?`; const result = await env.DB.prepare(query) .bind(...memoryIds, userId) .all(); const records: Record<string, EmailRecord> = {}; for (const row of (result.results as unknown as EmailRecord[])) { records[row.memoryId] = row; } return records; } export async function getEmailWithContent( memoryId: string, userId: string, env: Env, ): Promise<(EmailRecord & { content: string }) | null> { const res = await env.DB.prepare( 'SELECT e.*, m.content FROM emails e JOIN memories m ON e.memoryId = m.id WHERE e.memoryId = ? AND e.userId = ?', ) .bind(memoryId, userId) .first(); return res as (EmailRecord & { content: string }) | null; } export async function listEmails(userId: string, env: Env): Promise<EmailRecord[]> { const result = await env.DB.prepare( 'SELECT * FROM emails WHERE userId = ? ORDER BY date DESC, created_at DESC' ) .bind(userId) .all(); return result.results as unknown as EmailRecord[]; } export async function deleteEmail(memoryId: string, userId: string, env: Env): Promise<void> { await env.DB.prepare('DELETE FROM emails WHERE memoryId = ? AND userId = ?') .bind(memoryId, userId) .run(); } export async function searchEmailMemories( query: string, userId: string, env: Env, company?: string, ): Promise<Array<EmailRecord & { score: number }>> { const vectorResults = await searchMemories(query, userId, env); const ids = vectorResults.map((v) => v.id); const metadataMap = await getEmailsMetadata(ids, userId, env); return vectorResults .map((match) => { const meta = metadataMap[match.id]; if (!meta) return undefined; if (company && meta.company !== company) return undefined; return { ...meta, score: match.score }; }) .filter(Boolean) as Array<EmailRecord & { score: number }>; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aiwithbenefits/mcp-memory'

If you have feedback or need assistance with the MCP directory API, please join our Discord server