小手机系统API开发文档

本文档介绍如何在小手机系统中开发自定义应用并调用系统API。

目录

  1. 快速开始
  2. API概览
  3. 权限系统
  4. API详细说明
  5. 示例代码
  6. 错误处理
  7. 最佳实践

快速开始

1. 创建HTML应用

在小手机系统中,进入"应用商店" -> "创建应用",创建一个新的HTML应用。

2. 基础HTML结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的应用</title>
    <style>
        /* 你的样式 */
    </style>
</head>
<body>
    <h1>欢迎使用小手机API</h1>
    
    <script>
        // 在这里调用API
    </script>
</body>
</html>

3. 检查API是否可用

if (window.phoneAPI) {
    console.log('小手机API已就绪');
} else {
    console.log('API未就绪,请确保在小手机系统中运行');
}

API概览

核心API列表

API方法权限要求说明
requestAuth()请求用户授权
checkPermission()检查权限状态
getAuthCode()获取已保存的授权码
聊天记录
getChatHistory()read_chat获取聊天记录
getChatSessions()read_chat获取会话列表
getMemories()read_chat获取长期记忆列表
addMemory()write_memory添加长期记忆
updateMemory()write_memory修改长期记忆
addMessage()write_chat添加聊天记录
用户
getUserInfo()read_user获取用户信息
AI功能
callLLM()call_llm调用AI对话
callTTS()call_tts语音合成
角色卡
getCharacterCards()read_character获取所有角色卡
getCharacterCard()read_character获取单个角色卡
createCharacterCard()write_character创建角色卡
updateCharacterCard()write_character更新角色卡
deleteCharacterCard()write_character删除角色卡
世界书
getWorldBooks()read_worldbook获取所有世界书
getWorldBookCategories()read_worldbook获取世界书分类
createWorldBook()write_worldbook创建世界书
updateWorldBook()write_worldbook更新世界书
deleteWorldBook()write_worldbook删除世界书
通讯录
getContacts()read_contact获取所有联系人
getContact()read_contact获取单个联系人
createContact()write_contact创建联系人
updateContact()write_contact更新联系人
deleteContact()write_contact删除联系人
角色信息
getCharacterFullInfo()read_contact获取角色完整信息(名称、头像、角色卡、世界书、记忆)

权限系统

权限类型

权限类型说明
聊天记录
read_chat读取获取完整的聊天记录内容
write_memory写入添加和修改角色的长期记忆
write_chat写入在聊天中发送消息
用户
read_user读取获取你的昵称、头像等基本信息
AI功能
call_llm写入调用AI大模型进行对话
call_tts写入将文字转换为语音
角色卡
read_character读取查看和使用角色卡信息
write_character写入创建和修改角色卡
世界书
read_worldbook读取查看世界书内容
write_worldbook写入创建和修改世界书
通讯录
read_contact读取查看通讯录中的人物
write_contact写入添加和修改通讯录人物

权限级别

授权码使用规则

API权限类型是否需要授权码授权码类型
读取类API
getChatHistory()读取❌ 不需要-
getChatSessions()读取❌ 不需要-
getUserInfo()读取❌ 不需要-
getMemories()读取❌ 不需要-
getCharacterCards()读取❌ 不需要-
getCharacterCard()读取❌ 不需要-
getWorldBooks()读取❌ 不需要-
getWorldBookCategories()读取❌ 不需要-
getContacts()读取❌ 不需要-
getContact()读取❌ 不需要-
写入类API
callLLM()写入✅ 需要call_llm
callTTS()写入✅ 需要call_tts
addMemory()写入✅ 需要write_memory
updateMemory()写入✅ 需要write_memory
addMessage()写入✅ 需要write_chat
createCharacterCard()写入✅ 需要write_character
updateCharacterCard()写入✅ 需要write_character
deleteCharacterCard()写入✅ 需要write_character
createWorldBook()写入✅ 需要write_worldbook
updateWorldBook()写入✅ 需要write_worldbook
deleteWorldBook()写入✅ 需要write_worldbook
createContact()写入✅ 需要write_contact
updateContact()写入✅ 需要write_contact
deleteContact()写入✅ 需要write_contact

请求授权

// 请求单个权限
const result = await window.phoneAPI.requestAuth(['read_chat']);

// 请求多个权限
const result = await window.phoneAPI.requestAuth([
    'read_chat',
    'call_llm',
    'read_user'
]);

