84 lines
2.3 KiB
Go
Raw Normal View History

2026-09-17 18:49:22 +08:00
package feishu_util
import (
"context"
"fmt"
larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
larkwiki "github.com/larksuite/oapi-sdk-go/v3/service/wiki/v2"
)
// WikiNode 知识库节点解析结果。
type WikiNode struct {
SpaceID string
NodeToken string
ObjToken string
ObjType string
Title string
}
// ResolveWikiNode 通过知识库 node_token 获取实际云文档 obj_token。
// 知识库 URL 中的 token 不是 spreadsheet_token读写表格内容前必须先转换。
func (c *Client) ResolveWikiNode(ctx context.Context, wikiToken string) (*WikiNode, error) {
if wikiToken == "" {
return nil, fmt.Errorf("wikiToken 为空")
}
req := larkwiki.NewGetNodeSpaceReqBuilder().
Token(wikiToken).
Build()
resp, err := c.Lark.Wiki.V2.Space.GetNode(ctx, req)
if err != nil {
return nil, fmt.Errorf("获取知识库节点失败: %w", err)
}
if !resp.Success() {
return nil, fmt.Errorf("获取知识库节点失败: code=%d msg=%s log_id=%s detail=%s",
resp.Code, resp.Msg, resp.RequestId(), larkcore.Prettify(resp.CodeError))
}
if resp.Data == nil || resp.Data.Node == nil {
return nil, fmt.Errorf("获取知识库节点返回空数据")
}
n := resp.Data.Node
node := &WikiNode{}
if n.SpaceId != nil {
node.SpaceID = *n.SpaceId
}
if n.NodeToken != nil {
node.NodeToken = *n.NodeToken
}
if n.ObjToken != nil {
node.ObjToken = *n.ObjToken
}
if n.ObjType != nil {
node.ObjType = *n.ObjType
}
if n.Title != nil {
node.Title = *n.Title
}
if node.ObjToken == "" {
return nil, fmt.Errorf("知识库节点未返回 obj_token")
}
return node, nil
}
// ResolveSpreadsheetToken 将 SpreadsheetRef 解析为可调用 Sheets API 的 spreadsheet_token。
func (c *Client) ResolveSpreadsheetToken(ctx context.Context, ref *SpreadsheetRef) (string, error) {
if ref == nil {
return "", fmt.Errorf("SpreadsheetRef 为空")
}
if ref.SpreadsheetToken != "" {
return ref.SpreadsheetToken, nil
}
if ref.WikiToken == "" {
return "", fmt.Errorf("既无 SpreadsheetToken 也无 WikiToken")
}
node, err := c.ResolveWikiNode(ctx, ref.WikiToken)
if err != nil {
return "", err
}
if node.ObjType != "" && node.ObjType != "sheet" {
return "", fmt.Errorf("知识库节点类型为 %s不是电子表格(sheet)", node.ObjType)
}
ref.SpreadsheetToken = node.ObjToken
return node.ObjToken, nil
}