golembot 0.12.0-beta.1 → 0.13.0
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/README.md +15 -0
- package/README.zh-CN.md +15 -0
- package/dist/channel.d.ts +14 -1
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js.map +1 -1
- package/dist/channels/dingtalk.d.ts +4 -2
- package/dist/channels/dingtalk.d.ts.map +1 -1
- package/dist/channels/dingtalk.js +16 -1
- package/dist/channels/dingtalk.js.map +1 -1
- package/dist/channels/discord.d.ts +4 -2
- package/dist/channels/discord.d.ts.map +1 -1
- package/dist/channels/discord.js +13 -1
- package/dist/channels/discord.js.map +1 -1
- package/dist/channels/feishu-format.d.ts +25 -7
- package/dist/channels/feishu-format.d.ts.map +1 -1
- package/dist/channels/feishu-format.js +74 -27
- package/dist/channels/feishu-format.js.map +1 -1
- package/dist/channels/feishu.d.ts +10 -2
- package/dist/channels/feishu.d.ts.map +1 -1
- package/dist/channels/feishu.js +84 -26
- package/dist/channels/feishu.js.map +1 -1
- package/dist/channels/slack-format.d.ts +20 -0
- package/dist/channels/slack-format.d.ts.map +1 -0
- package/dist/channels/slack-format.js +132 -0
- package/dist/channels/slack-format.js.map +1 -0
- package/dist/channels/slack.d.ts +5 -2
- package/dist/channels/slack.d.ts.map +1 -1
- package/dist/channels/slack.js +21 -2
- package/dist/channels/slack.js.map +1 -1
- package/dist/channels/telegram-format.d.ts +21 -0
- package/dist/channels/telegram-format.d.ts.map +1 -0
- package/dist/channels/telegram-format.js +167 -0
- package/dist/channels/telegram-format.js.map +1 -0
- package/dist/channels/telegram.d.ts +4 -2
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +16 -2
- package/dist/channels/telegram.js.map +1 -1
- package/dist/channels/wecom.d.ts +4 -2
- package/dist/channels/wecom.d.ts.map +1 -1
- package/dist/channels/wecom.js +17 -1
- package/dist/channels/wecom.js.map +1 -1
- package/dist/cli.js +205 -13
- package/dist/cli.js.map +1 -1
- package/dist/gateway.d.ts +10 -2
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +38 -2
- package/dist/gateway.js.map +1 -1
- package/dist/registry.d.ts +38 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +185 -0
- package/dist/registry.js.map +1 -0
- package/dist/workspace.d.ts +0 -2
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js.map +1 -1
- package/package.json +1 -1
- package/skills/general/SKILL.md +11 -0
- package/skills/im-adapter/SKILL.md +11 -6
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ Embed into Slack bots, internal tools, SaaS products, customer support — anyth
|
|
|
60
60
|
| **Auto-upgrade** | Agent gets smarter? Your assistant gets smarter. Zero code changes. | You maintain everything yourself |
|
|
61
61
|
| **Transparency** | `ls` the directory = see what the assistant knows and does | Black box pipelines |
|
|
62
62
|
| **Engine lock-in** | Change one line in config to swap engines | Rewrite everything |
|
|
63
|
+
| **Skills** | 13,000+ community skills from ClawHub, one command to install | Write your own tools and prompts from scratch |
|
|
63
64
|
|
|
64
65
|
## Quick Start
|
|
65
66
|
|
|
@@ -73,6 +74,7 @@ golembot onboard # guided setup (recommended)
|
|
|
73
74
|
golembot init -e claude-code -n my-bot
|
|
74
75
|
golembot run # REPL conversation
|
|
75
76
|
golembot gateway # start IM + HTTP service
|
|
77
|
+
golembot skill search "data analysis" # browse 13,000+ ClawHub skills
|
|
76
78
|
```
|
|
77
79
|
|
|
78
80
|
## Architecture
|
|
@@ -155,6 +157,19 @@ skills/
|
|
|
155
157
|
|
|
156
158
|
`ls skills/` is the complete list of what your assistant can do.
|
|
157
159
|
|
|
160
|
+
## 13,000+ Skills from ClawHub
|
|
161
|
+
|
|
162
|
+
GolemBot is fully compatible with [ClawHub](https://clawhub.ai) — the largest AI agent skill marketplace by OpenClaw. The `SKILL.md` format is 100% compatible, so all 13,000+ community skills work out of the box.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
golembot skill search "data analysis" # discover skills
|
|
166
|
+
golembot skill add clawhub:data-analysis # one command to install
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Agent-powered skill discovery:** Your agent can search and install skills autonomously during conversations. Ask it "find me a good code review skill" — it searches ClawHub, shows results, and installs on your confirmation.
|
|
170
|
+
|
|
171
|
+
All skill commands support `--json` for programmatic access. The pluggable registry interface supports additional skill sources beyond ClawHub.
|
|
172
|
+
|
|
158
173
|
## Docker Deployment
|
|
159
174
|
|
|
160
175
|
```dockerfile
|
package/README.zh-CN.md
CHANGED
|
@@ -60,6 +60,7 @@ for await (const event of bot.chat('分析上个月的销售数据')) {
|
|
|
60
60
|
| **自动升级** | Agent 变强了?你的助手自动变强,零代码改动 | 你自己维护所有东西 |
|
|
61
61
|
| **透明度** | `ls` 目录 = 看到助手知道什么、做了什么 | 黑盒流水线 |
|
|
62
62
|
| **引擎锁定** | 改一行配置换引擎 | 全部重写 |
|
|
63
|
+
| **技能生态** | ClawHub 13,000+ 社区技能,一条命令安装 | 自己从零编写工具和 prompt |
|
|
63
64
|
|
|
64
65
|
## 快速开始
|
|
65
66
|
|
|
@@ -73,6 +74,7 @@ golembot onboard # 引导式安装(推荐)
|
|
|
73
74
|
golembot init -e claude-code -n my-bot
|
|
74
75
|
golembot run # REPL 对话
|
|
75
76
|
golembot gateway # 启动 IM + HTTP 服务
|
|
77
|
+
golembot skill search "数据分析" # 浏览 13,000+ ClawHub 社区技能
|
|
76
78
|
```
|
|
77
79
|
|
|
78
80
|
## 架构
|
|
@@ -155,6 +157,19 @@ skills/
|
|
|
155
157
|
|
|
156
158
|
`ls skills/` 就是助手能力的完整清单。
|
|
157
159
|
|
|
160
|
+
## 13,000+ ClawHub 社区技能
|
|
161
|
+
|
|
162
|
+
GolemBot 与 [ClawHub](https://clawhub.ai) 完全兼容 —— OpenClaw 旗下最大的 AI agent 技能市场。`SKILL.md` 格式 100% 兼容,13,000+ 社区技能开箱即用。
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
golembot skill search "数据分析" # 发现技能
|
|
166
|
+
golembot skill add clawhub:data-analysis # 一条命令安装
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Agent 自主发现技能:** 你的 Agent 可以在对话中自主搜索和安装技能。对它说"帮我找个好用的代码审查 skill"—— 它会搜索 ClawHub、展示结果,你确认后自动安装。
|
|
170
|
+
|
|
171
|
+
所有 skill 命令支持 `--json` 输出,方便程序化调用。可插拔的 registry 接口支持未来接入更多技能来源。
|
|
172
|
+
|
|
158
173
|
## Docker 部署
|
|
159
174
|
|
|
160
175
|
```dockerfile
|
package/dist/channel.d.ts
CHANGED
|
@@ -13,12 +13,19 @@ export interface ChannelMessage {
|
|
|
13
13
|
*/
|
|
14
14
|
mentioned?: boolean;
|
|
15
15
|
}
|
|
16
|
+
export interface MentionTarget {
|
|
17
|
+
name: string;
|
|
18
|
+
platformId: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ReplyOptions {
|
|
21
|
+
mentions?: MentionTarget[];
|
|
22
|
+
}
|
|
16
23
|
export interface ChannelAdapter {
|
|
17
24
|
readonly name: string;
|
|
18
25
|
/** Optional: override the default 4000-char message split limit for this channel. */
|
|
19
26
|
readonly maxMessageLength?: number;
|
|
20
27
|
start(onMessage: (msg: ChannelMessage) => void | Promise<void>): Promise<void>;
|
|
21
|
-
reply(msg: ChannelMessage, text: string): Promise<void>;
|
|
28
|
+
reply(msg: ChannelMessage, text: string, options?: ReplyOptions): Promise<void>;
|
|
22
29
|
stop(): Promise<void>;
|
|
23
30
|
/**
|
|
24
31
|
* Optional: send a "typing…" indicator to the chat.
|
|
@@ -26,6 +33,12 @@ export interface ChannelAdapter {
|
|
|
26
33
|
* Implementations should be idempotent and best-effort (errors are ignored).
|
|
27
34
|
*/
|
|
28
35
|
typing?(msg: ChannelMessage): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Optional: resolve group members for @mention support.
|
|
38
|
+
* Returns a map of display name → platform-specific user ID.
|
|
39
|
+
* Called by the gateway when the AI reply contains @mentions.
|
|
40
|
+
*/
|
|
41
|
+
getGroupMembers?(chatId: string): Promise<Map<string, string>>;
|
|
29
42
|
}
|
|
30
43
|
export declare function buildSessionKey(msg: ChannelMessage): string;
|
|
31
44
|
/**
|
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;OAIG;IACH,eAAe,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAGpE"}
|
package/dist/channel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AA8CA,MAAM,UAAU,eAAe,CAAC,GAAmB;IACjD,OAAO,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;SACnC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IACzD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC/D,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,oBAAoB,OAAO,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import type { ChannelAdapter, ChannelMessage } from '../channel.js';
|
|
1
|
+
import type { ChannelAdapter, ChannelMessage, ReplyOptions } from '../channel.js';
|
|
2
2
|
import type { DingtalkChannelConfig } from '../workspace.js';
|
|
3
3
|
export declare class DingtalkAdapter implements ChannelAdapter {
|
|
4
4
|
readonly name = "dingtalk";
|
|
5
5
|
readonly maxMessageLength = 4000;
|
|
6
6
|
private config;
|
|
7
7
|
private dwClient;
|
|
8
|
+
private seenMsgIds;
|
|
9
|
+
private static readonly MAX_SEEN;
|
|
8
10
|
constructor(config: DingtalkChannelConfig);
|
|
9
11
|
start(onMessage: (msg: ChannelMessage) => void): Promise<void>;
|
|
10
|
-
reply(msg: ChannelMessage, text: string): Promise<void>;
|
|
12
|
+
reply(msg: ChannelMessage, text: string, options?: ReplyOptions): Promise<void>;
|
|
11
13
|
stop(): Promise<void>;
|
|
12
14
|
}
|
|
13
15
|
//# sourceMappingURL=dingtalk.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dingtalk.d.ts","sourceRoot":"","sources":["../../src/channels/dingtalk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"dingtalk.d.ts","sourceRoot":"","sources":["../../src/channels/dingtalk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,qBAAa,eAAgB,YAAW,cAAc;IACpD,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,gBAAgB,QAAQ;IACjC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAO;gBAE3B,MAAM,EAAE,qBAAqB;IAInC,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA6D9D,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB/E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
|
|
@@ -3,6 +3,8 @@ export class DingtalkAdapter {
|
|
|
3
3
|
maxMessageLength = 4000;
|
|
4
4
|
config;
|
|
5
5
|
dwClient;
|
|
6
|
+
seenMsgIds = new Set();
|
|
7
|
+
static MAX_SEEN = 500;
|
|
6
8
|
constructor(config) {
|
|
7
9
|
this.config = config;
|
|
8
10
|
}
|
|
@@ -20,6 +22,19 @@ export class DingtalkAdapter {
|
|
|
20
22
|
clientSecret: this.config.clientSecret,
|
|
21
23
|
});
|
|
22
24
|
this.dwClient.registerCallbackListener(TOPIC_ROBOT, async (res) => {
|
|
25
|
+
// Deduplicate re-delivered events.
|
|
26
|
+
const msgId = res.headers?.messageId || JSON.parse(res.data).msgId;
|
|
27
|
+
if (msgId) {
|
|
28
|
+
if (this.seenMsgIds.has(msgId)) {
|
|
29
|
+
this.dwClient.socketCallBackResponse(res.headers.messageId, { status: 'SUCCESS' });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.seenMsgIds.add(msgId);
|
|
33
|
+
if (this.seenMsgIds.size > DingtalkAdapter.MAX_SEEN) {
|
|
34
|
+
const entries = [...this.seenMsgIds];
|
|
35
|
+
this.seenMsgIds = new Set(entries.slice(entries.length >> 1));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
23
38
|
const data = JSON.parse(res.data);
|
|
24
39
|
const text = data.text?.content?.trim() || '';
|
|
25
40
|
if (!text)
|
|
@@ -41,7 +56,7 @@ export class DingtalkAdapter {
|
|
|
41
56
|
await this.dwClient.connect();
|
|
42
57
|
console.log(`[dingtalk] Stream connection established`);
|
|
43
58
|
}
|
|
44
|
-
async reply(msg, text) {
|
|
59
|
+
async reply(msg, text, options) {
|
|
45
60
|
const raw = msg.raw;
|
|
46
61
|
const webhook = raw?._sessionWebhook;
|
|
47
62
|
if (!webhook)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dingtalk.js","sourceRoot":"","sources":["../../src/channels/dingtalk.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,UAAU,CAAC;IAClB,gBAAgB,GAAG,IAAI,CAAC;IACzB,MAAM,CAAwB;IAC9B,QAAQ,CAAM;
|
|
1
|
+
{"version":3,"file":"dingtalk.js","sourceRoot":"","sources":["../../src/channels/dingtalk.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,UAAU,CAAC;IAClB,gBAAgB,GAAG,IAAI,CAAC;IACzB,MAAM,CAAwB;IAC9B,QAAQ,CAAM;IACd,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,CAAU,QAAQ,GAAG,GAAG,CAAC;IAEvC,YAAY,MAA6B;QACvC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAwC;QAClD,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QAEtC,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC3B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;SACvC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CACpC,WAAW,EACX,KAAK,EAAE,GAAQ,EAAE,EAAE;YACjB,mCAAmC;YACnC,MAAM,KAAK,GAAuB,GAAG,CAAC,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;YACvF,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/B,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;oBACnF,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC;oBACpD,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;oBACrC,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI;gBAAE,OAAO;YAElB,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,KAAK,GAAG,CAAC;YAE9C,MAAM,UAAU,GAAmB;gBACjC,WAAW,EAAE,UAAU;gBACvB,QAAQ,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE;gBACnD,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,MAAM,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;gBACjC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;gBAClC,IAAI;gBACJ,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBACrC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,cAAc,EAAE;aACvD,CAAC;YAEF,SAAS,CAAC,UAAU,CAAC,CAAC;YAEtB,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACrF,CAAC,CACF,CAAC;QAEF,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAmB,EAAE,IAAY,EAAE,OAAsB;QACnE,MAAM,GAAG,GAAG,GAAG,CAAC,GAA2D,CAAC;QAC5E,MAAM,OAAO,GAAG,GAAG,EAAE,eAAe,CAAC;QACrC,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SACxB,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,CAAC;QAC5D,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC/E,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,6BAA6B,CAAC,GAAG,WAAW,CAAC;QACvD,CAAC;QAED,MAAM,KAAK,CAAC,OAAO,EAAE;YACnB,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelAdapter, ChannelMessage } from '../channel.js';
|
|
1
|
+
import type { ChannelAdapter, ChannelMessage, ReplyOptions } from '../channel.js';
|
|
2
2
|
import type { DiscordChannelConfig } from '../workspace.js';
|
|
3
3
|
export declare class DiscordAdapter implements ChannelAdapter {
|
|
4
4
|
readonly name = "discord";
|
|
@@ -6,9 +6,11 @@ export declare class DiscordAdapter implements ChannelAdapter {
|
|
|
6
6
|
readonly maxMessageLength = 2000;
|
|
7
7
|
private config;
|
|
8
8
|
private client;
|
|
9
|
+
private seenMsgIds;
|
|
10
|
+
private static readonly MAX_SEEN;
|
|
9
11
|
constructor(config: DiscordChannelConfig);
|
|
10
12
|
start(onMessage: (msg: ChannelMessage) => void | Promise<void>): Promise<void>;
|
|
11
|
-
reply(msg: ChannelMessage, text: string): Promise<void>;
|
|
13
|
+
reply(msg: ChannelMessage, text: string, options?: ReplyOptions): Promise<void>;
|
|
12
14
|
typing(msg: ChannelMessage): Promise<void>;
|
|
13
15
|
stop(): Promise<void>;
|
|
14
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../../src/channels/discord.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../../src/channels/discord.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,qBAAa,cAAe,YAAW,cAAc;IACnD,QAAQ,CAAC,IAAI,aAAa;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,gBAAgB,QAAQ;IAEjC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAO;gBAE3B,MAAM,EAAE,oBAAoB;IAIlC,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAyE9E,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/E,MAAM,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B"}
|
package/dist/channels/discord.js
CHANGED
|
@@ -4,6 +4,8 @@ export class DiscordAdapter {
|
|
|
4
4
|
maxMessageLength = 2000;
|
|
5
5
|
config;
|
|
6
6
|
client = null;
|
|
7
|
+
seenMsgIds = new Set();
|
|
8
|
+
static MAX_SEEN = 500;
|
|
7
9
|
constructor(config) {
|
|
8
10
|
this.config = config;
|
|
9
11
|
}
|
|
@@ -40,6 +42,16 @@ export class DiscordAdapter {
|
|
|
40
42
|
return;
|
|
41
43
|
if (!message.content)
|
|
42
44
|
return; // skip embed-only messages
|
|
45
|
+
// Deduplicate re-delivered events.
|
|
46
|
+
if (message.id) {
|
|
47
|
+
if (this.seenMsgIds.has(message.id))
|
|
48
|
+
return;
|
|
49
|
+
this.seenMsgIds.add(message.id);
|
|
50
|
+
if (this.seenMsgIds.size > DiscordAdapter.MAX_SEEN) {
|
|
51
|
+
const entries = [...this.seenMsgIds];
|
|
52
|
+
this.seenMsgIds = new Set(entries.slice(entries.length >> 1));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
43
55
|
const isDM = !message.guild;
|
|
44
56
|
// Detect mention via Discord's native <@userId> token (works even without botName).
|
|
45
57
|
const mentionPattern = new RegExp(`<@!?${botId}>`);
|
|
@@ -60,7 +72,7 @@ export class DiscordAdapter {
|
|
|
60
72
|
});
|
|
61
73
|
});
|
|
62
74
|
}
|
|
63
|
-
async reply(msg, text) {
|
|
75
|
+
async reply(msg, text, options) {
|
|
64
76
|
const raw = msg.raw;
|
|
65
77
|
await raw.reply({ content: text });
|
|
66
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/channels/discord.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,SAAS,CAAC;IAC1B,kEAAkE;IACzD,gBAAgB,GAAG,IAAI,CAAC;IAEzB,MAAM,CAAuB;IAC7B,MAAM,GAAQ,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/channels/discord.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,23 +24,41 @@ export interface CardElement {
|
|
|
24
24
|
content: string;
|
|
25
25
|
};
|
|
26
26
|
content?: string;
|
|
27
|
+
text_size?: string;
|
|
27
28
|
}
|
|
28
29
|
export interface CardContent {
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
schema: string;
|
|
31
|
+
body: {
|
|
32
|
+
elements: CardElement[];
|
|
33
|
+
};
|
|
34
|
+
header?: {
|
|
35
|
+
title: {
|
|
36
|
+
tag: string;
|
|
37
|
+
content: string;
|
|
38
|
+
};
|
|
39
|
+
template?: string;
|
|
31
40
|
};
|
|
32
|
-
elements: CardElement[];
|
|
33
41
|
}
|
|
34
42
|
/** Detect whether text contains Markdown formatting. */
|
|
35
43
|
export declare function hasMarkdown(text: string): boolean;
|
|
36
44
|
/** Convert Markdown text to Feishu post rich-text structure. */
|
|
37
45
|
export declare function markdownToPost(markdown: string): PostContent;
|
|
38
46
|
/**
|
|
39
|
-
* Convert Markdown text to a Feishu interactive card structure.
|
|
47
|
+
* Convert Markdown text to a Feishu interactive card v2 structure.
|
|
48
|
+
*
|
|
49
|
+
* Uses the card v2 `markdown` component which natively renders full CommonMark
|
|
50
|
+
* syntax including bold, italic, strikethrough, links, lists, code blocks,
|
|
51
|
+
* blockquotes, headings, and tables.
|
|
40
52
|
*
|
|
41
|
-
*
|
|
42
|
-
* strikethrough, links, and code blocks. We only preprocess syntax that
|
|
43
|
-
* lark_md does not support (checkboxes, blockquotes).
|
|
53
|
+
* Only checkboxes need preprocessing (not supported by card markdown).
|
|
44
54
|
*/
|
|
45
55
|
export declare function markdownToCard(markdown: string): CardContent;
|
|
56
|
+
/**
|
|
57
|
+
* Replace `@name` patterns in post content with Feishu `{ tag: 'at', user_id }` elements.
|
|
58
|
+
* Mutates the post in-place.
|
|
59
|
+
*/
|
|
60
|
+
export declare function injectMentionsIntoPost(post: PostContent, mentions: Array<{
|
|
61
|
+
name: string;
|
|
62
|
+
platformId: string;
|
|
63
|
+
}>): void;
|
|
46
64
|
//# sourceMappingURL=feishu-format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feishu-format.d.ts","sourceRoot":"","sources":["../../src/channels/feishu-format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE;QACL,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;KAC1B,CAAC;CACH;AAMD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"feishu-format.d.ts","sourceRoot":"","sources":["../../src/channels/feishu-format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE;QACL,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;KAC1B,CAAC;CACH;AAMD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;IAClC,MAAM,CAAC,EAAE;QACP,KAAK,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAsBD,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAOD,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAuC5D;AAsHD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAc5D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,IAAI,CAuDN"}
|
|
@@ -81,15 +81,10 @@ function parseLine(line) {
|
|
|
81
81
|
const icon = checkboxMatch[1].toLowerCase() === 'x' ? '\u2705 ' : '\u2B1C ';
|
|
82
82
|
return [{ tag: 'text', text: icon }, ...parseInline(checkboxMatch[2])];
|
|
83
83
|
}
|
|
84
|
-
// Unordered list
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
return [{ tag: 'text', text: '
|
|
88
|
-
}
|
|
89
|
-
// Ordered list
|
|
90
|
-
const orderedMatch = trimmed.match(/^(\d+)\.\s+(.+)$/);
|
|
91
|
-
if (orderedMatch) {
|
|
92
|
-
return [{ tag: 'text', text: `${orderedMatch[1]}. ` }, ...parseInline(orderedMatch[2])];
|
|
84
|
+
// Unordered list: - item → • item
|
|
85
|
+
const ulMatch = trimmed.match(/^[-*]\s+(.+)$/);
|
|
86
|
+
if (ulMatch) {
|
|
87
|
+
return [{ tag: 'text', text: '• ' }, ...parseInline(ulMatch[1])];
|
|
93
88
|
}
|
|
94
89
|
// Horizontal rule
|
|
95
90
|
if (/^[-*_]{3,}$/.test(trimmed)) {
|
|
@@ -172,41 +167,93 @@ function parseInline(text) {
|
|
|
172
167
|
// Markdown -> Card (interactive)
|
|
173
168
|
// ---------------------------------------------------------------------------
|
|
174
169
|
/**
|
|
175
|
-
* Convert Markdown text to a Feishu interactive card structure.
|
|
170
|
+
* Convert Markdown text to a Feishu interactive card v2 structure.
|
|
171
|
+
*
|
|
172
|
+
* Uses the card v2 `markdown` component which natively renders full CommonMark
|
|
173
|
+
* syntax including bold, italic, strikethrough, links, lists, code blocks,
|
|
174
|
+
* blockquotes, headings, and tables.
|
|
176
175
|
*
|
|
177
|
-
*
|
|
178
|
-
* strikethrough, links, and code blocks. We only preprocess syntax that
|
|
179
|
-
* lark_md does not support (checkboxes, blockquotes).
|
|
176
|
+
* Only checkboxes need preprocessing (not supported by card markdown).
|
|
180
177
|
*/
|
|
181
178
|
export function markdownToCard(markdown) {
|
|
182
179
|
const preprocessed = preprocessForCard(markdown);
|
|
183
180
|
return {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
181
|
+
schema: '2.0',
|
|
182
|
+
body: {
|
|
183
|
+
elements: [
|
|
184
|
+
{
|
|
185
|
+
tag: 'markdown',
|
|
186
|
+
content: preprocessed,
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
191
190
|
};
|
|
192
191
|
}
|
|
193
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Replace `@name` patterns in post content with Feishu `{ tag: 'at', user_id }` elements.
|
|
194
|
+
* Mutates the post in-place.
|
|
195
|
+
*/
|
|
196
|
+
export function injectMentionsIntoPost(post, mentions) {
|
|
197
|
+
if (!mentions.length)
|
|
198
|
+
return;
|
|
199
|
+
const mentionMap = new Map(mentions.map(m => [m.name, m.platformId]));
|
|
200
|
+
for (let i = 0; i < post.zh_cn.content.length; i++) {
|
|
201
|
+
const line = post.zh_cn.content[i];
|
|
202
|
+
const newLine = [];
|
|
203
|
+
for (const el of line) {
|
|
204
|
+
if (el.tag !== 'text' || !el.text) {
|
|
205
|
+
newLine.push(el);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// Split text on @name patterns and replace with at elements
|
|
209
|
+
let remaining = el.text;
|
|
210
|
+
const mentionPattern = /@([\w\u4e00-\u9fff]{1,20})/g;
|
|
211
|
+
let lastIdx = 0;
|
|
212
|
+
let match;
|
|
213
|
+
// Reset regex state
|
|
214
|
+
mentionPattern.lastIndex = 0;
|
|
215
|
+
const parts = [];
|
|
216
|
+
while ((match = mentionPattern.exec(remaining)) !== null) {
|
|
217
|
+
const name = match[1];
|
|
218
|
+
const userId = mentionMap.get(name);
|
|
219
|
+
if (!userId)
|
|
220
|
+
continue;
|
|
221
|
+
// Text before the mention
|
|
222
|
+
if (match.index > lastIdx) {
|
|
223
|
+
const beforeText = remaining.slice(lastIdx, match.index);
|
|
224
|
+
parts.push({ ...el, text: beforeText });
|
|
225
|
+
}
|
|
226
|
+
// The @mention element
|
|
227
|
+
parts.push({ tag: 'at', user_id: userId });
|
|
228
|
+
lastIdx = match.index + match[0].length;
|
|
229
|
+
}
|
|
230
|
+
if (parts.length === 0) {
|
|
231
|
+
// No mentions found in this element
|
|
232
|
+
newLine.push(el);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Remaining text after last mention
|
|
236
|
+
if (lastIdx < remaining.length) {
|
|
237
|
+
parts.push({ ...el, text: remaining.slice(lastIdx) });
|
|
238
|
+
}
|
|
239
|
+
newLine.push(...parts);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
post.zh_cn.content[i] = newLine;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/** Preprocess Markdown for card v2 markdown component. */
|
|
194
246
|
function preprocessForCard(text) {
|
|
195
247
|
return text
|
|
196
248
|
.split('\n')
|
|
197
249
|
.map((line) => {
|
|
198
250
|
const trimmed = line.trim();
|
|
199
|
-
// Checkbox -> emoji
|
|
251
|
+
// Checkbox -> emoji (not supported by card markdown)
|
|
200
252
|
const cbMatch = trimmed.match(/^[-*]\s+\[([ xX])\]\s+(.+)$/);
|
|
201
253
|
if (cbMatch) {
|
|
202
254
|
const icon = cbMatch[1].toLowerCase() === 'x' ? '\u2705' : '\u2B1C';
|
|
203
255
|
return `${icon} ${cbMatch[2]}`;
|
|
204
256
|
}
|
|
205
|
-
// Blockquote -> emoji prefix
|
|
206
|
-
const quoteMatch = trimmed.match(/^>\s*(.*)$/);
|
|
207
|
-
if (quoteMatch) {
|
|
208
|
-
return `\uD83D\uDCAC ${quoteMatch[1]}`;
|
|
209
|
-
}
|
|
210
257
|
return line;
|
|
211
258
|
})
|
|
212
259
|
.join('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feishu-format.js","sourceRoot":"","sources":["../../src/channels/feishu-format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"feishu-format.js","sourceRoot":"","sources":["../../src/channels/feishu-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelAdapter, ChannelMessage } from '../channel.js';
|
|
1
|
+
import type { ChannelAdapter, ChannelMessage, ReplyOptions } from '../channel.js';
|
|
2
2
|
import type { FeishuChannelConfig } from '../workspace.js';
|
|
3
3
|
export declare class FeishuAdapter implements ChannelAdapter {
|
|
4
4
|
readonly name = "feishu";
|
|
@@ -7,10 +7,18 @@ export declare class FeishuAdapter implements ChannelAdapter {
|
|
|
7
7
|
private client;
|
|
8
8
|
private wsClient;
|
|
9
9
|
private userNameCache;
|
|
10
|
+
/** Recent message IDs used to deduplicate re-delivered events. */
|
|
11
|
+
private seenMsgIds;
|
|
12
|
+
private static readonly MAX_SEEN;
|
|
13
|
+
/** Cached group members: chatId → (displayName → open_id). */
|
|
14
|
+
private groupMemberCache;
|
|
15
|
+
private groupMemberCacheTime;
|
|
16
|
+
private static readonly MEMBER_CACHE_TTL;
|
|
10
17
|
constructor(config: FeishuChannelConfig);
|
|
11
18
|
private resolveUserName;
|
|
12
19
|
start(onMessage: (msg: ChannelMessage) => void): Promise<void>;
|
|
13
|
-
|
|
20
|
+
getGroupMembers(chatId: string): Promise<Map<string, string>>;
|
|
21
|
+
reply(msg: ChannelMessage, text: string, options?: ReplyOptions): Promise<void>;
|
|
14
22
|
stop(): Promise<void>;
|
|
15
23
|
}
|
|
16
24
|
//# sourceMappingURL=feishu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feishu.d.ts","sourceRoot":"","sources":["../../src/channels/feishu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"feishu.d.ts","sourceRoot":"","sources":["../../src/channels/feishu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AACjG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,qBAAa,aAAc,YAAW,cAAc;IAClD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,gBAAgB,QAAQ;IACjC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAM;IAEtB,OAAO,CAAC,aAAa,CAA6B;IAClD,kEAAkE;IAClE,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAO;IAEvC,8DAA8D;IAC9D,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,oBAAoB,CAA6B;IACzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;gBAE9C,MAAM,EAAE,mBAAmB;YAIzB,eAAe;IAiBvB,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA+H9D,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAuC7D,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC/E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAM5B"}
|