@satorijs/adapter-lark 3.9.5 → 3.10.1
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/bot.d.ts +1 -4
- package/lib/content.d.ts +4 -1
- package/lib/index.cjs +74 -33
- package/lib/internal.d.ts +3 -3
- package/lib/utils.d.ts +2 -2
- package/package.json +2 -2
- package/src/bot.ts +6 -16
- package/src/content.ts +5 -0
- package/src/http.ts +4 -1
- package/src/internal.ts +7 -6
- package/src/message.ts +49 -17
- package/src/utils.ts +44 -23
package/lib/bot.d.ts
CHANGED
|
@@ -5,17 +5,14 @@ import { Internal } from './internal';
|
|
|
5
5
|
export declare class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config> {
|
|
6
6
|
static inject: string[];
|
|
7
7
|
static MessageEncoder: typeof LarkMessageEncoder;
|
|
8
|
-
_token?: string;
|
|
9
8
|
_refresher?: NodeJS.Timeout;
|
|
10
9
|
http: HTTP;
|
|
11
10
|
assetsQuester: HTTP;
|
|
12
|
-
internal: Internal
|
|
11
|
+
internal: Internal<C>;
|
|
13
12
|
constructor(ctx: C, config: LarkBot.Config);
|
|
14
13
|
getResourceUrl(type: string, message_id: string, file_key: string): string;
|
|
15
14
|
initialize(): Promise<void>;
|
|
16
15
|
private refreshToken;
|
|
17
|
-
get token(): string;
|
|
18
|
-
set token(v: string);
|
|
19
16
|
editMessage(channelId: string, messageId: string, content: h.Fragment): Promise<void>;
|
|
20
17
|
deleteMessage(channelId: string, messageId: string): Promise<void>;
|
|
21
18
|
getMessage(channelId: string, messageId: string, recursive?: boolean): Promise<Universal.Message>;
|
package/lib/content.d.ts
CHANGED
|
@@ -299,6 +299,9 @@ export declare namespace MessageContent {
|
|
|
299
299
|
name?: string;
|
|
300
300
|
required?: boolean;
|
|
301
301
|
action_type?: 'link' | 'request' | 'multi' | 'form_submit' | 'form_reset';
|
|
302
|
+
value?: Record<string, string>;
|
|
303
|
+
url?: string;
|
|
304
|
+
multi_url?: Omit<URLs, 'url'>;
|
|
302
305
|
}
|
|
303
306
|
interface ConfirmElement {
|
|
304
307
|
title: PlainTextElement;
|
|
@@ -421,7 +424,7 @@ export declare namespace MessageContent {
|
|
|
421
424
|
type Width = 'default' | 'fill' | string;
|
|
422
425
|
type Type = 'default' | 'primary' | 'danger' | 'text' | 'primary_text' | 'danger_text' | 'primary_filled' | 'danger_filled' | 'laser';
|
|
423
426
|
}
|
|
424
|
-
type Element = DivElement | MarkdownElement | HRElement | ActionElement | NoteElement | ChartElement | TableElement | ImageElement | FormElement | InputElement | ButtonElement;
|
|
427
|
+
type Element = DivElement | MarkdownElement | HRElement | ActionElement | NoteElement | ChartElement | TableElement | ImageElement | FormElement | InputElement | ButtonElement | CheckerElement;
|
|
425
428
|
}
|
|
426
429
|
interface Template {
|
|
427
430
|
type: 'template';
|
package/lib/index.cjs
CHANGED
|
@@ -136,27 +136,43 @@ async function adaptSession(bot, body) {
|
|
|
136
136
|
session.type = "interaction/command";
|
|
137
137
|
let content = body.event.action.value.content;
|
|
138
138
|
const args = [], options = /* @__PURE__ */ Object.create(null);
|
|
139
|
+
const setOption = /* @__PURE__ */ __name((key, value) => {
|
|
140
|
+
if (key in options) {
|
|
141
|
+
options[key] += "," + value;
|
|
142
|
+
} else {
|
|
143
|
+
options[key] = value;
|
|
144
|
+
}
|
|
145
|
+
}, "setOption");
|
|
139
146
|
for (const [key, value] of Object.entries(body.event.action.form_value ?? {})) {
|
|
140
|
-
if (
|
|
147
|
+
if (key.startsWith("@@")) {
|
|
148
|
+
if (value) args.push(key.slice(2));
|
|
149
|
+
} else if (key.startsWith("@")) {
|
|
150
|
+
const [_key] = key.slice(1).split("=", 1);
|
|
151
|
+
setOption(_key, key.slice(2 + _key.length));
|
|
152
|
+
} else if (+key * 0 === 0) {
|
|
141
153
|
args[+key] = value;
|
|
142
154
|
} else {
|
|
143
|
-
|
|
155
|
+
setOption(key, value);
|
|
144
156
|
}
|
|
145
157
|
}
|
|
146
158
|
const toArg = /* @__PURE__ */ __name((value) => {
|
|
147
159
|
if (typeof value === "string") {
|
|
148
160
|
return `'${value}'`;
|
|
149
|
-
} else if (typeof value === "number") {
|
|
150
|
-
return value;
|
|
151
161
|
} else {
|
|
152
|
-
return
|
|
162
|
+
return value;
|
|
153
163
|
}
|
|
154
164
|
}, "toArg");
|
|
155
165
|
for (let i = 0; i < args.length; ++i) {
|
|
156
166
|
content += ` ${toArg(args[i])}`;
|
|
157
167
|
}
|
|
158
168
|
for (const [key, value] of Object.entries(options)) {
|
|
159
|
-
|
|
169
|
+
if (value === true) {
|
|
170
|
+
content += ` --${key} 1`;
|
|
171
|
+
} else if (value === false) {
|
|
172
|
+
content += ` --${key} 0`;
|
|
173
|
+
} else {
|
|
174
|
+
content += ` --${key} ${toArg(value)}`;
|
|
175
|
+
}
|
|
160
176
|
}
|
|
161
177
|
if (body.event.action.input_value) {
|
|
162
178
|
content += ` ${toArg(body.event.action.input_value)}`;
|
|
@@ -322,6 +338,7 @@ var HttpServer = class extends import_core2.Adapter {
|
|
|
322
338
|
});
|
|
323
339
|
if (!result) return ctx.status = 403;
|
|
324
340
|
}
|
|
341
|
+
if (!ctx.request.is("json")) return ctx.status = 415;
|
|
325
342
|
const body = this._tryDecryptBody(ctx.request.body);
|
|
326
343
|
if (body?.type === "url_verification" && body?.challenge && typeof body.challenge === "string") {
|
|
327
344
|
ctx.response.body = { challenge: body.challenge };
|
|
@@ -576,13 +593,13 @@ var LarkMessageEncoder = class extends import_core3.MessageEncoder {
|
|
|
576
593
|
} else if (type === "at") {
|
|
577
594
|
if (this.card) {
|
|
578
595
|
if (attrs.type === "all") {
|
|
579
|
-
this.textContent += `<at id=all>${attrs.name ?? "
|
|
596
|
+
this.textContent += `<at id=all>${attrs.name ?? ""}</at>`;
|
|
580
597
|
} else {
|
|
581
598
|
this.textContent += `<at id=${attrs.id}>${attrs.name ?? ""}</at>`;
|
|
582
599
|
}
|
|
583
600
|
} else {
|
|
584
601
|
if (attrs.type === "all") {
|
|
585
|
-
this.textContent += `<at user_id="all">${attrs.name ?? "
|
|
602
|
+
this.textContent += `<at user_id="all">${attrs.name ?? ""}</at>`;
|
|
586
603
|
} else {
|
|
587
604
|
this.textContent += `<at user_id="${attrs.id}">${attrs.name ?? ""}</at>`;
|
|
588
605
|
}
|
|
@@ -620,7 +637,7 @@ var LarkMessageEncoder = class extends import_core3.MessageEncoder {
|
|
|
620
637
|
const length = this.card?.elements.length;
|
|
621
638
|
await this.render(children);
|
|
622
639
|
if (this.card?.elements.length > length) {
|
|
623
|
-
const elements = this.card?.elements.
|
|
640
|
+
const elements = this.card?.elements.splice(length);
|
|
624
641
|
this.card.elements.push({
|
|
625
642
|
tag: "form",
|
|
626
643
|
name: attrs.name || "Form",
|
|
@@ -628,24 +645,56 @@ var LarkMessageEncoder = class extends import_core3.MessageEncoder {
|
|
|
628
645
|
});
|
|
629
646
|
}
|
|
630
647
|
} else if (type === "input") {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
tag: "
|
|
636
|
-
name: attrs.name,
|
|
637
|
-
|
|
638
|
-
|
|
648
|
+
if (attrs.type === "checkbox") {
|
|
649
|
+
this.flushText();
|
|
650
|
+
await this.render(children);
|
|
651
|
+
this.card?.elements.push({
|
|
652
|
+
tag: "checker",
|
|
653
|
+
name: (attrs.argument ? "@@" : attrs.option ? `@${attrs.option}=` : "") + attrs.name,
|
|
654
|
+
checked: attrs.checked,
|
|
655
|
+
text: {
|
|
639
656
|
tag: "plain_text",
|
|
640
|
-
content:
|
|
641
|
-
}
|
|
642
|
-
|
|
657
|
+
content: this.textContent
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
} else if (attrs.type === "submit") {
|
|
661
|
+
this.flushText(true);
|
|
662
|
+
await this.render(children);
|
|
663
|
+
this.card?.elements.push({
|
|
664
|
+
tag: "button",
|
|
665
|
+
name: attrs.name,
|
|
666
|
+
text: {
|
|
643
667
|
tag: "plain_text",
|
|
644
|
-
content:
|
|
668
|
+
content: this.textContent
|
|
645
669
|
},
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
670
|
+
action_type: "form_submit",
|
|
671
|
+
value: {
|
|
672
|
+
_satori_type: "command",
|
|
673
|
+
content: attrs.text
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
} else {
|
|
677
|
+
this.flushText();
|
|
678
|
+
await this.render(children);
|
|
679
|
+
this.card?.elements.push({
|
|
680
|
+
tag: "action",
|
|
681
|
+
actions: [{
|
|
682
|
+
tag: "input",
|
|
683
|
+
name: attrs.name,
|
|
684
|
+
width: attrs.width,
|
|
685
|
+
label: this.textContent && {
|
|
686
|
+
tag: "plain_text",
|
|
687
|
+
content: this.textContent
|
|
688
|
+
},
|
|
689
|
+
placeholder: attrs.placeholder && {
|
|
690
|
+
tag: "plain_text",
|
|
691
|
+
content: attrs.placeholder
|
|
692
|
+
},
|
|
693
|
+
behaviors: this.createBehavior(attrs)
|
|
694
|
+
}]
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
this.textContent = "";
|
|
649
698
|
} else if (type === "button") {
|
|
650
699
|
this.card ??= { elements: [] };
|
|
651
700
|
this.flushText(true);
|
|
@@ -883,7 +932,6 @@ var LarkBot = class extends import_core5.Bot {
|
|
|
883
932
|
}
|
|
884
933
|
static inject = ["server", "http"];
|
|
885
934
|
static MessageEncoder = LarkMessageEncoder;
|
|
886
|
-
_token;
|
|
887
935
|
_refresher;
|
|
888
936
|
http;
|
|
889
937
|
assetsQuester;
|
|
@@ -931,7 +979,7 @@ var LarkBot = class extends import_core5.Bot {
|
|
|
931
979
|
app_secret: this.config.appSecret
|
|
932
980
|
});
|
|
933
981
|
this.logger.debug("refreshed token %s", token);
|
|
934
|
-
this.
|
|
982
|
+
this.http.config.headers.Authorization = `Bearer ${token}`;
|
|
935
983
|
} catch (error) {
|
|
936
984
|
this.logger.error("failed to refresh token, retrying in 10s");
|
|
937
985
|
this.logger.error(error);
|
|
@@ -941,13 +989,6 @@ var LarkBot = class extends import_core5.Bot {
|
|
|
941
989
|
this._refresher = setTimeout(() => this.refreshToken(), timeout);
|
|
942
990
|
this.online();
|
|
943
991
|
}
|
|
944
|
-
get token() {
|
|
945
|
-
return this._token;
|
|
946
|
-
}
|
|
947
|
-
set token(v) {
|
|
948
|
-
this._token = v;
|
|
949
|
-
this.http.config.headers.Authorization = `Bearer ${v}`;
|
|
950
|
-
}
|
|
951
992
|
async editMessage(channelId, messageId, content) {
|
|
952
993
|
const encoder = new LarkMessageEncoder(this, channelId);
|
|
953
994
|
encoder.editMessageIds = [messageId];
|
package/lib/internal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dict, HTTP } from '@satorijs/core';
|
|
1
|
+
import { Context, Dict, HTTP } from '@satorijs/core';
|
|
2
2
|
import { LarkBot } from './bot';
|
|
3
3
|
export interface Internal {
|
|
4
4
|
}
|
|
@@ -28,9 +28,9 @@ export interface InternalRoute {
|
|
|
28
28
|
multipart?: boolean;
|
|
29
29
|
type?: 'raw-json' | 'binary';
|
|
30
30
|
}
|
|
31
|
-
export declare class Internal {
|
|
31
|
+
export declare class Internal<C extends Context = Context> {
|
|
32
32
|
private bot;
|
|
33
|
-
constructor(bot: LarkBot);
|
|
33
|
+
constructor(bot: LarkBot<C>);
|
|
34
34
|
private _assertResponse;
|
|
35
35
|
private _buildData;
|
|
36
36
|
static define(routes: Dict<Partial<Record<HTTP.Method, string | InternalRoute>>>): void;
|
package/lib/utils.d.ts
CHANGED
|
@@ -146,9 +146,9 @@ export type Sender = {
|
|
|
146
146
|
tenant_key: string;
|
|
147
147
|
});
|
|
148
148
|
export declare function adaptSender(sender: Sender, session: Session): Session;
|
|
149
|
-
export declare function adaptMessage(bot: LarkBot
|
|
149
|
+
export declare function adaptMessage<C extends Context = Context>(bot: LarkBot<C>, data: Events['im.message.receive_v1'], session: Session, details?: boolean): Promise<Session>;
|
|
150
150
|
export declare function adaptSession<C extends Context>(bot: LarkBot<C>, body: EventPayload): Promise<C[typeof import("cordis").Context.session]>;
|
|
151
|
-
export declare function decodeMessage(bot: LarkBot
|
|
151
|
+
export declare function decodeMessage<C extends Context = Context>(bot: LarkBot<C>, body: Message, details?: boolean): Promise<Universal.Message>;
|
|
152
152
|
/**
|
|
153
153
|
* Get ID type from id string
|
|
154
154
|
* @see https://open.larksuite.com/document/home/user-identity-introduction/introduction
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@satorijs/adapter-lark",
|
|
3
3
|
"description": "Lark (飞书) Adapter for Satorijs",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.10.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@cordisjs/plugin-server": "^0.2.5",
|
|
38
38
|
"@satorijs/core": "^4.5.0",
|
|
39
39
|
"cordis": "^3.18.1",
|
|
40
|
-
"cosmokit": "^1.
|
|
40
|
+
"cosmokit": "^1.7.2",
|
|
41
41
|
"dedent": "^1.5.3"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
package/src/bot.ts
CHANGED
|
@@ -18,11 +18,10 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
|
|
|
18
18
|
static inject = ['server', 'http']
|
|
19
19
|
static MessageEncoder = LarkMessageEncoder
|
|
20
20
|
|
|
21
|
-
_token?: string
|
|
22
21
|
_refresher?: NodeJS.Timeout
|
|
23
22
|
http: HTTP
|
|
24
23
|
assetsQuester: HTTP
|
|
25
|
-
internal: Internal
|
|
24
|
+
internal: Internal<C>
|
|
26
25
|
|
|
27
26
|
constructor(ctx: C, config: LarkBot.Config) {
|
|
28
27
|
super(ctx, config, 'lark')
|
|
@@ -86,7 +85,7 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
|
|
|
86
85
|
app_secret: this.config.appSecret,
|
|
87
86
|
})
|
|
88
87
|
this.logger.debug('refreshed token %s', token)
|
|
89
|
-
this.
|
|
88
|
+
this.http.config.headers!.Authorization = `Bearer ${token}`
|
|
90
89
|
} catch (error) {
|
|
91
90
|
this.logger.error('failed to refresh token, retrying in 10s')
|
|
92
91
|
this.logger.error(error)
|
|
@@ -97,15 +96,6 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
|
|
|
97
96
|
this.online()
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
get token() {
|
|
101
|
-
return this._token
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
set token(v: string) {
|
|
105
|
-
this._token = v
|
|
106
|
-
this.http.config.headers.Authorization = `Bearer ${v}`
|
|
107
|
-
}
|
|
108
|
-
|
|
109
99
|
async editMessage(channelId: string, messageId: string, content: h.Fragment) {
|
|
110
100
|
const encoder = new LarkMessageEncoder(this, channelId)
|
|
111
101
|
encoder.editMessageIds = [messageId]
|
|
@@ -118,9 +108,9 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
|
|
|
118
108
|
|
|
119
109
|
async getMessage(channelId: string, messageId: string, recursive = true) {
|
|
120
110
|
const data = await this.internal.getImMessage(messageId)
|
|
121
|
-
const message = await Utils.decodeMessage(this, data.items[0], recursive)
|
|
111
|
+
const message = await Utils.decodeMessage(this, data.items![0], recursive)
|
|
122
112
|
const im = await this.internal.getImChat(channelId)
|
|
123
|
-
message.channel
|
|
113
|
+
message.channel!.type = im.chat_mode === 'p2p' ? Universal.Channel.Type.DIRECT : Universal.Channel.Type.TEXT
|
|
124
114
|
return message
|
|
125
115
|
}
|
|
126
116
|
|
|
@@ -132,7 +122,7 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
|
|
|
132
122
|
|
|
133
123
|
async getUser(userId: string, guildId?: string) {
|
|
134
124
|
const data = await this.internal.getContactUser(userId)
|
|
135
|
-
return Utils.decodeUser(data.user)
|
|
125
|
+
return Utils.decodeUser(data.user!)
|
|
136
126
|
}
|
|
137
127
|
|
|
138
128
|
async getChannel(channelId: string) {
|
|
@@ -156,7 +146,7 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
|
|
|
156
146
|
|
|
157
147
|
async getGuildMemberList(guildId: string, after?: string) {
|
|
158
148
|
const members = await this.internal.getImChatMembers(guildId, { page_token: after })
|
|
159
|
-
const data = members.items
|
|
149
|
+
const data = members.items!.map(v => ({ user: { id: v.member_id, name: v.name }, name: v.name }))
|
|
160
150
|
return { data, next: members.page_token }
|
|
161
151
|
}
|
|
162
152
|
|
package/src/content.ts
CHANGED
|
@@ -378,6 +378,10 @@ export namespace MessageContent {
|
|
|
378
378
|
name?: string
|
|
379
379
|
required?: boolean
|
|
380
380
|
action_type?: 'link' | 'request' | 'multi' | 'form_submit' | 'form_reset'
|
|
381
|
+
// legacy fields
|
|
382
|
+
value?: Record<string, string>
|
|
383
|
+
url?: string
|
|
384
|
+
multi_url?: Omit<URLs, 'url'>
|
|
381
385
|
}
|
|
382
386
|
|
|
383
387
|
export interface ConfirmElement {
|
|
@@ -526,6 +530,7 @@ export namespace MessageContent {
|
|
|
526
530
|
| FormElement
|
|
527
531
|
| InputElement
|
|
528
532
|
| ButtonElement
|
|
533
|
+
| CheckerElement
|
|
529
534
|
}
|
|
530
535
|
|
|
531
536
|
export interface Template {
|
package/src/http.ts
CHANGED
|
@@ -43,6 +43,9 @@ export class HttpServer<C extends Context = Context> extends Adapter<C, LarkBot<
|
|
|
43
43
|
if (!result) return (ctx.status = 403)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// only accept JSON body
|
|
47
|
+
if (!ctx.request.is('json')) return ctx.status = 415
|
|
48
|
+
|
|
46
49
|
// try to decrypt message first if encryptKey is set
|
|
47
50
|
const body = this._tryDecryptBody(ctx.request.body)
|
|
48
51
|
// respond challenge message
|
|
@@ -81,7 +84,7 @@ export class HttpServer<C extends Context = Context> extends Adapter<C, LarkBot<
|
|
|
81
84
|
if (!header) return
|
|
82
85
|
const { app_id, event_type } = header
|
|
83
86
|
body.type = event_type // add type to body to ease typescript type narrowing
|
|
84
|
-
const bot = this.bots.find((bot) => bot.config.appId === app_id)
|
|
87
|
+
const bot = this.bots.find((bot) => bot.config.appId === app_id)!
|
|
85
88
|
const session = await adaptSession(bot, body)
|
|
86
89
|
bot.dispatch(session)
|
|
87
90
|
}
|
package/src/internal.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dict, HTTP, makeArray } from '@satorijs/core'
|
|
1
|
+
import { Context, Dict, HTTP, makeArray } from '@satorijs/core'
|
|
2
2
|
import { LarkBot } from './bot'
|
|
3
3
|
|
|
4
4
|
export interface Internal {}
|
|
@@ -33,8 +33,8 @@ export interface InternalRoute {
|
|
|
33
33
|
type?: 'raw-json' | 'binary'
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export class Internal {
|
|
37
|
-
constructor(private bot: LarkBot) {}
|
|
36
|
+
export class Internal<C extends Context = Context> {
|
|
37
|
+
constructor(private bot: LarkBot<C>) {}
|
|
38
38
|
|
|
39
39
|
private _assertResponse(response: HTTP.Response<BaseResponse>) {
|
|
40
40
|
if (!response.data.code) return
|
|
@@ -113,12 +113,13 @@ export class Internal {
|
|
|
113
113
|
const { argIndex, itemsKey = 'items', tokenKey = 'page_token' } = route.pagination
|
|
114
114
|
const iterArgs = [...args]
|
|
115
115
|
iterArgs[argIndex] = { ...args[argIndex] }
|
|
116
|
-
|
|
116
|
+
type Pagniation = { data: any[]; next?: any }
|
|
117
|
+
let pagination: Pagniation | undefined
|
|
117
118
|
result.next = async function () {
|
|
118
|
-
pagination ??= await this[Symbol.for('satori.pagination')]()
|
|
119
|
+
pagination ??= await this[Symbol.for('satori.pagination')]() as Pagniation
|
|
119
120
|
if (pagination.data.length) return { done: false, value: pagination.data.shift() }
|
|
120
121
|
if (!pagination.next) return { done: true, value: undefined }
|
|
121
|
-
pagination = await this[Symbol.for('satori.pagination')]()
|
|
122
|
+
pagination = await this[Symbol.for('satori.pagination')]() as Pagniation
|
|
122
123
|
return this.next()
|
|
123
124
|
}
|
|
124
125
|
result[Symbol.asyncIterator] = function () {
|
package/src/message.ts
CHANGED
|
@@ -208,13 +208,13 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
208
208
|
} else if (type === 'at') {
|
|
209
209
|
if (this.card) {
|
|
210
210
|
if (attrs.type === 'all') {
|
|
211
|
-
this.textContent += `<at id=all>${attrs.name ?? '
|
|
211
|
+
this.textContent += `<at id=all>${attrs.name ?? ''}</at>`
|
|
212
212
|
} else {
|
|
213
213
|
this.textContent += `<at id=${attrs.id}>${attrs.name ?? ''}</at>`
|
|
214
214
|
}
|
|
215
215
|
} else {
|
|
216
216
|
if (attrs.type === 'all') {
|
|
217
|
-
this.textContent += `<at user_id="all">${attrs.name ?? '
|
|
217
|
+
this.textContent += `<at user_id="all">${attrs.name ?? ''}</at>`
|
|
218
218
|
} else {
|
|
219
219
|
this.textContent += `<at user_id="${attrs.id}">${attrs.name ?? ''}</at>`
|
|
220
220
|
}
|
|
@@ -253,7 +253,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
253
253
|
const length = this.card?.elements.length
|
|
254
254
|
await this.render(children)
|
|
255
255
|
if (this.card?.elements.length > length) {
|
|
256
|
-
const elements = this.card?.elements.
|
|
256
|
+
const elements = this.card?.elements.splice(length)
|
|
257
257
|
this.card.elements.push({
|
|
258
258
|
tag: 'form',
|
|
259
259
|
name: attrs.name || 'Form',
|
|
@@ -261,24 +261,56 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
261
261
|
})
|
|
262
262
|
}
|
|
263
263
|
} else if (type === 'input') {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
tag: '
|
|
269
|
-
name: attrs.name,
|
|
270
|
-
|
|
271
|
-
|
|
264
|
+
if (attrs.type === 'checkbox') {
|
|
265
|
+
this.flushText()
|
|
266
|
+
await this.render(children)
|
|
267
|
+
this.card?.elements.push({
|
|
268
|
+
tag: 'checker',
|
|
269
|
+
name: (attrs.argument ? '@@' : attrs.option ? `@${attrs.option}=` : '') + attrs.name,
|
|
270
|
+
checked: attrs.checked,
|
|
271
|
+
text: {
|
|
272
272
|
tag: 'plain_text',
|
|
273
|
-
content:
|
|
273
|
+
content: this.textContent,
|
|
274
274
|
},
|
|
275
|
-
|
|
275
|
+
})
|
|
276
|
+
} else if (attrs.type === 'submit') {
|
|
277
|
+
this.flushText(true)
|
|
278
|
+
await this.render(children)
|
|
279
|
+
this.card?.elements.push({
|
|
280
|
+
tag: 'button',
|
|
281
|
+
name: attrs.name,
|
|
282
|
+
text: {
|
|
276
283
|
tag: 'plain_text',
|
|
277
|
-
content:
|
|
284
|
+
content: this.textContent,
|
|
278
285
|
},
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
286
|
+
action_type: 'form_submit',
|
|
287
|
+
value: {
|
|
288
|
+
_satori_type: 'command',
|
|
289
|
+
content: attrs.text,
|
|
290
|
+
},
|
|
291
|
+
})
|
|
292
|
+
} else {
|
|
293
|
+
this.flushText()
|
|
294
|
+
await this.render(children)
|
|
295
|
+
this.card?.elements.push({
|
|
296
|
+
tag: 'action',
|
|
297
|
+
actions: [{
|
|
298
|
+
tag: 'input',
|
|
299
|
+
name: attrs.name,
|
|
300
|
+
width: attrs.width,
|
|
301
|
+
label: this.textContent && {
|
|
302
|
+
tag: 'plain_text',
|
|
303
|
+
content: this.textContent,
|
|
304
|
+
},
|
|
305
|
+
placeholder: attrs.placeholder && {
|
|
306
|
+
tag: 'plain_text',
|
|
307
|
+
content: attrs.placeholder,
|
|
308
|
+
},
|
|
309
|
+
behaviors: this.createBehavior(attrs),
|
|
310
|
+
}],
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
this.textContent = ''
|
|
282
314
|
} else if (type === 'button') {
|
|
283
315
|
this.card ??= { elements: [] }
|
|
284
316
|
this.flushText(true)
|
package/src/utils.ts
CHANGED
|
@@ -168,7 +168,12 @@ export function adaptSender(sender: Sender, session: Session): Session {
|
|
|
168
168
|
return session
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
export async function adaptMessage
|
|
171
|
+
export async function adaptMessage<C extends Context = Context>(
|
|
172
|
+
bot: LarkBot<C>,
|
|
173
|
+
data: Events['im.message.receive_v1'],
|
|
174
|
+
session: Session,
|
|
175
|
+
details = true,
|
|
176
|
+
): Promise<Session> {
|
|
172
177
|
const json = JSON.parse(data.message.content)
|
|
173
178
|
const content: (string | h)[] = []
|
|
174
179
|
switch (data.message.message_type) {
|
|
@@ -182,7 +187,7 @@ export async function adaptMessage(bot: LarkBot, data: Events['im.message.receiv
|
|
|
182
187
|
// Lark's `at` Element would be `@user_id` in text
|
|
183
188
|
text.split(' ').forEach((word) => {
|
|
184
189
|
if (word.startsWith('@')) {
|
|
185
|
-
const mention = data.message.mentions.find((mention) => mention.key === word)
|
|
190
|
+
const mention = data.message.mentions.find((mention) => mention.key === word)!
|
|
186
191
|
content.push(h.at(mention.id.open_id, { name: mention.name }))
|
|
187
192
|
} else {
|
|
188
193
|
content.push(word)
|
|
@@ -251,27 +256,43 @@ export async function adaptSession<C extends Context>(bot: LarkBot<C>, body: Eve
|
|
|
251
256
|
session.type = 'interaction/command'
|
|
252
257
|
let content = body.event.action.value.content
|
|
253
258
|
const args: any[] = [], options = Object.create(null)
|
|
259
|
+
const setOption = (key: string, value: any) => {
|
|
260
|
+
if (key in options) {
|
|
261
|
+
options[key] += ',' + value
|
|
262
|
+
} else {
|
|
263
|
+
options[key] = value
|
|
264
|
+
}
|
|
265
|
+
}
|
|
254
266
|
for (const [key, value] of Object.entries(body.event.action.form_value ?? {})) {
|
|
255
|
-
if (
|
|
267
|
+
if (key.startsWith('@@')) {
|
|
268
|
+
if (value) args.push(key.slice(2))
|
|
269
|
+
} else if (key.startsWith('@')) {
|
|
270
|
+
const [_key] = key.slice(1).split('=', 1)
|
|
271
|
+
setOption(_key, key.slice(2 + _key.length))
|
|
272
|
+
} else if (+key * 0 === 0) {
|
|
256
273
|
args[+key] = value
|
|
257
274
|
} else {
|
|
258
|
-
|
|
275
|
+
setOption(key, value)
|
|
259
276
|
}
|
|
260
277
|
}
|
|
261
278
|
const toArg = (value: any) => {
|
|
262
279
|
if (typeof value === 'string') {
|
|
263
280
|
return `'${value}'`
|
|
264
|
-
} else
|
|
281
|
+
} else { // number, boolean
|
|
265
282
|
return value
|
|
266
|
-
} else {
|
|
267
|
-
return `''`
|
|
268
283
|
}
|
|
269
284
|
}
|
|
270
285
|
for (let i = 0; i < args.length; ++i) {
|
|
271
286
|
content += ` ${toArg(args[i])}`
|
|
272
287
|
}
|
|
273
288
|
for (const [key, value] of Object.entries(options)) {
|
|
274
|
-
|
|
289
|
+
if (value === true) {
|
|
290
|
+
content += ` --${key} 1`
|
|
291
|
+
} else if (value === false) {
|
|
292
|
+
content += ` --${key} 0`
|
|
293
|
+
} else {
|
|
294
|
+
content += ` --${key} ${toArg(value)}`
|
|
295
|
+
}
|
|
275
296
|
}
|
|
276
297
|
if (body.event.action.input_value) {
|
|
277
298
|
content += ` ${toArg(body.event.action.input_value)}`
|
|
@@ -291,8 +312,8 @@ export async function adaptSession<C extends Context>(bot: LarkBot<C>, body: Eve
|
|
|
291
312
|
}
|
|
292
313
|
|
|
293
314
|
// TODO: This function has many duplicated code with `adaptMessage`, should refactor them
|
|
294
|
-
export async function decodeMessage(bot: LarkBot
|
|
295
|
-
const json = JSON.parse(body.body
|
|
315
|
+
export async function decodeMessage<C extends Context = Context>(bot: LarkBot<C>, body: Message, details = true): Promise<Universal.Message> {
|
|
316
|
+
const json = JSON.parse(body.body!.content)
|
|
296
317
|
const content: h[] = []
|
|
297
318
|
switch (body.msg_type) {
|
|
298
319
|
case 'text': {
|
|
@@ -305,7 +326,7 @@ export async function decodeMessage(bot: LarkBot, body: Message, details = true)
|
|
|
305
326
|
// Lark's `at` Element would be `@user_id` in text
|
|
306
327
|
text.split(' ').forEach((word) => {
|
|
307
328
|
if (word.startsWith('@')) {
|
|
308
|
-
const mention = body.mentions
|
|
329
|
+
const mention = body.mentions!.find((mention) => mention.key === word)!
|
|
309
330
|
content.push(h.at(mention.id, { name: mention.name }))
|
|
310
331
|
} else {
|
|
311
332
|
content.push(h.text(word))
|
|
@@ -314,37 +335,37 @@ export async function decodeMessage(bot: LarkBot, body: Message, details = true)
|
|
|
314
335
|
break
|
|
315
336
|
}
|
|
316
337
|
case 'image':
|
|
317
|
-
content.push(h.image(bot.getResourceUrl('image', body.message_id
|
|
338
|
+
content.push(h.image(bot.getResourceUrl('image', body.message_id!, json.image_key)))
|
|
318
339
|
break
|
|
319
340
|
case 'audio':
|
|
320
|
-
content.push(h.audio(bot.getResourceUrl('file', body.message_id
|
|
341
|
+
content.push(h.audio(bot.getResourceUrl('file', body.message_id!, json.file_key)))
|
|
321
342
|
break
|
|
322
343
|
case 'media':
|
|
323
|
-
content.push(h.video(bot.getResourceUrl('file', body.message_id
|
|
344
|
+
content.push(h.video(bot.getResourceUrl('file', body.message_id!, json.file_key), {
|
|
324
345
|
poster: json.image_key,
|
|
325
346
|
}))
|
|
326
347
|
break
|
|
327
348
|
case 'file':
|
|
328
|
-
content.push(h.file(bot.getResourceUrl('file', body.message_id
|
|
349
|
+
content.push(h.file(bot.getResourceUrl('file', body.message_id!, json.file_key)))
|
|
329
350
|
break
|
|
330
351
|
}
|
|
331
352
|
|
|
332
353
|
return {
|
|
333
|
-
timestamp: +body.update_time
|
|
334
|
-
createdAt: +body.create_time
|
|
335
|
-
updatedAt: +body.update_time
|
|
354
|
+
timestamp: +body.update_time!,
|
|
355
|
+
createdAt: +body.create_time!,
|
|
356
|
+
updatedAt: +body.update_time!,
|
|
336
357
|
id: body.message_id,
|
|
337
358
|
messageId: body.message_id,
|
|
338
359
|
user: {
|
|
339
|
-
id: body.sender
|
|
360
|
+
id: body.sender!.id,
|
|
340
361
|
},
|
|
341
362
|
channel: {
|
|
342
|
-
id: body.chat_id
|
|
363
|
+
id: body.chat_id!,
|
|
343
364
|
type: Universal.Channel.Type.TEXT,
|
|
344
365
|
},
|
|
345
366
|
content: content.map((c) => c.toString()).join(' '),
|
|
346
367
|
elements: content,
|
|
347
|
-
quote: (body.upper_message_id && details) ? await bot.getMessage(body.chat_id
|
|
368
|
+
quote: (body.upper_message_id && details) ? await bot.getMessage(body.chat_id!, body.upper_message_id, false) : undefined,
|
|
348
369
|
}
|
|
349
370
|
}
|
|
350
371
|
|
|
@@ -371,7 +392,7 @@ export function decodeChannel(channelId: string, guild: GetImChatResponse): Univ
|
|
|
371
392
|
|
|
372
393
|
export function decodeGuild(guild: ListChat): Universal.Guild {
|
|
373
394
|
return {
|
|
374
|
-
id: guild.chat_id
|
|
395
|
+
id: guild.chat_id!,
|
|
375
396
|
name: guild.name,
|
|
376
397
|
avatar: guild.avatar,
|
|
377
398
|
}
|
|
@@ -379,7 +400,7 @@ export function decodeGuild(guild: ListChat): Universal.Guild {
|
|
|
379
400
|
|
|
380
401
|
export function decodeUser(user: User): Universal.User {
|
|
381
402
|
return {
|
|
382
|
-
id: user.open_id
|
|
403
|
+
id: user.open_id!,
|
|
383
404
|
avatar: user.avatar?.avatar_origin,
|
|
384
405
|
isBot: false,
|
|
385
406
|
name: user.name,
|