OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb / hyper-social / bridge-email / lib / adapter.js

113 lines · javascript ref:
import { createEnvelope, TYPES, PLATFORMS } from 'bridge-envelope'

// Extract email address from "Name <addr>" format
function extractEmail (from) {
  const match = from.match(/<([^>]+)>/)
  return match ? match[1] : from.trim()
}

// Extract display name from "Name <addr>" format
function extractName (from) {
  const match = from.match(/^"?([^"<]+)"?\s*</)
  return match ? match[1].trim() : extractEmail(from)
}

// Convert parsed email to bridge envelope
function emailToEnvelope (email) {
  if (!email) return null

  const from = email.from || ''
  const author = extractName(from)
  const subject = email.subject || ''
  const body = email.body || ''

  if (!body.trim() && !subject.trim()) return null

  // Skip bridge-generated emails
  if (email.body?.includes('[email]') || email.body?.includes('[Email]')) return null

  const content = subject ? `[${subject}] ${body}` : body

  const envelope = createEnvelope({
    type: TYPES.TEXT,
    platform: PLATFORMS.EMAIL,
    author,
    content,
    channel: extractEmail(from)
  })

  // Preserve email metadata for threading
  envelope._messageId = email.messageId || ''
  envelope._subject = subject
  envelope._from = from
  envelope._to = email.to || ''
  envelope._date = email.date || ''

  return envelope
}

// Convert Keet message to email-ready format
function keetToEmail (keetMsg, bridgeIdentity) {
  if (!keetMsg) return null

  // Skip own messages
  if (keetMsg.memberId === bridgeIdentity) return null

  // Skip system messages
  if (keetMsg.type === 'system') return null

  const text = keetMsg.text || ''
  if (!text.trim()) return null

  // Skip already bridged from email
  if (text.includes('[email]') || text.includes('[Email]')) return null

  const name = keetMsg.name || keetMsg.username || 'someone'

  return {
    author: name,
    text,
    subject: `[Keet] Message from ${name}`,
    body: `${name} wrote:\n\n${text}\n\n---\nRelayed via bridge-email from Keet P2P chat`
  }
}

// Format email envelope for display in Keet
function emailToKeetText (envelope) {
  if (!envelope) return ''

  let text = `[email] ${envelope.author}`

  if (envelope._subject) {
    text += ` — ${envelope._subject}`
  }

  // Truncate long emails for chat display
  const body = envelope.content.replace(`[${envelope._subject}] `, '')
  const maxLen = 500
  if (body.length > maxLen) {
    text += `: ${body.slice(0, maxLen)}...`
  } else {
    text += `: ${body}`
  }

  return text
}

// Format Keet message as email subject/body
function keetToEmailText (author, text) {
  return {
    subject: `[Keet] Message from ${author}`,
    body: `${author} wrote:\n\n${text}\n\n---\nRelayed via bridge-email from Keet P2P chat`
  }
}

export {
  emailToEnvelope,
  keetToEmail,
  emailToKeetText,
  keetToEmailText,
  extractEmail,
  extractName
}