# Jd Follow Up Email Check

> Scan Gmail for the last 48 hours of job-application emails, classify each as Rejected, Interview Scheduled, or Acknowledged/Under Review, then update the Notion follow-up-email log and set Archive=true for rejected records in Job Applications DB. Use when the user mentions follow-up email check, job email scan, rejection check, application status update from email, or daily email triage.

- Skill: `rayliu66/jd-follow-up-email-check` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add rayliu66/jd-follow-up-email-check`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rayliu66/jd-follow-up-email-check/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: Rayliu66 (https://skillmd.com/u/rayliu66)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/rayliu66/jd-follow-up-email-check

---


# JD Follow-Up Email Check

## Purpose

Scan recent Gmail messages, extract job-application outcomes by reading **full message bodies** (not just subjects), group them by status, log results to a Notion page, and archive rejected records in the Job Applications DB.

---

## Required Inputs

| Input | Default | Description |
|-------|---------|-------------|
| `lookback` | `2d` (48 hours) | Gmail `newer_than` value |
| `notion_log_page` | `33c8d41a5cff80d3b905c9b53c6f65e9` | Notion page ID for the follow-up-email log |
| `job_db_data_source` | `collection://90f20bdb-0f9d-4180-acaf-3e1ad674c9aa` | Job Applications DB data source URL |

If the user provides different values, use those instead.

---

## Execution Steps

### Step 1 — Search Gmail

Use the Gmail MCP `search_emails` tool with multiple queries in parallel:

**Query A — Rejections:**
```
newer_than:{lookback} ("not selected" OR "regret to inform" OR "other candidates" OR "position has been filled" OR "decided to pursue other" OR "will not be moving forward" OR "unsuccessful" OR "unable to offer" OR "no longer under consideration")
```

**Query B — Interview / Moving Forward:**
```
newer_than:{lookback} ("invite you to interview" OR "would like to schedule" OR "phone screen" OR "video interview" OR "next round" OR "advance to" OR "proceed to" OR "we are pleased to" OR shortlisted OR "technical assessment")
```

**Query C — Acknowledgments (application received / under review):**
```
newer_than:{lookback} (subject:"thank you for applying" OR subject:"received your application" OR subject:"thank you for your application" OR subject:"thanks for applying" OR subject:"Welcome to")
```

Set `max: 50` for each query.

### Step 2 — Read Full Bodies

For **every** email returned in Step 1, call `get_message` to retrieve the full body.
Parallel calls are fine — batch up to ~10 at a time.

### Step 3 — Classify & Extract

For each message, read the **body text** (not just subject) and extract:

| Field | How to extract |
|-------|----------------|
| **Company** | Sender name/domain, or company name mentioned in the body |
| **Job title** | Named role in the body; fall back to subject if body is truncated |
| **Outcome** | One of: `Rejected`, `Interview Scheduled`, `Acknowledged` |

**Classification rules (from body content):**

| Outcome | Body signals |
|---------|-------------|
| `Rejected` | "regret to inform", "other candidates", "not selected", "will not be moving forward", "position has been filled", "unable to offer", "unsuccessful", explicit closure language |
| `Interview Scheduled` | "invite you to interview", "schedule a call", "phone screen", "next round", "pleased to advance", explicit interview/assessment invitation |
| `Acknowledged` | "received your application", "we will review", "team is reviewing", "will be in touch if", generic auto-reply confirmations |

If the body is truncated and ambiguous, classify as `Acknowledged` and note `(body truncated)`.

**Build CompTitle** — this is the **primary lookup key** against the Job Applications DB.

The DB already stores a `CompTitle` property on every record in the format:
```
company name|job title
```
All lowercase, single pipe `|` separator, no extra spaces around the pipe.
Examples from the DB: `mastercard|lead product manager- technical`, `sanofi|product owner, digital portfolio`

**From each email, build the same format:**
1. Extract the **company name** from the body/sender (use the short brand name, e.g. "Mastercard" not "MasterCard People Services").
2. Extract the **job title** exactly as it appears in the body (preserve punctuation like hyphens, commas).
3. Lowercase everything, join with `|`.

