Skip to content

插件 API 参考文档

UnityAI-Tauri 插件系统完整 API 参考

概述

插件通过 postMessage 协议与主应用通信。所有消息都遵循统一的格式:

typescript
interface Message {
  type: string;
  payload?: any;
  error?: string;
}

认证 API

请求 Token

插件 → 主应用

javascript
window.parent.postMessage({
  type: 'request_token'
}, '*');

主应用 → 插件

javascript
{
  type: 'token_response',
  payload: {
    token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
  }
}

说明:

  • Token 是 JWT 格式
  • 默认有效期 24 小时
  • Token 包含用户 ID 和权限信息
  • 过期后需要重新请求

错误响应:

javascript
{
  type: 'error',
  error: 'User not authenticated'
}

数据存储 API

保存数据

插件 → 主应用

javascript
window.parent.postMessage({
  type: 'save_data',
  payload: {
    pluginId: 'your-plugin-id',
    key: 'settings',
    value: JSON.stringify({ theme: 'dark', language: 'zh-CN' })
  }
}, '*');

参数:

  • pluginId (string, 必需): 插件唯一标识符
  • key (string, 必需): 数据键名
  • value (string, 必需): 数据值(必须是字符串,复杂对象需要 JSON.stringify)

主应用 → 插件

javascript
{
  type: 'api_response',
  payload: {
    success: true,
    message: 'Data saved successfully'
  }
}

存储限制:

  • 单个 value 建议不超过 1MB
  • 总存储空间按用户配额管理
  • 数据按 user_id + plugin_id + key 隔离

读取数据

插件 → 主应用

javascript
window.parent.postMessage({
  type: 'get_data',
  payload: {
    pluginId: 'your-plugin-id'
  }
}, '*');

参数:

  • pluginId (string, 必需): 插件唯一标识符

主应用 → 插件

javascript
{
  type: 'api_response',
  payload: {
    data: {
      'settings': '{"theme":"dark","language":"zh-CN"}',
      'user_preference': '{"notifications":true}',
      'note_123': '{"title":"标题","content":"内容"}'
    }
  }
}

说明:

  • 返回该插件的所有数据
  • 数据以 key-value 对象形式返回
  • value 都是字符串,需要 JSON.parse 解析

删除数据

插件 → 主应用

javascript
window.parent.postMessage({
  type: 'api_call',
  payload: {
    endpoint: `/api/plugins/${pluginId}/data/${key}`,
    method: 'DELETE'
  }
}, '*');

参数:

  • endpoint (string, 必需): API 端点路径
  • method (string, 必需): HTTP 方法(DELETE)

主应用 → 插件

javascript
{
  type: 'api_response',
  payload: {
    success: true,
    message: 'Data deleted successfully'
  }
}

API 调用

通用 API 调用

插件 → 主应用

javascript
window.parent.postMessage({
  type: 'api_call',
  payload: {
    endpoint: '/api/plugins/your-plugin-id/custom-endpoint',
    method: 'POST',
    body: {
      action: 'process',
      data: { foo: 'bar' }
    }
  }
}, '*');

参数:

  • endpoint (string, 必需): API 端点路径
  • method (string, 必需): HTTP 方法(GET, POST, PUT, DELETE)
  • body (object, 可选): 请求体(仅 POST/PUT)

主应用 → 插件

javascript
{
  type: 'api_response',
  payload: {
    // API 返回的数据
  }
}

说明:

  • 主应用会自动添加 Authorization header
  • 请求会通过主应用代理,避免 CORS 问题
  • 超时时间 30 秒

支持的端点

获取插件信息

GET /api/plugins/{pluginId}

返回插件的详细信息(名称、版本、描述等)。

获取用户插件列表

GET /api/user/plugins

返回当前用户已安装的所有插件。

评分插件

POST /api/plugins/{pluginId}/rate
Body: { rating: 5 }

为插件评分(1-5 星)。

获取用户评分

GET /api/plugins/{pluginId}/rating

获取当前用户对该插件的评分。

错误处理

错误响应格式

javascript
{
  type: 'error',
  error: 'Error message description'
}

常见错误

错误信息原因解决方案
User not authenticatedToken 未获取或已过期重新调用 request_token
Invalid plugin IDpluginId 不存在或拼写错误检查 pluginId 是否正确
Data too large数据超过大小限制分片存储或压缩数据
Rate limit exceeded请求过于频繁添加防抖或节流
Permission denied插件权限不足检查插件权限配置

错误处理示例

javascript
window.addEventListener('message', (event) => {
  const { type, payload, error } = event.data;

  if (type === 'error') {
    console.error('操作失败:', error);
    
    // 根据错误类型处理
    if (error.includes('not authenticated')) {
      // 重新认证
      requestToken();
    } else if (error.includes('Rate limit')) {
      // 延迟重试
      setTimeout(() => retryOperation(), 5000);
    } else {
      // 显示错误给用户
      showErrorMessage(error);
    }
  }
});

安全最佳实践

1. Origin 验证

生产环境必须验证消息来源:

javascript
window.addEventListener('message', (event) => {
  // 只接受来自主应用的消息
  if (event.origin !== 'https://app.unityai.com') {
    return;
  }
  
  // 处理消息
});

2. Token 安全

javascript
// ❌ 错误:不要在 localStorage 中存储 Token
localStorage.setItem('token', token);

// ✅ 正确:只在内存中保存
let authToken = null;

window.addEventListener('message', (event) => {
  if (event.data.type === 'token_response') {
    authToken = event.data.payload.token;
  }
});

