mcpField
L
listener-creator

listener-creator

github.com/anthropics生产力2.8k165 次安装33 周前更新
代码仓库

关于 listener-creator

listener-creator 是用于创建 TypeScript 邮件监听器的 Skill,可监控邮件事件并执行自定义操作,涵盖 AI 分类和定时任务等邮件工作流。

主要功能

  1. 01创建 TypeScript 邮件监听器
  2. 02处理多种邮件事件
  3. 03筛选并分类邮件内容
  4. 04通知、归档、加星和添加标签
  5. 05设置定时邮件操作

适用场景

  1. 01紧急邮件到达时提醒
  2. 02自动归档新闻邮件
  3. 03跟踪包裹相关邮件
  4. 04定时发送邮件摘要

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anthropics/claude-agent-sdk-demos --skill listener-creator

安装后在 Claude Code 中输入/listener-creator确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

templates/
ai-classifier.ts
auto-archive.ts
package-tracker.ts
urgent-watcher.ts

详细介绍

监听器创建器

创建 TypeScript 监听器文件,用于监控电子邮件事件,并在满足条件时执行自定义逻辑。

何时使用此技能

当用户想要:

  • 接收特定电子邮件的通知(“老板发送紧急邮件时通知我”)
  • 自动处理某些电子邮件(“自动归档新闻邮件”)
  • 监控特定模式(“监控包裹追踪邮件”)
  • 设置定时操作(“每天上午 9 点发送邮件摘要”)
  • 创建自定义电子邮件工作流

监听器的工作方式

监听器是位于 agent/custom_scripts/listeners/ 的 TypeScript 文件,它们会:

  1. 导出一个 config 对象,用于定义事件类型和元数据
  2. 导出一个 handler 函数,用于筛选和处理事件
  3. 使用 ListenerContext 方法执行操作(通知、归档、加星标等)

系统会自动加载已启用的监听器,并在发生匹配的事件时执行它们。

创建监听器

1. 理解用户意图

解析用户的请求,确定:

  • 事件类型:什么会触发此监听器?(email_received、email_sent、email_starred、email_archived、email_labeled、scheduled_time)
  • 筛选条件:要匹配哪些特定邮件或事件?(发件人、主题关键词、基于时间的条件)
  • 操作:应该执行什么操作?(通知、归档、加星标、标记为已读、添加标签)
  • 优先级:紧急程度如何?(high/normal/low)
2. 选择事件类型
// 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. 编写监听器文件

在 agent/custom_scripts/listeners/ 中创建文件,结构如下:

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("[email protected]")) 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. 文件命名约定

使用与监听器用途相符的 kebab-case 命名:

  • boss-urgent-watcher.ts
  • auto-archive-newsletters.ts
  • package-tracking.ts
  • daily-summary.ts
5. 可用的上下文方法

ListenerContext 提供以下方法:

// 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"
});

推荐方法:AI 驱动的分类

默认使用 context.callAgent() 进行智能决策,而不是使用硬编码的关键词列表。这样可以获得更高的准确性和适应性。

// 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");

示例和模板

常见模式可参考模板文件:

最佳实践

  1. 优先使用 AI 分类:使用 context.callAgent() 进行智能决策,而不是使用硬编码的关键词列表
  2. 尽早筛选:如果邮件不符合基本条件(例如发件人),则尽早返回
  3. 使用清晰的 ID:为监听器使用描述性强且唯一的 ID
  4. 错误处理:适当时使用 try-catch 包装上下文方法调用
  5. 性能:使用 "haiku" 模型进行快速 AI 分类(通常少于 1 秒)
  6. 谨慎通知:仅在确实重要时通知
  7. 避免硬编码列表:让 AI 判断紧急程度、重要性或类别,而不是进行关键词匹配

类型导入

始终从正确的位置导入类型:

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

// For scheduled listeners:
import type { ListenerConfig, ListenerContext } from "../types";

// For labeled event:
import type { ListenerConfig, Email, ListenerContext } from "../types";

常见模式

AI 驱动(优先)

基本筛选(发件人/类型)→ 调用 AI Agent 进行智能分类 → 根据 AI 结果采取操作 → 重要时发送通知

对于大多数监听器,推荐使用这种方法,因为它:

  • 避免脆弱的关键词匹配
  • 能适应细微的语言差异和上下文
  • 能更好地判断紧急程度和分类
  • 减少误报
简单通知(谨慎使用)

基本筛选(仅发件人)→ 通知 → 可选:加星标/添加标签

仅在以下情况下使用:触发条件完全基于身份(例如,“所有来自 X 的邮件都通知我”)

自动归档

基本筛选 → 归档 → 标记为已读 → 可选:发送通知

定时任务

在指定时间运行 → 查询邮件 → 分析 → 发送摘要

创建文件

当用户请求创建监听器时:

  1. 如果意图不明确,请提出澄清问题:

    • 发送者是谁?包含哪些关键词?
    • 应执行什么操作?
    • 紧急程度如何?
  2. 选择合适的事件类型(通常为 email_received)

  3. 在 agent/custom_scripts/listeners/ 中编写 TypeScript 文件

  4. 使用 Write 工具创建文件,并包含:

    • 正确的导入语句
    • 描述清晰的配置
    • 带有早期过滤逻辑的处理程序
    • 适当的上下文方法调用
  5. 以 Markdown 格式返回监听器引用,使用 [listener:filename.ts] 格式(例如 [listener:boss-urgent-watcher.ts]),方便在 UI 中解析和链接

  6. 向用户确认监听器符合其意图

输出格式示例

向用户展示创建的监听器时,请使用以下格式:

Created listener: [listener:boss-urgent-watcher.ts]

This listener will:
- Monitor emails from [email protected]
- Use AI to detect urgent emails (not just keywords)
- Send high-priority notifications for truly urgent emails
- Star emails that require immediate action

何时使用 AI,何时使用简单过滤

以下情况使用 AI(context.callAgent()):

  • 检测紧急程度、重要性或情感倾向
  • 对电子邮件内容或意图进行分类
  • 从电子邮件正文中提取结构化数据
  • 根据上下文做出细致的判断
  • 任何涉及“理解”电子邮件内容的逻辑

以下情况使用简单过滤:

  • 检查确切的发件人/收件人
  • 对电子邮件字段进行基本模式匹配(例如,“来自特定域名”)
  • 基于身份的触发条件(例如,“来自 X 人的所有电子邮件”)

除非过滤条件纯粹基于身份,否则默认使用 AI。

定时监听器

对于基于时间的操作(每日摘要、每周报告):

export const config: ListenerConfig = {
  id: "daily_summary",
  name: "Daily Email Summary",
  enabled: true,
  event: "scheduled_time"
  // Note: Cron schedule configured separately in scheduler
};

export async function handler(
  data: { timestamp: Date },
  context: ListenerContext
): Promise<void> {
  // Your scheduled logic here
  await context.notify("Good morning! Your daily summary...");
}

注意:定时监听器需要在监听器文件之外配置 cron 调度器。

参考

完整规范:请参阅项目根目录下的 LISTENERS_SPEC.md,了解以下内容的完整详情:

  • 所有事件类型
  • 完整的类型定义
  • ListenersManager 实现
  • 高级示例
  • 错误处理模式

评论

支持 Markdown