Skip to main content
ClaudeWave
ES, Spanish
Skill2.8k estrellas del repoactualizado 2mo ago

listener-creator

The listener-creator skill generates TypeScript event listeners that monitor email activity and automatically trigger custom actions based on specified conditions. Use it when you need to set up email automation workflows, receive notifications for specific email patterns, or automatically process emails that match criteria like sender, subject keywords, or time-based triggers.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/anthropics/claude-agent-sdk-demos /tmp/listener-creator && cp -r /tmp/listener-creator/email-agent/agent/.claude/skills/listener-creator ~/.claude/skills/listener-creator
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Listener Creator

Creates TypeScript listener files that monitor email events and execute custom logic when conditions are met.

## When to Use This Skill

Use this skill when the user wants to:
- Get notifications about specific emails ("notify me when boss sends urgent emails")
- Automatically handle certain emails ("auto-archive newsletters")
- Monitor for patterns ("watch for package tracking emails")
- Set up scheduled actions ("daily email summary at 9am")
- Create custom email workflows

## How Listeners Work

Listeners are TypeScript files in `agent/custom_scripts/listeners/` that:
1. Export a `config` object defining the event type and metadata
2. Export a `handler` function that filters and processes events
3. Use `ListenerContext` methods to perform actions (notify, archive, star, etc.)

The system automatically loads enabled listeners and executes them when matching events occur.

## Creating a Listener

### 1. Understand the User's Intent

Parse the user's request to identify:
- **Event type**: What triggers this listener? (email_received, email_sent, email_starred, email_archived, email_labeled, scheduled_time)
- **Filter conditions**: What specific emails/events to match? (sender, subject keywords, time-based)
- **Actions**: What should happen? (notify, archive, star, mark as read, add label)
- **Priority**: How urgent is this? (high/normal/low)

### 2. Choose an Event Type

```typescript
// Available event types:
- "email_received"  // Most common - new email arrives
- "email_sent"      // User sends an email
- "email_starred"   // Email is starred
- "email_archived"  // Email is archived
- "email_labeled"   // Label added to email
- "scheduled_time"  // Time-based (cron) - requires scheduler setup
```

### 3. Write the Listener File

Create a file in `agent/custom_scripts/listeners/` with this structure:

```typescript
import type { ListenerConfig, Email, ListenerContext } from "../types";

export const config: ListenerConfig = {
  id: "unique_listener_id",           // kebab-case, descriptive
  name: "Human Readable Name",         // For UI display
  description: "What this does",       // Optional but helpful
  enabled: true,                       // Start enabled
  event: "email_received"              // Event type
};

export async function handler(email: Email, context: ListenerContext): Promise<void> {
  // 1. Basic filter (identity/sender only)
  if (!email.from.includes("example@email.com")) return;

  // 2. Use AI for intelligent classification (PREFERRED over keyword matching)
  const analysis = await context.callAgent<{ isUrgent: boolean; reason: string }>({
    prompt: `Is this email urgent?\nSubject: ${email.subject}\nBody: ${email.body.substring(0, 500)}`,
    schema: {
      type: "object",
      properties: {
        isUrgent: { type: "boolean" },
        reason: { type: "string" }
      },
      required: ["isUrgent", "reason"]
    },
    model: "haiku"
  });

  if (!analysis.isUrgent) return;

  // 3. Perform actions via context methods
  await context.notify(`Urgent email: ${email.subject}\n${analysis.reason}`, {
    priority: "high"
  });

  await context.starEmail(email.messageId);
}
```

### 4. File Naming Convention

Use kebab-case matching the listener's purpose:
- `boss-urgent-watcher.ts`
- `auto-archive-newsletters.ts`
- `package-tracking.ts`
- `daily-summary.ts`

### 5. Available Context Methods

The `ListenerContext` provides these methods:

```typescript
// Notifications
await context.notify(message, { priority: "high" | "normal" | "low" });

// Email actions
await context.archiveEmail(emailId);
await context.starEmail(emailId);
await context.unstarEmail(emailId);
await context.markAsRead(emailId);
await context.markAsUnread(emailId);
await context.addLabel(emailId, "label-name");
await context.removeLabel(emailId, "label-name");

// AI-powered analysis
const result = await context.callAgent<ResultType>({
  prompt: "Your prompt with email content",
  schema: {
    type: "object",
    properties: { field: { type: "string" } },
    required: ["field"]
  },
  model: "haiku" // or "sonnet" or "opus"
});
```

## Recommended Approach: AI-Powered Classification

**Default to using `context.callAgent()` for intelligent decision-making** instead of hard-coded keyword lists. This provides better accuracy and adaptability.

```typescript
// PREFERRED: AI-based urgency detection
const analysis = await context.callAgent<{ isUrgent: boolean; reason: string }>({
  prompt: `Analyze if this email is urgent:
Subject: ${email.subject}
Body: ${email.body.substring(0, 500)}

Is this email urgent or time-sensitive? Consider context, not just keywords.`,

  schema: {
    type: "object",
    properties: {
      isUrgent: { type: "boolean" },
      reason: { type: "string" }
    },
    required: ["isUrgent", "reason"]
  },
  model: "haiku" // Fast and cost-effective
});

if (analysis.isUrgent) {
  await context.notify(`Urgent: ${email.subject}\n${analysis.reason}`);
}

// AVOID: Hard-coded keyword lists (brittle and prone to false positives)
// const isUrgent = subject.includes("urgent") || subject.includes("asap");
```

## Examples and Templates

Reference the template files for common patterns:

- **[ai-classifier.ts](templates/ai-classifier.ts)**: ⭐ AI-powered email classification (RECOMMENDED)
- **[urgent-watcher.ts](templates/urgent-watcher.ts)**: AI-based urgent email detection
- **[auto-archive.ts](templates/auto-archive.ts)**: Automatically archives newsletters
- **[package-tracker.ts](templates/package-tracker.ts)**: Package tracking with status extraction

## Best Practices

1. **Prefer AI Classification**: Use `context.callAgent()` instead of hard-coded keyword lists for intelligent decision-making
2. **Filter Early**: Return early if email doesn't match basic criteria (like sender)
3. **Clear IDs**: Use descriptive, unique listener IDs
4. **Error Handling**: Wrap context method calls in try-catch when appropriate
5. **Performance**: Use "haiku" model fo
action-creatorSkill

Creates user-specific one-click action templates that execute email operations when clicked in the chat interface. Use when user wants reusable actions for their specific workflows (send payment reminder to ACME Corp, forward bugs to engineering, archive old newsletters from specific sources).

competitive-analysisSlash Command

Perform competitive analysis on companies or products

docxSkill

Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks

executive-briefingSkill

Transforms research findings into executive-ready briefings. Automatically activated when user mentions 'executive', 'briefing', 'C-suite', 'board', 'leadership', or 'presentation'.

fact-checkSlash Command

Fact-check claims or verify information

inbox-searcherSubagent

Email inbox search specialist, takes in appropriate context for the email and a goal of what to search for. Return the answer to the question.

market-trendsSlash Command

Research current market trends in a specific industry or domain

pdfSkill

Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale.