fix: support bot identity for drive search (#1670)

This commit is contained in:
liujinkun2025
2026-06-30 21:59:51 +08:00
committed by GitHub
parent 6f2cddfce1
commit 214318aa02
4 changed files with 56 additions and 3 deletions

View File

@@ -72,7 +72,7 @@ var DriveSearch = common.Shortcut{
Description: "Search Lark docs, Wiki, and spreadsheet files with flat filters (Search v2: doc_wiki/search)",
Risk: "read",
Scopes: []string{"search:docs:read"},
AuthTypes: []string{"user"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
Flags: []common.Flag{
{Name: "query", Desc: "search keyword (may be empty to browse by filter only)"},

View File

@@ -3,7 +3,10 @@
package drive
import "testing"
import (
"reflect"
"testing"
)
// TestShortcutsIncludesExpectedCommands verifies the drive shortcut registry contains the expected commands.
func TestShortcutsIncludesExpectedCommands(t *testing.T) {
@@ -58,3 +61,12 @@ func TestShortcutsIncludesExpectedCommands(t *testing.T) {
}
}
}
func TestDriveSearchSupportsUserAndBotIdentity(t *testing.T) {
t.Parallel()
want := []string{"user", "bot"}
if !reflect.DeepEqual(DriveSearch.AuthTypes, want) {
t.Fatalf("DriveSearch.AuthTypes = %v, want %v", DriveSearch.AuthTypes, want)
}
}

View File

@@ -3,7 +3,7 @@
> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
基于 Search v2 接口 `POST /open-apis/search/v2/doc_wiki/search`,以**用户身份**统一搜索云空间(云盘/云存储)对象。
基于 Search v2 接口 `POST /open-apis/search/v2/doc_wiki/search`支持以**用户身份或应用身份**统一搜索云空间(云盘/云存储)对象。
核心特性:
@@ -14,6 +14,8 @@
> **资源发现入口统一**`drive +search` 同样返回 `SHEET` / `Base` / `FOLDER` 等全部云空间(云盘/云存储)对象,不只是文档 / Wiki。用户说"找一个表格"、"找报表"、"最近打开的表格"时,也从这里开始;定位后再切到对应业务 skill如 `lark-sheets`)做对象内部操作。
> **身份边界**普通关键词、类型、文件夹、Wiki 空间、owner/open_id 等显式过滤支持 `--as user` 或 `--as bot`。`--mine` / `--created-by-me` 依赖当前登录用户 open_id 自动填充过滤条件;应用身份下如果没有配置用户 open_id请改用显式 `--creator-ids` / `--original-creator-ids`。
## 命令
> **关键约束:搜索关键词必须通过 `--query` 传递。**

View File

@@ -164,6 +164,45 @@ func TestDriveSearchDryRun_RequestShape(t *testing.T) {
}
}
func TestDriveSearchDryRun_BotIdentity(t *testing.T) {
setDriveSearchE2EEnv(t)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
t.Cleanup(cancel)
result, err := clie2e.RunCmd(ctx, clie2e.Request{
Args: []string{
"drive", "+search",
"--query", "season report",
"--page-size", "5",
"--dry-run",
},
DefaultAs: "bot",
})
require.NoError(t, err)
result.AssertExitCode(t, 0)
require.Contains(t, result.Args, "--as")
require.Contains(t, result.Args, "bot")
out := result.Stdout
if got := gjson.Get(out, "api.0.method").String(); got != "POST" {
t.Fatalf("method=%q, want POST\nstdout:\n%s\nstderr:\n%s", got, out, result.Stderr)
}
if got := gjson.Get(out, "api.0.url").String(); got != "/open-apis/search/v2/doc_wiki/search" {
t.Fatalf("url=%q, want Search v2 doc_wiki/search\nstdout:\n%s\nstderr:\n%s", got, out, result.Stderr)
}
if got := gjson.Get(out, "api.0.body.query").String(); got != "season report" {
t.Fatalf("body.query=%q, want season report\nstdout:\n%s", got, out)
}
helpResult, err := clie2e.RunCmd(ctx, clie2e.Request{
Args: []string{"drive", "+search", "--help"},
})
require.NoError(t, err)
helpResult.AssertExitCode(t, 0)
require.Contains(t, helpResult.Stdout, "identity type: user | bot")
}
// TestDriveSearchDryRun_OpenedClamping locks in the agent-facing slice
// notice for --opened-* spans over 90 days: the request body must carry
// the most recent 90-day window, and stderr must list slice N's flag