3. 数据验证

javascript
// 保存前验证数据
function saveData(key, value) {
  // 验证 key
  if (!key || typeof key !== 'string') {
    throw new Error('Invalid key');
  }
  
  // 验证 value 大小
  const valueStr = JSON.stringify(value);
  if (valueStr.length > 1024 * 1024) { // 1MB
    throw new Error('Data too large');
  }
  
  // 保存
  window.parent.postMessage({
    type: 'save_data',
    payload: { pluginId: PLUGIN_ID, key, value: valueStr }
  }, '*');
}

4. XSS 防护

javascript
// ❌ 错误:直接插入 HTML
element.innerHTML = userInput;

// ✅ 正确:使用 textContent 或转义
element.textContent = userInput;

// 或使用 DOMPurify 清理
element.innerHTML = DOMPurify.sanitize(userInput);

性能优化

1. 批量操作

javascript
// ❌ 错误:逐个保存
notes.forEach(note => {
  saveData(`note_${note.id}`, JSON.stringify(note));
});

// ✅ 正确:批量保存
const batch = notes.reduce((acc, note) => {
  acc[`note_${note.id}`] = JSON.stringify(note);
  return acc;
}, {});

// 一次性保存所有数据
Object.entries(batch).forEach(([key, value]) => {
  saveData(key, value);
});

2. 防抖和节流

javascript
// 防抖:延迟执行
let saveTimeout;
function autoSave(data) {
  clearTimeout(saveTimeout);
  saveTimeout = setTimeout(() => {
    saveData('draft', JSON.stringify(data));
  }, 1000);
}

// 节流:限制频率
let lastSaveTime = 0;
function throttledSave(data) {
  const now = Date.now();
  if (now - lastSaveTime > 1000) {
    saveData('draft', JSON.stringify(data));
    lastSaveTime = now;
  }
}

3. 缓存

javascript
let dataCache = null;
let cacheTime = null;
const CACHE_TTL = 60000; // 1 分钟

function loadData(forceRefresh = false) {
  if (!forceRefresh && dataCache && Date.now() - cacheTime < CACHE_TTL) {
    return Promise.resolve(dataCache);
  }
  
  return new Promise((resolve) => {
    window.parent.postMessage({
      type: 'get_data',
      payload: { pluginId: PLUGIN_ID }
    }, '*');
    
    const handler = (event) => {
      if (event.data.type === 'api_response') {
        dataCache = event.data.payload.data;
        cacheTime = Date.now();
        window.removeEventListener('message', handler);
        resolve(dataCache);
      }
    };
    
    window.addEventListener('message', handler);
  });
}

TypeScript 类型定义

typescript
// 消息类型
type MessageType = 
  | 'request_token'
  | 'token_response'
  | 'save_data'
  | 'get_data'
  | 'api_call'
  | 'api_response'
  | 'error';

// 插件消息
interface PluginMessage {
  type: MessageType;
  payload?: any;
  error?: string;
}

// Token 响应
interface TokenResponse {
  type: 'token_response';
  payload: {
    token: string;
  };
}

// 数据保存请求
interface SaveDataRequest {
  type: 'save_data';
  payload: {
    pluginId: string;
    key: string;
    value: string;
  };
}

// 数据读取请求
interface GetDataRequest {
  type: 'get_data';
  payload: {
    pluginId: string;
  };
}

// API 调用请求
interface ApiCallRequest {
  type: 'api_call';
  payload: {
    endpoint: string;
    method: 'GET' | 'POST' | 'PUT' | 'DELETE';
    body?: any;
  };
}

// API 响应
interface ApiResponse {
  type: 'api_response';
  payload: any;
}

// 错误响应
interface ErrorResponse {
  type: 'error';
  error: string;
}

// 插件信息
interface Plugin {
  id: string;
  name: string;
  description?: string;
  version: string;
  author?: string;
  icon_url?: string;
  cloud_url: string;
  category?: string;
  permissions?: string;
  average_rating?: number;
  total_ratings: number;
}

调试技巧

1. 消息日志

javascript
// 记录所有消息
window.addEventListener('message', (event) => {
  console.log('[Plugin Message]', {
    origin: event.origin,
    type: event.data.type,
    payload: event.data.payload,
    error: event.data.error
  });
});

2. 性能监控

javascript
// 监控 API 调用时间
function apiCall(endpoint, method, body) {
  const startTime = performance.now();
  
  window.parent.postMessage({
    type: 'api_call',
    payload: { endpoint, method, body }
  }, '*');
  
  const handler = (event) => {
    if (event.data.type === 'api_response') {
      const duration = performance.now() - startTime;
      console.log(`API call to ${endpoint} took ${duration}ms`);
      window.removeEventListener('message', handler);
    }
  };
  
  window.addEventListener('message', handler);
}

3. 错误追踪

javascript
// 全局错误处理
window.addEventListener('error', (event) => {
  console.error('[Plugin Error]', {
    message: event.message,
    filename: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    error: event.error
  });
});

// Promise 错误处理
window.addEventListener('unhandledrejection', (event) => {
  console.error('[Plugin Promise Rejection]', event.reason);
});

版本兼容性

API最低版本说明
request_token1.0.0基础认证
save_data1.0.0数据存储
get_data1.0.0数据读取
api_call1.0.0API 调用
批量删除1.1.0支持批量删除数据
数据加密1.2.0计划中

相关资源

获取帮助

HAMA | 蛤蟆数字