@openclaw/feishu 2026.5.27-beta.1 → 2026.5.28-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +2 -2
- package/dist/{channel-DS2vP1nr.js → channel-DLfxURF2.js} +16 -12
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CxRDzbEQ.js → channel.runtime-i-X8-ZXc.js} +5 -5
- package/dist/{client-BnH2fRL2.js → client-DcSzLkSX.js} +3 -2
- package/dist/{drive-DwgWWkJi.js → drive-Grnpj510.js} +1 -1
- package/dist/{monitor-DNYcF9wy.js → monitor-w8w3-7EH.js} +2 -2
- package/dist/{monitor.account-vUWzYlT_.js → monitor.account-tuA8NuVQ.js} +8 -8
- package/dist/{monitor.state-CxrHFQX2.js → monitor.state-B6SoAUys.js} +6 -5
- package/dist/{probe-Da81t6a5.js → probe-RvCg70BY.js} +1 -1
- package/dist/{send-jDh7bucI.js → send-CKZz15KQ.js} +1 -1
- package/dist/setup-api.js +1 -1
- package/node_modules/@larksuiteoapi/node-sdk/README.md +4 -0
- package/node_modules/@larksuiteoapi/node-sdk/README.zh.md +4 -0
- package/node_modules/@larksuiteoapi/node-sdk/es/index.js +33 -1
- package/node_modules/@larksuiteoapi/node-sdk/lib/index.js +33 -1
- package/node_modules/@larksuiteoapi/node-sdk/package.json +1 -1
- package/node_modules/@larksuiteoapi/node-sdk/types/index.d.ts +19 -0
- package/npm-shrinkwrap.json +7 -7
- package/package.json +5 -5
package/dist/api.js
CHANGED
|
@@ -2,9 +2,9 @@ import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as bu
|
|
|
2
2
|
import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
|
|
3
3
|
import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-fuyBHOVu.js";
|
|
4
4
|
import { r as listEnabledFeishuAccounts } from "./accounts-CXnY5H8g.js";
|
|
5
|
-
import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-
|
|
5
|
+
import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-DLfxURF2.js";
|
|
6
6
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
7
|
-
import { a as jsonToolResult, d as registerFeishuChatTools, f as createFeishuToolClient, m as resolveFeishuToolAccount, n as registerFeishuDriveTools, o as toolExecutionErrorResult, p as resolveAnyEnabledFeishuToolsConfig, s as unknownToolActionResult } from "./drive-
|
|
7
|
+
import { a as jsonToolResult, d as registerFeishuChatTools, f as createFeishuToolClient, m as resolveFeishuToolAccount, n as registerFeishuDriveTools, o as toolExecutionErrorResult, p as resolveAnyEnabledFeishuToolsConfig, s as unknownToolActionResult } from "./drive-Grnpj510.js";
|
|
8
8
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { homedir } from "node:os";
|
|
@@ -1647,7 +1647,7 @@ const feishuSetupWizard = {
|
|
|
1647
1647
|
});
|
|
1648
1648
|
let probeResult = null;
|
|
1649
1649
|
if (configured && account.configured) try {
|
|
1650
|
-
const { probeFeishu } = await import("./probe-
|
|
1650
|
+
const { probeFeishu } = await import("./probe-RvCg70BY.js").then((n) => n.n);
|
|
1651
1651
|
probeResult = await probeFeishu(account);
|
|
1652
1652
|
} catch {}
|
|
1653
1653
|
if (!configured) return [formatFeishuStatusLine("needs-credentials")];
|
|
@@ -1722,7 +1722,7 @@ const meta = {
|
|
|
1722
1722
|
aliases: ["lark"],
|
|
1723
1723
|
order: 70
|
|
1724
1724
|
};
|
|
1725
|
-
const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-
|
|
1725
|
+
const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-i-X8-ZXc.js"), "feishuChannelRuntime");
|
|
1726
1726
|
function toFeishuMessageSendResult(result, kind) {
|
|
1727
1727
|
const receipt = result.receipt ?? createFeishuSendReceipt({
|
|
1728
1728
|
messageId: result.messageId,
|
|
@@ -1754,7 +1754,7 @@ const feishuMessageAdapter = defineChannelMessageAdapter({
|
|
|
1754
1754
|
}
|
|
1755
1755
|
});
|
|
1756
1756
|
async function createFeishuActionClient(account) {
|
|
1757
|
-
const { createFeishuClient } = await import("./client-
|
|
1757
|
+
const { createFeishuClient } = await import("./client-DcSzLkSX.js").then((n) => n.t);
|
|
1758
1758
|
return createFeishuClient(account);
|
|
1759
1759
|
}
|
|
1760
1760
|
const collectFeishuSecurityWarnings = createAllowlistProviderGroupPolicyWarningCollector({
|
|
@@ -1960,13 +1960,17 @@ function readFirstString(params, keys, fallback) {
|
|
|
1960
1960
|
}
|
|
1961
1961
|
if (typeof fallback === "string" && fallback.trim()) return fallback.trim();
|
|
1962
1962
|
}
|
|
1963
|
-
function
|
|
1963
|
+
function isPositiveSafeInteger(value) {
|
|
1964
|
+
return Number.isSafeInteger(value) && value > 0;
|
|
1965
|
+
}
|
|
1966
|
+
function readOptionalPositiveInteger(params, keys) {
|
|
1964
1967
|
for (const key of keys) {
|
|
1965
1968
|
const value = params[key];
|
|
1966
|
-
if (typeof value === "number" &&
|
|
1969
|
+
if (typeof value === "number" && isPositiveSafeInteger(value)) return value;
|
|
1967
1970
|
if (typeof value === "string" && value.trim()) {
|
|
1968
|
-
const
|
|
1969
|
-
|
|
1971
|
+
const trimmed = value.trim();
|
|
1972
|
+
const parsed = /^\d+$/.test(trimmed) ? Number(trimmed) : NaN;
|
|
1973
|
+
if (isPositiveSafeInteger(parsed)) return parsed;
|
|
1970
1974
|
}
|
|
1971
1975
|
}
|
|
1972
1976
|
}
|
|
@@ -2262,7 +2266,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2262
2266
|
chatId,
|
|
2263
2267
|
startTime: readFirstString(ctx.params, ["startTime", "start_time"]),
|
|
2264
2268
|
endTime: readFirstString(ctx.params, ["endTime", "end_time"]),
|
|
2265
|
-
pageSize:
|
|
2269
|
+
pageSize: readOptionalPositiveInteger(ctx.params, ["pageSize", "page_size"]),
|
|
2266
2270
|
pageToken: readFirstString(ctx.params, ["pageToken", "page_token"]),
|
|
2267
2271
|
accountId: ctx.accountId ?? void 0
|
|
2268
2272
|
})
|
|
@@ -2285,7 +2289,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2285
2289
|
provider: "feishu",
|
|
2286
2290
|
action: "channel-info",
|
|
2287
2291
|
channel,
|
|
2288
|
-
members: await runtime.getChatMembers(client, chatId,
|
|
2292
|
+
members: await runtime.getChatMembers(client, chatId, readOptionalPositiveInteger(ctx.params, ["pageSize", "page_size"]), readFirstString(ctx.params, ["pageToken", "page_token"]), resolveFeishuMemberIdType(ctx.params))
|
|
2289
2293
|
});
|
|
2290
2294
|
}
|
|
2291
2295
|
if (ctx.action === "member-info") {
|
|
@@ -2304,13 +2308,13 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2304
2308
|
ok: true,
|
|
2305
2309
|
channel: "feishu",
|
|
2306
2310
|
action: "member-info",
|
|
2307
|
-
...await runtime.getChatMembers(client, chatId,
|
|
2311
|
+
...await runtime.getChatMembers(client, chatId, readOptionalPositiveInteger(ctx.params, ["pageSize", "page_size"]), readFirstString(ctx.params, ["pageToken", "page_token"]), resolveFeishuMemberIdType(ctx.params))
|
|
2308
2312
|
});
|
|
2309
2313
|
}
|
|
2310
2314
|
if (ctx.action === "channel-list") {
|
|
2311
2315
|
const runtime = await loadFeishuChannelRuntime();
|
|
2312
2316
|
const query = readFirstString(ctx.params, ["query"]);
|
|
2313
|
-
const limit =
|
|
2317
|
+
const limit = readOptionalPositiveInteger(ctx.params, ["limit"]);
|
|
2314
2318
|
const scope = readFirstString(ctx.params, ["scope", "kind"]) ?? "all";
|
|
2315
2319
|
if (scope === "groups" || scope === "group" || scope === "channels" || scope === "channel") return jsonActionResult({
|
|
2316
2320
|
ok: true,
|
|
@@ -2542,7 +2546,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2542
2546
|
})
|
|
2543
2547
|
}),
|
|
2544
2548
|
gateway: { startAccount: async (ctx) => {
|
|
2545
|
-
const { monitorFeishuProvider } = await import("./monitor-
|
|
2549
|
+
const { monitorFeishuProvider } = await import("./monitor-w8w3-7EH.js");
|
|
2546
2550
|
const account = resolveFeishuRuntimeAccount({
|
|
2547
2551
|
cfg: ctx.cfg,
|
|
2548
2552
|
accountId: ctx.accountId
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as feishuPlugin } from "./channel-
|
|
1
|
+
import { t as feishuPlugin } from "./channel-DLfxURF2.js";
|
|
2
2
|
export { feishuPlugin };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-CXnY5H8g.js";
|
|
2
|
-
import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-
|
|
3
|
-
import { r as createFeishuClient } from "./client-
|
|
4
|
-
import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-
|
|
2
|
+
import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-DLfxURF2.js";
|
|
3
|
+
import { r as createFeishuClient } from "./client-DcSzLkSX.js";
|
|
4
|
+
import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-Grnpj510.js";
|
|
5
5
|
import { chunkTextForOutbound } from "./runtime-api.js";
|
|
6
|
-
import { a as sendCardFeishu, c as sendStructuredCardFeishu, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, n as getMessageFeishu, o as sendMarkdownCardFeishu, s as sendMessageFeishu, t as editMessageFeishu } from "./send-
|
|
7
|
-
import { t as probeFeishu } from "./probe-
|
|
6
|
+
import { a as sendCardFeishu, c as sendStructuredCardFeishu, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, n as getMessageFeishu, o as sendMarkdownCardFeishu, s as sendMessageFeishu, t as editMessageFeishu } from "./send-CKZz15KQ.js";
|
|
7
|
+
import { t as probeFeishu } from "./probe-RvCg70BY.js";
|
|
8
8
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
9
|
import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
|
|
10
10
|
import path from "node:path";
|
|
@@ -2,6 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
4
4
|
import { readPluginPackageVersion, resolveAmbientNodeProxyAgent } from "openclaw/plugin-sdk/extension-shared";
|
|
5
|
+
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
5
6
|
//#region extensions/feishu/src/client-timeout.ts
|
|
6
7
|
/** Default HTTP timeout for Feishu API requests (30 seconds). */
|
|
7
8
|
const FEISHU_HTTP_TIMEOUT_MS = 3e4;
|
|
@@ -15,8 +16,8 @@ function resolveConfiguredHttpTimeoutMs(creds) {
|
|
|
15
16
|
if (typeof fromDirectField === "number" && Number.isFinite(fromDirectField) && fromDirectField > 0) return clampTimeout(fromDirectField);
|
|
16
17
|
const envRaw = process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR];
|
|
17
18
|
if (envRaw) {
|
|
18
|
-
const envValue =
|
|
19
|
-
if (
|
|
19
|
+
const envValue = parseStrictPositiveInteger(envRaw);
|
|
20
|
+
if (envValue !== void 0) return clampTimeout(envValue);
|
|
20
21
|
}
|
|
21
22
|
const timeout = creds.config?.httpTimeoutMs;
|
|
22
23
|
if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) return FEISHU_HTTP_TIMEOUT_MS;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as formatFeishuApiError, f as isRecord$1, h as readString, i as listFeishuAccountIds, l as encodeQuery, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as extractReplyText, y as parseFeishuCommentTarget } from "./accounts-CXnY5H8g.js";
|
|
2
|
-
import { r as createFeishuClient } from "./client-
|
|
2
|
+
import { r as createFeishuClient } from "./client-DcSzLkSX.js";
|
|
3
3
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
5
|
import { Type } from "typebox";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
|
|
2
|
-
import { l as fetchBotIdentityForMonitor } from "./monitor.state-
|
|
2
|
+
import { l as fetchBotIdentityForMonitor } from "./monitor.state-B6SoAUys.js";
|
|
3
3
|
//#region extensions/feishu/src/monitor.ts
|
|
4
4
|
let monitorAccountRuntimePromise;
|
|
5
5
|
async function loadMonitorAccountRuntime() {
|
|
6
|
-
monitorAccountRuntimePromise ??= import("./monitor.account-
|
|
6
|
+
monitorAccountRuntimePromise ??= import("./monitor.account-tuA8NuVQ.js");
|
|
7
7
|
return await monitorAccountRuntimePromise;
|
|
8
8
|
}
|
|
9
9
|
async function monitorFeishuProvider(opts = {}) {
|
|
@@ -2,15 +2,15 @@ import { t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
|
|
|
2
2
|
import { i as resolveReceiveIdType } from "./targets-BUjQ1TcA.js";
|
|
3
3
|
import { t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
|
|
4
4
|
import { _ as buildFeishuCommentTarget, f as isRecord$1, h as readString, l as encodeQuery, m as parseCommentContentElements, p as normalizeString, s as resolveFeishuRuntimeAccount, u as extractReplyText, v as normalizeCommentFileType } from "./accounts-CXnY5H8g.js";
|
|
5
|
-
import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-
|
|
5
|
+
import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-DLfxURF2.js";
|
|
6
6
|
import { c as decodeFeishuCardAction, o as buildFeishuCardActionTextFallback, s as createFeishuCardInteractionEnvelope } from "./send-result-DSTSkRDM.js";
|
|
7
7
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
8
|
-
import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-
|
|
9
|
-
import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-
|
|
8
|
+
import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-DcSzLkSX.js";
|
|
9
|
+
import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-Grnpj510.js";
|
|
10
10
|
import { createReplyPrefixContext, evaluateSupplementalContextVisibility, loadSessionStore, normalizeAgentId as normalizeAgentId$2, resolveChannelContextVisibilityMode, resolveSessionStoreEntry } from "./runtime-api.js";
|
|
11
|
-
import { _ as normalizeFeishuExternalKey, a as sendCardFeishu, c as sendStructuredCardFeishu, d as isFeishuBroadcastMention, f as isMentionForwardRequest, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, l as parsePostContent, m as saveMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-
|
|
12
|
-
import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-
|
|
13
|
-
import { a as feishuWebhookRateLimiter, c as wsClients, i as botOpenIds, l as fetchBotIdentityForMonitor, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as httpServers, r as botNames, s as recordWebhookStatus, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS } from "./monitor.state-
|
|
11
|
+
import { _ as normalizeFeishuExternalKey, a as sendCardFeishu, c as sendStructuredCardFeishu, d as isFeishuBroadcastMention, f as isMentionForwardRequest, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, l as parsePostContent, m as saveMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-CKZz15KQ.js";
|
|
12
|
+
import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-RvCg70BY.js";
|
|
13
|
+
import { a as feishuWebhookRateLimiter, c as wsClients, i as botOpenIds, l as fetchBotIdentityForMonitor, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as httpServers, r as botNames, s as recordWebhookStatus, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS } from "./monitor.state-B6SoAUys.js";
|
|
14
14
|
import { asBoolean, asNullableRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
15
15
|
import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
|
|
16
16
|
import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
@@ -22,6 +22,7 @@ import os from "node:os";
|
|
|
22
22
|
import path from "node:path";
|
|
23
23
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
24
24
|
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
25
|
+
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
25
26
|
import { createPersistentDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
26
27
|
import { applyBasicWebhookRequestGuards, resolveRequestClientIp } from "openclaw/plugin-sdk/webhook-ingress";
|
|
27
28
|
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
@@ -4074,8 +4075,7 @@ function buildCommentSessionKey(params) {
|
|
|
4074
4075
|
});
|
|
4075
4076
|
}
|
|
4076
4077
|
function parseTimestampMs(value) {
|
|
4077
|
-
|
|
4078
|
-
return Number.isFinite(parsed) ? parsed : Date.now();
|
|
4078
|
+
return parseStrictNonNegativeInteger(value) ?? Date.now();
|
|
4079
4079
|
}
|
|
4080
4080
|
async function handleFeishuCommentEvent(params) {
|
|
4081
4081
|
const account = resolveFeishuRuntimeAccount({
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { t as probeFeishu } from "./probe-
|
|
1
|
+
import { t as probeFeishu } from "./probe-RvCg70BY.js";
|
|
2
2
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
3
4
|
import { WEBHOOK_ANOMALY_COUNTER_DEFAULTS, WEBHOOK_RATE_LIMIT_DEFAULTS, createFixedWindowRateLimiter, createWebhookAnomalyTracker } from "openclaw/plugin-sdk/webhook-ingress";
|
|
4
5
|
//#region extensions/feishu/src/monitor.startup.ts
|
|
5
6
|
const FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS = 3e4;
|
|
6
7
|
const FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV = "OPENCLAW_FEISHU_STARTUP_PROBE_TIMEOUT_MS";
|
|
7
|
-
function resolveStartupProbeTimeoutMs() {
|
|
8
|
-
const raw =
|
|
8
|
+
function resolveStartupProbeTimeoutMs(env = process.env) {
|
|
9
|
+
const raw = env[FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV];
|
|
9
10
|
if (raw) {
|
|
10
|
-
const parsed =
|
|
11
|
-
if (
|
|
11
|
+
const parsed = parseStrictPositiveInteger(raw);
|
|
12
|
+
if (parsed !== void 0) return parsed;
|
|
12
13
|
console.warn(`[feishu] ${FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV}="${raw}" is invalid; using default ${FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS}ms`);
|
|
13
14
|
}
|
|
14
15
|
return FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { r as createFeishuClient } from "./client-
|
|
2
|
+
import { r as createFeishuClient } from "./client-DcSzLkSX.js";
|
|
3
3
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
4
4
|
//#region extensions/feishu/src/async.ts
|
|
5
5
|
const RACE_TIMEOUT = Symbol("race-timeout");
|
|
@@ -2,7 +2,7 @@ import { i as resolveReceiveIdType, r as normalizeFeishuTarget } from "./targets
|
|
|
2
2
|
import { c as createFeishuApiError, f as isRecord$1, g as requestFeishuApi, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
|
|
3
3
|
import { i as toFeishuSendResult, r as resolveFeishuReceiptKind, t as assertFeishuMessageApiSuccess } from "./send-result-DSTSkRDM.js";
|
|
4
4
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
5
|
-
import { r as createFeishuClient } from "./client-
|
|
5
|
+
import { r as createFeishuClient } from "./client-DcSzLkSX.js";
|
|
6
6
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
7
|
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
|
|
8
8
|
import fs from "node:fs";
|
package/dist/setup-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-
|
|
1
|
+
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-DLfxURF2.js";
|
|
2
2
|
export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
|
|
@@ -691,6 +691,10 @@ try {
|
|
|
691
691
|
| signal | `AbortSignal` to cancel the polling | AbortSignal | No | - |
|
|
692
692
|
| onQRCodeReady | Callback when the verification URL is ready. Receives `{ url, expireIn }`. You can render the URL as a QR code for users to scan, or display it as a link | function | Yes | - |
|
|
693
693
|
| onStatusChange | Callback on polling status changes. Receives `{ status, interval? }`. Status values: `polling`, `slow_down`, `domain_switched` | function | No | - |
|
|
694
|
+
| appPreset | Pre-fill values for the app-creation page. All fields are optional; users can still edit them on the page | AppPreset | No | - |
|
|
695
|
+
| appPreset.avatar | App avatar URL(s). 1-6 URLs supported; the first one is selected by default. Allowed formats: png / jpg / jpeg / webp / gif (gif is sampled to a single frame, not animated) | string \| string[] | No | - |
|
|
696
|
+
| appPreset.name | App name. Supports the `{user}` placeholder (replaced with the scanning user's name) | string | No | - |
|
|
697
|
+
| appPreset.desc | App description. Supports the `{user}` placeholder | string | No | - |
|
|
694
698
|
|
|
695
699
|
#### Return value
|
|
696
700
|
|
|
@@ -753,6 +753,10 @@ try {
|
|
|
753
753
|
| signal | 用于取消轮询的 `AbortSignal` | AbortSignal | 否 | - |
|
|
754
754
|
| onQRCodeReady | 验证链接就绪时的回调,参数为 `{ url, expireIn }`。可将 URL 渲染为二维码供用户扫码,或直接作为链接展示 | function | 是 | - |
|
|
755
755
|
| onStatusChange | 轮询状态变化时的回调,参数为 `{ status, interval? }`。status 取值:`polling`、`slow_down`、`domain_switched` | function | 否 | - |
|
|
756
|
+
| appPreset | 预设应用信息(头像、名称、描述)。所有字段都是可选的,用户扫码后仍可在页面手动修改 | AppPreset | 否 | - |
|
|
757
|
+
| appPreset.avatar | 应用头像 URL,支持 1-6 个;传多个时默认选中第一个。支持 png / jpg / jpeg / webp / gif(gif 自动取一帧,不保留动图) | string \| string[] | 否 | - |
|
|
758
|
+
| appPreset.name | 应用名称,支持 `{user}` 占位符(替换为扫码用户名称) | string | 否 | - |
|
|
759
|
+
| appPreset.desc | 应用描述,支持 `{user}` 占位符 | string | 否 | - |
|
|
756
760
|
|
|
757
761
|
#### 返回值
|
|
758
762
|
|
|
@@ -89750,6 +89750,35 @@ const SDK_NAME = 'node-sdk';
|
|
|
89750
89750
|
const DEFAULT_FEISHU_DOMAIN = 'accounts.feishu.cn';
|
|
89751
89751
|
const DEFAULT_LARK_DOMAIN = 'accounts.larksuite.com';
|
|
89752
89752
|
const ENDPOINT = '/oauth/v1/app/registration';
|
|
89753
|
+
const AVATAR_MAX_COUNT = 6;
|
|
89754
|
+
/**
|
|
89755
|
+
* Append `avatar` / `name` / `desc` query params to the QR code URL.
|
|
89756
|
+
* `URLSearchParams` handles URL encoding automatically.
|
|
89757
|
+
*/
|
|
89758
|
+
function applyAppPreset(qrCodeUrl, preset) {
|
|
89759
|
+
const { avatar, name, desc } = preset;
|
|
89760
|
+
if (avatar !== undefined) {
|
|
89761
|
+
const avatars = Array.isArray(avatar) ? avatar : [avatar];
|
|
89762
|
+
if (avatars.length === 0) {
|
|
89763
|
+
throw new Error('appPreset.avatar must contain at least 1 URL');
|
|
89764
|
+
}
|
|
89765
|
+
if (avatars.length > AVATAR_MAX_COUNT) {
|
|
89766
|
+
throw new Error(`appPreset.avatar supports at most ${AVATAR_MAX_COUNT} URLs, got ${avatars.length}`);
|
|
89767
|
+
}
|
|
89768
|
+
avatars.forEach((url, idx) => {
|
|
89769
|
+
if (typeof url !== 'string' || url === '') {
|
|
89770
|
+
throw new Error(`appPreset.avatar[${idx}] must be a non-empty string`);
|
|
89771
|
+
}
|
|
89772
|
+
qrCodeUrl.searchParams.append('avatar', url);
|
|
89773
|
+
});
|
|
89774
|
+
}
|
|
89775
|
+
if (name !== undefined) {
|
|
89776
|
+
qrCodeUrl.searchParams.set('name', name);
|
|
89777
|
+
}
|
|
89778
|
+
if (desc !== undefined) {
|
|
89779
|
+
qrCodeUrl.searchParams.set('desc', desc);
|
|
89780
|
+
}
|
|
89781
|
+
}
|
|
89753
89782
|
function requestRegistration(baseUrl, params) {
|
|
89754
89783
|
var _a;
|
|
89755
89784
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -89867,13 +89896,16 @@ function startPolling(ctx) {
|
|
|
89867
89896
|
function registerApp(options) {
|
|
89868
89897
|
var _a, _b, _c, _d;
|
|
89869
89898
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89870
|
-
const { domain, source, signal, onQRCodeReady, onStatusChange } = options;
|
|
89899
|
+
const { domain, source, signal, onQRCodeReady, onStatusChange, appPreset } = options;
|
|
89871
89900
|
const baseUrl = `https://${domain !== null && domain !== void 0 ? domain : DEFAULT_FEISHU_DOMAIN}`;
|
|
89872
89901
|
const beginRes = yield begin(baseUrl);
|
|
89873
89902
|
const qrCodeUrl = new URL(beginRes.verification_uri_complete);
|
|
89874
89903
|
qrCodeUrl.searchParams.set('from', 'sdk');
|
|
89875
89904
|
qrCodeUrl.searchParams.set('source', source ? `${SDK_NAME}/${source}` : SDK_NAME);
|
|
89876
89905
|
qrCodeUrl.searchParams.set('tp', 'sdk');
|
|
89906
|
+
if (appPreset) {
|
|
89907
|
+
applyAppPreset(qrCodeUrl, appPreset);
|
|
89908
|
+
}
|
|
89877
89909
|
onQRCodeReady({
|
|
89878
89910
|
url: qrCodeUrl.toString(),
|
|
89879
89911
|
expireIn: (_a = beginRes.expires_in) !== null && _a !== void 0 ? _a : 600,
|
|
@@ -89768,6 +89768,35 @@ const SDK_NAME = 'node-sdk';
|
|
|
89768
89768
|
const DEFAULT_FEISHU_DOMAIN = 'accounts.feishu.cn';
|
|
89769
89769
|
const DEFAULT_LARK_DOMAIN = 'accounts.larksuite.com';
|
|
89770
89770
|
const ENDPOINT = '/oauth/v1/app/registration';
|
|
89771
|
+
const AVATAR_MAX_COUNT = 6;
|
|
89772
|
+
/**
|
|
89773
|
+
* Append `avatar` / `name` / `desc` query params to the QR code URL.
|
|
89774
|
+
* `URLSearchParams` handles URL encoding automatically.
|
|
89775
|
+
*/
|
|
89776
|
+
function applyAppPreset(qrCodeUrl, preset) {
|
|
89777
|
+
const { avatar, name, desc } = preset;
|
|
89778
|
+
if (avatar !== undefined) {
|
|
89779
|
+
const avatars = Array.isArray(avatar) ? avatar : [avatar];
|
|
89780
|
+
if (avatars.length === 0) {
|
|
89781
|
+
throw new Error('appPreset.avatar must contain at least 1 URL');
|
|
89782
|
+
}
|
|
89783
|
+
if (avatars.length > AVATAR_MAX_COUNT) {
|
|
89784
|
+
throw new Error(`appPreset.avatar supports at most ${AVATAR_MAX_COUNT} URLs, got ${avatars.length}`);
|
|
89785
|
+
}
|
|
89786
|
+
avatars.forEach((url, idx) => {
|
|
89787
|
+
if (typeof url !== 'string' || url === '') {
|
|
89788
|
+
throw new Error(`appPreset.avatar[${idx}] must be a non-empty string`);
|
|
89789
|
+
}
|
|
89790
|
+
qrCodeUrl.searchParams.append('avatar', url);
|
|
89791
|
+
});
|
|
89792
|
+
}
|
|
89793
|
+
if (name !== undefined) {
|
|
89794
|
+
qrCodeUrl.searchParams.set('name', name);
|
|
89795
|
+
}
|
|
89796
|
+
if (desc !== undefined) {
|
|
89797
|
+
qrCodeUrl.searchParams.set('desc', desc);
|
|
89798
|
+
}
|
|
89799
|
+
}
|
|
89771
89800
|
function requestRegistration(baseUrl, params) {
|
|
89772
89801
|
var _a;
|
|
89773
89802
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -89885,13 +89914,16 @@ function startPolling(ctx) {
|
|
|
89885
89914
|
function registerApp(options) {
|
|
89886
89915
|
var _a, _b, _c, _d;
|
|
89887
89916
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89888
|
-
const { domain, source, signal, onQRCodeReady, onStatusChange } = options;
|
|
89917
|
+
const { domain, source, signal, onQRCodeReady, onStatusChange, appPreset } = options;
|
|
89889
89918
|
const baseUrl = `https://${domain !== null && domain !== void 0 ? domain : DEFAULT_FEISHU_DOMAIN}`;
|
|
89890
89919
|
const beginRes = yield begin(baseUrl);
|
|
89891
89920
|
const qrCodeUrl = new URL(beginRes.verification_uri_complete);
|
|
89892
89921
|
qrCodeUrl.searchParams.set('from', 'sdk');
|
|
89893
89922
|
qrCodeUrl.searchParams.set('source', source ? `${SDK_NAME}/${source}` : SDK_NAME);
|
|
89894
89923
|
qrCodeUrl.searchParams.set('tp', 'sdk');
|
|
89924
|
+
if (appPreset) {
|
|
89925
|
+
applyAppPreset(qrCodeUrl, appPreset);
|
|
89926
|
+
}
|
|
89895
89927
|
onQRCodeReady({
|
|
89896
89928
|
url: qrCodeUrl.toString(),
|
|
89897
89929
|
expireIn: (_a = beginRes.expires_in) !== null && _a !== void 0 ? _a : 600,
|
|
@@ -300741,6 +300741,23 @@ interface StatusChangeInfo {
|
|
|
300741
300741
|
status: 'polling' | 'slow_down' | 'domain_switched';
|
|
300742
300742
|
interval?: number;
|
|
300743
300743
|
}
|
|
300744
|
+
/**
|
|
300745
|
+
* Pre-fill values shown on the app-creation page after the user scans the QR
|
|
300746
|
+
* code. All fields are optional and the user can still edit them on the page;
|
|
300747
|
+
* the final values are whatever the user submits.
|
|
300748
|
+
*/
|
|
300749
|
+
interface AppPreset {
|
|
300750
|
+
/**
|
|
300751
|
+
* App avatar URL(s). Pass a single URL or 1-6 URLs. The first one is the
|
|
300752
|
+
* default selection. Each URL must point to a publicly reachable image
|
|
300753
|
+
* (png / jpg / jpeg / webp / gif).
|
|
300754
|
+
*/
|
|
300755
|
+
avatar?: string | string[];
|
|
300756
|
+
/** App name. Supports `{user}` placeholder, replaced with the scanning user's name. */
|
|
300757
|
+
name?: string;
|
|
300758
|
+
/** App description. Supports `{user}` placeholder. */
|
|
300759
|
+
desc?: string;
|
|
300760
|
+
}
|
|
300744
300761
|
interface RegisterAppOptions {
|
|
300745
300762
|
domain?: string;
|
|
300746
300763
|
larkDomain?: string;
|
|
@@ -300748,6 +300765,8 @@ interface RegisterAppOptions {
|
|
|
300748
300765
|
signal?: AbortSignal;
|
|
300749
300766
|
onQRCodeReady: (info: QRCodeInfo) => void;
|
|
300750
300767
|
onStatusChange?: (info: StatusChangeInfo) => void;
|
|
300768
|
+
/** Pre-fill values for the app-creation page. See {@link AppPreset}. */
|
|
300769
|
+
appPreset?: AppPreset;
|
|
300751
300770
|
}
|
|
300752
300771
|
interface UserInfo {
|
|
300753
300772
|
open_id?: string;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.28-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/feishu",
|
|
9
|
-
"version": "2026.5.
|
|
9
|
+
"version": "2026.5.28-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@larksuiteoapi/node-sdk": "1.
|
|
11
|
+
"@larksuiteoapi/node-sdk": "1.66.0",
|
|
12
12
|
"typebox": "1.1.38",
|
|
13
13
|
"zod": "4.4.3"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.5.
|
|
16
|
+
"openclaw": ">=2026.5.28-beta.1"
|
|
17
17
|
},
|
|
18
18
|
"peerDependenciesMeta": {
|
|
19
19
|
"openclaw": {
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"node_modules/@larksuiteoapi/node-sdk": {
|
|
25
|
-
"version": "1.
|
|
26
|
-
"resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.
|
|
27
|
-
"integrity": "sha512-
|
|
25
|
+
"version": "1.66.0",
|
|
26
|
+
"resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.66.0.tgz",
|
|
27
|
+
"integrity": "sha512-ueKbbdvmVGVie3KvKbvHZqvDC/gg3M0rRDeyQanQWK+i2bQgiiTpIfpqVWvxuTgprV31yqV7HPMjN6KegWSCfA==",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"axios": "~1.13.3",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.28-beta.1",
|
|
4
4
|
"description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@larksuiteoapi/node-sdk": "1.
|
|
11
|
+
"@larksuiteoapi/node-sdk": "1.66.0",
|
|
12
12
|
"typebox": "1.1.38",
|
|
13
13
|
"zod": "4.4.3"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.5.
|
|
16
|
+
"openclaw": ">=2026.5.28-beta.1"
|
|
17
17
|
},
|
|
18
18
|
"peerDependenciesMeta": {
|
|
19
19
|
"openclaw": {
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"minHostVersion": ">=2026.4.25"
|
|
45
45
|
},
|
|
46
46
|
"compat": {
|
|
47
|
-
"pluginApi": ">=2026.5.
|
|
47
|
+
"pluginApi": ">=2026.5.28-beta.1"
|
|
48
48
|
},
|
|
49
49
|
"build": {
|
|
50
|
-
"openclawVersion": "2026.5.
|
|
50
|
+
"openclawVersion": "2026.5.28-beta.1"
|
|
51
51
|
},
|
|
52
52
|
"release": {
|
|
53
53
|
"publishToClawHub": true,
|