// 处理结果
if (result.success) {
    console.log('授权成功');
    // result.data 是授权结果数组,每个权限对应一个结果
    result.data.forEach(authResult => {
        console.log('权限:', authResult.permissionType);
        console.log('授权码:', authResult.authCode);  // 写入权限会有授权码
        console.log('级别:', authResult.level);  // 'always' 或 'once'
    });
    
    // 获取第一个权限的授权码(用于单个权限)
    const authCode = result.data[0]?.authCode;
} else {
    console.log('授权失败:', result.error);
    if (result.error === '弹窗被阻止,请允许弹窗后重试') {
        alert('请允许浏览器弹窗,然后重新点击授权按钮');
    }
}

注意: 授权窗口会以弹窗形式打开,请确保浏览器允许弹窗,否则授权会失败。


API详细说明

1. 获取聊天记录

const result = await window.phoneAPI.getChatHistory(
    sessionId,  // 会话ID(必需)
    limit       // 限制条数(可选,默认全部)
);

if (result.success) {
    const messages = result.data;
    messages.forEach(msg => {
        console.log(msg.senderId, ':', msg.content);
    });
}

注意: 此API需要 read_chat 权限,但不需要授权码。

返回数据格式:

{
    id: string;
    sessionId: string;
    senderId: string;
    content: string;
    type: 'text' | 'voice' | 'image' | 'sticker';
    timestamp: Date;
    status: 'sent' | 'delivered' | 'read';
}

2. 添加长期记忆

const result = await window.phoneAPI.addMemory(
    sessionId,  // 会话ID(必需)
    content,    // 记忆内容(必需)
    authCode    // 授权码(必需)
);

if (result.success) {
    console.log('记忆已添加:', result.data.id);
}

3. 修改长期记忆

const result = await window.phoneAPI.updateMemory(
    memoryId,   // 记忆ID(必需)
    content,    // 新内容(必需)
    authCode    // 授权码(必需)
);

if (result.success) {
    console.log('记忆已更新');
}

4. 添加聊天记录

const result = await window.phoneAPI.addMessage(
    sessionId,  // 会话ID(必需)
    content,    // 消息内容(必需)
    authCode,   // 授权码(必需)
    senderId    // 发送者ID(可选,默认为 app_应用ID)
);

if (result.success) {
    console.log('消息已发送:', result.data.id);
}

5. 获取用户信息

const result = await window.phoneAPI.getUserInfo(authCode);

if (result.success) {
    const user = result.data;
    console.log('昵称:', user.name);
    console.log('头像:', user.avatar);
}

返回数据格式:

{
    id: string;
    name: string;
    avatar: string;
    settings: object;
    balance?: number;
    createdAt: Date;
}

6. 调用LLM

const result = await window.phoneAPI.callLLM(
    [
        { role: 'system', content: '你是一个助手' },
        { role: 'user', content: '你好' }
    ],
    authCode,
    {
        temperature: 0.7,    // 可选,默认0.7
        max_tokens: 2000     // 可选
    }
);

if (result.success) {
    console.log('AI回复:', result.data.content);
    console.log('使用模型:', result.data.model);
}

7. 调用TTS

const result = await window.phoneAPI.callTTS(
    '你好,这是测试文本',
    authCode,
    {
        voiceId: 'male-qn-qingse',  // 可选,音色ID
        speed: 1.0,                  // 可选,语速 (0.5-2.0)
        vol: 1.0,                    // 可选,音量 (0.1-10.0)
        pitch: 0,                    // 可选,音调 (-12 到 12)
        emotion: 'happy'             // 可选,情感 (happy, sad, angry, neutral等)
    }
);

if (result.success) {
    const audio = new Audio(result.data.audioUrl);
    audio.play();
}

参数说明:

注意: 具体支持的参数取决于系统配置的TTS提供商(MiniMax或其他)

8. 获取会话列表

const result = await window.phoneAPI.getChatSessions(authCode);

if (result.success) {
    const sessions = result.data;
    sessions.forEach(session => {
        console.log('会话:', session.name, 'ID:', session.id);
    });
}

9. 获取长期记忆列表

const result = await window.phoneAPI.getMemories(sessionId, authCode);

if (result.success) {
    const memories = result.data;
    memories.forEach(memory => {
        console.log('记忆:', memory.content);
    });
}

10. 检查权限状态

const result = await window.phoneAPI.checkPermission('read_chat');

if (result.success) {
    console.log('是否已授权:', result.data.granted);
    console.log('授权级别:', result.data.level); // 'always' | 'once' | undefined
}

11. 获取授权码

const result = await window.phoneAPI.getAuthCode('call_llm');

if (result.success && result.data) {
    console.log('授权码:', result.data.code);
    console.log('级别:', result.data.level);
}

12. 角色卡API

获取所有角色卡:

const result = await window.phoneAPI.getCharacterCards();

if (result.success) {
    result.data.forEach(character => {
        console.log('角色:', character.name);
        console.log('设定:', character.systemPrompt);
    });
}

创建角色卡:

const result = await window.phoneAPI.createCharacterCard({
    name: '新角色',
    avatar: 'https://example.com/avatar.png',  // 可选
    systemPrompt: '你是一个友善的助手...',
    tags: ['助手', 'AI']
}, authCode);

if (result.success) {
    console.log('创建成功,ID:', result.data.id);
}

更新角色卡:

const result = await window.phoneAPI.updateCharacterCard(
    characterId,
    { name: '新名称', systemPrompt: '新设定...' },
    authCode
);

删除角色卡:

const result = await window.phoneAPI.deleteCharacterCard(characterId, authCode);

13. 世界书API

获取所有世界书:

const result = await window.phoneAPI.getWorldBooks();

if (result.success) {
    result.data.forEach(book => {
        console.log('世界书:', book.name);
    });
}

获取世界书分类:

const result = await window.phoneAPI.getWorldBookCategories();

创建世界书:

const result = await window.phoneAPI.createWorldBook({
    name: '新世界书',
    categoryId: 'category-id',  // 可选
    content: '世界设定内容...'
}, authCode);

更新世界书:

const result = await window.phoneAPI.updateWorldBook(
    bookId,
    { name: '新名称', content: '新内容...' },
    authCode
);

删除世界书:

const result = await window.phoneAPI.deleteWorldBook(bookId, authCode);

14. 通讯录API

获取所有联系人:

const result = await window.phoneAPI.getContacts();

if (result.success) {
    result.data.forEach(contact => {
        console.log('联系人:', contact.name);
        console.log('类型:', contact.type); // 'private' | 'group'
    });
}

获取单个联系人:

const result = await window.phoneAPI.getContact(contactId);

创建联系人:

const result = await window.phoneAPI.createContact({
    name: '新联系人',
    avatar: 'https://example.com/avatar.png',  // 可选
    type: 'private',  // 'private' | 'group'
    memberIds: []  // 群聊时填写成员ID
}, authCode);

更新联系人:

const result = await window.phoneAPI.updateContact(
    contactId,
    { name: '新名称', avatar: '新头像URL' },
    authCode
);

删除联系人:

const result = await window.phoneAPI.deleteContact(contactId, authCode);

15. 角色完整信息API

获取角色完整信息(名称、头像、角色卡、世界书、记忆):

const result = await window.phoneAPI.getCharacterFullInfo(sessionId);

if (result.success) {
    const { contact, characterCards, worldBooks, memories } = result.data;
    
    // 角色名称和头像
    console.log('角色名称:', contact.name);
    console.log('角色头像:', contact.avatar);
    console.log('角色类型:', contact.type); // 'private' | 'group'
    
    // 角色卡信息
    console.log('\n角色卡数量:', characterCards.length);
    characterCards.forEach(card => {
        console.log('- 角色卡名称:', card.name);
        console.log('  设定:', card.systemPrompt);
        console.log('  标签:', card.tags);
    });
    
    // 世界书信息
    console.log('\n世界书数量:', worldBooks.length);
    worldBooks.forEach(book => {
        console.log('- 世界书名称:', book.name);
        console.log('  内容:', book.content);
    });
    
    // 长期记忆
    console.log('\n长期记忆数量:', memories.length);
    memories.forEach(memory => {
        console.log('- 记忆内容:', memory.content);
        console.log('  创建时间:', memory.createdAt);
    });
}

返回数据结构:

