@max1874/feishu 0.2.25 → 0.2.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max1874/feishu",
3
- "version": "0.2.25",
3
+ "version": "0.2.27",
4
4
  "type": "module",
5
5
  "description": "OpenClaw Feishu/Lark channel plugin",
6
6
  "license": "MIT",
package/src/channel.ts CHANGED
@@ -55,6 +55,7 @@ export const feishuPlugin: ChannelPlugin<ResolvedFeishuAccount> = {
55
55
  messageToolHints: () => [
56
56
  "- Feishu targeting: omit `target` to reply to the current conversation (auto-inferred). Explicit targets: `user:open_id` or `chat:chat_id`.",
57
57
  "- Feishu supports interactive cards for rich messages.",
58
+ "- Use feishu_chat_messages to read message history. Omit chat_id to read from the current conversation.",
58
59
  ],
59
60
  },
60
61
  groups: {
package/src/docx.ts CHANGED
@@ -868,6 +868,13 @@ const SetPermissionSchema = Type.Object({
868
868
  }),
869
869
  });
870
870
 
871
+ const TransferOwnerSchema = Type.Object({
872
+ doc_token: Type.String({ description: "Document token" }),
873
+ new_owner_open_id: Type.Optional(
874
+ Type.String({ description: "Open ID of the new owner. Omit to transfer to the current conversation sender." }),
875
+ ),
876
+ });
877
+
871
878
  // Wiki Schemas
872
879
  const WikiTokenSchema = Type.Object({
873
880
  wiki_token: Type.String({ description: "Wiki token (extract from URL /wiki/XXX)" }),
@@ -1247,5 +1254,145 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
1247
1254
  { name: "feishu_app_scopes" },
1248
1255
  );
1249
1256
 
1250
- api.logger.info?.(`feishu_doc: Registered 14 document/wiki tools`);
1257
+ // Tool 15: feishu_chat_messages
1258
+ const ChatMessagesSchema = Type.Object({
1259
+ chat_id: Type.Optional(
1260
+ Type.String({
1261
+ description: "Chat ID (oc_xxx). Omit to use the current conversation.",
1262
+ }),
1263
+ ),
1264
+ start_time: Type.Optional(
1265
+ Type.String({ description: "Start time, Unix timestamp in seconds" }),
1266
+ ),
1267
+ end_time: Type.Optional(
1268
+ Type.String({ description: "End time, Unix timestamp in seconds" }),
1269
+ ),
1270
+ sort_type: Type.Optional(
1271
+ Type.Union([Type.Literal("ByCreateTimeAsc"), Type.Literal("ByCreateTimeDesc")], {
1272
+ description: "Sort order (default: ByCreateTimeDesc)",
1273
+ }),
1274
+ ),
1275
+ page_size: Type.Optional(
1276
+ Type.Number({ description: "Page size, 1-50 (default 20)" }),
1277
+ ),
1278
+ page_token: Type.Optional(
1279
+ Type.String({ description: "Pagination token from previous response" }),
1280
+ ),
1281
+ });
1282
+
1283
+ api.registerTool(
1284
+ {
1285
+ name: "feishu_chat_messages",
1286
+ label: "Feishu Chat Messages",
1287
+ description:
1288
+ "Read message history from a Feishu chat (group or DM). " +
1289
+ "Omit chat_id to read from the current conversation. " +
1290
+ "Returns messages with sender info, content, and timestamps. " +
1291
+ "Requires im:message scope; bot must be a member of the chat.",
1292
+ parameters: ChatMessagesSchema,
1293
+ async execute(_toolCallId, params) {
1294
+ const {
1295
+ chat_id,
1296
+ start_time,
1297
+ end_time,
1298
+ sort_type,
1299
+ page_size,
1300
+ page_token,
1301
+ } = params as {
1302
+ chat_id?: string;
1303
+ start_time?: string;
1304
+ end_time?: string;
1305
+ sort_type?: "ByCreateTimeAsc" | "ByCreateTimeDesc";
1306
+ page_size?: number;
1307
+ page_token?: string;
1308
+ };
1309
+ try {
1310
+ const container_id = chat_id || getConversationContext()?.chatId;
1311
+ if (!container_id) {
1312
+ return json({
1313
+ error:
1314
+ "No chat_id provided and no current conversation context available.",
1315
+ });
1316
+ }
1317
+
1318
+ const client = getClient();
1319
+ const res = await client.im.message.list({
1320
+ params: {
1321
+ container_id_type: "chat",
1322
+ container_id,
1323
+ ...(start_time && { start_time }),
1324
+ ...(end_time && { end_time }),
1325
+ ...(sort_type && { sort_type }),
1326
+ ...(page_size && { page_size }),
1327
+ ...(page_token && { page_token }),
1328
+ },
1329
+ });
1330
+
1331
+ if (res.code !== 0) throw new Error(res.msg);
1332
+
1333
+ const messages = (res.data?.items ?? []).map((m) => {
1334
+ let content: unknown = m.body?.content;
1335
+ if (typeof content === "string") {
1336
+ try {
1337
+ content = JSON.parse(content);
1338
+ } catch {
1339
+ // keep raw string
1340
+ }
1341
+ }
1342
+ return {
1343
+ message_id: m.message_id,
1344
+ msg_type: m.msg_type,
1345
+ sender: m.sender,
1346
+ content,
1347
+ create_time: m.create_time,
1348
+ deleted: m.deleted,
1349
+ };
1350
+ });
1351
+
1352
+ return json({
1353
+ messages,
1354
+ has_more: res.data?.has_more ?? false,
1355
+ page_token: res.data?.page_token,
1356
+ });
1357
+ } catch (err) {
1358
+ return json({ error: err instanceof Error ? err.message : String(err) });
1359
+ }
1360
+ },
1361
+ },
1362
+ { name: "feishu_chat_messages" },
1363
+ );
1364
+
1365
+ // Tool 16: feishu_doc_transfer_owner
1366
+ api.registerTool(
1367
+ {
1368
+ name: "feishu_doc_transfer_owner",
1369
+ label: "Feishu Doc Transfer Owner",
1370
+ description:
1371
+ "Transfer ownership of a Feishu document to another user. " +
1372
+ "If new_owner_open_id is omitted, transfers to the current conversation sender.",
1373
+ parameters: TransferOwnerSchema,
1374
+ async execute(_toolCallId, params) {
1375
+ const { doc_token, new_owner_open_id } = params as {
1376
+ doc_token: string;
1377
+ new_owner_open_id?: string;
1378
+ };
1379
+ try {
1380
+ const openId = new_owner_open_id || getConversationContext()?.senderOpenId;
1381
+ if (!openId) {
1382
+ return json({
1383
+ error:
1384
+ "No new_owner_open_id provided and no current conversation context available.",
1385
+ });
1386
+ }
1387
+ const result = await transferOwner(getClient(), doc_token, openId);
1388
+ return json(result);
1389
+ } catch (err) {
1390
+ return json({ error: err instanceof Error ? err.message : String(err) });
1391
+ }
1392
+ },
1393
+ },
1394
+ { name: "feishu_doc_transfer_owner" },
1395
+ );
1396
+
1397
+ api.logger.info?.(`feishu_doc: Registered 16 document/wiki/messaging tools`);
1251
1398
  }