@openclaw/feishu 2026.3.12 → 2026.3.13

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/src/send.ts CHANGED
@@ -43,6 +43,10 @@ function isWithdrawnReplyError(err: unknown): boolean {
43
43
  type FeishuCreateMessageClient = {
44
44
  im: {
45
45
  message: {
46
+ reply: (opts: {
47
+ path: { message_id: string };
48
+ data: { content: string; msg_type: string; reply_in_thread?: true };
49
+ }) => Promise<{ code?: number; msg?: string; data?: { message_id?: string } }>;
46
50
  create: (opts: {
47
51
  params: { receive_id_type: "chat_id" | "email" | "open_id" | "union_id" | "user_id" };
48
52
  data: { receive_id: string; content: string; msg_type: string };
@@ -51,6 +55,30 @@ type FeishuCreateMessageClient = {
51
55
  };
52
56
  };
53
57
 
58
+ type FeishuMessageSender = {
59
+ id?: string;
60
+ id_type?: string;
61
+ sender_type?: string;
62
+ };
63
+
64
+ type FeishuMessageGetItem = {
65
+ message_id?: string;
66
+ chat_id?: string;
67
+ chat_type?: FeishuChatType;
68
+ msg_type?: string;
69
+ body?: { content?: string };
70
+ sender?: FeishuMessageSender;
71
+ create_time?: string;
72
+ };
73
+
74
+ type FeishuGetMessageResponse = {
75
+ code?: number;
76
+ msg?: string;
77
+ data?: FeishuMessageGetItem & {
78
+ items?: FeishuMessageGetItem[];
79
+ };
80
+ };
81
+
54
82
  /** Send a direct message as a fallback when a reply target is unavailable. */
55
83
  async function sendFallbackDirect(
56
84
  client: FeishuCreateMessageClient,
@@ -74,6 +102,50 @@ async function sendFallbackDirect(
74
102
  return toFeishuSendResult(response, params.receiveId);
75
103
  }
76
104
 
105
+ async function sendReplyOrFallbackDirect(
106
+ client: FeishuCreateMessageClient,
107
+ params: {
108
+ replyToMessageId?: string;
109
+ replyInThread?: boolean;
110
+ content: string;
111
+ msgType: string;
112
+ directParams: {
113
+ receiveId: string;
114
+ receiveIdType: "chat_id" | "email" | "open_id" | "union_id" | "user_id";
115
+ content: string;
116
+ msgType: string;
117
+ };
118
+ directErrorPrefix: string;
119
+ replyErrorPrefix: string;
120
+ },
121
+ ): Promise<FeishuSendResult> {
122
+ if (!params.replyToMessageId) {
123
+ return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
124
+ }
125
+
126
+ let response: { code?: number; msg?: string; data?: { message_id?: string } };
127
+ try {
128
+ response = await client.im.message.reply({
129
+ path: { message_id: params.replyToMessageId },
130
+ data: {
131
+ content: params.content,
132
+ msg_type: params.msgType,
133
+ ...(params.replyInThread ? { reply_in_thread: true } : {}),
134
+ },
135
+ });
136
+ } catch (err) {
137
+ if (!isWithdrawnReplyError(err)) {
138
+ throw err;
139
+ }
140
+ return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
141
+ }
142
+ if (shouldFallbackFromReplyTarget(response)) {
143
+ return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
144
+ }
145
+ assertFeishuMessageApiSuccess(response, params.replyErrorPrefix);
146
+ return toFeishuSendResult(response, params.directParams.receiveId);
147
+ }
148
+
77
149
  function parseInteractiveCardContent(parsed: unknown): string {
78
150
  if (!parsed || typeof parsed !== "object") {
79
151
  return "[Interactive Card]";
@@ -166,36 +238,7 @@ export async function getMessageFeishu(params: {
166
238
  try {
167
239
  const response = (await client.im.message.get({
168
240
  path: { message_id: messageId },
169
- })) as {
170
- code?: number;
171
- msg?: string;
172
- data?: {
173
- items?: Array<{
174
- message_id?: string;
175
- chat_id?: string;
176
- chat_type?: FeishuChatType;
177
- msg_type?: string;
178
- body?: { content?: string };
179
- sender?: {
180
- id?: string;
181
- id_type?: string;
182
- sender_type?: string;
183
- };
184
- create_time?: string;
185
- }>;
186
- message_id?: string;
187
- chat_id?: string;
188
- chat_type?: FeishuChatType;
189
- msg_type?: string;
190
- body?: { content?: string };
191
- sender?: {
192
- id?: string;
193
- id_type?: string;
194
- sender_type?: string;
195
- };
196
- create_time?: string;
197
- };
198
- };
241
+ })) as FeishuGetMessageResponse;
199
242
 
200
243
  if (response.code !== 0) {
201
244
  return null;
@@ -290,32 +333,15 @@ export async function sendMessageFeishu(
290
333
  const { content, msgType } = buildFeishuPostMessagePayload({ messageText });
291
334
 
292
335
  const directParams = { receiveId, receiveIdType, content, msgType };
293
-
294
- if (replyToMessageId) {
295
- let response: { code?: number; msg?: string; data?: { message_id?: string } };
296
- try {
297
- response = await client.im.message.reply({
298
- path: { message_id: replyToMessageId },
299
- data: {
300
- content,
301
- msg_type: msgType,
302
- ...(replyInThread ? { reply_in_thread: true } : {}),
303
- },
304
- });
305
- } catch (err) {
306
- if (!isWithdrawnReplyError(err)) {
307
- throw err;
308
- }
309
- return sendFallbackDirect(client, directParams, "Feishu send failed");
310
- }
311
- if (shouldFallbackFromReplyTarget(response)) {
312
- return sendFallbackDirect(client, directParams, "Feishu send failed");
313
- }
314
- assertFeishuMessageApiSuccess(response, "Feishu reply failed");
315
- return toFeishuSendResult(response, receiveId);
316
- }
317
-
318
- return sendFallbackDirect(client, directParams, "Feishu send failed");
336
+ return sendReplyOrFallbackDirect(client, {
337
+ replyToMessageId,
338
+ replyInThread,
339
+ content,
340
+ msgType,
341
+ directParams,
342
+ directErrorPrefix: "Feishu send failed",
343
+ replyErrorPrefix: "Feishu reply failed",
344
+ });
319
345
  }
320
346
 
321
347
  export type SendFeishuCardParams = {
@@ -334,32 +360,15 @@ export async function sendCardFeishu(params: SendFeishuCardParams): Promise<Feis
334
360
  const content = JSON.stringify(card);
335
361
 
336
362
  const directParams = { receiveId, receiveIdType, content, msgType: "interactive" };
337
-
338
- if (replyToMessageId) {
339
- let response: { code?: number; msg?: string; data?: { message_id?: string } };
340
- try {
341
- response = await client.im.message.reply({
342
- path: { message_id: replyToMessageId },
343
- data: {
344
- content,
345
- msg_type: "interactive",
346
- ...(replyInThread ? { reply_in_thread: true } : {}),
347
- },
348
- });
349
- } catch (err) {
350
- if (!isWithdrawnReplyError(err)) {
351
- throw err;
352
- }
353
- return sendFallbackDirect(client, directParams, "Feishu card send failed");
354
- }
355
- if (shouldFallbackFromReplyTarget(response)) {
356
- return sendFallbackDirect(client, directParams, "Feishu card send failed");
357
- }
358
- assertFeishuMessageApiSuccess(response, "Feishu card reply failed");
359
- return toFeishuSendResult(response, receiveId);
360
- }
361
-
362
- return sendFallbackDirect(client, directParams, "Feishu card send failed");
363
+ return sendReplyOrFallbackDirect(client, {
364
+ replyToMessageId,
365
+ replyInThread,
366
+ content,
367
+ msgType: "interactive",
368
+ directParams,
369
+ directErrorPrefix: "Feishu card send failed",
370
+ replyErrorPrefix: "Feishu card reply failed",
371
+ });
363
372
  }
364
373
 
365
374
  export async function updateCardFeishu(params: {