@openclaw/feishu 2026.7.2-beta.1 → 2026.7.2-beta.3
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 +322 -176
- package/dist/{app-registration-BwQ-aGTe.js → app-registration-BzkyrVZu.js} +11 -11
- package/dist/{channel-DdPQ2HGh.js → channel-BdnXYU6g.js} +36 -50
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-DJ_B-bpG.js → channel.runtime-CVIzo2dV.js} +102 -17
- package/dist/{client-BUC-R2Wi.js → client-87BmeMpj.js} +51 -16
- package/dist/{drive-Bpe8ONK_.js → drive-BHv8WW9i.js} +2 -2
- package/dist/{monitor-M3iYtoh4.js → monitor-BVQf7-Bl.js} +2 -2
- package/dist/{monitor.account-F99J862T.js → monitor.account-Blbf2T6J.js} +752 -423
- package/dist/{monitor.startup-DpZzunQn.js → monitor.startup-Cy8NPGAX.js} +1 -1
- package/dist/{probe-CAloGqgG.js → probe-BgboTHIn.js} +1 -1
- package/dist/{secret-contract-DnlMcrn5.js → secret-contract-BCpDLdg9.js} +17 -26
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-CpnLYueT.js → send-DcrXbqqA.js} +87 -8
- package/dist/{send-result-CPS7AozW.js → send-result-DfE5Fhz6.js} +31 -16
- package/dist/setup-api.js +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +34 -8
- package/package.json +4 -4
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as readFeishuJsonResponse } from "./json-response-CheljwGr.js";
|
|
2
2
|
import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
|
|
3
|
+
import { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime";
|
|
3
4
|
import { sleep } from "openclaw/plugin-sdk/runtime-env";
|
|
4
5
|
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
5
|
-
import { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime";
|
|
6
6
|
//#region extensions/feishu/src/app-registration.ts
|
|
7
7
|
/**
|
|
8
8
|
* Feishu app registration via OAuth device-code flow.
|
|
@@ -14,7 +14,7 @@ import { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime";
|
|
|
14
14
|
const FEISHU_ACCOUNTS_URL = "https://accounts.feishu.cn";
|
|
15
15
|
const LARK_ACCOUNTS_URL = "https://accounts.larksuite.com";
|
|
16
16
|
const REGISTRATION_PATH = "/oauth/v1/app/registration";
|
|
17
|
-
const
|
|
17
|
+
const APP_REGISTRATION_REQUEST_TIMEOUT_MS = 1e4;
|
|
18
18
|
const DEFAULT_REGISTRATION_POLL_INTERVAL_SECONDS = 5;
|
|
19
19
|
const DEFAULT_REGISTRATION_EXPIRE_SECONDS = 600;
|
|
20
20
|
function accountsBaseUrl(domain) {
|
|
@@ -26,20 +26,22 @@ async function postRegistration(baseUrl, body, options) {
|
|
|
26
26
|
init: {
|
|
27
27
|
method: "POST",
|
|
28
28
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
29
|
-
body: new URLSearchParams(body).toString()
|
|
30
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
29
|
+
body: new URLSearchParams(body).toString()
|
|
31
30
|
},
|
|
32
31
|
auditContext: "feishu.app-registration.post",
|
|
33
32
|
fetchImpl: options?.fetchImpl,
|
|
34
|
-
lookupFn: options?.lookupFn
|
|
33
|
+
lookupFn: options?.lookupFn,
|
|
34
|
+
timeoutMs: options?.timeoutMs
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
async function fetchFeishuJson(params) {
|
|
38
|
+
const timeoutMs = params.timeoutMs ?? APP_REGISTRATION_REQUEST_TIMEOUT_MS;
|
|
38
39
|
const { response, release } = await fetchWithSsrFGuard({
|
|
39
40
|
url: params.url,
|
|
40
41
|
init: params.init,
|
|
41
42
|
fetchImpl: params.fetchImpl,
|
|
42
43
|
lookupFn: params.lookupFn,
|
|
44
|
+
timeoutMs,
|
|
43
45
|
policy: { allowedHostnames: [new URL(params.url).hostname] },
|
|
44
46
|
auditContext: params.auditContext
|
|
45
47
|
});
|
|
@@ -90,7 +92,7 @@ async function pollAppRegistration(params) {
|
|
|
90
92
|
let currentInterval = params.interval;
|
|
91
93
|
let domain = initialDomain;
|
|
92
94
|
let domainSwitched = false;
|
|
93
|
-
const expireInMs = finiteSecondsToTimerSafeMilliseconds(expireIn) ??
|
|
95
|
+
const expireInMs = finiteSecondsToTimerSafeMilliseconds(expireIn) ?? DEFAULT_REGISTRATION_EXPIRE_SECONDS * 1e3;
|
|
94
96
|
const deadline = Date.now() + expireInMs;
|
|
95
97
|
while (Date.now() < deadline) {
|
|
96
98
|
if (abortSignal?.aborted) return { status: "timeout" };
|
|
@@ -164,8 +166,7 @@ async function getAppOwnerOpenId(params) {
|
|
|
164
166
|
body: JSON.stringify({
|
|
165
167
|
app_id: params.appId,
|
|
166
168
|
app_secret: params.appSecret
|
|
167
|
-
})
|
|
168
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
169
|
+
})
|
|
169
170
|
},
|
|
170
171
|
auditContext: "feishu.app-registration.owner-token",
|
|
171
172
|
fetchImpl: params.fetchImpl,
|
|
@@ -179,8 +180,7 @@ async function getAppOwnerOpenId(params) {
|
|
|
179
180
|
headers: {
|
|
180
181
|
Authorization: `Bearer ${tokenData.tenant_access_token}`,
|
|
181
182
|
"Content-Type": "application/json"
|
|
182
|
-
}
|
|
183
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
183
|
+
}
|
|
184
184
|
},
|
|
185
185
|
auditContext: "feishu.app-registration.owner-app",
|
|
186
186
|
fetchImpl: params.fetchImpl,
|
|
@@ -195,7 +195,7 @@ async function getAppOwnerOpenId(params) {
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
function sleepRegistrationPollInterval(intervalSeconds) {
|
|
198
|
-
return sleep(finiteSecondsToTimerSafeMilliseconds(intervalSeconds) ??
|
|
198
|
+
return sleep(finiteSecondsToTimerSafeMilliseconds(intervalSeconds) ?? DEFAULT_REGISTRATION_POLL_INTERVAL_SECONDS * 1e3);
|
|
199
199
|
}
|
|
200
200
|
//#endregion
|
|
201
201
|
export { beginAppRegistration, getAppOwnerOpenId, initAppRegistration, pollAppRegistration, printQrCode };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { a as resolveDefaultFeishuAccountId, d as isRecord$1, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-BDoGHJDk.js";
|
|
2
2
|
import { i as resolveReceiveIdType, n as looksLikeFeishuId, r as normalizeFeishuTarget } from "./targets-BUjQ1TcA.js";
|
|
3
|
-
import {
|
|
3
|
+
import { A as resolveFeishuChatType, D as resolveFeishuGroupToolPolicy, N as createFeishuCardInteractionEnvelope, _ as canEnumerateAllFeishuPeers, a as readNativeFeishuCardJson, b as resolveFeishuChatReadPreliminaryAuthorization, g as canEnumerateAllFeishuGroups, h as authorizeFeishuChatMemberRead, k as normalizeFeishuChatType, m as assertFeishuChatReadAllowed, n as createFeishuSendReceipt, u as chunkFeishuMarkdown, v as isFeishuGroupReadAllowed, w as resolveFeishuGroupConfig, y as isFeishuGroupReadEnabled } from "./send-result-DfE5Fhz6.js";
|
|
4
4
|
import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, o as resolveConfiguredFeishuGroupSessionScope, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
|
|
5
5
|
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DXH5hux1.js";
|
|
6
6
|
import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
|
|
7
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-
|
|
7
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-BCpDLdg9.js";
|
|
8
8
|
import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
|
|
9
9
|
import { t as resolveFeishuSessionConversation } from "./session-conversation-BksWrfzm.js";
|
|
10
10
|
import { createLazyRuntimeModule, createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
|
|
@@ -18,16 +18,16 @@ import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing
|
|
|
18
18
|
import { createAllowlistProviderGroupPolicyWarningCollector, projectConfigAccountIdWarningCollector } from "openclaw/plugin-sdk/channel-policy";
|
|
19
19
|
import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
|
|
20
20
|
import { applyDirectoryQueryAndLimit, createChannelDirectoryAdapter, createRuntimeDirectoryLiveAdapter, listDirectoryGroupEntriesFromMapKeysAndAllowFrom, listDirectoryUserEntriesFromAllowFrom, listDirectoryUserEntriesFromAllowFromAndMapKeys } from "openclaw/plugin-sdk/directory-runtime";
|
|
21
|
-
import {
|
|
21
|
+
import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationChartFallbackText, renderMessagePresentationFallbackText, renderMessagePresentationTableFallbackText, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
|
|
22
22
|
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
23
23
|
import { buildProbeChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
24
24
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
25
25
|
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
26
|
-
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$
|
|
26
|
+
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$3 } from "openclaw/plugin-sdk/account-resolution";
|
|
27
27
|
import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
28
28
|
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
|
29
29
|
import { normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/account-id";
|
|
30
|
-
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
30
|
+
import { DmPolicySchema, GroupPolicySchema, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
31
31
|
import { z } from "zod";
|
|
32
32
|
import { buildSecretInputSchema, hasConfiguredSecretInput as hasConfiguredSecretInput$2 } from "openclaw/plugin-sdk/secret-input";
|
|
33
33
|
import fs from "node:fs";
|
|
@@ -36,7 +36,7 @@ import path from "node:path";
|
|
|
36
36
|
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
37
37
|
import { deleteSessionEntry, isValidAgentHarnessSessionStoreEntry, listSessionEntries, loadTranscriptEventsSync, parseSqliteSessionFileMarker, resolveSessionStoreBackupPaths, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
38
38
|
import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
|
|
39
|
-
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$
|
|
39
|
+
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, createSetupTranslator, formatDocsLink, hasConfiguredSecretInput as hasConfiguredSecretInput$1, mergeAllowFromEntries, patchTopLevelChannelConfigSection, promptSingleChannelSecretInput, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
40
40
|
//#region extensions/feishu/src/approval-auth.ts
|
|
41
41
|
function normalizeFeishuApproverId(value) {
|
|
42
42
|
const trimmed = normalizeOptionalLowercaseString(normalizeFeishuTarget(String(value)));
|
|
@@ -55,16 +55,7 @@ const feishuApprovalAuth = createChannelApprovalAuth({
|
|
|
55
55
|
//#endregion
|
|
56
56
|
//#region extensions/feishu/src/config-schema.ts
|
|
57
57
|
const ChannelActionsSchema = z.object({ reactions: z.boolean().optional() }).strict().optional();
|
|
58
|
-
const
|
|
59
|
-
"open",
|
|
60
|
-
"pairing",
|
|
61
|
-
"allowlist"
|
|
62
|
-
]);
|
|
63
|
-
const GroupPolicySchema = z.union([z.enum([
|
|
64
|
-
"open",
|
|
65
|
-
"allowlist",
|
|
66
|
-
"disabled"
|
|
67
|
-
]), z.literal("allowall").transform(() => "open")]);
|
|
58
|
+
const FeishuGroupPolicySchema = z.union([GroupPolicySchema, z.literal("allowall").transform(() => "open")]);
|
|
68
59
|
const FeishuDomainSchema = z.union([z.enum(["feishu", "lark"]), z.string().url().startsWith("https://")]);
|
|
69
60
|
const FeishuConnectionModeSchema = z.enum(["websocket", "webhook"]);
|
|
70
61
|
const TtsOverrideSchema = z.object({
|
|
@@ -196,17 +187,12 @@ const ReactionNotificationModeSchema = z.enum([
|
|
|
196
187
|
* causing the reply to appear as a topic (话题) under the original message.
|
|
197
188
|
*/
|
|
198
189
|
const ReplyInThreadSchema = z.enum(["disabled", "enabled"]).optional();
|
|
199
|
-
const FeishuGroupSchema =
|
|
200
|
-
requireMention: z.boolean().optional(),
|
|
190
|
+
const FeishuGroupSchema = buildGroupEntrySchema({
|
|
201
191
|
tools: ToolPolicySchema,
|
|
202
|
-
skills: z.array(z.string()).optional(),
|
|
203
|
-
enabled: z.boolean().optional(),
|
|
204
|
-
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
|
205
|
-
systemPrompt: z.string().optional(),
|
|
206
192
|
groupSessionScope: GroupSessionScopeSchema,
|
|
207
193
|
topicSessionMode: TopicSessionModeSchema,
|
|
208
194
|
replyInThread: ReplyInThreadSchema
|
|
209
|
-
}).
|
|
195
|
+
}).omit({ toolsBySender: true });
|
|
210
196
|
const FeishuSharedConfigShape = {
|
|
211
197
|
webhookHost: z.string().optional(),
|
|
212
198
|
webhookPort: z.number().int().positive().optional(),
|
|
@@ -215,7 +201,7 @@ const FeishuSharedConfigShape = {
|
|
|
215
201
|
configWrites: z.boolean().optional(),
|
|
216
202
|
dmPolicy: DmPolicySchema.optional(),
|
|
217
203
|
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
|
218
|
-
groupPolicy:
|
|
204
|
+
groupPolicy: FeishuGroupPolicySchema.optional(),
|
|
219
205
|
groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
|
220
206
|
groupSenderAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
|
221
207
|
requireMention: z.boolean().optional(),
|
|
@@ -235,6 +221,8 @@ const FeishuSharedConfigShape = {
|
|
|
235
221
|
reactionNotifications: ReactionNotificationModeSchema,
|
|
236
222
|
typingIndicator: z.boolean().optional(),
|
|
237
223
|
resolveSenderNames: z.boolean().optional(),
|
|
224
|
+
allowBots: z.boolean().optional(),
|
|
225
|
+
vcAutoJoin: z.boolean().optional(),
|
|
238
226
|
tts: TtsOverrideSchema
|
|
239
227
|
};
|
|
240
228
|
/**
|
|
@@ -255,7 +243,7 @@ const FeishuAccountConfigSchema = z.object({
|
|
|
255
243
|
groupSessionScope: GroupSessionScopeSchema,
|
|
256
244
|
topicSessionMode: TopicSessionModeSchema
|
|
257
245
|
}).strict();
|
|
258
|
-
const FeishuChannelConfigSchema = buildChannelConfigSchema(z.object({
|
|
246
|
+
const FeishuChannelConfigSchema = buildChannelConfigSchema(buildMultiAccountChannelSchema(z.object({
|
|
259
247
|
enabled: z.boolean().optional(),
|
|
260
248
|
defaultAccount: z.string().optional(),
|
|
261
249
|
appId: z.string().optional(),
|
|
@@ -268,15 +256,17 @@ const FeishuChannelConfigSchema = buildChannelConfigSchema(z.object({
|
|
|
268
256
|
...FeishuSharedConfigShape,
|
|
269
257
|
dmPolicy: DmPolicySchema.optional().default("pairing"),
|
|
270
258
|
reactionNotifications: ReactionNotificationModeSchema.optional().default("own"),
|
|
271
|
-
groupPolicy:
|
|
259
|
+
groupPolicy: FeishuGroupPolicySchema.optional().default("allowlist"),
|
|
272
260
|
requireMention: z.boolean().optional(),
|
|
273
261
|
groupSessionScope: GroupSessionScopeSchema,
|
|
274
262
|
topicSessionMode: TopicSessionModeSchema,
|
|
275
263
|
dynamicAgentCreation: DynamicAgentCreationSchema,
|
|
276
264
|
typingIndicator: z.boolean().optional().default(true),
|
|
277
|
-
resolveSenderNames: z.boolean().optional().default(true)
|
|
278
|
-
|
|
279
|
-
|
|
265
|
+
resolveSenderNames: z.boolean().optional().default(true)
|
|
266
|
+
}).strict(), {
|
|
267
|
+
accountSchema: FeishuAccountConfigSchema,
|
|
268
|
+
optionalAccount: true
|
|
269
|
+
}).superRefine((value, ctx) => {
|
|
280
270
|
const defaultAccount = value.defaultAccount?.trim();
|
|
281
271
|
if (defaultAccount && value.accounts && Object.keys(value.accounts).length > 0) {
|
|
282
272
|
const normalizedDefaultAccount = normalizeAccountId$1(defaultAccount);
|
|
@@ -1229,7 +1219,7 @@ function setFeishuNamedAccountEnabled$1(cfg, accountId, enabled) {
|
|
|
1229
1219
|
const feishuSetupAdapter = {
|
|
1230
1220
|
resolveAccountId: ({ cfg, accountId }) => accountId?.trim() || resolveDefaultFeishuAccountId(cfg),
|
|
1231
1221
|
applyAccountConfig: ({ cfg, accountId }) => {
|
|
1232
|
-
if (!accountId || accountId === DEFAULT_ACCOUNT_ID$
|
|
1222
|
+
if (!accountId || accountId === DEFAULT_ACCOUNT_ID$2) return {
|
|
1233
1223
|
...cfg,
|
|
1234
1224
|
channels: {
|
|
1235
1225
|
...cfg.channels,
|
|
@@ -1281,7 +1271,7 @@ function formatFeishuStatusLine(status) {
|
|
|
1281
1271
|
*/
|
|
1282
1272
|
function patchFeishuConfig(cfg, accountId, patch) {
|
|
1283
1273
|
const feishuCfg = cfg.channels?.feishu;
|
|
1284
|
-
if (accountId === DEFAULT_ACCOUNT_ID$
|
|
1274
|
+
if (accountId === DEFAULT_ACCOUNT_ID$2) return patchTopLevelChannelConfigSection({
|
|
1285
1275
|
cfg,
|
|
1286
1276
|
channel,
|
|
1287
1277
|
enabled: true,
|
|
@@ -1305,7 +1295,7 @@ function patchFeishuConfig(cfg, accountId, patch) {
|
|
|
1305
1295
|
async function promptFeishuAllowFrom(params) {
|
|
1306
1296
|
const feishuCfg = params.cfg.channels?.feishu;
|
|
1307
1297
|
const resolvedAccountId = params.accountId ?? resolveDefaultFeishuAccountId(params.cfg);
|
|
1308
|
-
const existingAllowFrom = (resolvedAccountId !== DEFAULT_ACCOUNT_ID$
|
|
1298
|
+
const existingAllowFrom = (resolvedAccountId !== DEFAULT_ACCOUNT_ID$2 ? feishuCfg?.accounts?.[resolvedAccountId] : void 0)?.allowFrom ?? feishuCfg?.allowFrom ?? [];
|
|
1309
1299
|
await params.prompter.note([
|
|
1310
1300
|
t("wizard.feishu.allowlistIntro"),
|
|
1311
1301
|
t("wizard.feishu.allowlistFindUser"),
|
|
@@ -1345,7 +1335,7 @@ const feishuDmPolicy = {
|
|
|
1345
1335
|
allowFromKey: "channels.feishu.allowFrom",
|
|
1346
1336
|
resolveConfigKeys: (_cfg, accountId) => {
|
|
1347
1337
|
const resolvedAccountId = accountId ?? resolveDefaultFeishuAccountId(_cfg);
|
|
1348
|
-
return resolvedAccountId !== DEFAULT_ACCOUNT_ID$
|
|
1338
|
+
return resolvedAccountId !== DEFAULT_ACCOUNT_ID$2 ? {
|
|
1349
1339
|
policyKey: `channels.feishu.accounts.${resolvedAccountId}.dmPolicy`,
|
|
1350
1340
|
allowFromKey: `channels.feishu.accounts.${resolvedAccountId}.allowFrom`
|
|
1351
1341
|
} : {
|
|
@@ -1356,7 +1346,7 @@ const feishuDmPolicy = {
|
|
|
1356
1346
|
getCurrent: (cfg, accountId) => {
|
|
1357
1347
|
const feishuCfg = cfg.channels?.feishu;
|
|
1358
1348
|
const resolvedAccountId = accountId ?? resolveDefaultFeishuAccountId(cfg);
|
|
1359
|
-
if (resolvedAccountId !== DEFAULT_ACCOUNT_ID$
|
|
1349
|
+
if (resolvedAccountId !== DEFAULT_ACCOUNT_ID$2) {
|
|
1360
1350
|
const account = feishuCfg?.accounts?.[resolvedAccountId];
|
|
1361
1351
|
if (account?.dmPolicy) return account.dmPolicy;
|
|
1362
1352
|
}
|
|
@@ -1381,7 +1371,7 @@ function applyNewAppSecurityPolicy(cfg, accountId, openId, groupPolicy) {
|
|
|
1381
1371
|
next = patchFeishuConfig(next, accountId, groupPatch);
|
|
1382
1372
|
return next;
|
|
1383
1373
|
}
|
|
1384
|
-
const loadAppRegistrationModule = createLazyRuntimeModule(() => import("./app-registration-
|
|
1374
|
+
const loadAppRegistrationModule = createLazyRuntimeModule(() => import("./app-registration-BzkyrVZu.js"));
|
|
1385
1375
|
async function promptFeishuDomain(params) {
|
|
1386
1376
|
return await params.prompter.select({
|
|
1387
1377
|
message: t("wizard.feishu.domainPrompt"),
|
|
@@ -1606,7 +1596,7 @@ const feishuSetupWizard = {
|
|
|
1606
1596
|
});
|
|
1607
1597
|
let probeResult = null;
|
|
1608
1598
|
if (configured && account.configured) try {
|
|
1609
|
-
const { probeFeishu } = await import("./probe-
|
|
1599
|
+
const { probeFeishu } = await import("./probe-BgboTHIn.js").then((n) => n.n);
|
|
1610
1600
|
probeResult = await probeFeishu(account);
|
|
1611
1601
|
} catch {}
|
|
1612
1602
|
if (!configured) return [formatFeishuStatusLine("needs-credentials")];
|
|
@@ -1642,11 +1632,7 @@ const feishuSetupWizard = {
|
|
|
1642
1632
|
});
|
|
1643
1633
|
},
|
|
1644
1634
|
dmPolicy: feishuDmPolicy,
|
|
1645
|
-
disable: (cfg) =>
|
|
1646
|
-
cfg,
|
|
1647
|
-
channel,
|
|
1648
|
-
patch: { enabled: false }
|
|
1649
|
-
})
|
|
1635
|
+
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
|
|
1650
1636
|
};
|
|
1651
1637
|
//#endregion
|
|
1652
1638
|
//#region extensions/feishu/src/channel.ts
|
|
@@ -1682,7 +1668,7 @@ const meta = {
|
|
|
1682
1668
|
order: 70,
|
|
1683
1669
|
preferSessionLookupForAnnounceTarget: true
|
|
1684
1670
|
};
|
|
1685
|
-
const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-
|
|
1671
|
+
const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CVIzo2dV.js"), "feishuChannelRuntime");
|
|
1686
1672
|
function toFeishuMessageSendResult(result, kind) {
|
|
1687
1673
|
const receipt = result.receipt ?? createFeishuSendReceipt({
|
|
1688
1674
|
messageId: result.messageId,
|
|
@@ -1726,7 +1712,7 @@ const feishuMessageAdapter = defineChannelMessageAdapter({
|
|
|
1726
1712
|
}
|
|
1727
1713
|
});
|
|
1728
1714
|
async function createFeishuActionClient(account) {
|
|
1729
|
-
const { createFeishuClient } = await import("./client-
|
|
1715
|
+
const { createFeishuClient } = await import("./client-87BmeMpj.js").then((n) => n.t);
|
|
1730
1716
|
return createFeishuClient(account);
|
|
1731
1717
|
}
|
|
1732
1718
|
async function resolveFeishuChatTypeById(params) {
|
|
@@ -2164,7 +2150,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2164
2150
|
config: {
|
|
2165
2151
|
...feishuConfigAdapter,
|
|
2166
2152
|
setAccountEnabled: ({ cfg, accountId, enabled }) => {
|
|
2167
|
-
if (accountId === DEFAULT_ACCOUNT_ID$
|
|
2153
|
+
if (accountId === DEFAULT_ACCOUNT_ID$3) return {
|
|
2168
2154
|
...cfg,
|
|
2169
2155
|
channels: {
|
|
2170
2156
|
...cfg.channels,
|
|
@@ -2177,7 +2163,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2177
2163
|
return setFeishuNamedAccountEnabled(cfg, accountId, enabled);
|
|
2178
2164
|
},
|
|
2179
2165
|
deleteAccount: ({ cfg, accountId }) => {
|
|
2180
|
-
if (accountId === DEFAULT_ACCOUNT_ID$
|
|
2166
|
+
if (accountId === DEFAULT_ACCOUNT_ID$3) {
|
|
2181
2167
|
const next = { ...cfg };
|
|
2182
2168
|
const nextChannels = { ...cfg.channels };
|
|
2183
2169
|
delete nextChannels.feishu;
|
|
@@ -2233,14 +2219,14 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2233
2219
|
if (ctx.action === "thread-reply" && !replyToMessageId) throw new Error("Feishu thread-reply requires messageId.");
|
|
2234
2220
|
const text = readFirstString(ctx.params, ["text", "message"]);
|
|
2235
2221
|
const textCard = readNativeFeishuCardJson(text, { responsePrefix: resolveFeishuMessageActionResponsePrefix(ctx) });
|
|
2236
|
-
const interactive =
|
|
2237
|
-
const presentation = normalizeMessagePresentation(ctx.params.presentation) ?? (interactive ?
|
|
2222
|
+
const interactive = normalizeLegacyInteractiveReply(ctx.params.interactive);
|
|
2223
|
+
const presentation = normalizeMessagePresentation(ctx.params.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
|
|
2238
2224
|
const mediaUrl = readFeishuMediaParam(ctx.params);
|
|
2239
2225
|
const audioAsVoice = readBooleanParam(ctx.params, ["asVoice", "audioAsVoice"]);
|
|
2240
2226
|
if (textCard && !presentation) assertFeishuCardWithinEnvelope(textCard, "Feishu native card");
|
|
2241
2227
|
const generatedCard = presentation ? buildFeishuPresentationCard({
|
|
2242
2228
|
presentation,
|
|
2243
|
-
fallbackText: textCard ? void 0 :
|
|
2229
|
+
fallbackText: textCard ? void 0 : resolveLegacyInteractiveTextFallback({
|
|
2244
2230
|
text,
|
|
2245
2231
|
interactive
|
|
2246
2232
|
})
|
|
@@ -2755,7 +2741,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2755
2741
|
})
|
|
2756
2742
|
}),
|
|
2757
2743
|
status: createComputedAccountStatusAdapter({
|
|
2758
|
-
defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$
|
|
2744
|
+
defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$3, { port: null }),
|
|
2759
2745
|
buildChannelSummary: ({ snapshot }) => buildProbeChannelStatusSummary(snapshot, { port: snapshot.port ?? null }),
|
|
2760
2746
|
probeAccount: async ({ account }) => await (await loadFeishuChannelRuntime()).probeFeishu(account),
|
|
2761
2747
|
resolveAccountSnapshot: ({ account, runtime }) => ({
|
|
@@ -2771,7 +2757,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2771
2757
|
})
|
|
2772
2758
|
}),
|
|
2773
2759
|
gateway: { startAccount: async (ctx) => {
|
|
2774
|
-
const { monitorFeishuProvider } = await import("./monitor-
|
|
2760
|
+
const { monitorFeishuProvider } = await import("./monitor-BVQf7-Bl.js");
|
|
2775
2761
|
const account = resolveFeishuRuntimeAccount({
|
|
2776
2762
|
cfg: ctx.cfg,
|
|
2777
2763
|
accountId: ctx.accountId
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as feishuPlugin } from "./channel-
|
|
1
|
+
import { t as feishuPlugin } from "./channel-BdnXYU6g.js";
|
|
2
2
|
export { feishuPlugin };
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, v as parseFeishuCommentTarget } from "./accounts-BDoGHJDk.js";
|
|
2
|
-
import { c as isFeishuCardWithinEnvelope, l as listFeishuDirectoryGroups, o as assertFeishuCardWithinEnvelope, s as buildFeishuPresentationCardElements, u as listFeishuDirectoryPeers } from "./channel-
|
|
3
|
-
import { a as readNativeFeishuCardJson, d as chunkFeishuPostMarkdown, f as materializeFeishuPostMarkdownSoftBreaks, o as resolveFeishuCardTemplate, s as sanitizeNativeFeishuCard, u as chunkFeishuMarkdown } from "./send-result-
|
|
4
|
-
import { r as createFeishuClient } from "./client-
|
|
5
|
-
import { c as buildFeishuDirectChatMembers, d as getFeishuMemberInfo, l as getChatInfo, r as cleanupAmbientCommentTypingReaction, s as assertFeishuChatMember, t as deliverCommentThreadText, u as getChatMembers } from "./drive-
|
|
6
|
-
import { a as sendMarkdownCardFeishu, h as shouldSuppressFeishuTextForVoiceMedia, i as sendCardFeishu, m as sendMediaFeishu, n as getMessageFeishu, o as sendMessageFeishu, s as sendStructuredCardFeishu, t as editMessageFeishu,
|
|
7
|
-
import { t as probeFeishu } from "./probe-
|
|
2
|
+
import { c as isFeishuCardWithinEnvelope, l as listFeishuDirectoryGroups, o as assertFeishuCardWithinEnvelope, s as buildFeishuPresentationCardElements, u as listFeishuDirectoryPeers } from "./channel-BdnXYU6g.js";
|
|
3
|
+
import { a as readNativeFeishuCardJson, d as chunkFeishuPostMarkdown, f as materializeFeishuPostMarkdownSoftBreaks, o as resolveFeishuCardTemplate, s as sanitizeNativeFeishuCard, u as chunkFeishuMarkdown } from "./send-result-DfE5Fhz6.js";
|
|
4
|
+
import { r as createFeishuClient } from "./client-87BmeMpj.js";
|
|
5
|
+
import { c as buildFeishuDirectChatMembers, d as getFeishuMemberInfo, l as getChatInfo, r as cleanupAmbientCommentTypingReaction, s as assertFeishuChatMember, t as deliverCommentThreadText, u as getChatMembers } from "./drive-BHv8WW9i.js";
|
|
6
|
+
import { _ as buildFeishuMediaFallbackText, a as sendMarkdownCardFeishu, h as shouldSuppressFeishuTextForVoiceMedia, i as sendCardFeishu, m as sendMediaFeishu, n as getMessageFeishu, o as sendMessageFeishu, s as sendStructuredCardFeishu, t as editMessageFeishu, y as resolveFeishuIdentityHeaderTitle } from "./send-DcrXbqqA.js";
|
|
7
|
+
import { t as probeFeishu } from "./probe-BgboTHIn.js";
|
|
8
8
|
import { createReplyToFanout } from "openclaw/plugin-sdk/channel-outbound";
|
|
9
|
-
import {
|
|
9
|
+
import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
|
|
10
10
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
11
11
|
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
|
|
14
14
|
import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
|
|
15
15
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
16
|
-
import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
|
|
16
|
+
import { getReplyPayloadTtsSupplement, resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
|
|
17
17
|
import { statRegularFileSync } from "openclaw/plugin-sdk/security-runtime";
|
|
18
18
|
//#region extensions/feishu/src/directory.ts
|
|
19
19
|
const MAX_FEISHU_DIRECTORY_PAGES = 100;
|
|
@@ -167,14 +167,14 @@ function buildFeishuPayloadCard(params) {
|
|
|
167
167
|
}
|
|
168
168
|
const rawText = params.text ?? params.payload.text;
|
|
169
169
|
const textCard = readNativeFeishuCardJson(rawText);
|
|
170
|
-
const interactive =
|
|
171
|
-
const presentation = normalizeMessagePresentation(params.payload.presentation) ?? (interactive ?
|
|
170
|
+
const interactive = normalizeLegacyInteractiveReply(params.payload.interactive);
|
|
171
|
+
const presentation = normalizeMessagePresentation(params.payload.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
|
|
172
172
|
if (!presentation && !interactive) {
|
|
173
173
|
if (!textCard) return;
|
|
174
174
|
assertFeishuCardWithinEnvelope(textCard, "Feishu native card");
|
|
175
175
|
return markRenderedFeishuCard(textCard);
|
|
176
176
|
}
|
|
177
|
-
const text = textCard ? void 0 :
|
|
177
|
+
const text = textCard ? void 0 : resolveLegacyInteractiveTextFallback({
|
|
178
178
|
text: rawText,
|
|
179
179
|
interactive
|
|
180
180
|
});
|
|
@@ -393,6 +393,51 @@ async function sendFeishuFallbackPayload(params) {
|
|
|
393
393
|
}
|
|
394
394
|
return lastResult;
|
|
395
395
|
}
|
|
396
|
+
async function sendFeishuTtsSupplementPayload(params) {
|
|
397
|
+
const sendMedia = feishuOutbound.sendMedia;
|
|
398
|
+
const sendText = feishuOutbound.sendText;
|
|
399
|
+
if (!sendMedia || !sendText) throw new Error("Feishu TTS supplement delivery is not available.");
|
|
400
|
+
const { normalizedReplyToId } = resolveFeishuReplyMode({
|
|
401
|
+
replyToId: params.ctx.replyToId,
|
|
402
|
+
threadId: params.ctx.threadId
|
|
403
|
+
});
|
|
404
|
+
const nextReplyToId = createReplyToFanout({
|
|
405
|
+
replyToId: normalizedReplyToId,
|
|
406
|
+
replyToIdSource: params.ctx.replyToIdSource,
|
|
407
|
+
replyToMode: params.ctx.replyToMode
|
|
408
|
+
});
|
|
409
|
+
const ctx = {
|
|
410
|
+
...params.ctx,
|
|
411
|
+
payload: params.payload
|
|
412
|
+
};
|
|
413
|
+
let lastResult;
|
|
414
|
+
if (params.sendVisiblePayload) {
|
|
415
|
+
lastResult = await params.sendVisiblePayload(nextReplyToId());
|
|
416
|
+
await ctx.onDeliveryResult?.(lastResult);
|
|
417
|
+
} else if (params.supplement.visibleTextAlreadyDelivered !== true) {
|
|
418
|
+
const text = params.payload.text?.trim() ? params.payload.text : params.supplement.spokenText;
|
|
419
|
+
for (const chunk of chunkFeishuMarkdown(text, FEISHU_TEXT_CHUNK_LIMIT)) {
|
|
420
|
+
lastResult = await sendText({
|
|
421
|
+
...ctx,
|
|
422
|
+
text: chunk,
|
|
423
|
+
replyToId: nextReplyToId(),
|
|
424
|
+
onDeliveryResult: void 0
|
|
425
|
+
});
|
|
426
|
+
await ctx.onDeliveryResult?.(lastResult);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
for (const mediaUrl of normalizeStringEntries(resolvePayloadMediaUrls(params.payload))) lastResult = await sendMedia({
|
|
430
|
+
...ctx,
|
|
431
|
+
text: "",
|
|
432
|
+
mediaUrl,
|
|
433
|
+
replyToId: nextReplyToId(),
|
|
434
|
+
audioAsVoice: params.payload.audioAsVoice ?? ctx.audioAsVoice
|
|
435
|
+
});
|
|
436
|
+
return lastResult ?? {
|
|
437
|
+
channel: "feishu",
|
|
438
|
+
messageId: ""
|
|
439
|
+
};
|
|
440
|
+
}
|
|
396
441
|
const feishuOutbound = {
|
|
397
442
|
deliveryMode: "direct",
|
|
398
443
|
chunker: chunkFeishuMarkdown,
|
|
@@ -421,9 +466,10 @@ const feishuOutbound = {
|
|
|
421
466
|
renderPresentation: renderFeishuPresentationPayload,
|
|
422
467
|
sendPayload: async (ctx) => {
|
|
423
468
|
const { payload, presentationFallback } = consumeFeishuPresentationFallbackMarker(ctx.payload);
|
|
469
|
+
const ttsSupplement = getReplyPayloadTtsSupplement(payload);
|
|
424
470
|
if (parseFeishuCommentTarget(ctx.to)) {
|
|
425
|
-
const interactive =
|
|
426
|
-
const normalizedPresentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ?
|
|
471
|
+
const interactive = normalizeLegacyInteractiveReply(payload.interactive);
|
|
472
|
+
const normalizedPresentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
|
|
427
473
|
const textCard = readNativeFeishuCardJson(payload.text);
|
|
428
474
|
const presentationFallbackText = renderMessagePresentationFallbackText({
|
|
429
475
|
text: textCard ? void 0 : payload.text,
|
|
@@ -450,8 +496,13 @@ const feishuOutbound = {
|
|
|
450
496
|
identity: ctx.identity
|
|
451
497
|
});
|
|
452
498
|
if (!card) {
|
|
453
|
-
|
|
454
|
-
|
|
499
|
+
if (ttsSupplement) return await sendFeishuTtsSupplementPayload({
|
|
500
|
+
ctx,
|
|
501
|
+
payload,
|
|
502
|
+
supplement: ttsSupplement
|
|
503
|
+
});
|
|
504
|
+
const interactive = normalizeLegacyInteractiveReply(payload.interactive);
|
|
505
|
+
const presentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
|
|
455
506
|
return await sendFeishuFallbackPayload({
|
|
456
507
|
ctx,
|
|
457
508
|
payload: presentation ? {
|
|
@@ -466,6 +517,25 @@ const feishuOutbound = {
|
|
|
466
517
|
separateMediaAndText: presentationFallback || presentation !== void 0
|
|
467
518
|
});
|
|
468
519
|
}
|
|
520
|
+
if (ttsSupplement) return await sendFeishuTtsSupplementPayload({
|
|
521
|
+
ctx,
|
|
522
|
+
payload,
|
|
523
|
+
supplement: ttsSupplement,
|
|
524
|
+
sendVisiblePayload: async (replyToId) => {
|
|
525
|
+
const { replyToMessageId, replyInThread } = resolveFeishuReplyMode({
|
|
526
|
+
replyToId,
|
|
527
|
+
threadId: ctx.threadId
|
|
528
|
+
});
|
|
529
|
+
return attachChannelToResult("feishu", await sendCardFeishu({
|
|
530
|
+
cfg: ctx.cfg,
|
|
531
|
+
to: ctx.to,
|
|
532
|
+
card,
|
|
533
|
+
replyToMessageId,
|
|
534
|
+
replyInThread,
|
|
535
|
+
accountId: ctx.accountId ?? void 0
|
|
536
|
+
}));
|
|
537
|
+
}
|
|
538
|
+
});
|
|
469
539
|
const { normalizedReplyToId } = resolveFeishuReplyMode({
|
|
470
540
|
replyToId: ctx.replyToId,
|
|
471
541
|
threadId: ctx.threadId
|
|
@@ -532,6 +602,14 @@ const feishuOutbound = {
|
|
|
532
602
|
});
|
|
533
603
|
} catch (err) {
|
|
534
604
|
console.error(`[feishu] local image path auto-send failed:`, err);
|
|
605
|
+
return await sendOutboundText({
|
|
606
|
+
cfg,
|
|
607
|
+
to,
|
|
608
|
+
text: await buildFeishuMediaFallbackText({}),
|
|
609
|
+
accountId: accountId ?? void 0,
|
|
610
|
+
replyToMessageId,
|
|
611
|
+
replyInThread
|
|
612
|
+
});
|
|
535
613
|
}
|
|
536
614
|
if (parseFeishuCommentTarget(to)) return await sendOutboundText({
|
|
537
615
|
cfg,
|
|
@@ -589,7 +667,11 @@ const feishuOutbound = {
|
|
|
589
667
|
if (parseFeishuCommentTarget(to)) return await sendOutboundText({
|
|
590
668
|
cfg,
|
|
591
669
|
to,
|
|
592
|
-
text:
|
|
670
|
+
text: mediaUrl?.trim() ? await buildFeishuMediaFallbackText({
|
|
671
|
+
text,
|
|
672
|
+
mediaUrl,
|
|
673
|
+
mediaLinkStyle: "plain"
|
|
674
|
+
}) : text?.trim() ?? "",
|
|
593
675
|
accountId: accountId ?? void 0,
|
|
594
676
|
replyToMessageId,
|
|
595
677
|
replyInThread
|
|
@@ -632,7 +714,10 @@ const feishuOutbound = {
|
|
|
632
714
|
const fallbackResult = await sendOutboundText({
|
|
633
715
|
cfg,
|
|
634
716
|
to,
|
|
635
|
-
text:
|
|
717
|
+
text: await buildFeishuMediaFallbackText({
|
|
718
|
+
text: textSent ? void 0 : text,
|
|
719
|
+
mediaUrl
|
|
720
|
+
}),
|
|
636
721
|
accountId: accountId ?? void 0,
|
|
637
722
|
replyToMessageId,
|
|
638
723
|
replyInThread
|
|
@@ -62,8 +62,28 @@ function setRequestUserAgent(req) {
|
|
|
62
62
|
return req;
|
|
63
63
|
}
|
|
64
64
|
Lark.defaultHttpInstance.interceptors?.request?.use(setRequestUserAgent);
|
|
65
|
-
|
|
66
|
-
return
|
|
65
|
+
function isManagedProxyActive() {
|
|
66
|
+
return process.env["OPENCLAW_PROXY_ACTIVE"] === "1";
|
|
67
|
+
}
|
|
68
|
+
let cachedFeishuProxyAgent;
|
|
69
|
+
let pendingFeishuProxyAgent;
|
|
70
|
+
async function getFeishuProxyAgent() {
|
|
71
|
+
if (cachedFeishuProxyAgent) return cachedFeishuProxyAgent;
|
|
72
|
+
if (pendingFeishuProxyAgent) return pendingFeishuProxyAgent;
|
|
73
|
+
let resolutionError;
|
|
74
|
+
const pending = resolveAmbientNodeProxyAgent({ onError: (error) => {
|
|
75
|
+
resolutionError = error;
|
|
76
|
+
} }).then((agent) => {
|
|
77
|
+
if (!agent && isManagedProxyActive()) throw new Error("Feishu managed proxy is active but no proxy agent could be created", { cause: resolutionError });
|
|
78
|
+
cachedFeishuProxyAgent = agent;
|
|
79
|
+
return agent;
|
|
80
|
+
});
|
|
81
|
+
pendingFeishuProxyAgent = pending;
|
|
82
|
+
try {
|
|
83
|
+
return await pending;
|
|
84
|
+
} finally {
|
|
85
|
+
if (pendingFeishuProxyAgent === pending) pendingFeishuProxyAgent = void 0;
|
|
86
|
+
}
|
|
67
87
|
}
|
|
68
88
|
const clientCache = /* @__PURE__ */ new Map();
|
|
69
89
|
function resolveDomain(domain) {
|
|
@@ -74,25 +94,38 @@ function resolveDomain(domain) {
|
|
|
74
94
|
/**
|
|
75
95
|
* Create an HTTP instance that delegates to the Lark SDK's default instance
|
|
76
96
|
* but injects a default request timeout and User-Agent header to prevent
|
|
77
|
-
* indefinite hangs
|
|
97
|
+
* indefinite hangs, set a standardized User-Agent per OAPI best practices, and
|
|
98
|
+
* keep axios from taking a separate ambient proxy path for HTTPS requests.
|
|
78
99
|
*/
|
|
79
|
-
function
|
|
100
|
+
function createFeishuHttpInstance(defaultTimeoutMs) {
|
|
80
101
|
const base = feishuClientSdk.defaultHttpInstance;
|
|
81
|
-
function
|
|
82
|
-
|
|
102
|
+
async function injectRequestOptions(opts) {
|
|
103
|
+
const next = {
|
|
83
104
|
timeout: defaultTimeoutMs,
|
|
84
105
|
...opts
|
|
85
106
|
};
|
|
107
|
+
const agent = await getFeishuProxyAgent();
|
|
108
|
+
if (agent) {
|
|
109
|
+
if (isManagedProxyActive()) {
|
|
110
|
+
next.httpAgent = agent;
|
|
111
|
+
next.httpsAgent = agent;
|
|
112
|
+
} else {
|
|
113
|
+
next.httpAgent ??= agent;
|
|
114
|
+
next.httpsAgent ??= agent;
|
|
115
|
+
}
|
|
116
|
+
next.proxy = false;
|
|
117
|
+
}
|
|
118
|
+
return next;
|
|
86
119
|
}
|
|
87
120
|
return {
|
|
88
|
-
request: (opts) => base.request(
|
|
89
|
-
get: (url, opts) => base.get(url,
|
|
90
|
-
post: (url, data, opts) => base.post(url, data,
|
|
91
|
-
put: (url, data, opts) => base.put(url, data,
|
|
92
|
-
patch: (url, data, opts) => base.patch(url, data,
|
|
93
|
-
delete: (url, opts) => base.delete(url,
|
|
94
|
-
head: (url, opts) => base.head(url,
|
|
95
|
-
options: (url, opts) => base.options(url,
|
|
121
|
+
request: async (opts) => base.request(await injectRequestOptions(opts)),
|
|
122
|
+
get: async (url, opts) => base.get(url, await injectRequestOptions(opts)),
|
|
123
|
+
post: async (url, data, opts) => base.post(url, data, await injectRequestOptions(opts)),
|
|
124
|
+
put: async (url, data, opts) => base.put(url, data, await injectRequestOptions(opts)),
|
|
125
|
+
patch: async (url, data, opts) => base.patch(url, data, await injectRequestOptions(opts)),
|
|
126
|
+
delete: async (url, opts) => base.delete(url, await injectRequestOptions(opts)),
|
|
127
|
+
head: async (url, opts) => base.head(url, await injectRequestOptions(opts)),
|
|
128
|
+
options: async (url, opts) => base.options(url, await injectRequestOptions(opts))
|
|
96
129
|
};
|
|
97
130
|
}
|
|
98
131
|
/**
|
|
@@ -110,7 +143,7 @@ function createFeishuClient(creds) {
|
|
|
110
143
|
appSecret,
|
|
111
144
|
appType: feishuClientSdk.AppType.SelfBuild,
|
|
112
145
|
domain: resolveDomain(domain),
|
|
113
|
-
httpInstance:
|
|
146
|
+
httpInstance: createFeishuHttpInstance(defaultHttpTimeoutMs)
|
|
114
147
|
});
|
|
115
148
|
clientCache.set(accountId, {
|
|
116
149
|
client,
|
|
@@ -130,11 +163,13 @@ function createFeishuClient(creds) {
|
|
|
130
163
|
async function createFeishuWSClient(account, callbacks = {}) {
|
|
131
164
|
const { accountId, appId, appSecret, domain } = account;
|
|
132
165
|
if (!appId || !appSecret) throw new Error(`Feishu credentials not configured for account "${accountId}"`);
|
|
133
|
-
const agent = await
|
|
166
|
+
const agent = await getFeishuProxyAgent();
|
|
167
|
+
const defaultHttpTimeoutMs = resolveConfiguredHttpTimeoutMs(account);
|
|
134
168
|
return new feishuClientSdk.WSClient({
|
|
135
169
|
appId,
|
|
136
170
|
appSecret,
|
|
137
171
|
domain: resolveDomain(domain),
|
|
172
|
+
httpInstance: createFeishuHttpInstance(defaultHttpTimeoutMs),
|
|
138
173
|
...callbacks,
|
|
139
174
|
loggerLevel: feishuClientSdk.LoggerLevel.info,
|
|
140
175
|
wsConfig: FEISHU_WS_CONFIG,
|