@milerliu/feishu 0.1.12 → 0.1.14

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 +74 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milerliu/feishu",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "type": "module",
5
5
  "description": "OpenClaw Feishu/Lark channel plugin",
6
6
  "license": "MIT",
package/src/send.ts CHANGED
@@ -48,43 +48,91 @@ export async function sendStreamingMessageFeishu(params: {
48
48
  rawText = buildMentionedMessage(mentions, rawText);
49
49
  }
50
50
 
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
- }
51
+ // Create interactive card with streaming_update enabled
52
+ const card = {
53
+ header: {
54
+ title: {
55
+ tag: "plain_text",
56
+ content: "AI 回复",
57
+ },
58
+ },
59
+ config: {
60
+ wide_screen_mode: true,
61
+ streaming_update: true,
62
+ },
63
+ elements: [
64
+ {
65
+ tag: "markdown",
66
+ content: rawText,
67
+ },
68
+ ],
69
+ };
57
70
 
58
- // Send first chunk
59
- const firstContent = JSON.stringify({ text: chunks[0] });
60
- const firstResponse = await client.im.message.create({
71
+ const cardContent = JSON.stringify(card);
72
+
73
+ // Create the card message
74
+ const messageResponse = await client.im.message.create({
61
75
  params: { receive_id_type: receiveIdType },
62
76
  data: {
63
77
  receive_id: receiveId,
64
- content: firstContent,
65
- msg_type: "text",
78
+ content: cardContent,
79
+ msg_type: "interactive",
66
80
  },
67
81
  });
68
82
 
69
- if (firstResponse.code !== 0) {
70
- throw new Error(`Feishu streaming send failed: ${firstResponse.msg || `code ${firstResponse.code}`}`);
83
+ if (messageResponse.code !== 0) {
84
+ throw new Error(`Failed to send streaming card: ${messageResponse.msg || `code ${messageResponse.code}`}`);
71
85
  }
72
86
 
73
- const messageId = firstResponse.data?.message_id ?? "unknown";
87
+ const messageId = messageResponse.data?.message_id ?? "unknown";
74
88
 
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] });
79
-
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",
89
+ // Now update the message multiple times for streaming effect
90
+ // Use im.v1.message.update API
91
+ const chunkSize = 500;
92
+ const chunks: string[] = [];
93
+ for (let i = 0; i < rawText.length; i += chunkSize) {
94
+ chunks.push(rawText.slice(i, i + chunkSize));
95
+ }
96
+
97
+ // Send updates with delay
98
+ for (let i = 0; i < chunks.length; i++) {
99
+ const updateCard = {
100
+ header: {
101
+ title: {
102
+ tag: "plain_text",
103
+ content: "AI 回复",
104
+ },
86
105
  },
87
- });
106
+ config: {
107
+ wide_screen_mode: true,
108
+ streaming_update: true,
109
+ },
110
+ elements: [
111
+ {
112
+ tag: "markdown",
113
+ content: chunks[i],
114
+ },
115
+ ],
116
+ };
117
+
118
+ const updateContent = JSON.stringify(updateCard);
119
+
120
+ try {
121
+ await (client as any).im.v1.message.update({
122
+ path: { message_id: messageId },
123
+ data: {
124
+ msg_type: "interactive",
125
+ content: updateContent,
126
+ },
127
+ });
128
+ } catch (err) {
129
+ console.error(`Message update failed: ${err}`);
130
+ }
131
+
132
+ // Delay between updates
133
+ if (i < chunks.length - 1) {
134
+ await new Promise((resolve) => setTimeout(resolve, 150));
135
+ }
88
136
  }
89
137
 
90
138
  return {