Skip to content

TroodInc/trood-leader

Repository files navigation

trood-leader

Inbound relationship intelligence system that transforms emails and LinkedIn data into structured contacts, classifies them using embeddings, and enables controlled outreach via EmailOctopus.

Features

  • Contact Deduplication: Unique constraint on email, upsert logic
  • Email Ingestion: Accept JSON input, extract contact info, store messages
  • LinkedIn Import: CSV upload, parse names, upsert contacts
  • Message Aggregation: Combine last N messages per contact for analysis
  • Embeddings: External embedding service integration with versioning
  • Classification: Rule-based classification (investor, founder, vendor, recruiter, other)
  • EmailOctopus Integration: Safe export with duplicate prevention
  • Reply Tracking: Automatic detection of replies after outreach

Tech Stack

  • Node.js + TypeScript
  • Express.js
  • PostgreSQL + Prisma ORM
  • No authentication (MVP)
  • No queues or background workers

Setup

1. Install dependencies

npm install

2. Configure environment

cp .env.example .env
# Edit .env with your API keys and embedding URL

3. Setup database

npm run prisma:generate
npm run prisma:migrate

4. Run development server

npm run dev

API Endpoints

Import

  • POST /import/emails - Import emails from JSON
  • POST /import/linkedin - Import contacts from LinkedIn CSV

Contacts

  • GET /contacts - List contacts (filters: label, source, domain)
  • GET /contacts/:id - Get contact details
  • GET /contacts/:id/messages - Get contact messages (thread view)

Processing

  • POST /embeddings/generate - Generate embeddings for contacts
  • POST /classify - Classify contacts

Export

  • POST /export/emailoctopus - Export contacts to EmailOctopus
  • POST /export/emailoctopus/webhook - Webhook for status updates

Health

  • GET /health - Health check

Running with Docker + Local Embeddings

1. Install API dependencies

npm install

2. Install embedding server dependencies

npm install --prefix embedding-server

3. Start the local embedding server

node embedding-server/index.js

The embedding server runs locally on port 3001.

4. Start ngrok

ngrok http 3001

Copy the public ngrok URL, for example:

https://xxxx.ngrok.io

5. Set EMBEDDING_API_URL

Update your .env:

EMBEDDING_API_URL=https://xxxx.ngrok.io/embed

This lets the Dockerized API call your local embedding service over HTTP.

6. Start Docker services

docker-compose up --build

This starts:

  • api on port 3000
  • postgres on port 5432

7. Run Prisma migrations inside Docker

docker-compose exec api npx prisma migrate dev

8. Test the API

curl http://localhost:3000/health

You can then import sample data and run embedding/classification flows against the API container.

Sample Data

Sample data files are provided in the data/ directory:

  • sample-emails.json - Mock email data
  • sample-linkedin.csv - Sample LinkedIn export

Import sample emails

curl -X POST http://localhost:3000/import/emails \
  -H "Content-Type: application/json" \
  -d @data/sample-emails.json

Import LinkedIn CSV

curl -X POST http://localhost:3000/import/linkedin \
  -F "file=@data/sample-linkedin.csv"

Classify all contacts

curl -X POST http://localhost:3000/classify

Export to EmailOctopus

curl -X POST http://localhost:3000/export/emailoctopus \
  -H "Content-Type: application/json" \
  -d '{"contactIds": ["uuid1", "uuid2"]}'

Project Structure

/src
  /controllers    # Request handlers
  /services       # Business logic
  /routes         # Express routes
  /utils          # Helpers and config
/prisma
  schema.prisma   # Database schema
/data
  sample-*.json   # Sample data files
/embedding-server
  index.js        # Local mock embedding service
  package.json    # Embedding service dependencies
Dockerfile
docker-compose.yml

Environment Variables

Variable Description
DATABASE_URL PostgreSQL connection string
EMAILOCTOPUS_API_KEY EmailOctopus API key
EMAILOCTOPUS_LIST_ID EmailOctopus list ID
EMBEDDING_API_URL Public ngrok URL to the local embedding service
EMBEDDING_VERSION Embedding version for cache invalidation
PORT Server port (default: 3000)

License

MIT

About

Inbound relationship intelligence layer: turn emails & LinkedIn into structured contacts, segments, and automated outreach.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors