Skip to main content

OpenClaw API 集成指南:连接外部系统

·2932 words·6 mins

前言
#

OpenClaw 的强大之处在于能够连接各种外部系统——从云服务 API 到内部工具,从数据库到消息队列。通过 API 集成,AI 助手可以执行真实世界的操作,而不仅仅是回答问题。

本文将详解:

  • OpenClaw API 架构
  • 常见集成场景
  • 实战案例:GitHub、飞书、阿里云集成
  • 安全与认证
  • 性能优化

OpenClaw API 架构
#

工具调用流程
#

用户请求 → 语义理解 → 工具选择 → 参数提取 → API 调用 → 结果返回 → 自然语言响应

支持的 API 类型
#

  1. REST API - 最常见的 HTTP API
  2. GraphQL API - 灵活的数据查询
  3. gRPC - 高性能 RPC 框架
  4. WebSocket - 实时双向通信
  5. 命令行工具 - 本地 CLI 封装

集成场景分类
#

1. 云服务集成
#

  • 阿里云 ECS、RDS、OSS
  • AWS EC2、S3、Lambda
  • 腾讯云 CVM、COS

2. 开发工具集成
#

  • GitHub/GitLab
  • Jira/Confluence
  • Jenkins/GitLab CI

3. 通讯工具集成
#

  • 飞书/钉钉/企业微信
  • Slack/Discord
  • Telegram/WhatsApp

4. 监控系统集成
#

  • Prometheus/Grafana
  • Zabbix/Nagios
  • Datadog/New Relic

5. 数据库集成
#

  • MySQL/PostgreSQL
  • MongoDB/Redis
  • Elasticsearch

实战案例一:GitHub 集成
#

场景描述
#

通过 OpenClaw 管理 GitHub 仓库:

  • 查询 Issue/PR 状态
  • 创建/关闭 Issue
  • 合并 PR
  • 查看 CI/CD 状态

配置步骤
#

1. 生成 GitHub Token
#

# 在 GitHub Settings → Developer settings → Personal access tokens
# 选择 scopes: repo, workflow, admin:org

2. 配置 OpenClaw
#

openclaw.json 中添加:

{
  "tools": {
    "github": {
      "enabled": true,
      "config": {
        "token": "ghp_xxxxxxxxxxxxxxxxxxxx",
        "defaultOwner": "your-username",
        "defaultRepo": "your-repo"
      }
    }
  }
}

3. 创建 GitHub 工具
#

创建 ~/.openclaw/workspace/tools/github.js

const axios = require('axios');

class GitHubTool {
  constructor(config) {
    this.token = config.token;
    this.baseUrl = 'https://api.github.com';
    this.defaultOwner = config.defaultOwner;
    this.defaultRepo = config.defaultRepo;
  }

  async request(method, path, data = null) {
    const response = await axios({
      method,
      url: `${this.baseUrl}${path}`,
      headers: {
        'Authorization': `token ${this.token}`,
        'Accept': 'application/vnd.github.v3+json',
        'Content-Type': 'application/json'
      },
      data
    });
    return response.data;
  }

  async getIssue(owner, repo, issueNumber) {
    return await this.request('GET', `/repos/${owner}/${repo}/issues/${issueNumber}`);
  }

  async listIssues(owner, repo, options = {}) {
    const params = new URLSearchParams(options);
    return await this.request('GET', `/repos/${owner}/${repo}/issues?${params}`);
  }

  async createIssue(owner, repo, title, body, labels = []) {
    return await this.request('POST', `/repos/${owner}/${repo}/issues`, {
      title,
      body,
      labels
    });
  }

  async closeIssue(owner, repo, issueNumber) {
    return await this.request('PATCH', `/repos/${owner}/${repo}/issues/${issueNumber}`, {
      state: 'closed'
    });
  }

  async getPullRequest(owner, repo, prNumber) {
    return await this.request('GET', `/repos/${owner}/${repo}/pulls/${prNumber}`);
  }

  async mergePullRequest(owner, repo, prNumber, mergeMethod = 'merge') {
    return await this.request('PUT', `/repos/${owner}/${repo}/pulls/${prNumber}/merge`, {
      merge_method: mergeMethod
    });
  }

  async getWorkflowRuns(owner, repo, workflowId, options = {}) {
    const params = new URLSearchParams(options);
    return await this.request('GET', `/repos/${owner}/${repo}/actions/workflows/${workflowId}/runs?${params}`);
  }
}

module.exports = GitHubTool;

4. 创建技能定义
#

创建 skills/github/SKILL.md

# GitHub Skill

## Description
管理 GitHub 仓库,包括 Issue、PR、Workflow 等操作。

## Location
/root/.openclaw/workspace/skills/github/SKILL.md

## Activation
当用户提到 GitHub、仓库、Issue、PR、合并、工作流时自动激活。

## Triggers
- "GitHub"
- "Issue"
- "PR" / "Pull Request"
- "合并"
- "工作流"
- "CI/CD"

## Usage Examples

**查询 Issue:**

查看 #123 号 Issue 的状态 列出所有开放的 Issue


**创建 Issue:**

创建一个新 Issue:修复登录 bug


**管理 PR:**

查看 #45 号 PR 合并 #45 号 PR


**查看 Workflow:**

查看 main 分支的构建状态 最近的 CI 运行结果

使用示例
#

# 查询 Issue
openclaw tool github --action getIssue --owner openclaw --repo openclaw --number 123

# 创建 Issue
openclaw tool github --action createIssue \
  --owner openclaw \
  --repo openclaw \
  --title "Bug: 登录失败" \
  --body "详细描述..." \
  --labels "bug,priority-high"

# 合并 PR
openclaw tool github --action mergePullRequest \
  --owner openclaw \
  --repo openclaw \
  --number 45 \
  --method squash

实战案例二:飞书集成
#

场景描述
#

通过飞书 API 实现:

  • 发送消息通知
  • 创建/更新文档
  • 管理日历事件
  • 查询用户信息

配置步骤
#

1. 创建飞书应用
#

  1. 访问 https://open.feishu.cn/app
  2. 创建企业自建应用
  3. 获取 App ID 和 App Secret
  4. 配置权限 scopes

2. 配置 OpenClaw
#

openclaw.json 中(已有飞书配置):

{
  "channels": {
    "feishu": {
      "enabled": true,
      "accounts": {
        "main": {
          "appId": "cli_a92aff260f781bc0",
          "appSecret": "rrFxIY3Tb3gasjYQ3JrA8dy5MAw6z6o2"
        }
      }
    }
  }
}

3. 创建飞书工具
#

创建 ~/.openclaw/workspace/tools/feishu-api.js

const axios = require('axios');

class FeishuTool {
  constructor(config) {
    this.appId = config.appId;
    this.appSecret = config.appSecret;
    this.baseUrl = 'https://open.feishu.cn/open-apis';
    this.token = null;
    this.tokenExpire = 0;
  }

  async getTenantToken() {
    if (this.token && Date.now() < this.tokenExpire) {
      return this.token;
    }

    const response = await axios.post(`${this.baseUrl}/auth/v3/tenant_access_token/internal`, {
      app_id: this.appId,
      app_secret: this.appSecret
    });

    this.token = response.data.tenant_access_token;
    this.tokenExpire = Date.now() + (response.data.expire - 300) * 1000;
    
    return this.token;
  }

  async request(method, path, data = null) {
    const token = await this.getTenantToken();
    
    const response = await axios({
      method,
      url: `${this.baseUrl}${path}`,
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      data
    });

    if (response.data.code !== 0) {
      throw new Error(`Feishu API error: ${response.data.msg}`);
    }

    return response.data.data;
  }

  async sendMessage(chatId, content, msgType = 'text') {
    return await this.request('POST', '/im/v1/messages', {
      receive_id: chatId,
      msg_type: msgType,
      content: JSON.stringify(content)
    });
  }

  async sendInteractiveCard(chatId, card) {
    return await this.request('POST', '/im/v1/messages', {
      receive_id: chatId,
      msg_type: 'interactive',
      content: JSON.stringify(card)
    });
  }

  async createDoc(title, content, folderToken = null) {
    return await this.request('POST', '/docx/v1/documents', {
      title,
      content
    });
  }

  async getDocContent(docToken) {
    return await this.request('GET', `/docx/v1/documents/${docToken}`);
  }

  async updateDocBlock(docToken, blockId, content) {
    return await this.request('PUT', `/docx/v1/documents/${docToken}/blocks/${blockId}`, {
      content
    });
  }

  async createCalendarEvent(summary, start_time, end_time, attendees = []) {
    return await this.request('POST', '/calendar/v4/calendars/primary/events', {
      summary,
      start: { date_time: start_time, timezone: 'Asia/Shanghai' },
      end: { date_time: end_time, timezone: 'Asia/Shanghai' },
      attendees
    });
  }

  async getUserInfo(userId) {
    return await this.request('GET', `/contact/v1/users/${userId}`);
  }
}

module.exports = FeishuTool;

使用示例
#

// 发送文本消息
await feishu.sendMessage('ou_xxx', { text: '服务器告警:CPU 使用率 95%' });

// 发送交互式卡片
await feishu.sendInteractiveCard('ou_xxx', {
  config: {
    wide_screen_mode: true
  },
  header: {
    title: {
      tag: 'plain_text',
      content: '🚨 服务器告警'
    },
    template: 'red'
  },
  elements: [
    {
      tag: 'markdown',
      content: '**实例:** prod-web-01\n**CPU:** 95%\n**时间:** 2026-03-16 12:00'
    }
  ]
});

// 创建文档
const doc = await feishu.createDoc('服务器巡检报告', '# 服务器巡检报告\n\n## 概览\n\n所有服务器运行正常。');

// 创建日历事件
await feishu.createCalendarEvent(
  '周例会',
  '2026-03-17T10:00:00+08:00',
  '2026-03-17T11:00:00+08:00',
  ['ou_xxx1', 'ou_xxx2']
);

实战案例三:阿里云集成
#

场景描述
#

通过阿里云 OpenAPI 管理云资源:

  • ECS 实例管理
  • RDS 数据库监控
  • OSS 文件操作
  • 云监控指标查询

配置步骤
#

1. 安装阿里云 CLI
#

# macOS
brew install aliyun-cli

# Linux
curl -O https://aliyuncli.alicdn.com/aliyun-cli-linux-3.0.161-amd64.tgz
tar -xzf aliyun-cli-linux-3.0.161-amd64.tgz
sudo mv aliyun /usr/local/bin/

2. 配置凭证
#

aliyun configure
# 输入 AccessKey ID、Secret、Region

3. 创建阿里云工具
#

创建 ~/.openclaw/workspace/tools/aliyun.js

const { execSync } = require('child_process');

class AliyunTool {
  constructor(config) {
    this.region = config.region || 'cn-hangzhou';
  }

  async exec(command, args) {
    const cmd = `aliyun ${command} ${args.join(' ')} --output json`;
    const output = execSync(cmd, { encoding: 'utf8' });
    return JSON.parse(output);
  }

  // ECS 相关
  async describeInstances(instanceIds = []) {
    const ids = instanceIds.length > 0 
      ? `--InstanceIds "[${instanceIds.map(id => `"${id}"`).join(',')}]"`
      : '';
    
    return await this.exec('ecs DescribeInstances', [
      '--RegionId', this.region,
      ids
    ]);
  }

  async startInstance(instanceId) {
    return await this.exec('ecs StartInstance', [
      '--InstanceId', instanceId
    ]);
  }

  async stopInstance(instanceId) {
    return await this.exec('ecs StopInstance', [
      '--InstanceId', instanceId
    ]);
  }

  async rebootInstance(instanceId) {
    return await this.exec('ecs RebootInstance', [
      '--InstanceId', instanceId
    ]);
  }

  // 监控相关
  async describeMetricLast(namespace, metricName, dimensions) {
    return await this.exec('cms DescribeMetricLast', [
      '--Namespace', namespace,
      '--MetricName', metricName,
      '--Dimensions', JSON.stringify(dimensions)
    ]);
  }

  // RDS 相关
  async describeDBInstances(instanceId = null) {
    const args = ['--RegionId', this.region];
    if (instanceId) {
      args.push('--DBInstanceId', instanceId);
    }
    return await this.exec('rds DescribeDBInstances', args);
  }

  // OSS 相关
  async listBuckets() {
    return await this.exec('oss ls', []);
  }

  async uploadFile(bucket, key, filePath) {
    return await this.exec('oss cp', [
      filePath,
      `oss://${bucket}/${key}`
    ]);
  }

  async downloadFile(bucket, key, localPath) {
    return await this.exec('oss cp', [
      `oss://${bucket}/${key}`,
      localPath
    ]);
  }
}

module.exports = AliyunTool;

使用示例
#

// 查询所有 ECS 实例
const instances = await aliyun.describeInstances();
console.log(instances.Instances.Instance);

// 启动实例
await aliyun.startInstance('i-bp1234567890');

// 查询 CPU 使用率
const cpu = await aliyun.describeMetricLast(
  'acs_ecs_dashboard',
  'CPUUtilization',
  { instanceId: 'i-bp1234567890' }
);

// 查询 RDS 实例
const rdsInstances = await aliyun.describeDBInstances();

// 上传文件到 OSS
await aliyun.uploadFile('my-bucket', 'backup/db-2026-03-16.sql', '/tmp/db.sql');

安全与认证
#

1. 凭证管理
#

❌ 不要硬编码:

// 错误示例
const apiKey = 'sk-1234567890abcdef';

✅ 使用环境变量:

// 正确示例
const apiKey = process.env.API_KEY;

✅ 使用配置文件:

# ~/.openclaw/credentials.json
{
  "github": { "token": "ghp_..." },
  "aliyun": { "accessKeyId": "LTAI...", "accessKeySecret": "..." }
}

