---
id: "9717e64afe2a859eaacd"
url: "https://www.xmcsl.cn/project/feishu-cli-embed/02-one-click-app/02-%E4%B8%80%E9%94%AE%E5%88%9B%E5%BB%BA%E5%BA%94%E7%94%A8%EF%BC%88NodeJS%EF%BC%89.html"
source_url: "https://open.feishu.cn/document/mcp_open_tools/integrating-agents-with-feishu/scan-to-create-an-app-in-one-click-nodejs"
source_date: null
checked_at: "2026-11-05T04:21:48.909937+00:00"
status: "ready"
check_scope: "structure_only; not a factual or human review"
body_sha256: "c84f1ff61664be2d2570cb5620ae055a3619d7f72f5b89fee169ca2edf5da2b2"
---

# 一键创建应用（NodeJS） · 飞书 Agent 接入知识库

Node SDK 提供了 <code>registerApp</code> 方法，基于 OAuth 2.0 Device Authorization Grant（RFC 8628）协议实现一键创建应用。

 

调用该方法会返回一个验证链接，用户在飞书或 Lark 中打开该链接（或扫码）完成授权后，即可自动注册应用并获取凭据（App ID 和 App Secret），无需手动前往开发者后台创建。

 

查看源码：<a href="https://github.com/larksuite/node-sdk/blob/main/README.zh.md#%E4%B8%80%E9%94%AE%E5%88%9B%E5%BB%BA%E5%BA%94%E7%94%A8">node-sdk</a>

 

## 前提条件

 

<ul>&#10;<li>安装 <code>@larksuiteoapi/node-sdk</code>，且 SDK 版本为 1.61.1 及以上。</li>&#10;</ul>

 

```shell
  npm install @larksuiteoapi/node-sdk
```

 

## 快速开始示例

 

```typescript
import * as lark from '@larksuiteoapi/node-sdk';

try {
    const result = await lark.registerApp({
        onQRCodeReady(info) {
            console.log(`请扫码: ${info.url}`);
            console.log(`链接将在 ${info.expireIn} 秒后过期`);
        },
        onStatusChange(info) {
            // 处理状态变化：'polling' | 'slow_down' | 'domain_switched'
        },
    });

console.log('App ID:', result.client_id);
    console.log('App Secret:', result.client_secret);

// 用获取到的凭据初始化 Client
    const client = new lark.Client({
        appId: result.client_id,
        appSecret: result.client_secret,
    });
} catch (e) {
    // e.code: 'access_denied' | 'expired_token' | 'abort' | ...
    // e.description: 错误描述
    console.error(e.code, e.description);
}
```

 

## 自定义权限/事件/回调（addons）与更新已有应用

 

创建应用时，可通过 <code>addons</code> 在平台基础模板上<strong>增量</strong>申请权限、事件订阅和回调，这些配置会预填到用户扫码后的确认页中，用户确认后生效：

 

```typescript
// 创建：增量申请权限/事件/回调，且只允许创建新应用（不可选择已有应用）
const result = await lark.registerApp({
    addons: {
        scopes: { tenant: ['im:message:send_as_bot'], user: ['calendar:calendar:read'] },
        events: { items: { tenant: ['im.message.receive_v1'] } },
        callbacks: { items: ['card.action.trigger'] },
    },
    createOnly: true,
    onQRCodeReady(info) { /* ... */ },
});

// 更新：传入已有应用的 appId，让用户重新扫码确认，为该应用增量开通权限
await lark.registerApp({
    appId: 'cli_xxx',
    addons: { scopes: { tenant: ['drive:drive.metadata:readonly'] } },
    onQRCodeReady(info) { /* ... */ },
});

// 最小基座：丢弃默认模板（仅保留机器人能力，无业务权限），仅展示显式声明的配置项。
// 传入 `preset: false` 时，即使 addons 没有其他配置项也是合法的。
await lark.registerApp({
    addons: {
        preset: false,
        scopes: { tenant: ['im:message:send_as_bot'] },
    },
    onQRCodeReady(info) { /* ... */ },
});
```

 