Result: `"mastercard|lead product manager- technical"`

If the job title cannot be extracted, use `"company|(unknown role)"`.

**Match quality matters** — the CompTitle you build must match the DB value closely enough for the search to find it. Prefer the **exact role wording** from the email body over a paraphrased version.

### Step 4 — Update Notion Follow-Up Email Log

Use `notion-fetch` to get the current content of the log page (`notion_log_page`).

Then use `notion-update-page` with `replace_content` to write the grouped results.

**Content format:**

```markdown
# Follow-Up Email Check — {YYYY-MM-DD}

## Rejected

| Company | Job Title | CompTitle | Email Date |
|---------|-----------|-----------|------------|
| Manulife | Operations Risk & Control Governance Lead | manulife|operations risk & control governance lead | 2026-04-06 |

## Interview Scheduled

| Company | Job Title | CompTitle | Email Date |
|---------|-----------|-----------|------------|
(or "None found in the last {lookback}" if empty)

## Acknowledged / Under Review

| Company | Job Title | CompTitle | Email Date |
|---------|-----------|-----------|------------|
| Amazon | Sr. Manager, Product Manager, Sourcing Performance, SCOT | amazon|sr. manager, product manager, sourcing performance, scot | 2026-04-07 |
```

Use `replace_content` so each run produces a clean snapshot (not appended duplicates).

### Step 5 — Archive Rejected Records in Job Applications DB

For **each** rejected application, use the **CompTitle built in Step 3** to find and update the matching DB record:

1. **Search by CompTitle:** Use `notion-search` with `data_source_url: {job_db_data_source}` and the email-derived CompTitle as the query (e.g. `"sanofi|product owner, digital portfolio"`).
2. **Verify the match:** From the search results, fetch the candidate page(s) and check that the record's `CompTitle` property matches the email-derived CompTitle. This avoids false positives from semantic search returning loosely related records.
3. **If a matching record is found:**
   - Use `notion-update-page` → `update_properties` to set:
     - `"Archive"`: `"__YES__"`
     - `"Status"`: `"Rejected"`
   - Record the page URL for the output report.
4. **If multiple records share the same CompTitle** but have different Job IDs, only update the record whose Job ID matches the email (if the email contains one). If no Job ID is in the email, update **all** matching CompTitle records.
5. **If no match is found**, note it as `(no matching DB record)` in the output.

### Step 6 — Output Summary

Print a grouped report to the user:

```
## Rejected (archived)

| Company | Job Title | DB Record | Archive Updated |
|---------|-----------|-----------|-----------------|
| Manulife | Operations Risk & Control Governance Lead | notion.so/... | Yes |
| Sanofi | Product Owner, Digital Portfolio | notion.so/... | Yes |

## Interview Scheduled

| Company | Job Title |
|---------|-----------|
(none or listed)

## Acknowledged / Under Review

| Company | Job Title |
|---------|-----------|
| Amazon | Sr. Manager, Product Manager, ... |

---
Notion log updated: https://www.notion.so/33c8d41a5cff80d3b905c9b53c6f65e9
```

---

## Key Rules

1. **Always read full message bodies** — never classify from subject alone.
2. **CompTitle format** — `"company|job title"` all lowercase; this is the lookup key.
3. **Only archive on clear rejection** — "under review" or "high volume" auto-replies are NOT rejections.
4. **Idempotent** — running twice on the same day overwrites the Notion log (replace, not append).
5. **Parallel where safe** — `search_emails` queries and `get_message` calls may run in parallel; Notion writes must be sequential.
6. **Dedup across queries** — the same email may appear in multiple Gmail searches; deduplicate by message ID before classifying.

---

## MCP Tools Used

| Tool | Server | Purpose |
|------|--------|---------|
| `search_emails` | `user-gmail` | Find job-related emails |
| `get_message` | `user-gmail` | Read full body for classification |
| `notion-fetch` | `user-Notion` | Read current log page / DB schema |
| `notion-search` | `user-Notion` | Find matching Job Applications DB records by CompTitle |
| `notion-update-page` | `user-Notion` | Write log page + set Archive/Status on rejected records |

