@nextclaw/channel-runtime 0.2.12 → 0.4.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.
- package/dist/index.d.ts +6 -2
- package/dist/index.js +267 -138
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -99,8 +99,7 @@ declare class EmailChannel extends BaseChannel<Config["channels"]["email"]> {
|
|
|
99
99
|
|
|
100
100
|
declare class FeishuChannel extends BaseChannel<Config["channels"]["feishu"]> {
|
|
101
101
|
name: string;
|
|
102
|
-
private
|
|
103
|
-
private wsClient;
|
|
102
|
+
private clients;
|
|
104
103
|
private processedMessageIds;
|
|
105
104
|
private processedSet;
|
|
106
105
|
constructor(config: Config["channels"]["feishu"], bus: MessageBus);
|
|
@@ -110,6 +109,11 @@ declare class FeishuChannel extends BaseChannel<Config["channels"]["feishu"]> {
|
|
|
110
109
|
private handleIncoming;
|
|
111
110
|
private isDuplicate;
|
|
112
111
|
private addReaction;
|
|
112
|
+
private resolveOutboundAccount;
|
|
113
|
+
private isAllowedByPolicy;
|
|
114
|
+
private resolveMentionState;
|
|
115
|
+
private convertResource;
|
|
116
|
+
private buildInboundPayload;
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
declare class MochatChannel extends BaseChannel<Config["channels"]["mochat"]> {
|
package/dist/index.js
CHANGED
|
@@ -1264,138 +1264,237 @@ var EmailChannel = class extends BaseChannel {
|
|
|
1264
1264
|
}
|
|
1265
1265
|
};
|
|
1266
1266
|
|
|
1267
|
-
// src/channels/feishu.ts
|
|
1268
|
-
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
1269
|
-
var MSG_TYPE_MAP = {
|
|
1270
|
-
image: "[image]",
|
|
1271
|
-
audio: "[audio]",
|
|
1272
|
-
file: "[file]",
|
|
1273
|
-
sticker: "[sticker]"
|
|
1274
|
-
};
|
|
1267
|
+
// src/channels/feishu-message-support.ts
|
|
1275
1268
|
var TABLE_RE = /((?:^[ \t]*\|.+\|[ \t]*\n)(?:^[ \t]*\|[-:\s|]+\|[ \t]*\n)(?:^[ \t]*\|.+\|[ \t]*\n?)+)/gm;
|
|
1269
|
+
function extractSenderInfo(sender) {
|
|
1270
|
+
const senderIdObj = sender.sender_id ?? {};
|
|
1271
|
+
const senderOpenId = senderIdObj.open_id || sender.open_id || "";
|
|
1272
|
+
const senderUserId = senderIdObj.user_id || sender.user_id || "";
|
|
1273
|
+
const senderUnionId = senderIdObj.union_id || sender.union_id || "";
|
|
1274
|
+
return {
|
|
1275
|
+
senderId: senderOpenId || senderUserId || senderUnionId || "",
|
|
1276
|
+
senderType: sender.sender_type ?? sender.senderType,
|
|
1277
|
+
senderOpenId: senderOpenId || void 0,
|
|
1278
|
+
senderUserId: senderUserId || void 0,
|
|
1279
|
+
senderUnionId: senderUnionId || void 0
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
function extractMessageInfo(message) {
|
|
1283
|
+
const chatId = message.chat_id ?? "";
|
|
1284
|
+
const chatType = message.chat_type ?? "";
|
|
1285
|
+
return {
|
|
1286
|
+
chatId,
|
|
1287
|
+
chatType,
|
|
1288
|
+
isGroup: chatType === "group",
|
|
1289
|
+
msgType: message.msg_type ?? message.message_type ?? "",
|
|
1290
|
+
messageId: message.message_id ?? "",
|
|
1291
|
+
rawContent: typeof message.content === "string" ? message.content : ""
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
function extractMentions(root, message) {
|
|
1295
|
+
if (Array.isArray(root.mentions)) {
|
|
1296
|
+
return root.mentions;
|
|
1297
|
+
}
|
|
1298
|
+
if (Array.isArray(message.mentions)) {
|
|
1299
|
+
return message.mentions;
|
|
1300
|
+
}
|
|
1301
|
+
return [];
|
|
1302
|
+
}
|
|
1303
|
+
function buildInboundMetadata(params) {
|
|
1304
|
+
return {
|
|
1305
|
+
account_id: params.accountId,
|
|
1306
|
+
accountId: params.accountId,
|
|
1307
|
+
message_id: params.messageInfo.messageId,
|
|
1308
|
+
chat_id: params.messageInfo.chatId,
|
|
1309
|
+
chat_type: params.messageInfo.chatType,
|
|
1310
|
+
msg_type: params.messageInfo.msgType,
|
|
1311
|
+
is_group: params.messageInfo.isGroup,
|
|
1312
|
+
peer_kind: params.messageInfo.isGroup ? "group" : "direct",
|
|
1313
|
+
peer_id: params.messageInfo.isGroup ? params.messageInfo.chatId : params.senderInfo.senderId,
|
|
1314
|
+
sender_open_id: params.senderInfo.senderOpenId,
|
|
1315
|
+
sender_user_id: params.senderInfo.senderUserId,
|
|
1316
|
+
sender_union_id: params.senderInfo.senderUnionId,
|
|
1317
|
+
was_mentioned: params.mentionState.wasMentioned,
|
|
1318
|
+
require_mention: params.mentionState.requireMention
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
function inferFeishuResourceMimeType(resourceType) {
|
|
1322
|
+
if (resourceType === "image" || resourceType === "sticker") {
|
|
1323
|
+
return "image/*";
|
|
1324
|
+
}
|
|
1325
|
+
if (resourceType === "audio") {
|
|
1326
|
+
return "audio/*";
|
|
1327
|
+
}
|
|
1328
|
+
return void 0;
|
|
1329
|
+
}
|
|
1330
|
+
function buildFeishuCardElements(content) {
|
|
1331
|
+
const elements = [];
|
|
1332
|
+
let lastEnd = 0;
|
|
1333
|
+
for (const match of content.matchAll(TABLE_RE)) {
|
|
1334
|
+
const start = match.index ?? 0;
|
|
1335
|
+
const tableText = match[1] ?? "";
|
|
1336
|
+
const before = content.slice(lastEnd, start).trim();
|
|
1337
|
+
if (before) {
|
|
1338
|
+
elements.push({ tag: "markdown", content: before });
|
|
1339
|
+
}
|
|
1340
|
+
elements.push(parseMarkdownTable(tableText) ?? { tag: "markdown", content: tableText });
|
|
1341
|
+
lastEnd = start + tableText.length;
|
|
1342
|
+
}
|
|
1343
|
+
const remaining = content.slice(lastEnd).trim();
|
|
1344
|
+
if (remaining) {
|
|
1345
|
+
elements.push({ tag: "markdown", content: remaining });
|
|
1346
|
+
}
|
|
1347
|
+
if (!elements.length) {
|
|
1348
|
+
elements.push({ tag: "markdown", content });
|
|
1349
|
+
}
|
|
1350
|
+
return elements;
|
|
1351
|
+
}
|
|
1352
|
+
function parseMarkdownTable(tableText) {
|
|
1353
|
+
const lines = tableText.trim().split("\n").map((line) => line.trim()).filter(Boolean);
|
|
1354
|
+
if (lines.length < 3) {
|
|
1355
|
+
return null;
|
|
1356
|
+
}
|
|
1357
|
+
const split = (line) => line.replace(/^\|+|\|+$/g, "").split("|").map((item) => item.trim());
|
|
1358
|
+
const headers = split(lines[0]);
|
|
1359
|
+
const rows = lines.slice(2).map(split);
|
|
1360
|
+
return {
|
|
1361
|
+
tag: "table",
|
|
1362
|
+
page_size: rows.length + 1,
|
|
1363
|
+
columns: headers.map((header, index) => ({
|
|
1364
|
+
tag: "column",
|
|
1365
|
+
name: `c${index}`,
|
|
1366
|
+
display_name: header,
|
|
1367
|
+
width: "auto"
|
|
1368
|
+
})),
|
|
1369
|
+
rows: rows.map((row) => {
|
|
1370
|
+
const values = {};
|
|
1371
|
+
headers.forEach((_, index) => {
|
|
1372
|
+
values[`c${index}`] = row[index] ?? "";
|
|
1373
|
+
});
|
|
1374
|
+
return values;
|
|
1375
|
+
})
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
// src/channels/feishu.ts
|
|
1380
|
+
import {
|
|
1381
|
+
buildFeishuConvertContext,
|
|
1382
|
+
convertFeishuMessageContent,
|
|
1383
|
+
getDefaultFeishuAccountId,
|
|
1384
|
+
getEnabledFeishuAccounts,
|
|
1385
|
+
LarkClient
|
|
1386
|
+
} from "@nextclaw/feishu-core";
|
|
1276
1387
|
function isRecord(value) {
|
|
1277
1388
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1278
1389
|
}
|
|
1279
1390
|
var FeishuChannel = class extends BaseChannel {
|
|
1280
1391
|
name = "feishu";
|
|
1281
|
-
|
|
1282
|
-
wsClient = null;
|
|
1392
|
+
clients = /* @__PURE__ */ new Map();
|
|
1283
1393
|
processedMessageIds = [];
|
|
1284
1394
|
processedSet = /* @__PURE__ */ new Set();
|
|
1285
1395
|
constructor(config, bus) {
|
|
1286
1396
|
super(config, bus);
|
|
1287
1397
|
}
|
|
1288
1398
|
async start() {
|
|
1289
|
-
|
|
1399
|
+
const accounts = getEnabledFeishuAccounts(this.config);
|
|
1400
|
+
if (accounts.length === 0) {
|
|
1290
1401
|
throw new Error("Feishu appId/appSecret not configured");
|
|
1291
1402
|
}
|
|
1292
1403
|
this.running = true;
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1404
|
+
for (const account of accounts) {
|
|
1405
|
+
const client = LarkClient.fromAccount(account);
|
|
1406
|
+
const activeAccount = {
|
|
1407
|
+
accountId: account.accountId,
|
|
1408
|
+
client
|
|
1409
|
+
};
|
|
1410
|
+
const probe = await client.probe();
|
|
1411
|
+
if (probe.ok) {
|
|
1412
|
+
activeAccount.botOpenId = probe.botOpenId;
|
|
1413
|
+
activeAccount.botName = probe.botName;
|
|
1300
1414
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
});
|
|
1307
|
-
this.wsClient.start({ eventDispatcher: dispatcher });
|
|
1415
|
+
client.startWebsocket(async (data) => {
|
|
1416
|
+
await this.handleIncoming(account.accountId, data);
|
|
1417
|
+
});
|
|
1418
|
+
this.clients.set(account.accountId, activeAccount);
|
|
1419
|
+
}
|
|
1308
1420
|
}
|
|
1309
1421
|
async stop() {
|
|
1310
1422
|
this.running = false;
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
this.wsClient = null;
|
|
1423
|
+
for (const account of this.clients.values()) {
|
|
1424
|
+
account.client.closeWebsocket();
|
|
1314
1425
|
}
|
|
1426
|
+
this.clients.clear();
|
|
1315
1427
|
}
|
|
1316
1428
|
async send(msg) {
|
|
1317
|
-
|
|
1429
|
+
const account = this.resolveOutboundAccount(msg.metadata);
|
|
1430
|
+
if (!account) {
|
|
1318
1431
|
return;
|
|
1319
1432
|
}
|
|
1320
1433
|
const receiveIdType = msg.chatId.startsWith("oc_") ? "chat_id" : "open_id";
|
|
1321
|
-
const elements =
|
|
1434
|
+
const elements = buildFeishuCardElements(msg.content ?? "");
|
|
1322
1435
|
const card = {
|
|
1323
1436
|
config: { wide_screen_mode: true },
|
|
1324
1437
|
elements
|
|
1325
1438
|
};
|
|
1326
1439
|
const content = JSON.stringify(card);
|
|
1327
|
-
await
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
msg_type: "interactive",
|
|
1332
|
-
content
|
|
1333
|
-
}
|
|
1440
|
+
await account.client.sendInteractiveCard({
|
|
1441
|
+
receiveId: msg.chatId,
|
|
1442
|
+
receiveIdType,
|
|
1443
|
+
content
|
|
1334
1444
|
});
|
|
1335
1445
|
}
|
|
1336
|
-
async handleIncoming(data) {
|
|
1446
|
+
async handleIncoming(accountId, data) {
|
|
1447
|
+
const account = this.clients.get(accountId);
|
|
1448
|
+
if (!account) {
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1337
1451
|
const root = isRecord(data.event) ? data.event : data;
|
|
1338
1452
|
const message = root.message ?? data.message ?? {};
|
|
1339
1453
|
const sender = root.sender ?? message.sender ?? data.sender ?? {};
|
|
1340
|
-
const
|
|
1341
|
-
|
|
1342
|
-
const senderUserId = senderIdObj.user_id || sender.user_id || "";
|
|
1343
|
-
const senderUnionId = senderIdObj.union_id || sender.union_id || "";
|
|
1344
|
-
const senderId = senderOpenId || senderUserId || senderUnionId || "";
|
|
1345
|
-
const senderType = sender.sender_type ?? sender.senderType;
|
|
1346
|
-
if (senderType === "bot") {
|
|
1347
|
-
return;
|
|
1348
|
-
}
|
|
1349
|
-
const chatId = message.chat_id ?? "";
|
|
1350
|
-
const chatType = message.chat_type ?? "";
|
|
1351
|
-
const isGroup = chatType === "group";
|
|
1352
|
-
const msgType = message.msg_type ?? message.message_type ?? "";
|
|
1353
|
-
const messageId = message.message_id ?? "";
|
|
1354
|
-
if (!senderId || !chatId) {
|
|
1454
|
+
const senderInfo = extractSenderInfo(sender);
|
|
1455
|
+
if (senderInfo.senderType === "bot") {
|
|
1355
1456
|
return;
|
|
1356
1457
|
}
|
|
1357
|
-
|
|
1458
|
+
const messageInfo = extractMessageInfo(message);
|
|
1459
|
+
if (!senderInfo.senderId || !messageInfo.chatId) {
|
|
1358
1460
|
return;
|
|
1359
1461
|
}
|
|
1360
|
-
if (
|
|
1462
|
+
if (!this.isAllowedByPolicy({ senderId: senderInfo.senderId, chatId: messageInfo.chatId, isGroup: messageInfo.isGroup })) {
|
|
1361
1463
|
return;
|
|
1362
1464
|
}
|
|
1363
|
-
if (messageId) {
|
|
1364
|
-
|
|
1465
|
+
if (messageInfo.messageId && this.isDuplicate(`${accountId}:${messageInfo.messageId}`)) {
|
|
1466
|
+
return;
|
|
1365
1467
|
}
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
try {
|
|
1369
|
-
const parsed = JSON.parse(String(message.content));
|
|
1370
|
-
content = String(parsed.text ?? parsed.content ?? "");
|
|
1371
|
-
} catch {
|
|
1372
|
-
content = String(message.content);
|
|
1373
|
-
}
|
|
1468
|
+
if (messageInfo.messageId) {
|
|
1469
|
+
await this.addReaction(account, messageInfo.messageId, "THUMBSUP");
|
|
1374
1470
|
}
|
|
1375
|
-
|
|
1376
|
-
|
|
1471
|
+
const mentions = extractMentions(root, message);
|
|
1472
|
+
const mentionState = this.resolveMentionState({
|
|
1473
|
+
account,
|
|
1474
|
+
mentions,
|
|
1475
|
+
chatId: messageInfo.chatId,
|
|
1476
|
+
isGroup: messageInfo.isGroup,
|
|
1477
|
+
rawContent: messageInfo.rawContent
|
|
1478
|
+
});
|
|
1479
|
+
if (mentionState.requireMention && !mentionState.wasMentioned) {
|
|
1480
|
+
return;
|
|
1377
1481
|
}
|
|
1378
|
-
|
|
1482
|
+
const payload = this.buildInboundPayload(account, messageInfo, mentions);
|
|
1483
|
+
if (!payload) {
|
|
1379
1484
|
return;
|
|
1380
1485
|
}
|
|
1381
1486
|
await this.handleMessage({
|
|
1382
|
-
senderId:
|
|
1487
|
+
senderId: senderInfo.senderId,
|
|
1383
1488
|
// Always route by Feishu chat_id so DM/group sessions are stable.
|
|
1384
|
-
chatId,
|
|
1385
|
-
content,
|
|
1386
|
-
attachments:
|
|
1387
|
-
metadata: {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
peer_kind: isGroup ? "group" : "direct",
|
|
1394
|
-
peer_id: chatId,
|
|
1395
|
-
sender_open_id: senderOpenId || void 0,
|
|
1396
|
-
sender_user_id: senderUserId || void 0,
|
|
1397
|
-
sender_union_id: senderUnionId || void 0
|
|
1398
|
-
}
|
|
1489
|
+
chatId: messageInfo.chatId,
|
|
1490
|
+
content: payload.content,
|
|
1491
|
+
attachments: payload.attachments,
|
|
1492
|
+
metadata: buildInboundMetadata({
|
|
1493
|
+
accountId,
|
|
1494
|
+
messageInfo,
|
|
1495
|
+
senderInfo,
|
|
1496
|
+
mentionState
|
|
1497
|
+
})
|
|
1399
1498
|
});
|
|
1400
1499
|
}
|
|
1401
1500
|
isDuplicate(messageId) {
|
|
@@ -1412,69 +1511,99 @@ var FeishuChannel = class extends BaseChannel {
|
|
|
1412
1511
|
}
|
|
1413
1512
|
return false;
|
|
1414
1513
|
}
|
|
1415
|
-
async addReaction(messageId, emojiType) {
|
|
1416
|
-
if (!this.client) {
|
|
1417
|
-
return;
|
|
1418
|
-
}
|
|
1514
|
+
async addReaction(account, messageId, emojiType) {
|
|
1419
1515
|
try {
|
|
1420
|
-
await
|
|
1421
|
-
path: { message_id: messageId },
|
|
1422
|
-
data: { reaction_type: { emoji_type: emojiType } }
|
|
1423
|
-
});
|
|
1516
|
+
await account.client.addReaction(messageId, emojiType);
|
|
1424
1517
|
} catch {
|
|
1425
1518
|
}
|
|
1426
1519
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1520
|
+
resolveOutboundAccount(metadata) {
|
|
1521
|
+
const accountId = typeof metadata?.accountId === "string" ? metadata.accountId : typeof metadata?.account_id === "string" ? metadata.account_id : getDefaultFeishuAccountId(this.config);
|
|
1522
|
+
return this.clients.get(accountId) ?? this.clients.get(getDefaultFeishuAccountId(this.config)) ?? null;
|
|
1523
|
+
}
|
|
1524
|
+
isAllowedByPolicy(params) {
|
|
1525
|
+
if (!params.isGroup) {
|
|
1526
|
+
if (this.config.dmPolicy === "disabled") {
|
|
1527
|
+
return false;
|
|
1528
|
+
}
|
|
1529
|
+
if (this.config.dmPolicy === "allowlist" || this.config.dmPolicy === "pairing") {
|
|
1530
|
+
return this.isAllowed(params.senderId);
|
|
1531
|
+
}
|
|
1532
|
+
const allowFrom = this.config.allowFrom ?? [];
|
|
1533
|
+
return allowFrom.length === 0 || allowFrom.includes("*") || this.isAllowed(params.senderId);
|
|
1437
1534
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1535
|
+
if (this.config.groupPolicy === "disabled") {
|
|
1536
|
+
return false;
|
|
1537
|
+
}
|
|
1538
|
+
if (this.config.groupPolicy === "allowlist") {
|
|
1539
|
+
const allowFrom = this.config.groupAllowFrom ?? [];
|
|
1540
|
+
return allowFrom.includes("*") || allowFrom.includes(params.chatId);
|
|
1541
|
+
}
|
|
1542
|
+
return true;
|
|
1440
1543
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1544
|
+
resolveMentionState(params) {
|
|
1545
|
+
if (!params.isGroup) {
|
|
1546
|
+
return { wasMentioned: false, requireMention: false };
|
|
1547
|
+
}
|
|
1548
|
+
const groupRule = this.config.groups?.[params.chatId] ?? this.config.groups?.["*"];
|
|
1549
|
+
const requireMention = groupRule?.requireMention ?? this.config.requireMention ?? false;
|
|
1550
|
+
if (!requireMention) {
|
|
1551
|
+
return { wasMentioned: false, requireMention: false };
|
|
1552
|
+
}
|
|
1553
|
+
const patterns = [...this.config.mentionPatterns ?? [], ...groupRule?.mentionPatterns ?? []].map((pattern) => pattern.trim()).filter(Boolean);
|
|
1554
|
+
const rawText = params.rawContent.toLowerCase();
|
|
1555
|
+
const mentionedByPattern = patterns.some((pattern) => {
|
|
1556
|
+
try {
|
|
1557
|
+
return new RegExp(pattern, "i").test(rawText);
|
|
1558
|
+
} catch {
|
|
1559
|
+
return rawText.includes(pattern.toLowerCase());
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
const mentionedByIds = params.mentions.some((entry) => {
|
|
1563
|
+
if (!entry || typeof entry !== "object") {
|
|
1564
|
+
return false;
|
|
1565
|
+
}
|
|
1566
|
+
const mention = entry;
|
|
1567
|
+
const openId = (typeof mention.open_id === "string" ? mention.open_id : "") || (mention.id && typeof mention.id === "object" && "open_id" in mention.id ? mention.id.open_id ?? "" : typeof mention.id === "string" ? mention.id : "");
|
|
1568
|
+
const name = typeof mention.name === "string" ? mention.name : "";
|
|
1569
|
+
return openId === params.account.botOpenId || (params.account.botName ? name === params.account.botName : false);
|
|
1570
|
+
});
|
|
1571
|
+
return {
|
|
1572
|
+
wasMentioned: mentionedByPattern || mentionedByIds,
|
|
1573
|
+
requireMention
|
|
1574
|
+
};
|
|
1444
1575
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1576
|
+
convertResource(resource) {
|
|
1577
|
+
return {
|
|
1578
|
+
id: resource.fileKey,
|
|
1579
|
+
name: resource.fileName,
|
|
1580
|
+
source: "feishu",
|
|
1581
|
+
status: "remote-only",
|
|
1582
|
+
mimeType: inferFeishuResourceMimeType(resource.type),
|
|
1583
|
+
url: resource.fileKey
|
|
1584
|
+
};
|
|
1447
1585
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1586
|
+
buildInboundPayload(account, messageInfo, mentions) {
|
|
1587
|
+
const converted = convertFeishuMessageContent(
|
|
1588
|
+
messageInfo.rawContent,
|
|
1589
|
+
messageInfo.msgType,
|
|
1590
|
+
buildFeishuConvertContext({
|
|
1591
|
+
mentions,
|
|
1592
|
+
stripBotMentions: true,
|
|
1593
|
+
botOpenId: account.botOpenId,
|
|
1594
|
+
botName: account.botName
|
|
1595
|
+
})
|
|
1596
|
+
);
|
|
1597
|
+
const content = converted.content.trim();
|
|
1598
|
+
if (!content) {
|
|
1599
|
+
return null;
|
|
1600
|
+
}
|
|
1601
|
+
return {
|
|
1602
|
+
content,
|
|
1603
|
+
attachments: converted.resources.map((resource) => this.convertResource(resource))
|
|
1604
|
+
};
|
|
1454
1605
|
}
|
|
1455
|
-
|
|
1456
|
-
const headers = split(lines[0]);
|
|
1457
|
-
const rows = lines.slice(2).map(split);
|
|
1458
|
-
const columns = headers.map((header, index) => ({
|
|
1459
|
-
tag: "column",
|
|
1460
|
-
name: `c${index}`,
|
|
1461
|
-
display_name: header,
|
|
1462
|
-
width: "auto"
|
|
1463
|
-
}));
|
|
1464
|
-
const tableRows = rows.map((row) => {
|
|
1465
|
-
const values = {};
|
|
1466
|
-
headers.forEach((_, index) => {
|
|
1467
|
-
values[`c${index}`] = row[index] ?? "";
|
|
1468
|
-
});
|
|
1469
|
-
return values;
|
|
1470
|
-
});
|
|
1471
|
-
return {
|
|
1472
|
-
tag: "table",
|
|
1473
|
-
page_size: rows.length + 1,
|
|
1474
|
-
columns,
|
|
1475
|
-
rows: tableRows
|
|
1476
|
-
};
|
|
1477
|
-
}
|
|
1606
|
+
};
|
|
1478
1607
|
|
|
1479
1608
|
// src/channels/mochat.ts
|
|
1480
1609
|
import { io } from "socket.io-client";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/channel-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Runtime implementations for NextClaw builtin channel plugins.",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@larksuiteoapi/node-sdk": "^1.58.0",
|
|
19
18
|
"@slack/socket-mode": "^1.3.3",
|
|
20
19
|
"@slack/web-api": "^7.6.0",
|
|
21
20
|
"dingtalk-stream": "^2.1.4",
|
|
@@ -29,7 +28,8 @@
|
|
|
29
28
|
"undici": "^6.21.0",
|
|
30
29
|
"ws": "^8.18.0",
|
|
31
30
|
"socket.io-msgpack-parser": "^3.0.2",
|
|
32
|
-
"@nextclaw/core": "0.
|
|
31
|
+
"@nextclaw/core": "0.11.0",
|
|
32
|
+
"@nextclaw/feishu-core": "0.2.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/mailparser": "^3.4.6",
|