300 lines
9.7 KiB
Python
300 lines
9.7 KiB
Python
from __future__ import annotations
|
||
|
||
import logging
|
||
|
||
from yuxi.channel.extensions.feishu.client import get_client
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
FEISHU_WIKI_TOOLS = [
|
||
{
|
||
"name": "feishu_wiki_spaces",
|
||
"description": "列出飞书知识库空间",
|
||
"parameters": {},
|
||
},
|
||
{
|
||
"name": "feishu_wiki_nodes",
|
||
"description": "列出知识库节点",
|
||
"parameters": {"space_id": "知识空间 ID", "parent_node_token": "父节点 token(可选)"},
|
||
},
|
||
{
|
||
"name": "feishu_wiki_get_node",
|
||
"description": "获取知识库节点详情",
|
||
"parameters": {"node_token": "节点 token"},
|
||
},
|
||
{
|
||
"name": "feishu_wiki_create_node",
|
||
"description": "创建知识库节点",
|
||
"parameters": {"space_id": "空间 ID", "parent_node_token": "父节点 token", "title": "节点标题", "obj_type": "类型(docx/sheet/bitable)"},
|
||
},
|
||
{
|
||
"name": "feishu_wiki_update_node",
|
||
"description": "更新知识库节点",
|
||
"parameters": {"space_id": "空间 ID", "node_token": "节点 token", "title": "新标题"},
|
||
},
|
||
{
|
||
"name": "feishu_wiki_move_node",
|
||
"description": "移动知识库节点",
|
||
"parameters": {"space_id": "空间 ID", "node_token": "节点 token", "target_parent_token": "目标父节点 token"},
|
||
},
|
||
{
|
||
"name": "feishu_wiki_delete_node",
|
||
"description": "删除知识库节点",
|
||
"parameters": {"node_token": "节点 token"},
|
||
},
|
||
]
|
||
|
||
|
||
async def list_wiki_spaces(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.ListSpaceRequest(page_size=50)
|
||
resp = await client.wiki.v2.space.list_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
items = getattr(resp.data, "items", []) or []
|
||
return {
|
||
"success": True,
|
||
"spaces": [
|
||
{
|
||
"space_id": getattr(s, "space_id", ""),
|
||
"name": getattr(s, "name", ""),
|
||
"description": getattr(s, "description", ""),
|
||
}
|
||
for s in items
|
||
],
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu list_wiki_spaces error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def list_wiki_nodes(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
space_id: str,
|
||
parent_node_token: str = "",
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.ListSpaceNodeRequest(
|
||
space_id=space_id,
|
||
parent_node_token=parent_node_token if parent_node_token else None,
|
||
page_size=50,
|
||
)
|
||
resp = await client.wiki.v2.space_node.list_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
items = getattr(resp.data, "items", []) or []
|
||
return {
|
||
"success": True,
|
||
"nodes": [
|
||
{
|
||
"node_token": getattr(n, "node_token", ""),
|
||
"title": getattr(n, "title", ""),
|
||
"obj_type": getattr(n, "obj_type", ""),
|
||
"obj_token": getattr(n, "obj_token", ""),
|
||
"has_child": getattr(n, "has_child", False),
|
||
}
|
||
for n in items
|
||
],
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu list_wiki_nodes error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def get_wiki_node(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
node_token: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.GetNodeRequest(token=node_token)
|
||
resp = await client.wiki.v2.node.get_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
node = resp.data.node
|
||
return {
|
||
"success": True,
|
||
"node": {
|
||
"node_token": getattr(node, "node_token", ""),
|
||
"title": getattr(node, "title", ""),
|
||
"obj_type": getattr(node, "obj_type", ""),
|
||
"obj_token": getattr(node, "obj_token", ""),
|
||
"space_id": getattr(node, "space_id", ""),
|
||
},
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu get_wiki_node error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def create_wiki_node(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
space_id: str,
|
||
parent_node_token: str,
|
||
title: str,
|
||
obj_type: str = "docx",
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
from yuxi.channel.extensions.feishu.tools.doc import create_doc
|
||
|
||
doc_result = await create_doc(app_id, app_secret, domain, title, "", http_timeout_ms)
|
||
if not doc_result.get("success"):
|
||
return doc_result
|
||
|
||
doc_token = doc_result.get("document_id", "")
|
||
if not doc_token:
|
||
return {"success": False, "error": "Failed to get document_id from created doc"}
|
||
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.CreateSpaceNodeRequest(
|
||
space_id=space_id,
|
||
request_body=lark_oapi.wiki.v2.CreateSpaceNodeRequestBody(
|
||
parent_node_token=parent_node_token,
|
||
node_type="origin",
|
||
origin_node_token=doc_token,
|
||
title=title,
|
||
),
|
||
)
|
||
resp = await client.wiki.v2.space_node.create_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
node = getattr(resp.data, "node", None)
|
||
return {
|
||
"success": True,
|
||
"node_token": getattr(node, "node_token", "") if node else "",
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu create_wiki_node error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def update_wiki_node(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
space_id: str,
|
||
node_token: str,
|
||
title: str = "",
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.UpdateSpaceNodeRequest(
|
||
space_id=space_id,
|
||
node_token=node_token,
|
||
request_body=lark_oapi.wiki.v2.UpdateSpaceNodeRequestBody(
|
||
title=title if title else None,
|
||
),
|
||
)
|
||
resp = await client.wiki.v2.space_node.update_async(req)
|
||
|
||
if resp.success():
|
||
return {"success": True}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu update_wiki_node error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def move_wiki_node(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
space_id: str,
|
||
node_token: str,
|
||
target_parent_token: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.MoveSpaceNodeRequest(
|
||
space_id=space_id,
|
||
node_token=node_token,
|
||
request_body=lark_oapi.wiki.v2.MoveSpaceNodeRequestBody(
|
||
target_parent_token=target_parent_token,
|
||
),
|
||
)
|
||
resp = await client.wiki.v2.space_node.move_async(req)
|
||
|
||
if resp.success():
|
||
return {"success": True}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu move_wiki_node error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def delete_wiki_node(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
node_token: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.wiki.v2.DeleteSpaceNodeRequest(token=node_token)
|
||
resp = await client.wiki.v2.space_node.delete_async(req)
|
||
|
||
if resp.success():
|
||
return {"success": True}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu delete_wiki_node error")
|
||
return {"success": False, "error": "Internal error"}
|