@milerliu/feishu 0.1.10 → 0.1.12

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/send.ts +27 -95
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milerliu/feishu",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "description": "OpenClaw Feishu/Lark channel plugin",
6
6
  "license": "MIT",
package/src/send.ts CHANGED
@@ -41,118 +41,50 @@ export async function sendStreamingMessageFeishu(params: {
41
41
  }
42
42
 
43
43
  const receiveIdType = resolveReceiveIdType(receiveId);
44
- const tableMode = getFeishuRuntime().channel.text.resolveMarkdownTableMode({
45
- cfg,
46
- channel: "feishu",
47
- });
48
44
 
49
- // Build message content (with @mention support)
45
+ // Build message content with @mention support
50
46
  let rawText = text ?? "";
51
47
  if (mentions && mentions.length > 0) {
52
- rawText = buildMentionedCardContent(mentions, rawText);
48
+ rawText = buildMentionedMessage(mentions, rawText);
53
49
  }
54
- const messageText = getFeishuRuntime().channel.text.convertMarkdownTables(rawText, tableMode);
55
50
 
56
- // Build initial card with streaming_update header for proper streaming behavior
57
- const initialCard = {
58
- header: {
59
- title: {
60
- tag: "plain_text",
61
- content: "AI 回复",
62
- },
63
- },
64
- config: {
65
- wide_screen_mode: true,
66
- streaming_update: true, // Enable streaming update mode
67
- },
68
- elements: [
69
- {
70
- tag: "markdown",
71
- content: "",
72
- },
73
- ],
74
- };
75
-
76
- const content = JSON.stringify(initialCard);
51
+ // Split text into chunks for streaming effect
52
+ const chunkSize = 300;
53
+ const chunks: string[] = [];
54
+ for (let i = 0; i < rawText.length; i += chunkSize) {
55
+ chunks.push(rawText.slice(i, i + chunkSize));
56
+ }
77
57
 
78
- // Create initial card with empty content
79
- const response = await client.im.message.create({
58
+ // Send first chunk
59
+ const firstContent = JSON.stringify({ text: chunks[0] });
60
+ const firstResponse = await client.im.message.create({
80
61
  params: { receive_id_type: receiveIdType },
81
62
  data: {
82
63
  receive_id: receiveId,
83
- content,
84
- msg_type: "interactive",
64
+ content: firstContent,
65
+ msg_type: "text",
85
66
  },
86
67
  });
87
68
 
88
- if (response.code !== 0) {
89
- throw new Error(`Feishu streaming card creation failed: ${response.msg || `code ${response.code}`}`);
90
- }
91
-
92
- const messageId = response.data?.message_id ?? "unknown";
93
-
94
- // Extract card_id from response
95
- const cardData = response.data as Record<string, unknown> | undefined;
96
- const cardId = cardData?.card_id as string | undefined;
97
-
98
- if (!cardId) {
99
- console.warn('No card_id returned, falling back to regular card send');
100
- const fallbackCard = buildMarkdownCard(messageText);
101
- return sendCardFeishu({ cfg, to, card: fallbackCard });
69
+ if (firstResponse.code !== 0) {
70
+ throw new Error(`Feishu streaming send failed: ${firstResponse.msg || `code ${firstResponse.code}`}`);
102
71
  }
103
72
 
104
- // Stream content updates using Feishu message patch API
105
- const chunkSize = 300;
106
- const chunks: string[] = [];
107
- for (let i = 0; i < messageText.length; i += chunkSize) {
108
- chunks.push(messageText.slice(i, i + chunkSize));
109
- }
73
+ const messageId = firstResponse.data?.message_id ?? "unknown";
110
74
 
111
- // Send updates with small delay
112
- for (let i = 0; i < chunks.length; i++) {
113
- const partialContent = chunks.slice(0, i + 1).join("");
75
+ // Send remaining chunks as separate messages
76
+ for (let i = 1; i < chunks.length; i++) {
77
+ await new Promise((resolve) => setTimeout(resolve, 100));
78
+ const chunkContent = JSON.stringify({ text: chunks[i] });
114
79
 
115
- const updateCard = {
116
- header: {
117
- title: {
118
- tag: "plain_text",
119
- content: "AI 回复",
120
- },
121
- },
122
- config: {
123
- wide_screen_mode: true,
124
- streaming_update: true,
80
+ await client.im.message.create({
81
+ params: { receive_id_type: receiveIdType },
82
+ data: {
83
+ receive_id: receiveId,
84
+ content: chunkContent,
85
+ msg_type: "text",
125
86
  },
126
- elements: [
127
- {
128
- tag: "markdown",
129
- content: partialContent,
130
- },
131
- ],
132
- };
133
-
134
- const updateContent = JSON.stringify(updateCard);
135
-
136
- try {
137
- // Use im v1 message patch API for card updates
138
- const updateResponse = await (client as any).im.v1.message.patch({
139
- path: { message_id: messageId },
140
- data: {
141
- msg_type: "interactive",
142
- content: updateContent,
143
- },
144
- });
145
-
146
- if (updateResponse.code !== 0) {
147
- console.error(`Message patch failed: ${updateResponse.msg}`);
148
- }
149
- } catch (err) {
150
- console.error(`Message patch error: ${err}`);
151
- }
152
-
153
- if (i < chunks.length - 1) {
154
- await new Promise((resolve) => setTimeout(resolve, 150));
155
- }
87
+ });
156
88
  }
157
89
 
158
90
  return {