mirror of
https://github.com/breath57/dingtalk-skills.git
synced 2026-09-14 20:51:31 +08:00
chore: 更新共享测试基础设施
- conftest.py: operator_id fixture 支持从 DINGTALK_USER_ID 自动转换 - conftest.py: 新增 _userid_to_unionid 工具函数 - .env.example: 补充 dingtalk-todo 测试所需配置 - pyproject.toml/uv.lock: 新增 dotenv 依赖 - .gitignore/skills-lock.json: 同步更新
This commit is contained in:
@@ -5,3 +5,7 @@ __pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
.pytest_cache/
|
||||
|
||||
# local drafts & temp files (not for repo)
|
||||
docs/
|
||||
temp/
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"version": 1,
|
||||
"skills": {
|
||||
"agent-browser": {
|
||||
"source": "vercel-labs/agent-browser",
|
||||
"sourceType": "github",
|
||||
"computedHash": "57bfa07d34f966bccf791d49c9b6ce507fbba08f7dbf9e2ad15809e2dd29041e"
|
||||
},
|
||||
"skill-creator": {
|
||||
"source": "anthropics/skills",
|
||||
"sourceType": "github",
|
||||
|
||||
+50
-17
@@ -1,31 +1,64 @@
|
||||
# ── 钉钉应用凭证 ─────────────────────────────────────────────────
|
||||
# ╔══════════════════════════════════════════════════════════════════╗
|
||||
# ║ 公共配置(所有技能共用) ║
|
||||
# ╚══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# 钉钉应用凭证(开放平台 → 应用管理 → 凭证信息)
|
||||
DINGTALK_APP_KEY=your_app_key_here
|
||||
DINGTALK_APP_SECRET=your_app_secret_here
|
||||
|
||||
# ── 企业 corpId ───────────────────────────────────────────────────
|
||||
# 企业 corpId(开放平台 → 应用管理 → 基本信息)
|
||||
DINGTALK_CORP_ID=your_corp_id_here
|
||||
|
||||
# ── 测试数据 ──────────────────────────────────────────────────────
|
||||
# 测试用文档节点 ID(从 alidocs URL 末尾提取)
|
||||
# 操作者 unionId(开发者后台 → 调试工具 → 获取 unionId)
|
||||
OPERATOR_ID=your_union_id_here
|
||||
|
||||
# 写入测试开关(默认关闭,设置为 1 启用覆写文档/表格等破坏性测试)
|
||||
ENABLE_WRITE_TESTS=0
|
||||
|
||||
# ╔══════════════════════════════════════════════════════════════════╗
|
||||
# ║ dingtalk-document 知识库 & 文档 ║
|
||||
# ╚══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# 测试用文档节点 ID(从 alidocs URL 提取:/nodes/<nodeId>)
|
||||
TEST_NODE_ID=your_node_id_here
|
||||
# 测试用文档 URL
|
||||
|
||||
# 测试用文档完整 URL
|
||||
TEST_NODE_URL=https://alidocs.dingtalk.com/i/nodes/your_node_id_here
|
||||
|
||||
# 创建/删除临时文档时使用的知识库 workspaceId
|
||||
TEST_WORKSPACE_ID=your_workspace_id_here
|
||||
|
||||
# ── 操作者 unionId ────────────────────────────────────────────────
|
||||
# 在钉钉开发者后台 -> 调试工具 -> 获取 unionId
|
||||
OPERATOR_ID=your_union_id_here
|
||||
# ╔══════════════════════════════════════════════════════════════════╗
|
||||
# ║ dingtalk-ai-table AI 表格 ║
|
||||
# ╚══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# ── dingtalk-ai-table 测试数据 ────────────────────────────────────
|
||||
# 测试工作簿 ID(普通电子表格,即 .xlsx / SHEET 类型,非 .able AI表格)
|
||||
# 若留空,测试框架会在 TEST_WORKSPACE_ID 下自动创建临时工作簿并在结束后删除。
|
||||
# 手动指定时从 alidocs 链接中提取 /nodes/<workbookId>:
|
||||
# https://alidocs.dingtalk.com/i/nodes/<workbookId>
|
||||
# AI 表格(.able 文件)的 nodeId
|
||||
# 从分享链接提取:https://alidocs.dingtalk.com/i/nodes/<nodeId>
|
||||
TEST_NOTABLE_ID=your_notable_id_here
|
||||
|
||||
# 普通电子表格 workbookId(.xlsx / SHEET 类型,非 .able)
|
||||
# 若留空,测试框架会在 TEST_WORKSPACE_ID 下自动创建临时工作簿并在结束后删除
|
||||
TEST_WORKBOOK_ID=
|
||||
|
||||
# 用于自动创建测试工作簿的知识库 ID(TEST_WORKBOOK_ID 为空时生效)
|
||||
TEST_WORKSPACE_ID=QXvd5SLN2AxOQz0Z
|
||||
# ╔══════════════════════════════════════════════════════════════════╗
|
||||
# ║ dingtalk-message 消息发送 ║
|
||||
# ╚══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# ── 写入测试开关(默认关闭,设置为 1 启用覆写文档/表格测试)────────
|
||||
ENABLE_WRITE_TESTS=0
|
||||
# ── Webhook 机器人(群设置 → 智能群助手 → 自定义机器人)──────────
|
||||
# 完整 Webhook URL(含 access_token)
|
||||
TEST_WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=your_token_here
|
||||
# 加签密钥(选填,不配置则跳过加签测试)
|
||||
TEST_WEBHOOK_SECRET=
|
||||
|
||||
# ── 企业内部应用机器人 ──────────────────────────────────────────
|
||||
# 机器人 robotCode(通常等于 DINGTALK_APP_KEY)
|
||||
TEST_ROBOT_CODE=your_robot_code_here
|
||||
# 测试目标用户 userId(机器人单聊消息的接收人)
|
||||
TEST_USER_ID=your_user_id_here
|
||||
# 测试群的 openConversationId(机器人群聊消息用)
|
||||
# 可通过机器人收到群消息回调时获得,或调用 IM 接口创建群时返回
|
||||
TEST_OPEN_CONVERSATION_ID=your_open_conversation_id_here
|
||||
|
||||
# ── 工作通知 ────────────────────────────────────────────────────
|
||||
# 应用 agentId(开放平台 → 应用管理 → 基本信息)
|
||||
TEST_AGENT_ID=your_agent_id_here
|
||||
|
||||
+28
-1
@@ -26,9 +26,30 @@ def _require_env(key: str) -> str:
|
||||
APP_KEY = os.environ.get("DINGTALK_APP_KEY", "")
|
||||
APP_SECRET = os.environ.get("DINGTALK_APP_SECRET", "")
|
||||
OPERATOR_ID = os.environ.get("OPERATOR_ID", "")
|
||||
USER_ID = os.environ.get("DINGTALK_USER_ID", "")
|
||||
BASE = "https://api.dingtalk.com"
|
||||
|
||||
|
||||
def _userid_to_unionid(app_key: str, app_secret: str, user_id: str) -> str:
|
||||
"""通过旧版 API 将 userId 转换为 unionId。"""
|
||||
r = requests.get(
|
||||
"https://oapi.dingtalk.com/gettoken",
|
||||
params={"appkey": app_key, "appsecret": app_secret},
|
||||
timeout=15,
|
||||
)
|
||||
r.raise_for_status()
|
||||
old_token = r.json()["access_token"]
|
||||
r2 = requests.post(
|
||||
f"https://oapi.dingtalk.com/topapi/v2/user/get?access_token={old_token}",
|
||||
json={"userid": user_id},
|
||||
timeout=15,
|
||||
)
|
||||
r2.raise_for_status()
|
||||
data = r2.json()
|
||||
assert data.get("errcode") == 0, f"userId→unionId 转换失败:{data}"
|
||||
return data["result"]["unionid"] # 注意:无下划线
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def token() -> str:
|
||||
app_key = _require_env("DINGTALK_APP_KEY")
|
||||
@@ -46,7 +67,13 @@ def token() -> str:
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def operator_id() -> str:
|
||||
return _require_env("OPERATOR_ID")
|
||||
"""返回操作者 unionId。优先读 OPERATOR_ID,否则从 DINGTALK_USER_ID 自动转换。"""
|
||||
if OPERATOR_ID:
|
||||
return OPERATOR_ID
|
||||
user_id = _require_env("DINGTALK_USER_ID")
|
||||
app_key = _require_env("DINGTALK_APP_KEY")
|
||||
app_secret = _require_env("DINGTALK_APP_SECRET")
|
||||
return _userid_to_unionid(app_key, app_secret, user_id)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
||||
@@ -6,6 +6,7 @@ readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"alibabacloud-dingtalk>=2.2.38",
|
||||
"dotenv>=0.9.9",
|
||||
"requests>=2.32.5",
|
||||
]
|
||||
|
||||
|
||||
Generated
+22
@@ -387,6 +387,17 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/66/d3/a7daaee544c904548e665829b51a9fa2572acb82c73ad787a8ff90273002/darabonba_core-1.0.5-py3-none-any.whl", hash = "sha256:671ab8dbc4edc2a8f88013da71646839bb8914f1259efc069353243ef52ea27c", size = 24580, upload-time = "2025-12-12T07:53:59.494Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.9.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "python-dotenv" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/b7/545d2c10c1fc15e48653c91efde329a790f2eecfbbf2bd16003b5db2bab0/dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9", size = 1892, upload-time = "2025-02-19T22:15:01.647Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "frozenlist"
|
||||
version = "1.8.0"
|
||||
@@ -680,6 +691,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "1.2.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.5"
|
||||
@@ -701,6 +721,7 @@ version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "alibabacloud-dingtalk" },
|
||||
{ name = "dotenv" },
|
||||
{ name = "requests" },
|
||||
]
|
||||
|
||||
@@ -712,6 +733,7 @@ dev = [
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "alibabacloud-dingtalk", specifier = ">=2.2.38" },
|
||||
{ name = "dotenv", specifier = ">=0.9.9" },
|
||||
{ name = "requests", specifier = ">=2.32.5" },
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user