OpenClaw Gmail 集成:智能邮件管理

Gmail 是全球使用最广泛的邮件服务之一,拥有超过 15 亿用户。通过 OpenClaw 的 Gmail 集成,你可以创建一个智能邮件助手,实现自动回复、邮件分类、摘要生成、任务提取等功能,大幅提升邮件处理效率。本文将详细介绍如何配置和使用 OpenClaw 的 Gmail 功能。

Gmail API 概述

Gmail API 能力

功能 说明
读取邮件 获取邮件内容和元数据
发送邮件 以用户身份发送邮件
管理标签 创建、修改、删除标签
管理邮件 标记已读、归档、删除
草稿操作 创建、修改草稿

认证方式

OpenClaw 支持两种 Gmail 认证方式:

  1. OAuth 2.0(推荐):安全的用户授权方式
  2. 服务账号:适用于企业级应用

创建 Google Cloud 项目

步骤 1:创建项目

  1. 访问 Google Cloud Console
  2. 点击 新建项目
  3. 输入项目名称,点击 创建

步骤 2:启用 Gmail API

  1. 在左侧菜单中选择 API 和服务
  2. 搜索 Gmail API
  3. 点击 启用

步骤 3:创建 OAuth 凭据

  1. 进入 API 和服务凭据
  2. 点击 创建凭据OAuth 客户端 ID
  3. 选择 桌面应用Web 应用
  4. 下载凭据 JSON 文件

步骤 4:配置同意屏幕

  1. 点击 配置同意屏幕
  2. 选择 外部
  3. 填写必要信息
  4. 添加测试用户(开发阶段)

OpenClaw Gmail 配置

环境变量配置

# Gmail OAuth 凭据
GMAIL_CLIENT_ID=your-client-id.apps.googleusercontent.com
GMAIL_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxx

# OAuth 回调 URL(固定)
GMAIL_REDIRECT_URI=http://localhost:3000/auth/google/callback

# 用户刷新令牌(首次授权后获取)
GMAIL_REFRESH_TOKEN=1//0gxxxxxxxxxxxxxxxxxxxxxx

配置文件

plugins:
  - gmail

gmail:
  enabled: true
  clientId: "${GMAIL_CLIENT_ID}"
  clientSecret: "${GMAIL_CLIENT_SECRET}"
  redirectUri: "${GMAIL_REDIRECT_URI}"

  # 基础设置
  settings:
    # 是否自动转发
    autoForward: false
    forwardAddress: ""

    # 附件处理
    downloadAttachments: true
    maxAttachmentSize: "10MB"
    attachmentPath: "./data/gmail/attachments"

    # 标签管理
    syncLabels: true
    autoCreateLabels: true

  # 功能开关
  features:
    read: true
    send: true
    draft: true
    labels: true

  # 过滤规则
  filters:
    # 自动标记重要邮件
    - name: "important"
      conditions:
        from: "boss@company.com"
        subject: "重要"
      actions:
        addLabel: "Important"

    # 自动归档促销邮件
    - name: "promotions"
      conditions:
        category: "promotions"
      actions:
        addLabel: "Promotions"
        markRead: true

  # 通知设置
  notifications:
    enabled: true
    platforms:
      - "telegram"
    newEmailAlert: true

OAuth 授权流程

首次使用需要完成 OAuth 授权:

// 1. 生成授权 URL
const authUrl = gmail.getAuthUrl();

// 2. 用户访问并授权
// 用户访问 authUrl,登录 Google 账号并授权

// 3. 交换授权码获取刷新令牌
const refreshToken = await gmail.exchangeCode(code);

// 4. 保存 refreshToken 到配置
// 刷新令牌长期有效,可以重复使用

使用场景示例

场景 1:智能邮件摘要

// skills/email-summarizer/index.js
module.exports = {
  name: 'email-summarizer',

  async execute(params, context) {
    const { maxEmails = 10 } = params;

    // 1. 获取最新邮件
    const emails = await context.gmail.listMessages({
      maxResults: maxEmails,
      labelIds: ['INBOX'],
      q: 'is:unread'
    });

    // 2. 逐个获取邮件详情
    const emailDetails = await Promise.all(
      emails.map(async (email) => {
        const detail = await context.gmail.getMessage(email.id);
        return {
          subject: detail.subject,
          from: detail.from,
          snippet: detail.snippet,
          date: detail.date
        };
      })
    );

    // 3. 生成摘要
    const summary = await context.llm.summarize({
      prompt: `请为以下未读邮件生成简要摘要:
${JSON.stringify(emailDetails, null, 2)}`,
      format: 'markdown'
    });

    return {
      type: 'text',
      content: `📧 未读邮件摘要(共 ${emails.length} 封)\n\n${summary}`
    };
  }
};

场景 2:自动回复邮件

# config/gmail.yaml
gmail:
  features:
    autoReply: true

filters:
  - name: "auto-reply"
    conditions:
      subject: "咨询"
      - label: "INBOX"
    actions:
      # 触发自动回复技能
      triggerSkill: "auto-reply-skill"
// skills/auto-reply-skill/index.js
module.exports = {
  name: 'auto-reply-skill',

  async execute(params, context) {
    const { messageId, originalEmail } = params;
    const { subject, from } = originalEmail;

    // 1. 分析邮件内容
    const analysis = await context.llm.analyze({
      text: originalEmail.body,
      question: "这封邮件的核心需求是什么?需要如何回复?"
    });

    // 2. 生成回复
    const replyContent = await context.llm.generate({
      prompt: `请根据以下信息生成一封专业回复邮件:

原邮件主题:${subject}
发件人:${from}
分析结果:${analysis}

回复要求:
1. 语言专业、礼貌
2. 解决用户问题
3. 适当提及下一步行动`,
      maxTokens: 500
    });

    // 3. 发送回复
    const result = await context.gmail.sendMessage({
      to: from,
      subject: `Re: ${subject}`,
      body: replyContent,
      threadId: originalEmail.threadId
    });

    // 4. 标记原邮件为已读
    await context.gmail.modifyMessage(originalEmail.id, {
      removeLabelIds: ['UNREAD']
    });

    return {
      type: 'text',
      content: `✅ 自动回复已发送至 ${from}`
    };
  }
};

场景 3:邮件任务提取

// skills/task-extractor/index.js
module.exports = {
  name: 'task-extractor',

  async execute(params, context) {
    const { days = 7 } = params;

    // 1. 获取指定时间范围内的邮件
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - days);

    const emails = await context.gmail.listMessages({
      q: `after:${startDate.toISOString().split('T')[0]}`
    });

    // 2. 提取任务
    const tasks = [];
    for (const email of emails) {
      const detail = await context.gmail.getMessage(email.id);

      const extractedTasks = await context.llm.extract({
        text: `${detail.subject}\n${detail.body}`,
        schema: {
          type: 'array',
          items: {
            type: 'object',
            properties: {
              task: { type: 'string' },
              deadline: { type: 'string' },
              priority: { type: 'string', enum: ['high', 'medium', 'low'] }
            }
          }
        }
      });

      if (extractedTasks.length > 0) {
        tasks.push(...extractedTasks.map(t => ({
          ...t,
          source: detail.subject,
          emailId: detail.id
        })));
      }
    }

    // 3. 返回任务列表
    if (tasks.length === 0) {
      return { type: 'text', content: '未提取到任何任务' };
    }

    return {
      type: 'card',
      content: {
        header: {
          title: `📋 任务提取(共 ${tasks.length} 项)`
        },
        elements: tasks.map(task => ({
          tag: 'div',
          fields: [
            { is_short: true, text: `**任务**: ${task.task}` },
            { is_short: true, text: `**截止**: ${task.deadline || '待定'}` },
            { is_short: true, text: `**优先级**: ${task.priority}` }
          ]
        }))
      }
    };
  }
};

场景 4:邮件内容搜索

// skills/email-search/index.js
module.exports = {
  name: 'email-search',

  async execute(params, context) {
    const { query, maxResults = 10 } = params;

    // 1. 搜索邮件
    const results = await context.gmail.listMessages({
      q: query,
      maxResults
    });

    // 2. 获取详细信息
    const emails = await Promise.all(
      results.slice(0, 5).map(async (msg) => {
        const detail = await context.gmail.getMessage(msg.id);
        return {
          subject: detail.subject,
          from: detail.from,
          date: detail.date,
          snippet: detail.snippet
        };
      })
    );

    // 3. 格式化输出
    const output = emails.map((email, i) => 
      `${i + 1}. **${email.subject}**\n   发件人: ${email.from}\n   日期: ${email.date}\n   摘要: ${email.snippet}`
    ).join('\n\n');

    return {
      type: 'text',
      content: `🔍 搜索结果:${results.length} 封邮件\n\n${output}`
    };
  }
};

场景 5:定时邮件报告

# config/cron.yaml
tasks:
  - name: "weekly-email-report"
    description: "每周邮件统计报告"
    schedule: "0 9 * * 1"  # 每周一早上9点
    skill: "email-report"
    params:
      recipients:
        - "user@example.com"
      period: "week"
// skills/email-report/index.js
module.exports = {
  name: 'email-report',

  async execute(params, context) {
    const { period = 'week' } = params;

    // 计算时间范围
    const now = new Date();
    let startDate = new Date();
    if (period === 'day') {
      startDate.setDate(now.getDate() - 1);
    } else if (period === 'week') {
      startDate.setDate(now.getDate() - 7);
    } else {
      startDate.setMonth(now.getMonth() - 1);
    }

    // 1. 统计收件
    const received = await context.gmail.listMessages({
      q: `after:${startDate.toISOString().split('T')[0]} to:me`
    });

    // 2. 统计发件
    const sent = await context.gmail.listMessages({
      q: `after:${startDate.toISOString().split('T')[0]} from:me`
    });

    // 3. 按标签统计
    const labels = await context.gmail.getLabels();
    const labelStats = {};
    for (const label of labels) {
      const count = await context.gmail.getLabelCount(label.id);
      labelStats[label.name] = count;
    }

    // 4. 生成报告
    const report = `
📊 邮件统计报告(${period === 'day' ? '昨日' : period === 'week' ? '上周' : '上月'}

📥 收件:${received.length}
📤 发件:${sent.length}
🏷️ 标签统计:
${Object.entries(labelStats).map(([k, v]) => `- ${k}: ${v}`).join('\n')}

祝您工作顺利!
`;

    // 5. 发送报告
    return {
      type: 'text',
      content: report
    };
  }
};

高级功能

1. 邮件过滤规则

gmail:
  filters:
    # 自动分类重要邮件
    - name: "priority-emails"
      conditions:
        from:
          - "boss@company.com"
          - "client@important.com"
        subject: "紧急"
        is: "unread"
      actions:
        addLabel: "Important"
        star: true

    # 自动处理订阅
    - name: "newsletters"
      conditions:
        listUnsubscribe: true
      actions:
        addLabel: "Newsletters"
        markRead: true
        archive: true

2. IMAP 同步

gmail:
  features:
    imap: true

  imap:
    host: "imap.gmail.com"
    port: 993
    secure: true

3. SMTP 发送

gmail:
  features:
    smtp: true

  smtp:
    host: "smtp.gmail.com"
    port: 587
    secure: false  # TLS

安全最佳实践

1. 最小权限原则

只申请必要的 OAuth 权限:

const scopes = [
  'https://www.googleapis.com/auth/gmail.readonly',  // 只读
  'https://www.googleapis.com/auth/gmail.send',     // 发送
  // 不要申请 'https://www.googleapis.com/auth/gmail.settings.basic'
];

2. 令牌安全

gmail:
  # 加密存储令牌
  tokenStorage:
    type: "encrypted"
    key: "${TOKEN_ENCRYPTION_KEY}"

3. 访问控制

gmail:
  permissions:
    # 限制可发送的邮箱
    allowedSenders:
      - "user@domain.com"
    # 禁止发送的邮箱
    blockedSenders: []

常见问题

问题 1:OAuth 授权失败

解决方案: - 检查 Client ID 和 Secret - 确认回调 URL 正确 - 验证应用状态(非测试模式需发布) - 检查重定向 URI 设置

问题 2:刷新令牌失效

可能原因: - 用户撤销了访问权限 - 超过 6 个月未使用 - 应用权限被限制

解决方案: - 重新进行 OAuth 授权流程

问题 3:API 配额超限

解决方案: - 实现请求节流 - 使用缓存减少 API 调用 - 申请更高的配额

问题 4:邮件发送失败

检查: - 是否超过每日发送配额(500 封/天) - 收件人地址是否有效 - 是否包含可疑内容

性能优化

1. 缓存策略

gmail:
  cache:
    enabled: true
    ttl: 300  # 5分钟
    labels: true
    messages: true

2. 批量操作

// 批量标记已读
await context.gmail.batchModify({
  ids: messageIds,
  removeLabelIds: ['UNREAD']
});

3. 分页处理

// 处理大量邮件
let pageToken = null;
do {
  const result = await context.gmail.listMessages({
    pageToken,
    maxResults: 100
  });

  // 处理邮件...

  pageToken = result.nextPageToken;
} while (pageToken);

总结

OpenClaw 的 Gmail 集成让你能够:

  • ✅ 自动阅读和摘要邮件
  • ✅ 智能回复邮件
  • ✅ 提取任务和截止日期
  • ✅ 搜索历史邮件
  • ✅ 生成邮件统计报告

通过这些功能,你可以大幅提升邮件处理效率,把时间花在更有价值的工作上。


相关阅读: - OpenClaw 自动化工作流 - OpenClaw 技能开发 - OpenClaw 飞书集成