<ul>&#10;<li><code>addons.preset</code> 用于选择模板基座：<code>true</code> / 不传表示保留平台默认模板，并在其上叠加声明的配置项（增量，默认行为）；<code>false</code> 表示丢弃默认模板，从最小基座（仅机器人能力，无业务权限）开始，仅展示显式声明的配置项。仅当 <code>preset: false</code> 时 <code>addons</code> 可以不含其他配置项（最小基座、零增量），否则至少需包含一个权限、事件或回调。</li>&#10;<li><code>addons</code> 仅支持在基础模板上<strong>增量叠加</strong>，不支持删减基础权限。</li>&#10;<li>仅支持 5 类公开配置（应用/用户身份权限、应用/用户身份事件、回调）。敏感配置（事件订阅方式与回调地址、<code>security.&#42;</code>、加密 key 等）不能通过 <code>addons</code> 传入，需调用<a href="https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v7/application-v7/application-config/patch">更新应用开发配置 OpenAPI</a>。</li>&#10;<li>SDK 只校验数据形状，不校验权限点/事件/回调名称是否存在；平台目录中不存在的名称会被确认页忽略。</li>&#10;<li></li>&#10;</ul>

 

## registerApp 参数

 

<table>&#10;<thead>&#10;<tr>&#10;<th>参数</th>&#10;<th>描述</th>&#10;<th>类型</th>&#10;<th>必须</th>&#10;<th>默认</th>&#10;</tr>&#10;</thead>&#10;<tbody>&#10;<tr>&#10;<td>domain</td>&#10;<td>自定义认证域名（仅 host 部分）</td>&#10;<td>string</td>&#10;<td>否</td>&#10;<td><code>accounts.feishu.cn</code></td>&#10;</tr>&#10;<tr>&#10;<td>larkDomain</td>&#10;<td>自定义 Lark 认证域名（仅 host 部分），检测到 Lark 租户时自动切换</td>&#10;<td>string</td>&#10;<td>否</td>&#10;<td><code>accounts.larksuite.com</code></td>&#10;</tr>&#10;<tr>&#10;<td>source</td>&#10;<td>来源标识，拼入二维码 URL 的 <code>from</code> 参数，格式为 <code>node-sdk/&#123;source&#125;</code></td>&#10;<td>string</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>signal</td>&#10;<td>用于取消轮询的 <code>AbortSignal</code></td>&#10;<td>AbortSignal</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>onQRCodeReady</td>&#10;<td>验证链接就绪时的回调，参数为 <code>&#123; url, expireIn &#125;</code>。可将 URL 渲染为二维码供用户扫码，或直接作为链接展示</td>&#10;<td>function</td>&#10;<td>是</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>onStatusChange</td>&#10;<td>轮询状态变化时的回调，参数为 <code>&#123; status, interval? &#125;</code>。status 取值：<code>polling</code>、<code>slow&#95;down</code>、<code>domain&#95;switched</code></td>&#10;<td>function</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>appPreset</td>&#10;<td>预设应用信息（头像、名称、描述）。所有字段都是可选的，用户扫码后仍可在页面手动修改</td>&#10;<td>AppPreset</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>appPreset.avatar</td>&#10;<td>应用头像 URL，支持 1-6 个；传多个时默认选中第一个。支持 png / jpg / jpeg / webp / gif（gif 自动取一帧，不保留动图）</td>&#10;<td>string &#124; string&#91;&#93;</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>appPreset.name</td>&#10;<td>应用名称，支持 <code>&#123;user&#125;</code> 占位符（替换为扫码用户名称）</td>&#10;<td>string</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>appPreset.desc</td>&#10;<td>应用描述，支持 <code>&#123;user&#125;</code> 占位符</td>&#10;<td>string</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>addons</td>&#10;<td>增量权限/事件/回调配置，预填到扫码后的确认页，用户确认后生效。详见上方「自定义权限/事件/回调」</td>&#10;<td>AppAddons</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>addons.preset</td>&#10;<td>模板基座选择。<code>true</code>/不传：保留平台默认模板，在其上叠加声明的配置项；<code>false</code>：丢弃默认模板，使用最小基座（仅机器人能力，无业务权限）。传 <code>false</code> 时 <code>addons</code> 可不含其他配置项</td>&#10;<td>boolean</td>&#10;<td>否</td>&#10;<td><code>true</code></td>&#10;</tr>&#10;<tr>&#10;<td>addons.scopes.tenant</td>&#10;<td>应用身份权限列表，如 <code>im:message:send&#95;as&#95;bot</code></td>&#10;<td>string&#91;&#93;</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>addons.scopes.user</td>&#10;<td>用户身份权限列表，如 <code>calendar:calendar:read</code></td>&#10;<td>string&#91;&#93;</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>addons.events.items.tenant</td>&#10;<td>应用身份事件列表，如 <code>im.message.receive&#95;v1</code></td>&#10;<td>string&#91;&#93;</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>addons.events.items.user</td>&#10;<td>用户身份事件列表，如 <code>calendar.calendar.event.changed&#95;v4</code></td>&#10;<td>string&#91;&#93;</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>addons.callbacks.items</td>&#10;<td>回调列表，如 <code>card.action.trigger</code></td>&#10;<td>string&#91;&#93;</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>createOnly</td>&#10;<td>为 <code>true</code> 时落地页仅允许创建新应用，隐藏「选择已有应用」入口，避免误选已有应用导致其配置被覆盖。与 <code>appId</code> 同时传入时优先级更高</td>&#10;<td>boolean</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;<tr>&#10;<td>appId</td>&#10;<td>已有应用的 App ID（<code>cli&#95;</code> 开头）。传入后流程变为更新该应用的配置：确认页展示 <code>addons</code> 带来的权限 diff，用户确认后生效。<code>createOnly</code> 为 <code>true</code> 时被忽略，仍走创建新应用流程</td>&#10;<td>string</td>&#10;<td>否</td>&#10;<td>-</td>&#10;</tr>&#10;</tbody>&#10;</table>

 

