@xwang152/claw-lark 0.1.24 → 0.1.26
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/index.d.ts +6 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/src/policy.d.ts +84 -0
- package/dist/src/policy.js +137 -0
- package/dist/src/policy.js.map +1 -0
- package/dist/src/probe.d.ts +24 -0
- package/dist/src/probe.js +52 -0
- package/dist/src/probe.js.map +1 -0
- package/dist/src/types.d.ts +15 -0
- package/dist/src/utils.d.ts +32 -0
- package/dist/src/utils.js +96 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -19,7 +19,12 @@ export { addTypingIndicator, removeTypingIndicator, createTypingController, } fr
|
|
|
19
19
|
export type { TypingIndicatorState } from "./src/typing.js";
|
|
20
20
|
export { resolveLarkSenderName, clearSenderNameCache, getSenderNameCacheStats, prefetchLarkSenderNames, } from "./src/sender-name.js";
|
|
21
21
|
export { getLarkMessage, formatQuotedContext, isReplyMessage, buildMessageContextWithQuote, } from "./src/message-context.js";
|
|
22
|
-
export type { LarkDomain, LarkConnectionMode, LarkAccountConfig, ResolvedLarkAccount, LarkChannelConfig, LarkMessageEvent, ParsedMessage, SendResult, } from "./src/types.js";
|
|
22
|
+
export type { LarkDomain, LarkConnectionMode, DmPolicy, GroupPolicy, RenderMode, LarkAccountConfig, ResolvedLarkAccount, LarkChannelConfig, LarkGroupConfig, LarkMessageEvent, LarkMention, ParsedMessage, SendResult, } from "./src/types.js";
|
|
23
|
+
export { resolveLarkAllowlistMatch, resolveLarkGroupConfig, resolveLarkGroupToolPolicy, isLarkGroupAllowed, resolveLarkGroupRequireMention, resolveLarkReplyToMode, } from "./src/policy.js";
|
|
24
|
+
export { detectLarkIdType, normalizeLarkTarget, formatLarkTarget, inferReceiveIdType, looksLikeLarkId, } from "./src/utils.js";
|
|
25
|
+
export type { LarkIdType } from "./src/utils.js";
|
|
26
|
+
export { probeLark } from "./src/probe.js";
|
|
27
|
+
export type { LarkProbeResult } from "./src/probe.js";
|
|
23
28
|
declare const plugin: {
|
|
24
29
|
id: string;
|
|
25
30
|
name: string;
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,9 @@ export { extractMentionTargets, extractMessageBody, isMentionForwardRequest, for
|
|
|
22
22
|
export { addTypingIndicator, removeTypingIndicator, createTypingController, } from "./src/typing.js";
|
|
23
23
|
export { resolveLarkSenderName, clearSenderNameCache, getSenderNameCacheStats, prefetchLarkSenderNames, } from "./src/sender-name.js";
|
|
24
24
|
export { getLarkMessage, formatQuotedContext, isReplyMessage, buildMessageContextWithQuote, } from "./src/message-context.js";
|
|
25
|
+
export { resolveLarkAllowlistMatch, resolveLarkGroupConfig, resolveLarkGroupToolPolicy, isLarkGroupAllowed, resolveLarkGroupRequireMention, resolveLarkReplyToMode, } from "./src/policy.js";
|
|
26
|
+
export { detectLarkIdType, normalizeLarkTarget, formatLarkTarget, inferReceiveIdType, looksLikeLarkId, } from "./src/utils.js";
|
|
27
|
+
export { probeLark } from "./src/probe.js";
|
|
25
28
|
const plugin = {
|
|
26
29
|
id: "claw-lark",
|
|
27
30
|
name: "Lark",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,mCAAmC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,mCAAmC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAgBlC,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,MAAM,MAAM,GAAG;IACb,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,uBAAuB,EAAE;IACvC,QAAQ,CAAC,GAAsB;QAC7B,cAAc,CAAC,GAAG,CAAC,CAAC;QACpB,wCAAwC;QACxC,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAC5C,GAAG,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IAC3C,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group-level Policy and Access Control
|
|
3
|
+
*
|
|
4
|
+
* Handles per-group configuration for Lark/Feishu integration.
|
|
5
|
+
* Supports group-specific tool policies, mention requirements, and access control.
|
|
6
|
+
*/
|
|
7
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
|
8
|
+
import type { LarkGroupConfig } from "./types.js";
|
|
9
|
+
export type LarkAllowlistMatch = {
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
matchKey?: string;
|
|
12
|
+
matchSource?: "wildcard" | "id" | "name";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Resolve allowlist match for a sender.
|
|
16
|
+
*
|
|
17
|
+
* Checks if a sender is allowed based on allowlist configuration.
|
|
18
|
+
* Supports wildcards, IDs, and names.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveLarkAllowlistMatch(params: {
|
|
21
|
+
allowFrom: Array<string | number>;
|
|
22
|
+
senderId: string;
|
|
23
|
+
senderName?: string | null;
|
|
24
|
+
}): LarkAllowlistMatch;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve group configuration for a specific group.
|
|
27
|
+
*
|
|
28
|
+
* Looks up group-specific settings from the configuration.
|
|
29
|
+
* Supports case-insensitive group ID matching.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveLarkGroupConfig(params: {
|
|
32
|
+
cfg?: OpenClawConfig;
|
|
33
|
+
groupId?: string | null;
|
|
34
|
+
accountId?: string;
|
|
35
|
+
}): LarkGroupConfig | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve group tool policy for agent tool access control.
|
|
38
|
+
*
|
|
39
|
+
* Returns the tools configuration for a specific group.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveLarkGroupToolPolicy(params: {
|
|
42
|
+
cfg?: OpenClawConfig;
|
|
43
|
+
groupId?: string | null;
|
|
44
|
+
accountId?: string;
|
|
45
|
+
}): {
|
|
46
|
+
allow?: string[];
|
|
47
|
+
deny?: string[];
|
|
48
|
+
} | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a group is allowed based on policy.
|
|
51
|
+
*
|
|
52
|
+
* @param groupPolicy - "open" | "allowlist" | "disabled"
|
|
53
|
+
* @param allowFrom - Allowlist configuration
|
|
54
|
+
* @param senderId - Sender's ID
|
|
55
|
+
* @param senderName - Sender's display name (optional)
|
|
56
|
+
*/
|
|
57
|
+
export declare function isLarkGroupAllowed(params: {
|
|
58
|
+
groupPolicy: "open" | "allowlist" | "disabled";
|
|
59
|
+
allowFrom: Array<string | number>;
|
|
60
|
+
senderId: string;
|
|
61
|
+
senderName?: string | null;
|
|
62
|
+
}): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Resolve mention requirement for a group.
|
|
65
|
+
*
|
|
66
|
+
* Determines if @mention is required in a group based on
|
|
67
|
+
* group configuration or global default.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveLarkGroupRequireMention(params: {
|
|
70
|
+
cfg?: OpenClawConfig;
|
|
71
|
+
groupId?: string | null;
|
|
72
|
+
accountId?: string;
|
|
73
|
+
groupConfig?: LarkGroupConfig;
|
|
74
|
+
}): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Resolve reply-to mode for a group.
|
|
77
|
+
*
|
|
78
|
+
* Determines how replies should be threaded in a group chat.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveLarkReplyToMode(params: {
|
|
81
|
+
cfg?: OpenClawConfig;
|
|
82
|
+
groupId?: string | null;
|
|
83
|
+
accountId?: string;
|
|
84
|
+
}): "first" | "last" | "off";
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group-level Policy and Access Control
|
|
3
|
+
*
|
|
4
|
+
* Handles per-group configuration for Lark/Feishu integration.
|
|
5
|
+
* Supports group-specific tool policies, mention requirements, and access control.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Extract Lark channel config from OpenClaw config
|
|
9
|
+
*/
|
|
10
|
+
function getChannelConfig(cfg) {
|
|
11
|
+
return cfg.channels?.lark ?? {};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolve allowlist match for a sender.
|
|
15
|
+
*
|
|
16
|
+
* Checks if a sender is allowed based on allowlist configuration.
|
|
17
|
+
* Supports wildcards, IDs, and names.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveLarkAllowlistMatch(params) {
|
|
20
|
+
const allowFrom = params.allowFrom
|
|
21
|
+
.map((entry) => String(entry).trim().toLowerCase())
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
if (allowFrom.length === 0)
|
|
24
|
+
return { allowed: false };
|
|
25
|
+
if (allowFrom.includes("*")) {
|
|
26
|
+
return { allowed: true, matchKey: "*", matchSource: "wildcard" };
|
|
27
|
+
}
|
|
28
|
+
const senderId = params.senderId.toLowerCase();
|
|
29
|
+
if (allowFrom.includes(senderId)) {
|
|
30
|
+
return { allowed: true, matchKey: senderId, matchSource: "id" };
|
|
31
|
+
}
|
|
32
|
+
const senderName = params.senderName?.toLowerCase();
|
|
33
|
+
if (senderName && allowFrom.includes(senderName)) {
|
|
34
|
+
return { allowed: true, matchKey: senderName, matchSource: "name" };
|
|
35
|
+
}
|
|
36
|
+
return { allowed: false };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve group configuration for a specific group.
|
|
40
|
+
*
|
|
41
|
+
* Looks up group-specific settings from the configuration.
|
|
42
|
+
* Supports case-insensitive group ID matching.
|
|
43
|
+
*/
|
|
44
|
+
export function resolveLarkGroupConfig(params) {
|
|
45
|
+
const channelConfig = getChannelConfig(params.cfg ?? {});
|
|
46
|
+
const groupId = params.groupId?.trim();
|
|
47
|
+
const accountId = params.accountId ?? "default";
|
|
48
|
+
if (!groupId)
|
|
49
|
+
return undefined;
|
|
50
|
+
// First check account-level groups configuration
|
|
51
|
+
const accountConfig = channelConfig.accounts?.[accountId];
|
|
52
|
+
if (accountConfig?.groups) {
|
|
53
|
+
const direct = accountConfig.groups[groupId];
|
|
54
|
+
if (direct)
|
|
55
|
+
return direct;
|
|
56
|
+
// Try case-insensitive match
|
|
57
|
+
const lowered = groupId.toLowerCase();
|
|
58
|
+
const matchKey = Object.keys(accountConfig.groups).find((key) => key.toLowerCase() === lowered);
|
|
59
|
+
if (matchKey) {
|
|
60
|
+
return accountConfig.groups[matchKey];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Then check channel-level groups configuration
|
|
64
|
+
if (channelConfig.groups) {
|
|
65
|
+
const direct = channelConfig.groups[groupId];
|
|
66
|
+
if (direct)
|
|
67
|
+
return direct;
|
|
68
|
+
// Try case-insensitive match
|
|
69
|
+
const lowered = groupId.toLowerCase();
|
|
70
|
+
const matchKey = Object.keys(channelConfig.groups).find((key) => key.toLowerCase() === lowered);
|
|
71
|
+
if (matchKey) {
|
|
72
|
+
return channelConfig.groups[matchKey];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolve group tool policy for agent tool access control.
|
|
79
|
+
*
|
|
80
|
+
* Returns the tools configuration for a specific group.
|
|
81
|
+
*/
|
|
82
|
+
export function resolveLarkGroupToolPolicy(params) {
|
|
83
|
+
const groupConfig = resolveLarkGroupConfig(params);
|
|
84
|
+
return groupConfig?.tools;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if a group is allowed based on policy.
|
|
88
|
+
*
|
|
89
|
+
* @param groupPolicy - "open" | "allowlist" | "disabled"
|
|
90
|
+
* @param allowFrom - Allowlist configuration
|
|
91
|
+
* @param senderId - Sender's ID
|
|
92
|
+
* @param senderName - Sender's display name (optional)
|
|
93
|
+
*/
|
|
94
|
+
export function isLarkGroupAllowed(params) {
|
|
95
|
+
const { groupPolicy, allowFrom, senderId, senderName } = params;
|
|
96
|
+
if (groupPolicy === "disabled")
|
|
97
|
+
return false;
|
|
98
|
+
if (groupPolicy === "open")
|
|
99
|
+
return true;
|
|
100
|
+
return resolveLarkAllowlistMatch({
|
|
101
|
+
allowFrom,
|
|
102
|
+
senderId,
|
|
103
|
+
senderName,
|
|
104
|
+
}).allowed;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Resolve mention requirement for a group.
|
|
108
|
+
*
|
|
109
|
+
* Determines if @mention is required in a group based on
|
|
110
|
+
* group configuration or global default.
|
|
111
|
+
*/
|
|
112
|
+
export function resolveLarkGroupRequireMention(params) {
|
|
113
|
+
// If explicit group config is provided, use it
|
|
114
|
+
if (params.groupConfig) {
|
|
115
|
+
return params.groupConfig.requireMention ?? true;
|
|
116
|
+
}
|
|
117
|
+
// Otherwise, resolve from config
|
|
118
|
+
const groupConfig = resolveLarkGroupConfig(params);
|
|
119
|
+
if (groupConfig) {
|
|
120
|
+
return groupConfig.requireMention ?? true;
|
|
121
|
+
}
|
|
122
|
+
// Fall back to channel/account default
|
|
123
|
+
const channelConfig = getChannelConfig(params.cfg ?? {});
|
|
124
|
+
const accountId = params.accountId ?? "default";
|
|
125
|
+
const accountConfig = channelConfig.accounts?.[accountId];
|
|
126
|
+
return accountConfig?.requireMention ?? true;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Resolve reply-to mode for a group.
|
|
130
|
+
*
|
|
131
|
+
* Determines how replies should be threaded in a group chat.
|
|
132
|
+
*/
|
|
133
|
+
export function resolveLarkReplyToMode(params) {
|
|
134
|
+
const groupConfig = resolveLarkGroupConfig(params);
|
|
135
|
+
return groupConfig?.replyToMode ?? "first";
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark/Feishu Connection Probe
|
|
3
|
+
*
|
|
4
|
+
* Tests connectivity and retrieves bot information.
|
|
5
|
+
* Useful for configuration verification and debugging.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResolvedLarkAccount } from "./types.js";
|
|
8
|
+
export type LarkProbeResult = {
|
|
9
|
+
ok: true;
|
|
10
|
+
appId: string;
|
|
11
|
+
botName?: string;
|
|
12
|
+
botOpenId?: string;
|
|
13
|
+
} | {
|
|
14
|
+
ok: false;
|
|
15
|
+
appId?: string;
|
|
16
|
+
error: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Probe Lark/Feishu API to verify credentials and get bot info.
|
|
20
|
+
*
|
|
21
|
+
* @param account - The Lark account to test
|
|
22
|
+
* @returns Probe result with bot info if successful
|
|
23
|
+
*/
|
|
24
|
+
export declare function probeLark(account: ResolvedLarkAccount): Promise<LarkProbeResult>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark/Feishu Connection Probe
|
|
3
|
+
*
|
|
4
|
+
* Tests connectivity and retrieves bot information.
|
|
5
|
+
* Useful for configuration verification and debugging.
|
|
6
|
+
*/
|
|
7
|
+
import { createLarkClient } from "./client.js";
|
|
8
|
+
/**
|
|
9
|
+
* Probe Lark/Feishu API to verify credentials and get bot info.
|
|
10
|
+
*
|
|
11
|
+
* @param account - The Lark account to test
|
|
12
|
+
* @returns Probe result with bot info if successful
|
|
13
|
+
*/
|
|
14
|
+
export async function probeLark(account) {
|
|
15
|
+
if (!account.appId || !account.appSecret) {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
error: "missing credentials (appId, appSecret)",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const client = createLarkClient(account);
|
|
23
|
+
// Use bot info API to test connectivity
|
|
24
|
+
const response = await client.request({
|
|
25
|
+
method: "GET",
|
|
26
|
+
url: "/open-apis/bot/v3/info",
|
|
27
|
+
data: {},
|
|
28
|
+
});
|
|
29
|
+
if (response.code !== 0) {
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
appId: account.appId,
|
|
33
|
+
error: `API error: ${response.msg || `code ${response.code}`}`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const bot = response.bot || response.data?.bot;
|
|
37
|
+
return {
|
|
38
|
+
ok: true,
|
|
39
|
+
appId: account.appId,
|
|
40
|
+
botName: bot?.bot_name,
|
|
41
|
+
botOpenId: bot?.open_id,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return {
|
|
46
|
+
ok: false,
|
|
47
|
+
appId: account.appId,
|
|
48
|
+
error: err instanceof Error ? err.message : String(err),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/probe.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAe/C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAA4B;IAC1D,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACzC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,wCAAwC;SAChD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEzC,wCAAwC;QACxC,MAAM,QAAQ,GAAG,MAAO,MAAc,CAAC,OAAO,CAAC;YAC7C,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,wBAAwB;YAC7B,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,cAAc,QAAQ,CAAC,GAAG,IAAI,QAAQ,QAAQ,CAAC,IAAI,EAAE,EAAE;aAC/D,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;QAC/C,OAAO;YACL,EAAE,EAAE,IAAI;YACR,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,GAAG,EAAE,QAAQ;YACtB,SAAS,EAAE,GAAG,EAAE,OAAO;SACxB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export interface LarkAccountConfig {
|
|
|
30
30
|
mediaMaxMb?: number;
|
|
31
31
|
renderMode?: RenderMode;
|
|
32
32
|
historyLimit?: number;
|
|
33
|
+
groups?: Record<string, LarkGroupConfig>;
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
36
|
* Fully resolved account with all defaults applied.
|
|
@@ -61,6 +62,20 @@ export interface ResolvedLarkAccount {
|
|
|
61
62
|
export interface LarkChannelConfig {
|
|
62
63
|
enabled?: boolean;
|
|
63
64
|
accounts?: Record<string, LarkAccountConfig>;
|
|
65
|
+
groups?: Record<string, LarkGroupConfig>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Group-level configuration for specific Lark groups
|
|
69
|
+
*/
|
|
70
|
+
export interface LarkGroupConfig {
|
|
71
|
+
enabled?: boolean;
|
|
72
|
+
requireMention?: boolean;
|
|
73
|
+
replyToMode?: "first" | "last" | "off";
|
|
74
|
+
tools?: {
|
|
75
|
+
allow?: string[];
|
|
76
|
+
deny?: string[];
|
|
77
|
+
};
|
|
78
|
+
allowFrom?: string[];
|
|
64
79
|
}
|
|
65
80
|
/**
|
|
66
81
|
* Lark message event payload from im.message.receive_v1
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark/Feishu Target Utilities
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for ID detection, normalization, and type inference.
|
|
5
|
+
* Used across the plugin for consistent ID handling.
|
|
6
|
+
*/
|
|
7
|
+
export type LarkIdType = "chat_id" | "open_id" | "union_id" | "user_id";
|
|
8
|
+
/**
|
|
9
|
+
* Detect the type of a Lark ID from its format.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectLarkIdType(id: string): LarkIdType | null;
|
|
12
|
+
/**
|
|
13
|
+
* Normalize a Lark target ID by removing prefixes.
|
|
14
|
+
*
|
|
15
|
+
* Handles "chat:", "user:", "open_id:" prefixes.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeLarkTarget(raw: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Format a Lark ID with its type prefix for display.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatLarkTarget(id: string, type?: LarkIdType): string;
|
|
22
|
+
/**
|
|
23
|
+
* Infer the receive_id_type parameter for Lark API calls.
|
|
24
|
+
*
|
|
25
|
+
* Lark API requires receive_id_type to specify how to interpret the receive_id.
|
|
26
|
+
* This function detects the type based on the ID prefix.
|
|
27
|
+
*/
|
|
28
|
+
export declare function inferReceiveIdType(recipientId: string): "chat_id" | "open_id" | "union_id";
|
|
29
|
+
/**
|
|
30
|
+
* Check if a string looks like a Lark ID.
|
|
31
|
+
*/
|
|
32
|
+
export declare function looksLikeLarkId(raw: string): boolean;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark/Feishu Target Utilities
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for ID detection, normalization, and type inference.
|
|
5
|
+
* Used across the plugin for consistent ID handling.
|
|
6
|
+
*/
|
|
7
|
+
const CHAT_ID_PREFIX = "oc_";
|
|
8
|
+
const OPEN_ID_PREFIX = "ou_";
|
|
9
|
+
const UNION_ID_PREFIX = "on_";
|
|
10
|
+
const USER_ID_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
11
|
+
/**
|
|
12
|
+
* Detect the type of a Lark ID from its format.
|
|
13
|
+
*/
|
|
14
|
+
export function detectLarkIdType(id) {
|
|
15
|
+
const trimmed = id.trim();
|
|
16
|
+
if (trimmed.startsWith(CHAT_ID_PREFIX))
|
|
17
|
+
return "chat_id";
|
|
18
|
+
if (trimmed.startsWith(OPEN_ID_PREFIX))
|
|
19
|
+
return "open_id";
|
|
20
|
+
if (trimmed.startsWith(UNION_ID_PREFIX))
|
|
21
|
+
return "union_id";
|
|
22
|
+
if (USER_ID_REGEX.test(trimmed))
|
|
23
|
+
return "user_id";
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a Lark target ID by removing prefixes.
|
|
28
|
+
*
|
|
29
|
+
* Handles "chat:", "user:", "open_id:" prefixes.
|
|
30
|
+
*/
|
|
31
|
+
export function normalizeLarkTarget(raw) {
|
|
32
|
+
const trimmed = raw.trim();
|
|
33
|
+
if (!trimmed)
|
|
34
|
+
return null;
|
|
35
|
+
const lowered = trimmed.toLowerCase();
|
|
36
|
+
if (lowered.startsWith("chat:")) {
|
|
37
|
+
return trimmed.slice("chat:".length).trim() || null;
|
|
38
|
+
}
|
|
39
|
+
if (lowered.startsWith("user:")) {
|
|
40
|
+
return trimmed.slice("user:".length).trim() || null;
|
|
41
|
+
}
|
|
42
|
+
if (lowered.startsWith("open_id:")) {
|
|
43
|
+
return trimmed.slice("open_id:".length).trim() || null;
|
|
44
|
+
}
|
|
45
|
+
return trimmed;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Format a Lark ID with its type prefix for display.
|
|
49
|
+
*/
|
|
50
|
+
export function formatLarkTarget(id, type) {
|
|
51
|
+
const trimmed = id.trim();
|
|
52
|
+
if (type === "chat_id" || trimmed.startsWith(CHAT_ID_PREFIX)) {
|
|
53
|
+
return `chat:${trimmed}`;
|
|
54
|
+
}
|
|
55
|
+
if (type === "open_id" || trimmed.startsWith(OPEN_ID_PREFIX)) {
|
|
56
|
+
return `user:${trimmed}`;
|
|
57
|
+
}
|
|
58
|
+
return trimmed;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Infer the receive_id_type parameter for Lark API calls.
|
|
62
|
+
*
|
|
63
|
+
* Lark API requires receive_id_type to specify how to interpret the receive_id.
|
|
64
|
+
* This function detects the type based on the ID prefix.
|
|
65
|
+
*/
|
|
66
|
+
export function inferReceiveIdType(recipientId) {
|
|
67
|
+
if (recipientId.startsWith("oc_")) {
|
|
68
|
+
return "chat_id";
|
|
69
|
+
}
|
|
70
|
+
if (recipientId.startsWith("ou_")) {
|
|
71
|
+
return "open_id";
|
|
72
|
+
}
|
|
73
|
+
if (recipientId.startsWith("on_")) {
|
|
74
|
+
return "union_id";
|
|
75
|
+
}
|
|
76
|
+
// Default to open_id for other formats
|
|
77
|
+
return "open_id";
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if a string looks like a Lark ID.
|
|
81
|
+
*/
|
|
82
|
+
export function looksLikeLarkId(raw) {
|
|
83
|
+
const trimmed = raw.trim();
|
|
84
|
+
if (!trimmed)
|
|
85
|
+
return false;
|
|
86
|
+
if (/^(chat|user|open_id):/i.test(trimmed))
|
|
87
|
+
return true;
|
|
88
|
+
if (trimmed.startsWith(CHAT_ID_PREFIX))
|
|
89
|
+
return true;
|
|
90
|
+
if (trimmed.startsWith(OPEN_ID_PREFIX))
|
|
91
|
+
return true;
|
|
92
|
+
if (trimmed.startsWith(UNION_ID_PREFIX))
|
|
93
|
+
return true;
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
|