叁 · 推送

飞书推送

ctx.feishu

通过飞书官方 CLI lark-cli 发送文本 / Markdown 消息,支持 bot / user 身份、群聊 / 单聊 / 多群、@ 人、幂等键和 dryRun。

接口

const r = await ctx.feishu.send({
  markdown: '正文',                      // 或 text: '纯文本',二选一
  title: '标题',                         // 可选,作为加粗首行发送
  target: { chatId: 'oc_...' },          // 或 { userId: 'ou_...' } / { chatIds: ['oc_...', ...] }
  at: { userIds: ['ou_...'], all: false },
  idempotencyKey: 'evt_...',
  traceId: 'evt_...',
  signal,                                // 可选,中止时终止 lark-cli 子进程
})
// r.results: Array<{ target, ok, messageId?, error? }>

本 Service 通过子进程调用飞书官方 CLI lark-cli(npm 包 @larksuite/cli,已验证 1.0.96)的 lark-cli im +messages-send:

身份

身份需要的准备适用
botlark-cli config init,填写飞书应用的 App ID / App Secret服务器环境推荐,无需用户登录
user在 bot 的基础上再登录:运行 lark-cli auth login --scope "im:message.send_as_user im:message",或由业务包调用 ctx.feishu.login()(见下文)以登录用户的名义发送

两种身份都以 --as=<身份> 传给 lark-cli。凭据由 lark-cli 自己的配置与系统钥匙串保存,本包不读取、不保存。

目标

target 省略时使用配置的 defaultTarget;单次调用的 target 会覆盖它,多个业务包共用本包时互不影响。

目标格式说明
{ chatId }群 chat_id,oc_ 开头发到群
{ userId }用户 open_id,ou_ 开头发单聊
{ chatIds }多个 chat_id,最多 100 个去重后逐个发送

目标、@ 列表与幂等键在拼装参数前做格式校验,格式不符或以 - 开头的值会被拒绝(invalid_target)。lark-cli 一次只发一个目标,所以多群时逐个调用:单个群失败不中断其余的群,也不抛错,体现在 results 中;只有中止(aborted)会立即抛出。单目标时失败直接抛出。

正文、标题与 @

幂等与重试

登录状态与登录

const st = await ctx.feishu.status()
// { channel: 'feishu', identity: 'user', online: false, account?: '张三', detail, checkedAt }

const s = await ctx.feishu.login()     // 仅 user 身份;{ channel, verificationUrl, userCode?, expiresAt, completed, cancel() }
await postToOps(s.verificationUrl)      // 由业务包决定怎么把链接交给要登录的人
const after = await s.completed         // 授权完成后的状态

await ctx.feishu.logout()               // 仅 user 身份;返回退出后的状态

身份检查与 dryRun

larkPath 与 Windows

larkPath 必须是绝对路径;省略时启动时从 PATH 解析。Windows 上 npm 全局安装的是 lark-cli.cmd,本包会自动定位到它背后的 run.js 并用 node 运行。手动配置 larkPath 时,请指向可执行文件、.exe 或 .js,不要指向 .cmd / .bat。

配置

在 Profile 的 cordis.patch.yml 中按 id agent-kit-feishu 启用并给出配置。按 id 修改 config 时整段替换,未给出的字段使用默认值。下表由本包源码中的配置 schema 生成。

- id: agent-kit-feishu
  disabled: false
  config:
    # 只写需要改的字段,其余使用下表的默认值
字段默认值取值范围说明
identity 必填 — bot | user 发送身份;服务器环境推荐 bot(只需应用凭据,无需用户登录)
defaultTarget — 见说明 省略 target 时使用:群 chat_id(oc_…)、用户 open_id(ou_…)或多个群
profile — 匹配 /^[A-Za-z0-9._-]{1,64}$/ lark-cli 的命名配置(--profile)
larkPath — — lark-cli 可执行文件的绝对路径;默认从 PATH 解析。需指向可执行文件、.exe 或 .js(不支持 Windows 的 .cmd/.bat)
timeoutMs 20000 [1000, 120000] 单次 lark-cli 调用的超时时间。
killGraceMs 5000 ≥ 0 超时或卸载时,SIGTERM 之后等待多久再发 SIGKILL。
retry.maxAttempts 2 [0, 5] 给出幂等键时,可重试失败的最多重试次数。
preflightIntervalMs 3600000 ≥ 0 检查 lark-cli 身份状态的间隔,0 表示只在启动时检查
dryRun false — 附加 --dry-run,只解析参数、不真实发送;同时跳过身份检查。

约束与说明

错误码

所有错误都是 KitError:用 isKitError(e) 判断,按 code 与 retryable 决定是否重试。

code可重试含义
timeout 是 lark-cli 超时,子进程按「先 SIGTERM、宽限后 SIGKILL」回收。
exit_nonzero 视情况 lark-cli 非零退出;按错误类别(network / timeout / rate_limit / server / internal / unavailable)判断是否可重试。
bad_output 否 lark-cli 输出无法解析。
invalid_target 否 目标、@ 列表、正文或幂等键格式非法(例如 chat_id 不以 oc_ 开头、超过 100 个群)。
send_failed 否 lark-cli 报告 ok: false(多目标时体现在逐目标结果中)。
aborted 否 调用方 signal 中止或 Service 卸载。
spawn_failed 否 无法启动 lark-cli 子进程。
unsupported 否 bot 身份调用 login() / logout():bot 使用应用凭据,没有用户登录。
login_failed 否 lark-cli auth login 未能开始设备流登录。
invalid_config 否 配置或环境变量非法,Service 启动失败。