关于 listener-creator
listener-creator 是用于创建 TypeScript 邮件监听器的 Skill,可监控邮件事件并执行自定义操作,涵盖 AI 分类和定时任务等邮件工作流。
主要功能
- 01创建 TypeScript 邮件监听器
- 02处理多种邮件事件
- 03筛选并分类邮件内容
- 04通知、归档、加星和添加标签
- 05设置定时邮件操作
适用场景
- 01紧急邮件到达时提醒
- 02自动归档新闻邮件
- 03跟踪包裹相关邮件
- 04定时发送邮件摘要
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ claude-agent-sdk-demos --skill listener-creator安装后在 Claude Code 中输入/listener-creator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
templates/ai-classifier.tsauto-archive.tspackage-tracker.tsurgent-watcher.ts详细介绍
监听器创建器
创建 TypeScript 监听器文件,用于监控电子邮件事件,并在满足条件时执行自定义逻辑。
何时使用此技能
当用户想要:
- 接收特定电子邮件的通知(“老板发送紧急邮件时通知我”)
- 自动处理某些电子邮件(“自动归档新闻邮件”)
- 监控特定模式(“监控包裹追踪邮件”)
- 设置定时操作(“每天上午 9 点发送邮件摘要”)
- 创建自定义电子邮件工作流
监听器的工作方式
监听器是位于 agent/custom_scripts/listeners/ 的 TypeScript 文件,它们会:
- 导出一个
config对象,用于定义事件类型和元数据 - 导出一个
handler函数,用于筛选和处理事件 - 使用
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.tsauto-archive-newsletters.tspackage-tracking.tsdaily-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");
示例和模板
常见模式可参考模板文件:
- ai-classifier.ts:⭐ AI 驱动的电子邮件分类(推荐)
- urgent-watcher.ts:基于 AI 的紧急邮件检测
- auto-archive.ts:自动归档新闻邮件
- package-tracker.ts:追踪包裹并提取状态
最佳实践
- 优先使用 AI 分类:使用
context.callAgent()进行智能决策,而不是使用硬编码的关键词列表 - 尽早筛选:如果邮件不符合基本条件(例如发件人),则尽早返回
- 使用清晰的 ID:为监听器使用描述性强且唯一的 ID
- 错误处理:适当时使用 try-catch 包装上下文方法调用
- 性能:使用 "haiku" 模型进行快速 AI 分类(通常少于 1 秒)
- 谨慎通知:仅在确实重要时通知
- 避免硬编码列表:让 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 的邮件都通知我”)
自动归档
基本筛选 → 归档 → 标记为已读 → 可选:发送通知
定时任务
在指定时间运行 → 查询邮件 → 分析 → 发送摘要
创建文件
当用户请求创建监听器时:
-
如果意图不明确,请提出澄清问题:
- 发送者是谁?包含哪些关键词?
- 应执行什么操作?
- 紧急程度如何?
-
选择合适的事件类型(通常为
email_received) -
在
agent/custom_scripts/listeners/中编写 TypeScript 文件 -
使用 Write 工具创建文件,并包含:
- 正确的导入语句
- 描述清晰的配置
- 带有早期过滤逻辑的处理程序
- 适当的上下文方法调用
-
以 Markdown 格式返回监听器引用,使用
[listener:filename.ts]格式(例如[listener:boss-urgent-watcher.ts]),方便在 UI 中解析和链接 -
向用户确认监听器符合其意图
输出格式示例
向用户展示创建的监听器时,请使用以下格式:
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 实现
- 高级示例
- 错误处理模式