## 返回值

 

<table>&#10;<thead>&#10;<tr>&#10;<th>字段</th>&#10;<th>类型</th>&#10;<th>描述</th>&#10;</tr>&#10;</thead>&#10;<tbody>&#10;<tr>&#10;<td>client&#95;id</td>&#10;<td>string</td>&#10;<td>应用的 App ID</td>&#10;</tr>&#10;<tr>&#10;<td>client&#95;secret</td>&#10;<td>string</td>&#10;<td>应用的 App Secret</td>&#10;</tr>&#10;<tr>&#10;<td>user&#95;info</td>&#10;<td>object（可选）</td>&#10;<td>扫码授权的用户信息</td>&#10;</tr>&#10;<tr>&#10;<td>user&#95;info.open&#95;id</td>&#10;<td>string（可选）</td>&#10;<td>扫码用户的 open&#95;id</td>&#10;</tr>&#10;<tr>&#10;<td>user&#95;info.tenant&#95;brand</td>&#10;<td>string（可选）</td>&#10;<td>租户品牌，取值为 <code>"feishu"</code> 或 <code>"lark"</code></td>&#10;</tr>&#10;</tbody>&#10;</table>

 

## 错误处理

 

抛出的错误对象包含 <code>code</code> 和 <code>description</code> 字段：

 

<table>&#10;<thead>&#10;<tr>&#10;<th>code</th>&#10;<th>描述</th>&#10;</tr>&#10;</thead>&#10;<tbody>&#10;<tr>&#10;<td><code>access&#95;denied</code></td>&#10;<td>用户拒绝了授权</td>&#10;</tr>&#10;<tr>&#10;<td><code>expired&#95;token</code></td>&#10;<td>二维码过期或轮询超时</td>&#10;</tr>&#10;<tr>&#10;<td><code>abort</code></td>&#10;<td>通过 AbortSignal 取消操作</td>&#10;</tr>&#10;</tbody>&#10;</table>