# 设置文件权限
chmod 600 ~/.openclaw/credentials.json

2. 权限最小化
#

  • 只申请必要的 API 权限
  • 使用只读 Token 进行查询操作
  • 定期轮换密钥

3. 请求签名
#

对于需要签名的 API:

const crypto = require('crypto');

function signRequest(params, secret) {
  const sortedParams = Object.keys(params)
    .sort()
    .map(key => `${key}=${params[key]}`)
    .join('&');
  
  const stringToSign = `POST&${encodeURIComponent('/')}&${encodeURIComponent(sortedParams)}`;
  const signature = crypto
    .createHmac('sha1', secret + '&')
    .update(stringToSign)
    .digest('base64');
  
  return signature;
}

性能优化
#

1. 连接复用
#

const axios = require('axios');

// 创建复用实例
const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true })
});

2. 请求缓存
#

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 300 });

async function getCachedData(key, fetchFn) {
  const cached = cache.get(key);
  if (cached) {
    return cached;
  }
  
  const data = await fetchFn();
  cache.set(key, data);
  return data;
}

3. 批量请求
#

// ❌ 串行请求(慢)
for (const id of ids) {
  await api.getItem(id);
}

// ✅ 并行请求(快)
const results = await Promise.all(
  ids.map(id => api.getItem(id))
);

// ✅ 分批并行(避免限流)
const batchSize = 10;
const results = [];
for (let i = 0; i < ids.length; i += batchSize) {
  const batch = ids.slice(i, i + batchSize);
  const batchResults = await Promise.all(
    batch.map(id => api.getItem(id))
  );
  results.push(...batchResults);
  await sleep(100); // 避免限流
}

4. 超时与重试
#

const axiosRetry = require('axios-retry');

const client = axios.create();

axiosRetry(client, {
  retries: 3,
  retryDelay: axiosRetry.exponentialDelay,
  retryCondition: (error) => {
    return axiosRetry.isNetworkOrIdempotentRequestError(error) ||
           error.response?.status === 429; // 限流
  }
});

错误处理
#

统一错误处理
#

class ApiError extends Error {
  constructor(message, code, statusCode) {
    super(message);
    this.name = 'ApiError';
    this.code = code;
    this.statusCode = statusCode;
  }
}

async function safeApiCall(fn, fallback = null) {
  try {
    return await fn();
  } catch (error) {
    if (error.response?.status === 404) {
      throw new ApiError('资源未找到', 'NOT_FOUND', 404);
    }
    if (error.response?.status === 429) {
      throw new ApiError('请求过于频繁', 'RATE_LIMITED', 429);
    }
    if (error.response?.status >= 500) {
      throw new ApiError('服务器错误', 'SERVER_ERROR', error.response.status);
    }
    throw error;
  }
}

常见问题
#

Q: API 调用失败如何调试?
#

# 启用详细日志
export DEBUG=openclaw:tools:*
export OPENCLAW_LOG_LEVEL=debug

# 查看请求日志
tail -f ~/.openclaw/logs/gateway.log | grep -i api

Q: 如何处理 API 限流?
#

// 实现令牌桶限流
class RateLimiter {
  constructor(tokensPerSecond) {
    this.tokensPerSecond = tokensPerSecond;
    this.tokens = tokensPerSecond;
    this.lastRefill = Date.now();
  }

  async acquire() {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    this.tokens = Math.min(this.tokensPerSecond, this.tokens + elapsed * this.tokensPerSecond);
    this.lastRefill = now;

    if (this.tokens < 1) {
      const waitTime = (1 - this.tokens) / this.tokensPerSecond * 1000;
      await sleep(waitTime);
      return this.acquire();
    }

    this.tokens -= 1;
  }
}

Q: 如何测试 API 集成?
#

// 使用 Mock 服务器
const nock = require('nock');

nock('https://api.github.com')
  .get('/repos/openclaw/openclaw/issues/123')
  .reply(200, { number: 123, title: 'Test Issue' });

// 运行测试
const issue = await github.getIssue('openclaw', 'openclaw', 123);
assert.equal(issue.title, 'Test Issue');

总结
#

API 集成让 OpenClaw 能够:

  • ✅ 连接外部系统和服务
  • ✅ 执行真实世界的操作
  • ✅ 自动化复杂工作流
  • ✅ 提供实时数据和反馈

关键要点:

  1. 选择合适的集成方式(REST/GraphQL/gRPC)
  2. 做好认证和安全管理
  3. 实现错误处理和重试机制
  4. 优化性能和限流
  5. 编写完善的文档和测试

相关资源:

下一篇: 《OpenClaw 性能调优:优化配置与资源管理》