* feat(post-application): add schema and shared types for provider ingestion (#136) * test(orchestrator): ensure full localStorage shape in vitest setup * feat(post-application): add provider registry and dispatcher framework (#137) (#146) * Implement Gmail provider credential persistence (#147) * Add unified post-application provider action API (#148) * Implement Gmail ingestion sync with 95/60 relevance policy * Implement Gmail ingestion sync with 95/60 relevance policy (#149) * feat(post-application): add job mapping engine with llm rerank fallback * feat(post-application): add inbox review APIs with transactional approve/deny (#151) * feat(post-application): add tracking inbox UI with provider controls (#152) * oauth implementation * UI changes * see past runs in more detail * occurred at comes from email * state mismatch * better UI representation * comments * comments * comments * comments * documentation * explainer * set things manually * scrolling * any found email can be pending * searchable download * Email-to-Job Matching Decision Tree * email viewer list improvement * simplification initial commit * exclude discovered jobs * show only resady * dropdown * mermaid * syntax * targets is the same as logging that is done manually * event label * duplicate avoidance * clean up html * token saving * print * send idx not uuid * remove logging * formatting * better documentation * documentation * comments * process all * comments
242 lines
7.9 KiB
Markdown
242 lines
7.9 KiB
Markdown
# Post-Application Email Tracking
|
|
|
|
The Post-Application Tracking feature (also called "Tracking Inbox") automatically monitors your Gmail for job application responses and updates your job timeline accordingly.
|
|
|
|
## Overview
|
|
|
|
After you've applied to jobs, keeping track of responses can be tedious. This feature automates that process by:
|
|
|
|
1. **Scanning your Gmail** for recruitment-related emails
|
|
2. **Matching emails** to your tracked job applications using AI
|
|
3. **Updating your timeline** with interview invites, offers, rejections, and updates
|
|
4. **Asking for your review** when the AI is uncertain
|
|
|
|
## How It Works
|
|
|
|
### The Smart Router Flow
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A[Recruitment email arrives in Gmail] --> B[Smart Router AI analyzes content]
|
|
B --> C{How confident is the match?}
|
|
|
|
C -->|95-100%| D[Auto-linked to job]
|
|
D --> E[Timeline updated automatically]
|
|
|
|
C -->|50-94%| F[Goes to Inbox for review<br/>with suggested job match]
|
|
|
|
C -->|<50%| G{Is it relevant?}
|
|
G -->|Yes| H[Goes to Inbox as orphan<br/>relevant but job unclear]
|
|
G -->|No| I[Ignored - not job-related]
|
|
|
|
F --> J{You review in Inbox}
|
|
H --> J
|
|
J -->|Approve| K[Linked to selected job<br/>Timeline updated]
|
|
J -->|Ignore| L[Marked as not relevant]
|
|
```
|
|
|
|
### What the AI Analyzes
|
|
|
|
For each email, the Smart Router evaluates:
|
|
|
|
- **Content Relevance**: Is this email about a job application lifecycle?
|
|
- **Job Matching**: Which of your "Applied" or "Processing" jobs does this relate to?
|
|
- **Message Type**:
|
|
- Interview invitation (phone screen, technical, onsite)
|
|
- Offer received
|
|
- Rejection/withdrawal
|
|
- General update/status change
|
|
- **Confidence Score**: 0-100% certainty of the match
|
|
|
|
### Processing Outcomes
|
|
|
|
| Confidence | Processing | Your Action Required |
|
|
| ----------------------- | ------------------------------ | ---------------------------------------- |
|
|
| **95-100%** | Auto-linked to job | None - appears in timeline automatically |
|
|
| **50-94%** | Pending review with suggestion | Quick approve/ignore in Inbox |
|
|
| **<50% (relevant)** | Pending review as orphan | Approve with manual job selection |
|
|
| **<50% (not relevant)** | Ignored | None - filtered out |
|
|
|
|
## Setup
|
|
|
|
### Prerequisites
|
|
|
|
1. **Gmail account** with job application emails
|
|
2. **Google OAuth credentials** (see below)
|
|
|
|
### Step 1: Create Google OAuth Credentials
|
|
|
|
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
2. Create a new project or select existing
|
|
3. Enable the **Gmail API**
|
|
4. Configure **OAuth consent screen**:
|
|
- User Type: External
|
|
- Fill in app name, user support email, developer contact
|
|
- Add scope: `https://www.googleapis.com/auth/gmail.readonly`
|
|
- Add test users (your email)
|
|
5. Create **OAuth 2.0 Client ID**:
|
|
- Application type: Web application
|
|
- Authorized redirect URIs:
|
|
- `http://localhost:3005/oauth/gmail/callback` (local)
|
|
- `https://your-domain.com/oauth/gmail/callback` (production)
|
|
6. Copy the **Client ID** and **Client Secret**
|
|
|
|
### Step 2: Configure Environment Variables
|
|
|
|
Set these in your JobOps environment:
|
|
|
|
```bash
|
|
GMAIL_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
|
GMAIL_OAUTH_CLIENT_SECRET=your-client-secret
|
|
# Optional - defaults to /oauth/gmail/callback on current host
|
|
GMAIL_OAUTH_REDIRECT_URI=https://your-domain.com/oauth/gmail/callback
|
|
```
|
|
|
|
### Step 3: Connect Gmail in the UI
|
|
|
|
1. Restart JobOps with the new environment variables
|
|
2. Navigate to **Tracking Inbox** in the dashboard
|
|
3. Click **Connect Gmail**
|
|
4. Authorize JobOps to access your Gmail (read-only scope)
|
|
5. You're connected! The system will now sync emails automatically
|
|
|
|
## Using the Tracking Inbox
|
|
|
|
### Reviewing Pending Items
|
|
|
|
When emails need your review, they appear in the **Inbox**:
|
|
|
|
1. Go to **Tracking Inbox** → **Inbox** tab
|
|
2. Each item shows:
|
|
- Sender and subject
|
|
- AI confidence score
|
|
- Suggested job match (if available)
|
|
- Message type (interview, offer, etc.)
|
|
3. Choose an action:
|
|
- **Approve**: Links to the suggested job (or select a different one)
|
|
- **Ignore**: Marks as not relevant
|
|
|
|
### Understanding Confidence Scores
|
|
|
|
- **Green (95-100%)**: High confidence, auto-processed
|
|
- **Yellow (50-94%)**: Moderate confidence, needs review
|
|
- **Red (<50%)**: Low confidence or unclear match
|
|
|
|
### Timeline Updates
|
|
|
|
When you approve an email (or it's auto-approved), the system:
|
|
|
|
1. Creates a timeline event for the job
|
|
2. Updates the job stage (e.g., "Interview Scheduled", "Offer Received")
|
|
3. Records the event date from the email
|
|
|
|
## Privacy & Security
|
|
|
|
### What Data is Sent to AI
|
|
|
|
Only minimal job metadata is sent for matching:
|
|
|
|
- Company name
|
|
- Job title
|
|
- Snippets of email content
|
|
|
|
### Gmail Permissions
|
|
|
|
- **Scope**: `gmail.readonly` only
|
|
- **Access**: Read-only, cannot send/delete emails
|
|
- **Data Storage**: Email metadata stored locally in your SQLite database
|
|
|
|
### Data Retention
|
|
|
|
- Sync history retained for debugging
|
|
- You can disconnect Gmail at any time
|
|
- All email data is local to your instance
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**"No refresh token" error**
|
|
|
|
- Disconnect and reconnect Gmail
|
|
- This forces a fresh consent flow
|
|
|
|
**Emails not appearing**
|
|
|
|
- Check sync run history in Tracking Inbox → Runs
|
|
- Verify Gmail OAuth credentials are correct
|
|
- Ensure email subjects match recruitment keywords
|
|
|
|
**Wrong job matches**
|
|
|
|
- This is expected for low-confidence matches
|
|
- Use the Inbox to correct matches
|
|
|
|
### Viewing Sync History
|
|
|
|
Go to **Tracking Inbox** → **Runs** to see:
|
|
|
|
- When syncs ran
|
|
- How many messages were discovered
|
|
- How many were auto-linked vs. pending review
|
|
- Any errors that occurred
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Required | Description |
|
|
| --------------------------- | -------- | ------------------------------ |
|
|
| `GMAIL_OAUTH_CLIENT_ID` | Yes | Google OAuth client ID |
|
|
| `GMAIL_OAUTH_CLIENT_SECRET` | Yes | Google OAuth client secret |
|
|
| `GMAIL_OAUTH_REDIRECT_URI` | No | Custom redirect URI (optional) |
|
|
|
|
### Advanced Settings
|
|
|
|
Currently, the feature uses sensible defaults:
|
|
|
|
- Searches last 30 days of emails
|
|
- Looks for recruitment-related keywords in subjects
|
|
- Processes up to 100 messages per sync
|
|
- Runs automatically when you open the Tracking Inbox
|
|
|
|
## API Reference
|
|
|
|
### REST Endpoints
|
|
|
|
| Method | Endpoint | Description |
|
|
| ------ | ----------------------------------------- | --------------------- |
|
|
| GET | `/api/post-application/inbox` | List pending messages |
|
|
| POST | `/api/post-application/inbox/:id/approve` | Approve message |
|
|
| POST | `/api/post-application/inbox/:id/deny` | Ignore message |
|
|
| GET | `/api/post-application/runs` | List sync runs |
|
|
| POST | `/api/post-application/gmail/connect` | Start OAuth flow |
|
|
| GET | `/api/post-application/gmail/callback` | OAuth callback |
|
|
|
|
### Example: Approve an Inbox Item
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3005/api/post-application/inbox/msg_123/approve \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"jobId": "job_456",
|
|
"note": "Phone screen scheduled"
|
|
}'
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Review regularly**: Check your Inbox weekly to stay on top of pending matches
|
|
2. **Be decisive**: Approve or ignore items quickly to keep your Inbox clean
|
|
3. **Correct mismatches**: If the AI suggests the wrong job, select the correct one when approving
|
|
4. **Monitor sync runs**: Check the Runs tab occasionally to ensure syncing is working
|
|
5. **Privacy first**: Remember only minimal job data is sent to AI - your email content stays private
|
|
|
|
## Future Enhancements
|
|
|
|
Potential improvements planned:
|
|
|
|
- Multiple email provider support (Outlook, etc.)
|
|
- IMAP support for non-Gmail accounts
|
|
- Calendar integration for interview scheduling
|