Skip to content

picahq/hiring

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

4 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฏ Candidate Tracking System

An intelligent, fully-automated candidate screening system that processes job applicant emails from Wellfound, extracts candidate information using AI, scores candidates based on custom criteria, and stores everything in Airtable.

Next.js TypeScript License: MIT


๐ŸŒŸ Overview

Built for hiring managers and recruiters, this system eliminates the manual work of screening candidate emails. It automatically:

  • Fetches unprocessed candidate emails from Gmail
  • Uses GPT-4 to extract candidate details from HTML emails
  • Scores candidates based on customizable criteria (0-100 scale)
  • Labels processed emails in Gmail
  • Stores structured candidate data in Airtable

Perfect for: Recruiters processing high volumes of candidate applications, hiring teams using Wellfound/AngelList, and anyone who wants to automate their hiring pipeline.


โœจ Features

  • ๐Ÿค– Fully Automated Workflow - Zero manual intervention required
  • ๐Ÿง  AI-Powered Extraction - GPT-4.1 intelligently parses complex HTML emails
  • ๐Ÿ“Š Smart Scoring System - Customizable 100-point scoring criteria
  • ๐Ÿ“ง Gmail Integration - Automatic email labeling via Pica
  • ๐Ÿ“‹ Airtable Storage - Structured candidate data management
  • ๐Ÿ”„ Batch Processing - Handles 100+ emails per batch with pagination
  • ๐Ÿ’ช Retry Logic - Built-in 5-attempt retry for reliability
  • โšก Real-Time UI - Live progress tracking and status updates
  • ๐Ÿ›‘ Manual Controls - Stop, retry, or skip emails as needed
  • ๐ŸŽจ Modern Interface - Clean, responsive UI built with React

๐Ÿ—๏ธ How It Works

1. Load Emails
   โ†“
2. For Each Email:
   โ”œโ”€ Fetch email content via Pica Gmail API
   โ”œโ”€ Extract candidate details (Name, Email, Skills, etc.)
   โ”œโ”€ Calculate score based on criteria (0-100)
   โ”œโ”€ Label email as "Wellfound Candidate found"
   โ””โ”€ Store candidate record in Airtable
   โ†“
3. Move to Next Email (automatic)
   โ†“
4. Complete! โœ“

The system processes emails sequentially with a 2-second delay between each to avoid rate limits. It automatically continues until all emails are processed or an error occurs.


๐Ÿ› ๏ธ Tech Stack

Technology Purpose
Next.js 15.2.2 React framework (App Router)
TypeScript 5 Type-safe development
OpenAI GPT-4.1 AI model for extraction & scoring
Pica Toolkit Integration orchestration layer
Vercel AI SDK Streaming AI responses
Gmail API Email fetching & labeling (via Pica)
Airtable API Candidate data storage (via Pica)
Tailwind CSS 4 Modern styling
Radix UI Accessible UI components

๐Ÿ“‹ Prerequisites

Before you begin, ensure you have:

  1. Node.js 18.18+ installed (Download)
  2. Pica Account - Sign up at picaos.com
  3. Gmail Connection - Set up via Pica dashboard
  4. Airtable Account - Set up via Pica dashboard with a prepared candidate tracking base
  5. OpenAI API Key - For GPT-4 access

๐Ÿš€ Installation & Setup

1. Clone the Repository

git clone <your-repo-url>
cd candidates-tracking

2. Install Dependencies

Using npm:

npm install

Or using pnpm:

pnpm install

3. Set Up Environment Variables

Create a .env.local file in the root directory:

cp .env.example .env.local

Fill in your environment variables:

# Pica API Configuration
PICA_SECRET_KEY=your_pica_secret_key_here

# OpenAI API Key
OPENAI_API_KEY=your_openai_api_key_here

# Gmail Connection (via Pica)
NEXT_PUBLIC_GMAIL_CONNECTION_KEY=your_gmail_connection_key_here

# Airtable Configuration (via Pica)
AIRTABLE_CONNECTION_KEY=your_airtable_connection_key_here
AIRTABLE_BASE_ID=your_airtable_base_id_here
AIRTABLE_TABLE_ID=your_airtable_table_id_here

๐Ÿ“ Environment Variables Explained

Variable Description Where to Find
PICA_SECRET_KEY Your Pica API secret key Pica Dashboard โ†’ Settings โ†’ API Keys
OPENAI_API_KEY OpenAI API key for GPT-4 OpenAI Platform โ†’ API Keys
NEXT_PUBLIC_GMAIL_CONNECTION_KEY Gmail connection identifier Pica Dashboard โ†’ Connections โ†’ Gmail โ†’ Connection Key
AIRTABLE_CONNECTION_KEY Airtable connection identifier Pica Dashboard โ†’ Connections โ†’ Airtable โ†’ Connection Key
AIRTABLE_BASE_ID Your Airtable base ID Airtable base URL: app{BASE_ID}
AIRTABLE_TABLE_ID Your Airtable table ID Airtable table URL: tbl{TABLE_ID}

