mirror of
https://github.com/larksuite/cli.git
synced 2026-07-07 00:55:53 +08:00
Compare commits
2 Commits
v1.0.43
...
feat/conta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
296b34a501 | ||
|
|
a2cc5e124e |
@@ -110,6 +110,52 @@ function getMirrorUrls(env) {
|
||||
return urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide from a `curl --version` output whether curl is >= 7.70.0 — the
|
||||
* release (2020-04-29) that introduced --ssl-revoke-best-effort. Kept pure
|
||||
* (no I/O) so the version-comparison logic can be unit tested without
|
||||
* spawning a process. Reads the leading "curl X.Y.Z" token, ignoring the
|
||||
* trailing "libcurl/X.Y.Z" that may report a different version.
|
||||
*
|
||||
* @param {string} versionOutput raw stdout of `curl --version`
|
||||
* @returns {boolean} true when the parsed version is >= 7.70.0
|
||||
*/
|
||||
function isCurlVersionSupported(versionOutput) {
|
||||
const match = String(versionOutput).match(/^\s*curl\s+(\d+)\.(\d+)\.(\d+)/i);
|
||||
if (!match) return false;
|
||||
const major = parseInt(match[1], 10);
|
||||
const minor = parseInt(match[2], 10);
|
||||
return major > 7 || (major === 7 && minor >= 70);
|
||||
}
|
||||
|
||||
// Memoized probe result. curl's version is invariant for the lifetime of the
|
||||
// install, while download() runs once per mirror URL — so probe at most once.
|
||||
let _curlSupportsSslRevokeBestEffort;
|
||||
|
||||
/**
|
||||
* Detect whether the system curl supports --ssl-revoke-best-effort. Older
|
||||
* versions (notably the curl 7.55.1 shipped with older Windows 10 builds)
|
||||
* exit with "unknown option" if the flag is passed.
|
||||
*
|
||||
* @returns {boolean} true when curl >= 7.70.0 is available
|
||||
*/
|
||||
function curlSupportsSslRevokeBestEffort() {
|
||||
if (_curlSupportsSslRevokeBestEffort !== undefined) {
|
||||
return _curlSupportsSslRevokeBestEffort;
|
||||
}
|
||||
try {
|
||||
const output = execFileSync("curl", ["--version"], {
|
||||
stdio: ["ignore", "pipe", "ignore"],
|
||||
encoding: "utf8",
|
||||
timeout: 5000,
|
||||
});
|
||||
_curlSupportsSslRevokeBestEffort = isCurlVersionSupported(output);
|
||||
} catch (_) {
|
||||
_curlSupportsSslRevokeBestEffort = false;
|
||||
}
|
||||
return _curlSupportsSslRevokeBestEffort;
|
||||
}
|
||||
|
||||
function download(url, destPath) {
|
||||
assertAllowedHost(url);
|
||||
const args = [
|
||||
@@ -119,8 +165,11 @@ function download(url, destPath) {
|
||||
"--output", destPath,
|
||||
];
|
||||
// --ssl-revoke-best-effort: on Windows (Schannel), avoid CRYPT_E_REVOCATION_OFFLINE
|
||||
// errors when the certificate revocation list server is unreachable
|
||||
if (isWindows) args.unshift("--ssl-revoke-best-effort");
|
||||
// errors when the certificate revocation list server is unreachable.
|
||||
// Only use it when the system curl is new enough (>= 7.70.0).
|
||||
if (isWindows && curlSupportsSslRevokeBestEffort()) {
|
||||
args.unshift("--ssl-revoke-best-effort");
|
||||
}
|
||||
args.push(url);
|
||||
execFileSync("curl", args, { stdio: ["ignore", "ignore", "pipe"] });
|
||||
}
|
||||
@@ -294,4 +343,4 @@ if (require.main === module) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { getExpectedChecksum, verifyChecksum, assertAllowedHost, resolveMirrorUrls };
|
||||
module.exports = { getExpectedChecksum, verifyChecksum, assertAllowedHost, resolveMirrorUrls, curlSupportsSslRevokeBestEffort, isCurlVersionSupported };
|
||||
|
||||
@@ -9,7 +9,7 @@ const os = require("os");
|
||||
|
||||
const crypto = require("crypto");
|
||||
|
||||
const { getExpectedChecksum, verifyChecksum, assertAllowedHost, resolveMirrorUrls } = require("./install.js");
|
||||
const { getExpectedChecksum, verifyChecksum, assertAllowedHost, resolveMirrorUrls, isCurlVersionSupported } = require("./install.js");
|
||||
|
||||
describe("getExpectedChecksum", () => {
|
||||
function makeTmpChecksums(content) {
|
||||
@@ -278,3 +278,55 @@ describe("resolveMirrorUrls", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isCurlVersionSupported", () => {
|
||||
// --ssl-revoke-best-effort was introduced in curl 7.70.0; below that the
|
||||
// flag is unknown and `curl` exits non-zero (see issue #1099).
|
||||
it("returns false for curl 7.55.1 (older Windows 10, flag unknown)", () => {
|
||||
assert.equal(
|
||||
isCurlVersionSupported("curl 7.55.1 (x86_64-pc-win32) libcurl/7.55.1"),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it("returns false for curl 7.69.0 (just below the 7.70.0 threshold)", () => {
|
||||
assert.equal(
|
||||
isCurlVersionSupported("curl 7.69.0 (x86_64-pc-win32) libcurl/7.69.0"),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it("returns true for curl 7.70.0 (flag introduced here)", () => {
|
||||
assert.equal(
|
||||
isCurlVersionSupported("curl 7.70.0 (x86_64-pc-win32) libcurl/7.70.0"),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("returns true for a future major (curl 8.x)", () => {
|
||||
assert.equal(
|
||||
isCurlVersionSupported("curl 8.5.0 (x86_64-apple-darwin) libcurl/8.5.0"),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("returns false when no version can be parsed", () => {
|
||||
assert.equal(isCurlVersionSupported("not a curl version string"), false);
|
||||
assert.equal(isCurlVersionSupported(""), false);
|
||||
});
|
||||
|
||||
it("reads the leading 'curl X.Y.Z', not the trailing libcurl/X.Y.Z", () => {
|
||||
// Guards the regex against latching onto "libcurl/7.55.1" when the
|
||||
// curl binary itself is new enough.
|
||||
assert.equal(
|
||||
isCurlVersionSupported("curl 8.0.0 (x86_64) libcurl/7.55.1"),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("does not match a 'libcurl X.Y.Z' token (anchored to leading curl)", () => {
|
||||
// "libcurl 8.0.0" contains the substring "curl 8.0.0"; the leading
|
||||
// anchor keeps it from being mistaken for a real curl version line.
|
||||
assert.equal(isCurlVersionSupported("libcurl 8.0.0"), false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: lark-contact
|
||||
version: 1.0.0
|
||||
description: "飞书 / Lark 通讯录,用于按姓名 / 邮箱把员工解析成 open_id,以及按 open_id 反查员工的姓名 / 部门 / 邮箱 / 联系方式。当用户说出某人姓名而下一步需要发消息 / 加群 / 排日程时,先用本 skill 把姓名换成 ID;当输出里出现 open_id 需要展示成姓名给用户看,或用户直接询问某人的部门 / 邮箱 / 联系方式时,用本 skill 查。不负责部门树遍历、按部门列员工、组织架构图,这类需求走原生 OpenAPI。"
|
||||
description: "飞书 / Lark 通讯录:按姓名 / 邮箱解析成 open_id,或按 open_id 反查姓名 / 部门 / 邮箱 / 联系方式 / 个人状态 / 签名。当用户提到某人姓名要下一步发消息 / 排日程,或拿到 open_id 想查具体信息时使用。不负责部门树遍历、按部门列员工、组织架构图,这类需求走原生 OpenAPI。"
|
||||
metadata:
|
||||
requires:
|
||||
bins: ["lark-cli"]
|
||||
@@ -19,17 +19,29 @@ metadata:
|
||||
| 按姓名 / 邮箱搜员工拿 open_id | [`+search-user`](references/lark-contact-search-user.md) | 不支持 |
|
||||
| 已知 open_id 取他人资料 | `+search-user --user-ids <id>` | [`+get-user --user-id <id>`](references/lark-contact-get-user.md) |
|
||||
| 查看自己 | `+get-user` 或 `+search-user --user-ids me` | 不支持 |
|
||||
| 查同事的个人状态 / 签名 | `user_profiles batch_query` | 不支持 |
|
||||
|
||||
已知 open_id 只是想发消息 / 排日程,不必经过 contact —— 直接 [`lark-im`](../lark-im/SKILL.md) / [`lark-calendar`](../lark-calendar/SKILL.md)。
|
||||
|
||||
## 典型场景
|
||||
|
||||
找张三给他发消息:先搜,确认 open_id,再发:
|
||||
|
||||
```bash
|
||||
# 找张三给他发消息:先搜,确认 open_id,再发
|
||||
lark-cli contact +search-user --query "张三" --has-chatted --as user
|
||||
lark-cli im +messages-send --user-id ou_xxx --text "Hi!"
|
||||
```
|
||||
|
||||
批量查同事的个人状态 / 个性签名(先用 schema 看参数)。
|
||||
|
||||
```bash
|
||||
lark-cli schema contact.user_profiles.batch_query
|
||||
lark-cli contact user_profiles batch_query \
|
||||
--params '{"user_id_type":"open_id"}' \
|
||||
--data '{"user_ids":["ou_xxx","ou_yyy"],"query_option":{"include_personal_status":true,"include_description":true}}' \
|
||||
--as user
|
||||
```
|
||||
|
||||
搜索命中多条且后续操作有副作用(发消息、邀请会议等),把候选列给用户挑;不要擅自选第一条。
|
||||
|
||||
## 注意事项
|
||||
@@ -42,4 +54,4 @@ lark-cli im +messages-send --user-id ou_xxx --text "Hi!"
|
||||
|
||||
- 发消息 / 查聊天记录 → [`lark-im`](../lark-im/SKILL.md)
|
||||
- 排日程 / 邀请会议 → [`lark-calendar`](../lark-calendar/SKILL.md)
|
||||
- 部门树 / 按部门列员工 / 组织架构 ,通过 [`lark-openapi-explorer`](../lark-openapi-explorer/SKILL.md) 查找原生接口
|
||||
- 部门树 / 按部门列员工 / 组织架构 → [`lark-openapi-explorer`](../lark-openapi-explorer/SKILL.md) 查找原生接口
|
||||
|
||||
Reference in New Issue
Block a user