golembot 0.12.0-beta.1 → 0.12.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.
Files changed (48) hide show
  1. package/dist/channel.d.ts +14 -1
  2. package/dist/channel.d.ts.map +1 -1
  3. package/dist/channel.js.map +1 -1
  4. package/dist/channels/dingtalk.d.ts +4 -2
  5. package/dist/channels/dingtalk.d.ts.map +1 -1
  6. package/dist/channels/dingtalk.js +16 -1
  7. package/dist/channels/dingtalk.js.map +1 -1
  8. package/dist/channels/discord.d.ts +4 -2
  9. package/dist/channels/discord.d.ts.map +1 -1
  10. package/dist/channels/discord.js +13 -1
  11. package/dist/channels/discord.js.map +1 -1
  12. package/dist/channels/feishu-format.d.ts +25 -7
  13. package/dist/channels/feishu-format.d.ts.map +1 -1
  14. package/dist/channels/feishu-format.js +74 -27
  15. package/dist/channels/feishu-format.js.map +1 -1
  16. package/dist/channels/feishu.d.ts +10 -2
  17. package/dist/channels/feishu.d.ts.map +1 -1
  18. package/dist/channels/feishu.js +74 -26
  19. package/dist/channels/feishu.js.map +1 -1
  20. package/dist/channels/slack-format.d.ts +20 -0
  21. package/dist/channels/slack-format.d.ts.map +1 -0
  22. package/dist/channels/slack-format.js +132 -0
  23. package/dist/channels/slack-format.js.map +1 -0
  24. package/dist/channels/slack.d.ts +5 -2
  25. package/dist/channels/slack.d.ts.map +1 -1
  26. package/dist/channels/slack.js +21 -2
  27. package/dist/channels/slack.js.map +1 -1
  28. package/dist/channels/telegram-format.d.ts +21 -0
  29. package/dist/channels/telegram-format.d.ts.map +1 -0
  30. package/dist/channels/telegram-format.js +167 -0
  31. package/dist/channels/telegram-format.js.map +1 -0
  32. package/dist/channels/telegram.d.ts +4 -2
  33. package/dist/channels/telegram.d.ts.map +1 -1
  34. package/dist/channels/telegram.js +16 -2
  35. package/dist/channels/telegram.js.map +1 -1
  36. package/dist/channels/wecom.d.ts +4 -2
  37. package/dist/channels/wecom.d.ts.map +1 -1
  38. package/dist/channels/wecom.js +17 -1
  39. package/dist/channels/wecom.js.map +1 -1
  40. package/dist/gateway.d.ts +10 -2
  41. package/dist/gateway.d.ts.map +1 -1
  42. package/dist/gateway.js +38 -2
  43. package/dist/gateway.js.map +1 -1
  44. package/dist/workspace.d.ts +0 -2
  45. package/dist/workspace.d.ts.map +1 -1
  46. package/dist/workspace.js.map +1 -1
  47. package/package.json +1 -1
  48. package/skills/im-adapter/SKILL.md +11 -6
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
  /**
@@ -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;IACxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;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"}
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"}
@@ -1 +1 @@
1
- {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AA+BA,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
+ {"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;AACpE,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;gBAEV,MAAM,EAAE,qBAAqB;IAInC,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA+C9D,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
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":"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"}
1
+ {"version":3,"file":"dingtalk.js","sourceRoot":"","sources":["../../src/channels/dingtalk.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 { 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;AACpE,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;gBAEf,MAAM,EAAE,oBAAoB;IAIlC,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgE9E,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,MAAM,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B"}
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"}
@@ -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":"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"}
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
- config: {
30
- wide_screen_mode: boolean;
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
- * Feishu cards support `lark_md` which natively renders bold, italic,
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;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QAAE,gBAAgB,EAAE,OAAO,CAAA;KAAE,CAAC;IACtC,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAsBD,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAMD,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAuC5D;AA4HD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAY5D"}
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 listMatch = trimmed.match(/^[-*]\s+(.+)$/);
86
- if (listMatch) {
87
- return [{ tag: 'text', text: '\u2022 ' }, ...parseInline(listMatch[1])];
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
- * Feishu cards support `lark_md` which natively renders bold, italic,
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
- config: { wide_screen_mode: true },
185
- elements: [
186
- {
187
- tag: 'div',
188
- text: { tag: 'lark_md', content: preprocessed },
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
- /** Preprocess Markdown for lark_md compatibility. */
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":"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"}
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
- reply(msg: ChannelMessage, text: string): Promise<void>;
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;AACpE,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;gBAEtC,MAAM,EAAE,mBAAmB;YAIzB,eAAe;IAiBvB,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAyG9D,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAM5B"}
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;IAqH9D,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"}
@@ -1,4 +1,4 @@
1
- import { hasMarkdown, markdownToPost, markdownToCard } from './feishu-format.js';
1
+ import { hasMarkdown, markdownToCard } from './feishu-format.js';
2
2
  export class FeishuAdapter {
3
3
  name = 'feishu';
4
4
  maxMessageLength = 4000;
@@ -6,6 +6,13 @@ export class FeishuAdapter {
6
6
  client;
7
7
  wsClient;
8
8
  userNameCache = new Map();
9
+ /** Recent message IDs used to deduplicate re-delivered events. */
10
+ seenMsgIds = new Set();
11
+ static MAX_SEEN = 500;
12
+ /** Cached group members: chatId → (displayName → open_id). */
13
+ groupMemberCache = new Map();
14
+ groupMemberCacheTime = new Map();
15
+ static MEMBER_CACHE_TTL = 10 * 60 * 1000; // 10 minutes
9
16
  constructor(config) {
10
17
  this.config = config;
11
18
  }
@@ -66,6 +73,18 @@ export class FeishuAdapter {
66
73
  const eventDispatcher = new lark.EventDispatcher({}).register({
67
74
  'im.message.receive_v1': async (data) => {
68
75
  const { message, sender } = data;
76
+ // Deduplicate re-delivered events.
77
+ const msgId = message.message_id;
78
+ if (msgId) {
79
+ if (this.seenMsgIds.has(msgId))
80
+ return;
81
+ this.seenMsgIds.add(msgId);
82
+ if (this.seenMsgIds.size > FeishuAdapter.MAX_SEEN) {
83
+ // Evict oldest half.
84
+ const entries = [...this.seenMsgIds];
85
+ this.seenMsgIds = new Set(entries.slice(entries.length >> 1));
86
+ }
87
+ }
69
88
  if (message.message_type !== 'text')
70
89
  return;
71
90
  let content;
@@ -119,34 +138,63 @@ export class FeishuAdapter {
119
138
  await this.wsClient.start({ eventDispatcher });
120
139
  console.log(`[feishu] WebSocket connection established`);
121
140
  }
122
- async reply(msg, text) {
141
+ async getGroupMembers(chatId) {
142
+ const cached = this.groupMemberCache.get(chatId);
143
+ const ts = this.groupMemberCacheTime.get(chatId) ?? 0;
144
+ if (cached && Date.now() - ts < FeishuAdapter.MEMBER_CACHE_TTL)
145
+ return cached;
123
146
  if (!this.client)
124
- return;
125
- if (hasMarkdown(text)) {
126
- if (this.config.sendMarkdownAsCard) {
127
- // Interactive card native lark_md rendering
128
- const card = markdownToCard(text);
129
- await this.client.im.v1.message.create({
130
- params: { receive_id_type: 'chat_id' },
131
- data: {
132
- receive_id: msg.chatId,
133
- content: JSON.stringify(card),
134
- msg_type: 'interactive',
135
- },
136
- });
137
- }
138
- else {
139
- // Post rich text (default)
140
- const post = markdownToPost(text);
141
- await this.client.im.v1.message.create({
142
- params: { receive_id_type: 'chat_id' },
143
- data: {
144
- receive_id: msg.chatId,
145
- content: JSON.stringify(post),
146
- msg_type: 'post',
147
- },
147
+ return new Map();
148
+ try {
149
+ const token = await this.client.tokenManager.getTenantAccessToken();
150
+ const members = new Map();
151
+ let pageToken;
152
+ do {
153
+ const url = new URL(`https://open.feishu.cn/open-apis/im/v1/chats/${chatId}/members`);
154
+ url.searchParams.set('member_id_type', 'open_id');
155
+ if (pageToken)
156
+ url.searchParams.set('page_token', pageToken);
157
+ const resp = await fetch(url.toString(), {
158
+ headers: { Authorization: `Bearer ${token}` },
148
159
  });
160
+ const json = (await resp.json());
161
+ for (const item of json?.data?.items ?? []) {
162
+ if (item.name && item.member_id) {
163
+ members.set(item.name, item.member_id);
164
+ }
165
+ }
166
+ pageToken = json?.data?.has_more ? json?.data?.page_token : undefined;
167
+ } while (pageToken);
168
+ this.groupMemberCache.set(chatId, members);
169
+ this.groupMemberCacheTime.set(chatId, Date.now());
170
+ return members;
171
+ }
172
+ catch {
173
+ return cached ?? new Map();
174
+ }
175
+ }
176
+ async reply(msg, text, options) {
177
+ if (!this.client)
178
+ return;
179
+ const mentions = options?.mentions;
180
+ const hasMentions = mentions && mentions.length > 0;
181
+ if (hasMarkdown(text) || hasMentions) {
182
+ // Card v2 (default) — best markdown rendering with native headings, lists, code blocks
183
+ let mdText = text;
184
+ if (hasMentions) {
185
+ for (const m of mentions) {
186
+ mdText = mdText.replace(new RegExp(`@${m.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`, 'g'), `<at id=${m.platformId}></at>`);
187
+ }
149
188
  }
189
+ const card = markdownToCard(mdText);
190
+ await this.client.im.v1.message.create({
191
+ params: { receive_id_type: 'chat_id' },
192
+ data: {
193
+ receive_id: msg.chatId,
194
+ content: JSON.stringify(card),
195
+ msg_type: 'interactive',
196
+ },
197
+ });
150
198
  }
151
199
  else {
152
200
  // Plain text