52 lines
1.4 KiB
Go
52 lines
1.4 KiB
Go
|
|
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
|
|||
|
|
}
|