package feishu_util import ( "fmt" "net/url" "strings" ) // SpreadsheetRef 解析后的飞书表格定位信息。 type SpreadsheetRef struct { // RawURL 原始链接 RawURL string // WikiToken 知识库节点 token(URL 中 /wiki/ 后一段);非 wiki 链接为空 WikiToken string // SpreadsheetToken 电子表格 token;wiki 链接需再调接口换取 obj_token SpreadsheetToken string // SheetID URL 查询参数 sheet= 的值(可选) SheetID string } // ParseSpreadsheetURL 解析飞书表格/知识库链接。 // 支持: // - https://xxx.feishu.cn/wiki/{wikiToken}?sheet={sheetId} // - https://xxx.feishu.cn/sheets/{spreadsheetToken}?sheet={sheetId} func ParseSpreadsheetURL(raw string) (*SpreadsheetRef, error) { raw = strings.TrimSpace(raw) if raw == "" { return nil, fmt.Errorf("表格 URL 为空") } u, err := url.Parse(raw) if err != nil { return nil, fmt.Errorf("解析 URL 失败: %w", err) } ref := &SpreadsheetRef{RawURL: raw, SheetID: u.Query().Get("sheet")} path := strings.Trim(u.Path, "/") parts := strings.Split(path, "/") if len(parts) < 2 { return nil, fmt.Errorf("无法从 URL 解析 token: %s", raw) } switch parts[0] { case "wiki": ref.WikiToken = parts[1] case "sheets": ref.SpreadsheetToken = parts[1] default: return nil, fmt.Errorf("不支持的飞书链接类型 %q,仅支持 /wiki/ 或 /sheets/", parts[0]) } return ref, nil }