@xwang152/claw-lark 0.1.23 → 0.1.25
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 +8 -3
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/src/media.d.ts +63 -0
- package/dist/src/media.js +259 -0
- package/dist/src/media.js.map +1 -1
- package/dist/src/mention.d.ts +17 -0
- package/dist/src/mention.js +22 -0
- package/dist/src/mention.js.map +1 -1
- package/dist/src/message-context.d.ts +65 -0
- package/dist/src/message-context.js +105 -0
- package/dist/src/message-context.js.map +1 -0
- 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/sender-name.d.ts +54 -0
- package/dist/src/sender-name.js +108 -0
- package/dist/src/sender-name.js.map +1 -0
- package/dist/src/types.d.ts +15 -0
- package/dist/src/typing.d.ts +76 -0
- package/dist/src/typing.js +165 -0
- package/dist/src/typing.js.map +1 -0
- package/package.json +1 -1
|
@@ -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,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sender Name Resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves sender display names from open_id using Lark contact API.
|
|
5
|
+
* Caches results for 10 minutes to avoid excessive API calls.
|
|
6
|
+
*
|
|
7
|
+
* This is useful in group chats where the agent needs to distinguish
|
|
8
|
+
* who is speaking (by name rather than just open_id).
|
|
9
|
+
*/
|
|
10
|
+
import type { ResolvedLarkAccount } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Resolve sender display name from open_id.
|
|
13
|
+
*
|
|
14
|
+
* Uses the contact.user.get API to fetch the user's display name.
|
|
15
|
+
* Results are cached for 10 minutes to reduce API calls.
|
|
16
|
+
*
|
|
17
|
+
* @param params - Account and sender open_id
|
|
18
|
+
* @returns Display name or undefined if not found
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveLarkSenderName(params: {
|
|
21
|
+
account: ResolvedLarkAccount;
|
|
22
|
+
senderOpenId: string;
|
|
23
|
+
log?: (...args: any[]) => void;
|
|
24
|
+
}): Promise<string | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Clear the sender name cache.
|
|
27
|
+
*
|
|
28
|
+
* This can be useful for testing or when you need fresh data.
|
|
29
|
+
*/
|
|
30
|
+
export declare function clearSenderNameCache(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get cache statistics.
|
|
33
|
+
*
|
|
34
|
+
* Useful for monitoring and debugging.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getSenderNameCacheStats(): {
|
|
37
|
+
size: number;
|
|
38
|
+
entries: Array<{
|
|
39
|
+
openId: string;
|
|
40
|
+
name: string;
|
|
41
|
+
expireAt: number;
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Prefetch sender names for a list of open_ids.
|
|
46
|
+
*
|
|
47
|
+
* This can be useful for warming up the cache before processing
|
|
48
|
+
* a batch of messages.
|
|
49
|
+
*/
|
|
50
|
+
export declare function prefetchLarkSenderNames(params: {
|
|
51
|
+
account: ResolvedLarkAccount;
|
|
52
|
+
senderOpenIds: string[];
|
|
53
|
+
log?: (...args: any[]) => void;
|
|
54
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sender Name Resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves sender display names from open_id using Lark contact API.
|
|
5
|
+
* Caches results for 10 minutes to avoid excessive API calls.
|
|
6
|
+
*
|
|
7
|
+
* This is useful in group chats where the agent needs to distinguish
|
|
8
|
+
* who is speaking (by name rather than just open_id).
|
|
9
|
+
*/
|
|
10
|
+
import { createLarkClient } from "./client.js";
|
|
11
|
+
// Cache display names by open_id to avoid an API call on every message
|
|
12
|
+
const SENDER_NAME_TTL_MS = 10 * 60 * 1000; // 10 minutes
|
|
13
|
+
const senderNameCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Resolve sender display name from open_id.
|
|
16
|
+
*
|
|
17
|
+
* Uses the contact.user.get API to fetch the user's display name.
|
|
18
|
+
* Results are cached for 10 minutes to reduce API calls.
|
|
19
|
+
*
|
|
20
|
+
* @param params - Account and sender open_id
|
|
21
|
+
* @returns Display name or undefined if not found
|
|
22
|
+
*/
|
|
23
|
+
export async function resolveLarkSenderName(params) {
|
|
24
|
+
const { account, senderOpenId, log = console.log } = params;
|
|
25
|
+
if (!senderOpenId)
|
|
26
|
+
return undefined;
|
|
27
|
+
// Check cache first
|
|
28
|
+
const cached = senderNameCache.get(senderOpenId);
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
if (cached && cached.expireAt > now) {
|
|
31
|
+
return cached.name;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const client = createLarkClient(account);
|
|
35
|
+
// contact/v3/user/:user_id?user_id_type=open_id
|
|
36
|
+
const res = await client.contact.user.get({
|
|
37
|
+
path: { user_id: senderOpenId },
|
|
38
|
+
params: { user_id_type: "open_id" },
|
|
39
|
+
});
|
|
40
|
+
// Try multiple name fields in order of preference
|
|
41
|
+
const name = res?.data?.user?.name ||
|
|
42
|
+
res?.data?.user?.display_name ||
|
|
43
|
+
res?.data?.user?.nickname ||
|
|
44
|
+
res?.data?.user?.en_name;
|
|
45
|
+
if (name && typeof name === "string") {
|
|
46
|
+
// Cache the result
|
|
47
|
+
senderNameCache.set(senderOpenId, { name, expireAt: now + SENDER_NAME_TTL_MS });
|
|
48
|
+
return name;
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
// Best-effort. Don't fail message handling if name lookup fails.
|
|
54
|
+
log(`[lark] Failed to resolve sender name for ${senderOpenId}: ${String(err)}`);
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Clear the sender name cache.
|
|
60
|
+
*
|
|
61
|
+
* This can be useful for testing or when you need fresh data.
|
|
62
|
+
*/
|
|
63
|
+
export function clearSenderNameCache() {
|
|
64
|
+
senderNameCache.clear();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get cache statistics.
|
|
68
|
+
*
|
|
69
|
+
* Useful for monitoring and debugging.
|
|
70
|
+
*/
|
|
71
|
+
export function getSenderNameCacheStats() {
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
const entries = Array.from(senderNameCache.entries())
|
|
74
|
+
.filter(([, value]) => value.expireAt > now)
|
|
75
|
+
.map(([openId, value]) => ({
|
|
76
|
+
openId,
|
|
77
|
+
name: value.name,
|
|
78
|
+
expireAt: value.expireAt,
|
|
79
|
+
}));
|
|
80
|
+
return {
|
|
81
|
+
size: entries.length,
|
|
82
|
+
entries,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Prefetch sender names for a list of open_ids.
|
|
87
|
+
*
|
|
88
|
+
* This can be useful for warming up the cache before processing
|
|
89
|
+
* a batch of messages.
|
|
90
|
+
*/
|
|
91
|
+
export async function prefetchLarkSenderNames(params) {
|
|
92
|
+
const { account, senderOpenIds, log = console.log } = params;
|
|
93
|
+
// Only fetch names that aren't already cached
|
|
94
|
+
const now = Date.now();
|
|
95
|
+
const uncachedIds = senderOpenIds.filter((id) => {
|
|
96
|
+
const cached = senderNameCache.get(id);
|
|
97
|
+
return !cached || cached.expireAt <= now;
|
|
98
|
+
});
|
|
99
|
+
// Process in parallel with a limit to avoid overwhelming the API
|
|
100
|
+
const batchSize = 10;
|
|
101
|
+
for (let i = 0; i < uncachedIds.length; i += batchSize) {
|
|
102
|
+
const batch = uncachedIds.slice(i, i + batchSize);
|
|
103
|
+
await Promise.all(batch.map((id) => resolveLarkSenderName({ account, senderOpenId: id, log }).catch(() => {
|
|
104
|
+
// Ignore errors - best effort prefetch
|
|
105
|
+
})));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=sender-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender-name.js","sourceRoot":"","sources":["../../src/sender-name.ts"],"names":[],"mappings":"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"}
|
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,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typing Indicators for Lark/Feishu
|
|
3
|
+
*
|
|
4
|
+
* Since Lark/Feishu doesn't have a native typing indicator API,
|
|
5
|
+
* we use emoji reactions as a substitute.
|
|
6
|
+
*
|
|
7
|
+
* When the bot starts processing a message, it adds a "Typing" reaction.
|
|
8
|
+
* When the reply is sent, it removes the reaction.
|
|
9
|
+
*
|
|
10
|
+
* Reference: https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce
|
|
11
|
+
*/
|
|
12
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
|
13
|
+
export type TypingIndicatorState = {
|
|
14
|
+
messageId: string;
|
|
15
|
+
reactionId: string | null;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Add a typing indicator (reaction) to a message.
|
|
19
|
+
*
|
|
20
|
+
* This adds a visual indicator that the bot is "typing" or processing the message.
|
|
21
|
+
* Uses the "Typing" emoji reaction if available, falls back gracefully if not.
|
|
22
|
+
*
|
|
23
|
+
* @param params - Configuration and message ID
|
|
24
|
+
* @returns State object containing message ID and reaction ID (for later removal)
|
|
25
|
+
*/
|
|
26
|
+
export declare function addTypingIndicator(params: {
|
|
27
|
+
cfg: OpenClawConfig;
|
|
28
|
+
messageId: string;
|
|
29
|
+
accountId?: string;
|
|
30
|
+
}): Promise<TypingIndicatorState>;
|
|
31
|
+
/**
|
|
32
|
+
* Remove a typing indicator (reaction) from a message.
|
|
33
|
+
*
|
|
34
|
+
* This should be called after the reply is sent to clean up the typing indicator.
|
|
35
|
+
*
|
|
36
|
+
* @param params - Configuration and typing indicator state
|
|
37
|
+
*/
|
|
38
|
+
export declare function removeTypingIndicator(params: {
|
|
39
|
+
cfg: OpenClawConfig;
|
|
40
|
+
state: TypingIndicatorState;
|
|
41
|
+
accountId?: string;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Create a typing indicator controller for managing the lifecycle.
|
|
45
|
+
*
|
|
46
|
+
* This is useful for ensuring the typing indicator is removed even if errors occur.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const typing = createTypingController({ cfg, messageId });
|
|
51
|
+
* await typing.start();
|
|
52
|
+
* try {
|
|
53
|
+
* // ... process message and send reply ...
|
|
54
|
+
* } finally {
|
|
55
|
+
* await typing.stop();
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function createTypingController(params: {
|
|
60
|
+
cfg: OpenClawConfig;
|
|
61
|
+
messageId: string;
|
|
62
|
+
accountId?: string;
|
|
63
|
+
}): {
|
|
64
|
+
/**
|
|
65
|
+
* Start the typing indicator
|
|
66
|
+
*/
|
|
67
|
+
start(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Stop the typing indicator
|
|
70
|
+
*/
|
|
71
|
+
stop(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Get current state
|
|
74
|
+
*/
|
|
75
|
+
getState(): TypingIndicatorState | null;
|
|
76
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typing Indicators for Lark/Feishu
|
|
3
|
+
*
|
|
4
|
+
* Since Lark/Feishu doesn't have a native typing indicator API,
|
|
5
|
+
* we use emoji reactions as a substitute.
|
|
6
|
+
*
|
|
7
|
+
* When the bot starts processing a message, it adds a "Typing" reaction.
|
|
8
|
+
* When the reply is sent, it removes the reaction.
|
|
9
|
+
*
|
|
10
|
+
* Reference: https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce
|
|
11
|
+
*/
|
|
12
|
+
import { createLarkClient } from "./client.js";
|
|
13
|
+
// Lark emoji type for typing indicator
|
|
14
|
+
// Note: "Typing" may not be available in all Lark instances
|
|
15
|
+
// Fallback options: "THUMBSUP", "OK", "SMILE"
|
|
16
|
+
const TYPING_EMOJI = "Typing";
|
|
17
|
+
/**
|
|
18
|
+
* Extract Lark channel config from OpenClaw config
|
|
19
|
+
*/
|
|
20
|
+
function getChannelConfig(cfg) {
|
|
21
|
+
return cfg.channels?.lark ?? {};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Add a typing indicator (reaction) to a message.
|
|
25
|
+
*
|
|
26
|
+
* This adds a visual indicator that the bot is "typing" or processing the message.
|
|
27
|
+
* Uses the "Typing" emoji reaction if available, falls back gracefully if not.
|
|
28
|
+
*
|
|
29
|
+
* @param params - Configuration and message ID
|
|
30
|
+
* @returns State object containing message ID and reaction ID (for later removal)
|
|
31
|
+
*/
|
|
32
|
+
export async function addTypingIndicator(params) {
|
|
33
|
+
const { cfg, messageId, accountId = "default" } = params;
|
|
34
|
+
const channelConfig = getChannelConfig(cfg);
|
|
35
|
+
const accountConfig = channelConfig.accounts?.[accountId];
|
|
36
|
+
if (!accountConfig?.appId || !accountConfig?.appSecret) {
|
|
37
|
+
return { messageId, reactionId: null };
|
|
38
|
+
}
|
|
39
|
+
const client = createLarkClient({
|
|
40
|
+
accountId,
|
|
41
|
+
enabled: true,
|
|
42
|
+
configured: true,
|
|
43
|
+
appId: accountConfig.appId,
|
|
44
|
+
appSecret: accountConfig.appSecret,
|
|
45
|
+
domain: accountConfig.domain ?? "feishu",
|
|
46
|
+
connectionMode: "websocket",
|
|
47
|
+
webhookPort: 3000,
|
|
48
|
+
dmPolicy: "open",
|
|
49
|
+
dmAllowlist: [],
|
|
50
|
+
groupPolicy: "open",
|
|
51
|
+
groupAllowlist: [],
|
|
52
|
+
requireMention: true,
|
|
53
|
+
mediaMaxMb: 30,
|
|
54
|
+
renderMode: "auto",
|
|
55
|
+
historyLimit: 10,
|
|
56
|
+
});
|
|
57
|
+
try {
|
|
58
|
+
const response = await client.im.messageReaction.create({
|
|
59
|
+
path: { message_id: messageId },
|
|
60
|
+
data: {
|
|
61
|
+
reaction_type: { emoji_type: TYPING_EMOJI },
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
const reactionId = response?.data?.reaction_id ?? null;
|
|
65
|
+
return { messageId, reactionId };
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
// Silently fail - typing indicator is not critical
|
|
69
|
+
console.log(`[lark] Failed to add typing indicator: ${err}`);
|
|
70
|
+
return { messageId, reactionId: null };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Remove a typing indicator (reaction) from a message.
|
|
75
|
+
*
|
|
76
|
+
* This should be called after the reply is sent to clean up the typing indicator.
|
|
77
|
+
*
|
|
78
|
+
* @param params - Configuration and typing indicator state
|
|
79
|
+
*/
|
|
80
|
+
export async function removeTypingIndicator(params) {
|
|
81
|
+
const { cfg, state, accountId = "default" } = params;
|
|
82
|
+
if (!state.reactionId)
|
|
83
|
+
return;
|
|
84
|
+
const channelConfig = getChannelConfig(cfg);
|
|
85
|
+
const accountConfig = channelConfig.accounts?.[accountId];
|
|
86
|
+
if (!accountConfig?.appId || !accountConfig?.appSecret)
|
|
87
|
+
return;
|
|
88
|
+
const client = createLarkClient({
|
|
89
|
+
accountId,
|
|
90
|
+
enabled: true,
|
|
91
|
+
configured: true,
|
|
92
|
+
appId: accountConfig.appId,
|
|
93
|
+
appSecret: accountConfig.appSecret,
|
|
94
|
+
domain: accountConfig.domain ?? "feishu",
|
|
95
|
+
connectionMode: "websocket",
|
|
96
|
+
webhookPort: 3000,
|
|
97
|
+
dmPolicy: "open",
|
|
98
|
+
dmAllowlist: [],
|
|
99
|
+
groupPolicy: "open",
|
|
100
|
+
groupAllowlist: [],
|
|
101
|
+
requireMention: true,
|
|
102
|
+
mediaMaxMb: 30,
|
|
103
|
+
renderMode: "auto",
|
|
104
|
+
historyLimit: 10,
|
|
105
|
+
});
|
|
106
|
+
try {
|
|
107
|
+
await client.im.messageReaction.delete({
|
|
108
|
+
path: {
|
|
109
|
+
message_id: state.messageId,
|
|
110
|
+
reaction_id: state.reactionId,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
// Silently fail - cleanup is not critical
|
|
116
|
+
console.log(`[lark] Failed to remove typing indicator: ${err}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Create a typing indicator controller for managing the lifecycle.
|
|
121
|
+
*
|
|
122
|
+
* This is useful for ensuring the typing indicator is removed even if errors occur.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const typing = createTypingController({ cfg, messageId });
|
|
127
|
+
* await typing.start();
|
|
128
|
+
* try {
|
|
129
|
+
* // ... process message and send reply ...
|
|
130
|
+
* } finally {
|
|
131
|
+
* await typing.stop();
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export function createTypingController(params) {
|
|
136
|
+
let state = null;
|
|
137
|
+
return {
|
|
138
|
+
/**
|
|
139
|
+
* Start the typing indicator
|
|
140
|
+
*/
|
|
141
|
+
async start() {
|
|
142
|
+
state = await addTypingIndicator(params);
|
|
143
|
+
},
|
|
144
|
+
/**
|
|
145
|
+
* Stop the typing indicator
|
|
146
|
+
*/
|
|
147
|
+
async stop() {
|
|
148
|
+
if (state) {
|
|
149
|
+
await removeTypingIndicator({
|
|
150
|
+
cfg: params.cfg,
|
|
151
|
+
state,
|
|
152
|
+
accountId: params.accountId,
|
|
153
|
+
});
|
|
154
|
+
state = null;
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
/**
|
|
158
|
+
* Get current state
|
|
159
|
+
*/
|
|
160
|
+
getState() {
|
|
161
|
+
return state;
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=typing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typing.js","sourceRoot":"","sources":["../../src/typing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,uCAAuC;AACvC,4DAA4D;AAC5D,8CAA8C;AAC9C,MAAM,YAAY,GAAG,QAAQ,CAAC;AAO9B;;GAEG;AACH,SAAS,gBAAgB,CAAC,GAAmB;IAC3C,OAAQ,GAAG,CAAC,QAAQ,EAAE,IAA0B,IAAI,EAAE,CAAC;AACzD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAIxC;IACC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,MAAM,CAAC;IACzD,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC;IAE1D,IAAI,CAAC,aAAa,EAAE,KAAK,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,CAAC;QACvD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC;QAC9B,SAAS;QACT,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,aAAa,CAAC,KAAK;QAC1B,SAAS,EAAE,aAAa,CAAC,SAAS;QAClC,MAAM,EAAE,aAAa,CAAC,MAAM,IAAI,QAAQ;QACxC,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,MAAM;QACnB,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,IAAI;QACpB,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,MAAM;QAClB,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC;YACtD,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE;YAC/B,IAAI,EAAE;gBACJ,aAAa,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE;aAC5C;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAI,QAAgB,EAAE,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC;QAChE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,mDAAmD;QACnD,OAAO,CAAC,GAAG,CAAC,0CAA0C,GAAG,EAAE,CAAC,CAAC;QAC7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAI3C;IACC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,MAAM,CAAC;IACrD,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,OAAO;IAE9B,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC;IAE1D,IAAI,CAAC,aAAa,EAAE,KAAK,IAAI,CAAC,aAAa,EAAE,SAAS;QAAE,OAAO;IAE/D,MAAM,MAAM,GAAG,gBAAgB,CAAC;QAC9B,SAAS;QACT,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,aAAa,CAAC,KAAK;QAC1B,SAAS,EAAE,aAAa,CAAC,SAAS;QAClC,MAAM,EAAE,aAAa,CAAC,MAAM,IAAI,QAAQ;QACxC,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,MAAM;QACnB,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,IAAI;QACpB,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,MAAM;QAClB,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC;YACrC,IAAI,EAAE;gBACJ,UAAU,EAAE,KAAK,CAAC,SAAS;gBAC3B,WAAW,EAAE,KAAK,CAAC,UAAU;aAC9B;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0CAA0C;QAC1C,OAAO,CAAC,GAAG,CAAC,6CAA6C,GAAG,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAItC;IACC,IAAI,KAAK,GAAgC,IAAI,CAAC;IAE9C,OAAO;QACL;;WAEG;QACH,KAAK,CAAC,KAAK;YACT,KAAK,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,IAAI;YACR,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,qBAAqB,CAAC;oBAC1B,GAAG,EAAE,MAAM,CAAC,GAAG;oBACf,KAAK;oBACL,SAAS,EAAE,MAAM,CAAC,SAAS;iBAC5B,CAAC,CAAC;gBACH,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;QACH,CAAC;QAED;;WAEG;QACH,QAAQ;YACN,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|