๐Ÿ”Œ Pica Setup Guide

1. Create a Pica Account

  • Go to picaos.com and sign up
  • Navigate to your dashboard

2. Connect Gmail

  • Click "Connections" โ†’ "Add Connection"
  • Select Gmail
  • Authenticate with your Google account
  • Copy the Connection Key

3. Connect Airtable

  • Click "Connections" โ†’ "Add Connection"
  • Select Airtable
  • Authenticate with your Airtable account
  • Copy the Connection Key

4. Get Your API Key

  • Go to Settings โ†’ API Keys
  • Create a new API key
  • Copy your Pica Secret Key

๐Ÿ“Š Airtable Setup

1. Create a Base

Create a new Airtable base called "Candidate Tracking" (or any name you prefer).

2. Create a Table with These Fields

Your Airtable table must have these fields (exact names required):

Field Name Type Description
Name Single line text Candidate's full name
Email Email Candidate's email address
Location Single line text Candidate's location
Current Company Single line text Current employer
Current Title Single line text Current job title
School Single line text Educational institution
Degree Single line text Degree obtained
Skills Long text Comma-separated skills
Job Search Status Single line text Job search status from email
Years of Experience Single line text Years of experience (optional)
Score Number Calculated score (0-100)
Score Reasoning Long text Detailed scoring explanation

3. Get Your Base ID and Table ID

Base ID:

  • Open your Airtable base
  • Look at the URL: https://airtable.com/app{YOUR_BASE_ID}/...
  • Copy app{YOUR_BASE_ID} (e.g., appXYZ123)

Table ID:

  • Click on any table in your base
  • Look at the URL: https://airtable.com/app.../tbl{YOUR_TABLE_ID}/...
  • Copy tbl{YOUR_TABLE_ID} (e.g., tblABC456)

๐ŸŽฎ Running the Application

Development Mode

npm run dev

The application will start at http://localhost:3000

Production Build

npm run build
npm start

Linting

npm run lint

๐Ÿ“– Usage Guide

Step-by-Step Workflow

  1. Open the Application

    • Navigate to http://localhost:3000
    • You'll see the Candidate Hiring dashboard
  2. Load Emails

    • Click the "Load Emails" button
    • The system fetches up to 100 unprocessed emails matching the criteria
    • Currently searches for: subject:"is interested in Software Engineer (Integrations) at Pica" -label:"Wellfound Candidate found"
  3. Automatic Processing Begins

    • The system automatically processes each email:
      • โœ… Fetches email content
      • โœ… Extracts candidate information
      • โœ… Calculates score
      • โœ… Labels email in Gmail
      • โœ… Stores data in Airtable
    • Progress bar updates in real-time
    • 2-second delay between emails
  4. Monitor Progress

    • Progress Bar - Shows completion percentage
    • Status Badge - "Processing", "Error", "Complete"
    • Message View - Real-time AI processing logs
    • Current Email - Shows which email is being processed
  5. Handle Errors (if any)

    • If an error occurs, the system stops automatically
    • You'll see an error toast with details
    • Options available:
      • Retry - Reprocess the failed email
      • Skip - Move to the next email
  6. Manual Controls

    • Stop Processing - Stops the current workflow
    • Useful if you need to pause or review
  7. Completion

    • Once all emails are processed, you'll see a success message
    • All candidate data is now in your Airtable base
    • Processed emails are labeled in Gmail

๐ŸŽฏ Scoring Criteria

Candidates are scored out of 100 points based on the following criteria:

Criterion Points Description
AI/LLM Experience 30 Experience with LLM, LangChain, CrewAI, Generative AI, or similar
Python Experience 20 Has Python in their skills
Additional Languages 20 Experience with Rust or Scala
TypeScript Experience 10 Has TypeScript in their skills
Years of Experience 20 More than 3 years of software development experience

Total: 100 points

Example Scoring

Candidate A:

  • โœ… Has LangChain experience (30 points)
  • โœ… Python developer (20 points)
  • โŒ No Rust/Scala (0 points)
  • โœ… TypeScript skills (10 points)
  • โœ… 5 years experience (20 points)
  • Total: 80/100

Score Reasoning (stored in Airtable):

"Scored 80/100: Candidate has strong AI experience (30 points) with LangChain and LLM development, Python skills (20 points), TypeScript experience (10 points), and 5 years of professional experience (20 points). However, lacks Rust/Scala experience (0 points)."


๐Ÿ“ Project Structure

