[TERMINAL · SKILLS]
> mounting /skills...
> indexing 295 manifests...
> linking agents: claude · codex · gemini · cursor
> ready.
[░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
Terminal.skills
Use Cases/Build an Email Deliverability Monitor

Build an Email Deliverability Monitor

Build an email deliverability monitor with SPF/DKIM/DMARC validation, inbox placement testing, bounce rate tracking, sender reputation scoring, and blacklist checking for email infrastructure.

Development#redis#caching#database#pub-sub#queues
Works with:claude-codeopenai-codexgemini-clicursor

Skills stack · 4 skills

Avg quality 93/100·All SAFE
>

redis

v1.0.0

Build applications with Redis — caching, session storage, pub/sub, streams, rate limiting, leaderboards, and queues. Use when tasks involve in-memory data storage, real-time messaging, distributed locking, or performance optimization with caching layers.

93/100 quality
1.81× impact
SAFE
View skill
>

postgresql

v1.0.0

Assists with designing schemas, writing performant queries, managing indexes, and operating PostgreSQL databases. Use when working with JSONB, full-text search, window functions, CTEs, row-level security, replication, or performance tuning. Trigger words: postgresql, postgres, sql, database, jsonb, rls, window functions, cte.

87/100 quality
1.53× impact
SAFE
View skill
>

hono

v1.0.0

You are an expert in Hono, the ultrafast web framework for the edge. You help developers build APIs and web applications that run on Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda, and Vercel Edge — with a tiny footprint (~14KB), middleware ecosystem, JSX support, RPC client, and Web Standards API compatibility that makes code truly portable across runtimes.

93/100 quality
3.00× impact
SAFE
View skill
>

zod

v1.0.0

You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.

100/100 quality
1.21× impact
SAFE
View skill
$

The Problem

Sara leads engineering at a 25-person SaaS sending 500K emails/month. Delivery rate dropped from 95% to 72% over 3 months — nobody noticed until customers complained about missing password resets. SPF record was misconfigured during a DNS migration. DKIM keys hadn't been rotated in 2 years. Their IP landed on 2 blacklists. Bounce rate climbed to 8% (should be <2%). They need monitoring: check email authentication records, track delivery metrics, detect blacklisting, score sender reputation, and alert on problems before they affect users.

Step 1: Build the Monitor

typescript
import { pool } from "../db";
import { Redis } from "ioredis";
import { Resolver } from "node:dns/promises";
const redis = new Redis(process.env.REDIS_URL!);
const resolver = new Resolver();

interface DeliverabilityReport { domain: string; score: number; spf: AuthCheck; dkim: AuthCheck; dmarc: AuthCheck; blacklists: BlacklistCheck[]; metrics: EmailMetrics; recommendations: string[]; checkedAt: string; }
interface AuthCheck { status: "pass" | "fail" | "missing"; record: string | null; issues: string[]; }
interface BlacklistCheck { list: string; listed: boolean; }
interface EmailMetrics { sent: number; delivered: number; bounced: number; complained: number; opened: number; deliveryRate: number; bounceRate: number; complaintRate: number; openRate: number; }

const BLACKLISTS = ["zen.spamhaus.org", "bl.spamcop.net", "b.barracudacentral.org", "dnsbl.sorbs.net", "psbl.surriel.com"];

// Run full deliverability check
export async function checkDeliverability(domain: string, sendingIP?: string): Promise<DeliverabilityReport> {
  const spf = await checkSPF(domain);
  const dkim = await checkDKIM(domain);
  const dmarc = await checkDMARC(domain);
  const blacklists = sendingIP ? await checkBlacklists(sendingIP) : [];
  const metrics = await getEmailMetrics(domain);
  const recommendations: string[] = [];
  let score = 100;

  if (spf.status !== "pass") { score -= 20; recommendations.push(spf.status === "missing" ? "Add SPF record: v=spf1 include:_spf.google.com ~all" : `Fix SPF: ${spf.issues.join(", ")}`); }
  if (dkim.status !== "pass") { score -= 20; recommendations.push("Configure DKIM signing for your sending domain"); }
  if (dmarc.status !== "pass") { score -= 15; recommendations.push(dmarc.status === "missing" ? "Add DMARC record: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com" : `Fix DMARC: ${dmarc.issues.join(", ")}`); }

  const blacklisted = blacklists.filter((b) => b.listed);
  if (blacklisted.length > 0) { score -= blacklisted.length * 15; recommendations.push(`IP listed on ${blacklisted.length} blacklist(s): ${blacklisted.map((b) => b.list).join(", ")}. Request removal.`); }

  if (metrics.bounceRate > 5) { score -= 10; recommendations.push(`Bounce rate ${metrics.bounceRate.toFixed(1)}% is too high (target: <2%). Clean your email list.`); }
  if (metrics.complaintRate > 0.1) { score -= 10; recommendations.push(`Complaint rate ${metrics.complaintRate.toFixed(2)}% exceeds threshold (target: <0.1%). Add easy unsubscribe.`); }

  score = Math.max(0, score);
  const report: DeliverabilityReport = { domain, score, spf, dkim, dmarc, blacklists, metrics, recommendations, checkedAt: new Date().toISOString() };

  await pool.query(`INSERT INTO deliverability_reports (domain, score, spf_status, dkim_status, dmarc_status, blacklisted, recommendations, checked_at) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())`, [domain, score, spf.status, dkim.status, dmarc.status, blacklisted.length > 0, JSON.stringify(recommendations)]);

  if (score < 70) { await redis.rpush("notification:queue", JSON.stringify({ type: "deliverability_alert", domain, score, recommendations: recommendations.slice(0, 3) })); }

  return report;
}

async function checkSPF(domain: string): Promise<AuthCheck> {
  try {
    const records = await resolver.resolveTxt(domain);
    const spfRecord = records.find((r) => r.join("").startsWith("v=spf1"));
    if (!spfRecord) return { status: "missing", record: null, issues: ["No SPF record found"] };
    const record = spfRecord.join("");
    const issues: string[] = [];
    if (record.includes("+all")) issues.push("SPF uses +all (allows any server) — should be ~all or -all");
    if ((record.match(/include:/g) || []).length > 10) issues.push("Too many SPF includes (DNS lookup limit is 10)");
    return { status: issues.length > 0 ? "fail" : "pass", record, issues };
  } catch { return { status: "missing", record: null, issues: ["DNS lookup failed"] }; }
}

async function checkDKIM(domain: string): Promise<AuthCheck> {
  const selectors = ["default", "google", "selector1", "selector2", "k1", "mail"];
  for (const selector of selectors) {
    try {
      const records = await resolver.resolveTxt(`${selector}._domainkey.${domain}`);
      const dkimRecord = records.find((r) => r.join("").includes("v=DKIM1"));
      if (dkimRecord) {
        const record = dkimRecord.join("");
        const issues: string[] = [];
        if (record.includes("k=rsa") && !record.includes("p=")) issues.push("DKIM record missing public key");
        return { status: issues.length > 0 ? "fail" : "pass", record: `${selector}._domainkey: ${record.slice(0, 100)}`, issues };
      }
    } catch {}
  }
  return { status: "missing", record: null, issues: ["No DKIM record found for common selectors"] };
}

async function checkDMARC(domain: string): Promise<AuthCheck> {
  try {
    const records = await resolver.resolveTxt(`_dmarc.${domain}`);
    const dmarcRecord = records.find((r) => r.join("").startsWith("v=DMARC1"));
    if (!dmarcRecord) return { status: "missing", record: null, issues: ["No DMARC record found"] };
    const record = dmarcRecord.join("");
    const issues: string[] = [];
    if (record.includes("p=none")) issues.push("DMARC policy is 'none' — should be 'quarantine' or 'reject'");
    if (!record.includes("rua=")) issues.push("No aggregate report address (rua) configured");
    return { status: issues.length > 0 ? "fail" : "pass", record, issues };
  } catch { return { status: "missing", record: null, issues: ["DNS lookup failed"] }; }
}

async function checkBlacklists(ip: string): Promise<BlacklistCheck[]> {
  const reversed = ip.split(".").reverse().join(".");
  const results: BlacklistCheck[] = [];
  for (const list of BLACKLISTS) {
    try {
      await resolver.resolve4(`${reversed}.${list}`);
      results.push({ list, listed: true });
    } catch { results.push({ list, listed: false }); }
  }
  return results;
}

async function getEmailMetrics(domain: string): Promise<EmailMetrics> {
  const month = new Date().toISOString().slice(0, 7);
  const stats = await redis.hgetall(`email:metrics:${domain}:${month}`);
  const sent = parseInt(stats.sent || "0");
  const delivered = parseInt(stats.delivered || "0");
  const bounced = parseInt(stats.bounced || "0");
  const complained = parseInt(stats.complained || "0");
  const opened = parseInt(stats.opened || "0");
  return {
    sent, delivered, bounced, complained, opened,
    deliveryRate: sent > 0 ? (delivered / sent) * 100 : 0,
    bounceRate: sent > 0 ? (bounced / sent) * 100 : 0,
    complaintRate: sent > 0 ? (complained / sent) * 100 : 0,
    openRate: delivered > 0 ? (opened / delivered) * 100 : 0,
  };
}

// Track email events (from webhook)
export async function trackEmailEvent(domain: string, event: "sent" | "delivered" | "bounced" | "complained" | "opened"): Promise<void> {
  const month = new Date().toISOString().slice(0, 7);
  await redis.hincrby(`email:metrics:${domain}:${month}`, event, 1);
}

Results

  • Delivery drop caught — score dropped from 85 to 55 → alert fired → SPF misconfiguration found and fixed in 30 minutes; previously took 3 months to notice
  • Blacklist detection — IP on 2 blacklists discovered; removal requested; delivery rate recovered from 72% to 94% in 1 week
  • Authentication scored — SPF ✓, DKIM ✓, DMARC ✗ (p=none) → recommendation: upgrade to p=quarantine; step-by-step fixes provided
  • Bounce rate tracked — 8% → cleaned list → 1.5%; complaint rate 0.15% → added one-click unsubscribe → 0.03%; metrics drive action
  • Cron monitoring — weekly deliverability check; trend over time; catch issues before they become outages; password resets always arrive