{
    contact: {
        id: string;
        name: string;        // 角色名称
        avatar?: string;     // 角色头像URL
        type: 'private' | 'group';
        memberIds?: string[]; // 关联的角色卡ID列表
        worldId?: string;    // 关联的世界书ID
        // ... 其他字段
    },
    characterCards: [      // 关联的角色卡列表
        {
            id: string;
            name: string;
            avatar?: string;
            systemPrompt: string;
            tags?: string[];
            createdAt: Date;
        }
    ],
    worldBooks: [          // 关联的世界书列表
        {
            id: string;
            name: string;
            content: string;
            categoryId?: string;
            createdAt: Date;
        }
    ],
    memories: [            // 长期记忆列表
        {
            id: string;
            sessionId: string;
            content: string;
            createdAt: Date;
            updatedAt: Date;
        }
    ]
}

示例代码

完整测试示例

我们提供了一个完整的 API 测试应用 api_test.html,包含所有 API 的测试用例:

使用方法:

  1. 在小手机系统中创建一个新的 HTML 应用
  2. api_test.html 的内容复制到应用中
  3. 保存并运行应用
  4. 按界面提示测试各个 API 功能

api_test.html文件下载

错误处理

错误码说明

错误码说明处理方式
AUTH_REQUIRED需要授权调用 requestAuth() 获取授权
AUTH_INVALID授权码无效重新请求授权
AUTH_EXPIRED授权码已过期重新请求授权
AUTH_USED授权码已使用重新请求授权(一次性授权码)
PERMISSION_DENIED权限被拒绝用户拒绝了权限申请
API_ERRORAPI调用错误检查API配置或重试
PARAM_INVALID参数无效检查传入的参数
NOT_FOUND资源不存在检查ID是否正确

错误处理示例

async function safeAPICall() {
    try {
        const result = await window.phoneAPI.getChatHistory(sessionId, authCode);
        
        if (!result.success) {
            switch (result.errorCode) {
                case 'AUTH_REQUIRED':
                case 'AUTH_INVALID':
                case 'AUTH_EXPIRED':
                    // 需要重新授权
                    const authResult = await window.phoneAPI.requestAuth(['read_chat']);
                    if (authResult.success) {
                        // 使用新授权码重试
                        return await window.phoneAPI.getChatHistory(
                            sessionId, 
                            authResult.authCode
                        );
                    }
                    break;
                    
                case 'PERMISSION_DENIED':
                    alert('用户拒绝了权限申请');
                    break;
                    
                case 'NOT_FOUND':
                    alert('会话不存在');
                    break;
                    
                default:
                    alert('API调用失败:' + result.error);
            }
            return null;
        }
        
        return result.data;
    } catch (error) {
        console.error('API调用异常:', error);
        alert('发生错误:' + error.message);
        return null;
    }
}

最佳实践

1. 权限管理

// 缓存授权码
const authCache = {};

async function getAuthCode(permissionType) {
    // 检查缓存
    if (authCache[permissionType]) {
        // 检查权限状态
        const check = await window.phoneAPI.checkPermission(permissionType);
        if (check.success && check.data.granted) {
            return authCache[permissionType];
        }
    }
    
    // 重新申请
    const result = await window.phoneAPI.requestAuth([permissionType]);
    if (result.success) {
        authCache[permissionType] = result.authCode;
        return result.authCode;
    }
    return null;
}

2. 用户体验

async function loadDataWithLoading() {
    showLoading();
    try {
        const result = await window.phoneAPI.getChatHistory(sessionId, authCode);
        if (result.success) {
            displayData(result.data);
        } else {
            showError('加载失败:' + result.error);
        }
    } finally {
        hideLoading();
    }
}

3. 安全性

4. 性能优化


常见问题

Q: 如何获取会话ID?

const result = await window.phoneAPI.getChatSessions(authCode);
if (result.success) {
    const sessions = result.data;
    // 显示会话列表让用户选择
}

Q: 授权码过期了怎么办?

重新调用 requestAuth() 申请新的授权码。

Q: 可以同时申请多个权限吗?

可以,传入权限数组即可:

await window.phoneAPI.requestAuth(['read_chat', 'call_llm', 'read_user']);

Q: 如何调试应用?

Q: 应用可以在其他地方运行吗?

不可以,API只能在小手机系统的HTML应用中运行。


更新日志

v1.2.0 (2026-02-14)

v1.1.0 (2026-02-14)

v1.0.0 (2026-02-14)


技术支持

如有问题或建议,请联系:


文档版本: 1.2.0
最后更新: 2026-02-14