candidates-tracking/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ app/
โ”‚   โ”‚   โ”œโ”€โ”€ api/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ chat/
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ route.ts          # AI chat endpoint (GPT-4 streaming)
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ load-emails/
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ route.ts          # Gmail email fetching API
โ”‚   โ”‚   โ”œโ”€โ”€ page.tsx                  # Main UI component
โ”‚   โ”‚   โ”œโ”€โ”€ layout.tsx                # App layout
โ”‚   โ”‚   โ””โ”€โ”€ globals.css               # Global styles
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ ai-elements/              # AI UI components
โ”‚   โ”‚   โ”œโ”€โ”€ ui/                       # Reusable UI components
โ”‚   โ”‚   โ”œโ”€โ”€ OptimizedMessage.tsx      # Message rendering
โ”‚   โ”‚   โ””โ”€โ”€ VirtualizedMessageList.tsx # Efficient message list
โ”‚   โ””โ”€โ”€ lib/
โ”‚       โ”œโ”€โ”€ prompts/
โ”‚       โ”‚   โ””โ”€โ”€ candidate-tracking.ts # System prompt & instructions
โ”‚       โ”œโ”€โ”€ tools/
โ”‚       โ”‚   โ”œโ”€โ”€ gmail-tools.ts        # Gmail labeling tool
โ”‚       โ”‚   โ””โ”€โ”€ airtable-tools.ts     # Airtable insertion tool
โ”‚       โ””โ”€โ”€ utils.ts                  # Utility functions
โ”œโ”€โ”€ public/                           # Static assets
โ”œโ”€โ”€ .env.local                        # Environment variables (create this)
โ”œโ”€โ”€ .env.example                      # Environment template
โ”œโ”€โ”€ package.json                      # Dependencies
โ”œโ”€โ”€ next.config.ts                    # Next.js configuration
โ”œโ”€โ”€ tsconfig.json                     # TypeScript configuration
โ””โ”€โ”€ README.md                         # This file

Key Files to Modify

File Purpose Customize For
src/lib/prompts/candidate-tracking.ts System prompt, job description, scoring criteria Different roles, scoring systems
src/app/page.tsx (line 143) Email search query Different email subjects/filters
src/app/api/load-emails/route.ts Gmail API query parameters, max results Email filtering, pagination settings
src/lib/tools/gmail-tools.ts Gmail label name, retry logic Custom label names, retry behavior
src/lib/tools/airtable-tools.ts Airtable field mapping Custom Airtable schema

๐ŸŽจ Customization Guide

Change the Job Description

Edit src/lib/prompts/candidate-tracking.ts:

// Update lines 13-41 with your job description
Job Title: Your Job Title Here
Location: Your Location
Company: Your Company
...

Modify Scoring Criteria

Edit src/lib/prompts/candidate-tracking.ts:

// Update lines 44-86 with your scoring criteria
1. Criterion One (XX points):
   - Description
   ...

Change Email Filter

Edit src/app/page.tsx (line 143):

query: 'subject:"your email subject here" -label:"your label here"'

Gmail Query Syntax:

  • subject:"text" - Emails with specific subject
  • -label:"name" - Exclude emails with label
  • from:[email protected] - From specific sender
  • after:2025/01/01 - After specific date
  • Combine with spaces (AND logic)

Adjust Retry Logic

Edit tool files to change retry attempts:

// In src/lib/tools/gmail-tools.ts or airtable-tools.ts
const MAX_RETRIES = 5; // Change this number

๐Ÿ› Troubleshooting

Common Issues

โŒ "Missing PICA_SECRET_KEY" Error

  • Ensure all environment variables are set in .env.local
  • Restart the development server after adding variables
  • Check for typos in variable names

โŒ "Failed to fetch Gmail emails"

  • Verify your Gmail connection is active in Pica dashboard
  • Check NEXT_PUBLIC_GMAIL_CONNECTION_KEY is correct
  • Ensure Gmail API is enabled for your Pica account

โŒ "Failed to add candidate to Airtable"

  • Verify Airtable field names match exactly (case-sensitive)
  • Check AIRTABLE_BASE_ID and AIRTABLE_TABLE_ID are correct
  • Ensure Airtable connection has write permissions

โŒ "No emails found"

  • Check your Gmail query syntax
  • Verify emails exist matching the criteria
  • Ensure emails aren't already labeled

โŒ Processing stops unexpectedly

  • Check browser console for errors
  • Look for error toasts in the UI
  • Verify OpenAI API key has sufficient credits
  • Check if you hit Pica rate limits

Debug Mode

Enable detailed logging:

# In browser console
localStorage.setItem('debug', 'true')

Check server logs:

# Terminal where dev server is running
# All API calls and tool executions are logged with prefixes:
# ๐Ÿ“ง [GMAIL-TOOL]
# ๐Ÿ”ต [AIRTABLE-TOOL]
# ๐Ÿ”„ [STREAM]

๐Ÿค Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch
    git checkout -b feature/amazing-feature
  3. Make your changes
    • Write clean, commented code
    • Follow existing code style
    • Test thoroughly
  4. Commit your changes
    git commit -m "Add amazing feature"
  5. Push to your branch
    git push origin feature/amazing-feature
  6. Open a Pull Request

Code Style Guidelines

  • Use TypeScript for all new code
  • Follow existing naming conventions
  • Add comments for complex logic
  • Use descriptive variable names
  • Keep functions focused and small

๐Ÿ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ™ Acknowledgments


๐Ÿ“ง Support


Built with โค๏ธ for recruiters and hiring teams

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published