@satorijs/adapter-lark 3.6.0 → 3.6.2
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/lib/http.d.ts +5 -5
- package/lib/index.cjs +265 -103
- package/lib/index.cjs.map +2 -2
- package/lib/message.d.ts +9 -9
- package/lib/types/api.d.ts +2 -0
- package/lib/types/message/content.d.ts +386 -22
- package/lib/types/message/index.d.ts +18 -16
- package/lib/utils.d.ts +3 -3
- package/package.json +3 -3
- package/src/http.ts +6 -6
- package/src/message.ts +261 -114
- package/src/types/api.ts +2 -0
- package/src/types/message/content.ts +477 -42
- package/src/types/message/index.ts +18 -19
- package/src/utils.ts +21 -6
package/lib/http.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Adapter, Context, Schema } from '@satorijs/core';
|
|
2
|
-
import {
|
|
2
|
+
import { LarkBot } from './bot';
|
|
3
3
|
import { EventPayload } from './types';
|
|
4
|
-
export declare class HttpServer<C extends Context = Context> extends Adapter<C,
|
|
4
|
+
export declare class HttpServer<C extends Context = Context> extends Adapter<C, LarkBot<C>> {
|
|
5
5
|
static inject: string[];
|
|
6
6
|
private logger;
|
|
7
7
|
private ciphers;
|
|
8
|
-
constructor(ctx: C, bot:
|
|
9
|
-
fork(ctx: C, bot:
|
|
10
|
-
connect(bot:
|
|
8
|
+
constructor(ctx: C, bot: LarkBot<C>);
|
|
9
|
+
fork(ctx: C, bot: LarkBot<C>): Promise<void>;
|
|
10
|
+
connect(bot: LarkBot): Promise<void>;
|
|
11
11
|
dispatchSession(body: EventPayload): Promise<void>;
|
|
12
12
|
private _tryDecryptBody;
|
|
13
13
|
private _refreshCipher;
|
package/lib/index.cjs
CHANGED
|
@@ -116,6 +116,15 @@ async function adaptSession(bot, body) {
|
|
|
116
116
|
adaptSender(body.event.sender, session);
|
|
117
117
|
await adaptMessage(bot, body.event, session);
|
|
118
118
|
break;
|
|
119
|
+
case "application.bot.menu_v6":
|
|
120
|
+
if (body.event.event_key.startsWith("command:")) {
|
|
121
|
+
session.type = "interaction/command";
|
|
122
|
+
session.content = body.event.event_key.slice(8);
|
|
123
|
+
session.channelId = body.event.operator.operator_id.open_id;
|
|
124
|
+
session.userId = body.event.operator.operator_id.open_id;
|
|
125
|
+
session.isDirect = true;
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
119
128
|
case "card.action.trigger":
|
|
120
129
|
if (body.event.action.value?._satori_type === "command") {
|
|
121
130
|
session.type = "interaction/command";
|
|
@@ -138,11 +147,16 @@ async function adaptSession(bot, body) {
|
|
|
138
147
|
for (const [key, value] of Object.entries(options)) {
|
|
139
148
|
content += ` --${key} ${value}`;
|
|
140
149
|
}
|
|
150
|
+
if (body.event.action.input_value) {
|
|
151
|
+
content += ` ${body.event.action.input_value}`;
|
|
152
|
+
}
|
|
141
153
|
session.content = content;
|
|
142
154
|
session.messageId = body.event.context.open_message_id;
|
|
143
155
|
session.channelId = body.event.context.open_chat_id;
|
|
144
156
|
session.guildId = body.event.context.open_chat_id;
|
|
145
157
|
session.userId = body.event.operator.open_id;
|
|
158
|
+
const { data } = await bot.internal.getImChat(session.channelId);
|
|
159
|
+
session.isDirect = data.chat_mode === "p2p";
|
|
146
160
|
}
|
|
147
161
|
break;
|
|
148
162
|
}
|
|
@@ -314,6 +328,7 @@ var HttpServer = class extends import_core2.Adapter {
|
|
|
314
328
|
}
|
|
315
329
|
bot.logger.debug("received decryped event: %o", body);
|
|
316
330
|
this.dispatchSession(body);
|
|
331
|
+
ctx.body = {};
|
|
317
332
|
return ctx.status = 200;
|
|
318
333
|
});
|
|
319
334
|
bot.ctx.server.get(path + "/assets/:type/:message_id/:key", async (ctx) => {
|
|
@@ -385,18 +400,22 @@ var LarkMessageEncoder = class extends import_core3.MessageEncoder {
|
|
|
385
400
|
__name(this, "LarkMessageEncoder");
|
|
386
401
|
}
|
|
387
402
|
quote;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
403
|
+
textContent = "";
|
|
404
|
+
richContent = [];
|
|
405
|
+
card;
|
|
406
|
+
noteElements;
|
|
407
|
+
actionElements = [];
|
|
392
408
|
async post(data) {
|
|
393
409
|
try {
|
|
394
410
|
let resp;
|
|
395
|
-
if (this.quote) {
|
|
396
|
-
resp = await this.bot.internal.replyImMessage(this.quote,
|
|
411
|
+
if (this.quote?.id) {
|
|
412
|
+
resp = await this.bot.internal.replyImMessage(this.quote.id, {
|
|
413
|
+
...data,
|
|
414
|
+
reply_in_thread: this.quote.replyInThread
|
|
415
|
+
});
|
|
397
416
|
} else {
|
|
398
417
|
data.receive_id = this.channelId;
|
|
399
|
-
resp = await this.bot.internal
|
|
418
|
+
resp = await this.bot.internal.createImMessage(data, {
|
|
400
419
|
receive_id_type: extractIdType(this.channelId)
|
|
401
420
|
});
|
|
402
421
|
}
|
|
@@ -418,121 +437,264 @@ var LarkMessageEncoder = class extends import_core3.MessageEncoder {
|
|
|
418
437
|
this.errors.push(e);
|
|
419
438
|
}
|
|
420
439
|
}
|
|
421
|
-
|
|
422
|
-
if (this.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
message = {
|
|
426
|
-
...message,
|
|
427
|
-
...this.addition.file
|
|
428
|
-
};
|
|
440
|
+
flushText(button = false) {
|
|
441
|
+
if ((this.textContent || !button) && this.actionElements.length) {
|
|
442
|
+
this.card.elements.push({ tag: "action", actions: this.actionElements, layout: "flow" });
|
|
443
|
+
this.actionElements = [];
|
|
429
444
|
}
|
|
430
|
-
if (this.
|
|
431
|
-
|
|
445
|
+
if (this.textContent) {
|
|
446
|
+
this.richContent.push([{ tag: "md", text: this.textContent }]);
|
|
447
|
+
if (this.noteElements) {
|
|
448
|
+
this.noteElements.push({ tag: "plain_text", content: this.textContent });
|
|
449
|
+
} else if (this.card) {
|
|
450
|
+
this.card.elements.push({ tag: "markdown", content: this.textContent });
|
|
451
|
+
}
|
|
452
|
+
this.textContent = "";
|
|
432
453
|
}
|
|
433
|
-
|
|
434
|
-
|
|
454
|
+
}
|
|
455
|
+
async flush() {
|
|
456
|
+
this.flushText();
|
|
457
|
+
if (!this.card && !this.richContent.length) return;
|
|
458
|
+
if (this.card) {
|
|
459
|
+
this.bot.logger.debug("card", JSON.stringify(this.card.elements));
|
|
460
|
+
await this.post({
|
|
461
|
+
msg_type: "interactive",
|
|
462
|
+
content: JSON.stringify({
|
|
463
|
+
elements: this.card.elements
|
|
464
|
+
})
|
|
465
|
+
});
|
|
466
|
+
} else {
|
|
467
|
+
await this.post({
|
|
468
|
+
msg_type: "post",
|
|
469
|
+
content: JSON.stringify({
|
|
470
|
+
zh_cn: {
|
|
471
|
+
content: this.richContent
|
|
472
|
+
}
|
|
473
|
+
})
|
|
474
|
+
});
|
|
435
475
|
}
|
|
436
|
-
await this.post({
|
|
437
|
-
msg_type: this.richText ? "post" : this.addition ? this.addition.type : "text",
|
|
438
|
-
content: JSON.stringify(message)
|
|
439
|
-
});
|
|
440
476
|
this.quote = void 0;
|
|
441
|
-
this.
|
|
442
|
-
this.
|
|
443
|
-
this.
|
|
477
|
+
this.textContent = "";
|
|
478
|
+
this.richContent = [];
|
|
479
|
+
this.card = void 0;
|
|
444
480
|
}
|
|
445
|
-
async
|
|
481
|
+
async createImage(url) {
|
|
482
|
+
const { filename, type, data } = await this.bot.assetsQuester.file(url);
|
|
446
483
|
const payload = new FormData();
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
484
|
+
payload.append("image", new Blob([data], { type }), filename);
|
|
485
|
+
payload.append("image_type", "message");
|
|
486
|
+
const { data: { image_key } } = await this.bot.internal.createImImage(payload);
|
|
487
|
+
return image_key;
|
|
488
|
+
}
|
|
489
|
+
async sendFile(_type, attrs) {
|
|
490
|
+
const url = attrs.src || attrs.url;
|
|
491
|
+
const payload = new FormData();
|
|
492
|
+
const { filename, type, data } = await this.bot.assetsQuester.file(url);
|
|
493
|
+
payload.append("file", new Blob([data], { type }), filename);
|
|
494
|
+
payload.append("file_name", filename);
|
|
495
|
+
if (attrs.duration) {
|
|
496
|
+
payload.append("duration", attrs.duration);
|
|
497
|
+
}
|
|
498
|
+
if (_type === "audio") {
|
|
499
|
+
payload.append("file_type", "opus");
|
|
500
|
+
} else if (_type === "video") {
|
|
501
|
+
payload.append("file_type", "mp4");
|
|
459
502
|
} else {
|
|
460
|
-
|
|
461
|
-
if (
|
|
462
|
-
payload.append("file_type",
|
|
463
|
-
msgType = "audio";
|
|
464
|
-
} else if (type === "video") {
|
|
465
|
-
payload.append("file_type", "mp4");
|
|
466
|
-
msgType = "media";
|
|
503
|
+
const ext = filename.split(".").pop();
|
|
504
|
+
if (["doc", "xls", "ppt", "pdf"].includes(ext)) {
|
|
505
|
+
payload.append("file_type", ext);
|
|
467
506
|
} else {
|
|
468
|
-
|
|
469
|
-
if (["xls", "ppt", "pdf"].includes(ext)) {
|
|
470
|
-
payload.append("file_type", ext);
|
|
471
|
-
} else {
|
|
472
|
-
payload.append("file_type", "stream");
|
|
473
|
-
}
|
|
507
|
+
payload.append("file_type", "stream");
|
|
474
508
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
509
|
+
}
|
|
510
|
+
const { data: { file_key } } = await this.bot.internal.createImFile(payload);
|
|
511
|
+
await this.post({
|
|
512
|
+
msg_type: _type === "video" ? "media" : _type,
|
|
513
|
+
content: JSON.stringify({ file_key })
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
createBehavior(attrs) {
|
|
517
|
+
const behaviors = [];
|
|
518
|
+
if (attrs.type === "link") {
|
|
519
|
+
behaviors.push({
|
|
520
|
+
type: "open_url",
|
|
521
|
+
default_url: attrs.href
|
|
522
|
+
});
|
|
523
|
+
} else if (attrs.type === "input") {
|
|
524
|
+
behaviors.push({
|
|
525
|
+
type: "callback",
|
|
526
|
+
value: {
|
|
527
|
+
_satori_type: "command",
|
|
528
|
+
content: attrs.text
|
|
481
529
|
}
|
|
482
|
-
};
|
|
530
|
+
});
|
|
531
|
+
} else if (attrs.type === "action") {
|
|
483
532
|
}
|
|
533
|
+
return behaviors.length ? behaviors : void 0;
|
|
484
534
|
}
|
|
485
535
|
async visit(element) {
|
|
486
536
|
const { type, attrs, children } = element;
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
} else {
|
|
495
|
-
this.content += `<at user_id="${attrs.id}">${attrs.name}</at>`;
|
|
496
|
-
}
|
|
497
|
-
break;
|
|
537
|
+
if (type === "text") {
|
|
538
|
+
this.textContent += attrs.content;
|
|
539
|
+
} else if (type === "at") {
|
|
540
|
+
if (attrs.type === "all") {
|
|
541
|
+
this.textContent += `<at user_id="all">${attrs.name ?? "所有人"}</at>`;
|
|
542
|
+
} else {
|
|
543
|
+
this.textContent += `<at user_id="${attrs.id}">${attrs.name}</at>`;
|
|
498
544
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
545
|
+
} else if (type === "a") {
|
|
546
|
+
await this.render(children);
|
|
547
|
+
if (attrs.href) this.textContent += ` (${attrs.href})`;
|
|
548
|
+
} else if (type === "p") {
|
|
549
|
+
if (!this.textContent.endsWith("\n")) this.textContent += "\n";
|
|
550
|
+
await this.render(children);
|
|
551
|
+
if (!this.textContent.endsWith("\n")) this.textContent += "\n";
|
|
552
|
+
} else if (type === "br") {
|
|
553
|
+
this.textContent += "\n";
|
|
554
|
+
} else if (type === "sharp") {
|
|
555
|
+
} else if (type === "quote") {
|
|
556
|
+
await this.flush();
|
|
557
|
+
this.quote = attrs;
|
|
558
|
+
} else if (type === "img" || type === "image") {
|
|
559
|
+
const image_key = await this.createImage(attrs.src || attrs.url);
|
|
560
|
+
this.textContent += ``;
|
|
561
|
+
this.flushText();
|
|
562
|
+
this.richContent.push([{ tag: "img", image_key }]);
|
|
563
|
+
} else if (["video", "audio", "file"].includes(type)) {
|
|
564
|
+
await this.flush();
|
|
565
|
+
await this.sendFile(type, attrs);
|
|
566
|
+
} else if (type === "figure" || type === "message") {
|
|
567
|
+
await this.flush();
|
|
568
|
+
await this.render(children, true);
|
|
569
|
+
} else if (type === "hr") {
|
|
570
|
+
this.flushText();
|
|
571
|
+
this.richContent.push([{ tag: "hr" }]);
|
|
572
|
+
this.card?.elements.push({ tag: "hr" });
|
|
573
|
+
} else if (type === "form") {
|
|
574
|
+
this.flushText();
|
|
575
|
+
const length = this.card?.elements.length;
|
|
576
|
+
await this.render(children);
|
|
577
|
+
if (this.card?.elements.length > length) {
|
|
578
|
+
const elements = this.card?.elements.slice(length);
|
|
579
|
+
this.card.elements.push({
|
|
580
|
+
tag: "form",
|
|
581
|
+
name: attrs.name || "Form",
|
|
582
|
+
elements
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
} else if (type === "input") {
|
|
586
|
+
this.flushText();
|
|
587
|
+
this.card?.elements.push({
|
|
588
|
+
tag: "action",
|
|
589
|
+
actions: [{
|
|
590
|
+
tag: "input",
|
|
591
|
+
name: attrs.name,
|
|
592
|
+
width: attrs.width,
|
|
593
|
+
label: attrs.label && {
|
|
594
|
+
tag: "plain_text",
|
|
595
|
+
content: attrs.label
|
|
596
|
+
},
|
|
597
|
+
placeholder: attrs.placeholder && {
|
|
598
|
+
tag: "plain_text",
|
|
599
|
+
content: attrs.placeholder
|
|
600
|
+
},
|
|
601
|
+
behaviors: this.createBehavior(attrs)
|
|
602
|
+
}]
|
|
603
|
+
});
|
|
604
|
+
} else if (type === "button") {
|
|
605
|
+
this.card ??= { elements: [] };
|
|
606
|
+
this.flushText(true);
|
|
607
|
+
await this.render(children);
|
|
608
|
+
this.actionElements.push({
|
|
609
|
+
tag: "button",
|
|
610
|
+
text: {
|
|
611
|
+
tag: "plain_text",
|
|
612
|
+
content: this.textContent
|
|
613
|
+
},
|
|
614
|
+
disabled: attrs.disabled,
|
|
615
|
+
behaviors: this.createBehavior(attrs)
|
|
616
|
+
});
|
|
617
|
+
this.textContent = "";
|
|
618
|
+
} else if (type === "button-group") {
|
|
619
|
+
this.flushText();
|
|
620
|
+
await this.render(children);
|
|
621
|
+
this.flushText();
|
|
622
|
+
} else if (type.startsWith("lark:") || type.startsWith("feishu:")) {
|
|
623
|
+
const tag = type.slice(type.split(":", 1)[0].length + 1);
|
|
624
|
+
if (tag === "share-chat") {
|
|
514
625
|
await this.flush();
|
|
515
|
-
this.
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
626
|
+
await this.post({
|
|
627
|
+
msg_type: "share_chat",
|
|
628
|
+
content: JSON.stringify({ chat_id: attrs.chatId })
|
|
629
|
+
});
|
|
630
|
+
} else if (tag === "share-user") {
|
|
631
|
+
await this.flush();
|
|
632
|
+
await this.post({
|
|
633
|
+
msg_type: "share_user",
|
|
634
|
+
content: JSON.stringify({ user_id: attrs.userId })
|
|
635
|
+
});
|
|
636
|
+
} else if (tag === "system") {
|
|
637
|
+
await this.flush();
|
|
638
|
+
await this.render(children);
|
|
639
|
+
await this.post({
|
|
640
|
+
msg_type: "system",
|
|
641
|
+
content: JSON.stringify({
|
|
642
|
+
type: "divider",
|
|
643
|
+
params: { divider_text: { text: this.textContent } },
|
|
644
|
+
options: { need_rollup: attrs.needRollup }
|
|
645
|
+
})
|
|
646
|
+
});
|
|
647
|
+
this.textContent = "";
|
|
648
|
+
} else if (tag === "card") {
|
|
531
649
|
await this.flush();
|
|
650
|
+
this.card = {
|
|
651
|
+
elements: [],
|
|
652
|
+
header: attrs.title && {
|
|
653
|
+
template: attrs.color,
|
|
654
|
+
ud_icon: attrs.icon && {
|
|
655
|
+
tag: "standard_icon",
|
|
656
|
+
token: attrs.icon
|
|
657
|
+
},
|
|
658
|
+
title: {
|
|
659
|
+
tag: "plain_text",
|
|
660
|
+
content: attrs.title
|
|
661
|
+
},
|
|
662
|
+
subtitle: attrs.subtitle && {
|
|
663
|
+
tag: "plain_text",
|
|
664
|
+
content: attrs.subtitle
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
};
|
|
532
668
|
await this.render(children, true);
|
|
533
|
-
|
|
534
|
-
|
|
669
|
+
} else if (tag === "div") {
|
|
670
|
+
this.flushText();
|
|
671
|
+
await this.render(children);
|
|
672
|
+
this.card?.elements.push({
|
|
673
|
+
tag: "markdown",
|
|
674
|
+
text_align: attrs.align,
|
|
675
|
+
text_size: attrs.size,
|
|
676
|
+
content: this.textContent
|
|
677
|
+
});
|
|
678
|
+
this.textContent = "";
|
|
679
|
+
} else if (tag === "note") {
|
|
680
|
+
this.flushText();
|
|
681
|
+
this.noteElements = [];
|
|
535
682
|
await this.render(children);
|
|
683
|
+
this.flushText();
|
|
684
|
+
this.card?.elements.push({
|
|
685
|
+
tag: "note",
|
|
686
|
+
elements: this.noteElements
|
|
687
|
+
});
|
|
688
|
+
this.noteElements = void 0;
|
|
689
|
+
} else if (tag === "icon") {
|
|
690
|
+
this.flushText();
|
|
691
|
+
this.noteElements?.push({
|
|
692
|
+
tag: "standard_icon",
|
|
693
|
+
token: attrs.token
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
} else {
|
|
697
|
+
await this.render(children);
|
|
536
698
|
}
|
|
537
699
|
}
|
|
538
700
|
};
|