@satorijs/adapter-lark 3.6.1 → 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/index.cjs +126 -34
- package/lib/index.cjs.map +1 -1
- package/lib/message.d.ts +3 -1
- package/lib/types/api.d.ts +2 -0
- package/lib/types/message/content.d.ts +201 -16
- package/lib/types/message/index.d.ts +16 -0
- package/package.json +3 -3
- package/src/message.ts +117 -38
- package/src/types/api.ts +2 -0
- package/src/types/message/content.ts +229 -18
- package/src/types/message/index.ts +16 -0
- package/src/utils.ts +15 -0
|
@@ -112,9 +112,10 @@ export declare namespace MessageContent {
|
|
|
112
112
|
type Paragraph = InlineElement[] | [BlockElement];
|
|
113
113
|
}
|
|
114
114
|
interface Card {
|
|
115
|
-
config
|
|
115
|
+
config?: Card.Config;
|
|
116
116
|
card_link?: Card.URLs;
|
|
117
|
-
|
|
117
|
+
header?: Card.Header;
|
|
118
|
+
elements: Card.Element[];
|
|
118
119
|
}
|
|
119
120
|
namespace Card {
|
|
120
121
|
/** @see https://open.larksuite.com/document/common-capabilities/message-card/getting-started/card-structure/card-configuration */
|
|
@@ -174,16 +175,25 @@ export declare namespace MessageContent {
|
|
|
174
175
|
namespace TextTagElement {
|
|
175
176
|
type Color = 'neutral' | 'blue' | 'torqoise' | 'lime' | 'orange' | 'violet' | 'indigo' | 'wathet' | 'green' | 'yellow' | 'red' | 'purple' | 'carmine';
|
|
176
177
|
}
|
|
177
|
-
interface
|
|
178
|
+
interface BaseImageElement extends BaseElement<'image'> {
|
|
178
179
|
img_key: string;
|
|
179
180
|
alt?: PlainTextElement;
|
|
181
|
+
}
|
|
182
|
+
interface ImageElement extends BaseImageElement {
|
|
180
183
|
title?: PlainTextElement;
|
|
184
|
+
transparent?: string;
|
|
185
|
+
preview?: boolean;
|
|
186
|
+
corner_radius?: string;
|
|
187
|
+
scale_type?: 'crop_center' | 'fit_horizontal' | 'crop_top';
|
|
188
|
+
size?: 'large' | 'medium' | 'small' | 'tiny' | 'stretch_without_padding' | 'stretch' | string;
|
|
189
|
+
/** @deprecated */
|
|
181
190
|
custom_width?: number;
|
|
191
|
+
/** @deprecated */
|
|
182
192
|
compact_width?: boolean;
|
|
193
|
+
/** @deprecated */
|
|
183
194
|
mode?: 'crop_center' | 'fit_horizontal' | 'large' | 'medium' | 'small' | 'tiny';
|
|
184
|
-
preview?: boolean;
|
|
185
195
|
}
|
|
186
|
-
interface
|
|
196
|
+
interface HRElement extends BaseElement<'hr'> {
|
|
187
197
|
}
|
|
188
198
|
interface DivElement extends BaseElement<'div'> {
|
|
189
199
|
text?: DivPlainTextElement;
|
|
@@ -194,13 +204,70 @@ export declare namespace MessageContent {
|
|
|
194
204
|
text_align?: TextAlign;
|
|
195
205
|
href?: Record<string, URLs>;
|
|
196
206
|
}
|
|
197
|
-
interface
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
interface PersonElement extends BaseElement<'person'> {
|
|
208
|
+
user_id: string;
|
|
209
|
+
size?: 'large' | 'medium' | 'small' | 'extra_small';
|
|
210
|
+
}
|
|
211
|
+
interface PersonListElement extends BaseElement<'person_list'> {
|
|
212
|
+
persons: {
|
|
213
|
+
id: string;
|
|
214
|
+
}[];
|
|
215
|
+
size?: 'large' | 'medium' | 'small' | 'extra_small';
|
|
216
|
+
show_name?: boolean;
|
|
217
|
+
show_avatar?: boolean;
|
|
218
|
+
}
|
|
219
|
+
interface ChartElement extends BaseElement<'chart'> {
|
|
220
|
+
chart_spec: {};
|
|
221
|
+
aspect_ratio?: '1:1' | '2:1' | '4:3' | '16:9';
|
|
222
|
+
color_theme?: 'brand' | 'rainbow' | 'complementary' | 'converse' | 'primary';
|
|
223
|
+
preview?: boolean;
|
|
224
|
+
height?: 'auto' | string;
|
|
225
|
+
}
|
|
226
|
+
interface TableElement extends BaseElement<'table'> {
|
|
227
|
+
page_size?: number;
|
|
228
|
+
row_height?: 'low' | 'medium' | 'high' | string;
|
|
229
|
+
header_style?: TableElement.HeaderStyle;
|
|
230
|
+
columns: TableElement.Column[];
|
|
231
|
+
rows: object[];
|
|
232
|
+
}
|
|
233
|
+
namespace TableElement {
|
|
234
|
+
interface HeaderStyle {
|
|
235
|
+
text_align?: TextAlign;
|
|
236
|
+
text_size?: TextSize;
|
|
237
|
+
background_style?: 'grey' | 'none';
|
|
238
|
+
text_color?: 'default' | 'grey';
|
|
239
|
+
bold?: boolean;
|
|
240
|
+
lines?: number;
|
|
241
|
+
}
|
|
242
|
+
interface Column {
|
|
243
|
+
name: string;
|
|
244
|
+
display_name?: string;
|
|
245
|
+
width?: 'auto' | string;
|
|
246
|
+
horizontal_align?: 'left' | 'center' | 'right';
|
|
247
|
+
data_type?: 'text' | 'lark_md' | 'options' | 'number' | 'persons' | 'date' | 'markdown';
|
|
248
|
+
format?: {
|
|
249
|
+
percision?: number;
|
|
250
|
+
symbol?: string;
|
|
251
|
+
separator?: string;
|
|
252
|
+
};
|
|
253
|
+
date_format?: string;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
interface NoteElement extends BaseElement<'note'> {
|
|
257
|
+
elements: NoteElement.InnerElement[];
|
|
258
|
+
}
|
|
259
|
+
namespace NoteElement {
|
|
260
|
+
type InnerElement = IconElement | PlainTextElement | BaseImageElement;
|
|
261
|
+
}
|
|
262
|
+
interface FormElement extends BaseElement<'form'> {
|
|
263
|
+
name: string;
|
|
264
|
+
elements: Element[];
|
|
265
|
+
confirm?: ConfirmElement;
|
|
266
|
+
}
|
|
267
|
+
interface ActionElement extends BaseElement<'action'> {
|
|
268
|
+
actions: Element[];
|
|
201
269
|
layout?: 'bisected' | 'trisection' | 'flow';
|
|
202
270
|
}
|
|
203
|
-
type ActionElement = ButtonElement;
|
|
204
271
|
type ActionBehavior = OpenURLBehavior | CallbackBehavior;
|
|
205
272
|
interface OpenURLBehavior {
|
|
206
273
|
type: 'open_url';
|
|
@@ -213,30 +280,148 @@ export declare namespace MessageContent {
|
|
|
213
280
|
type: 'callback';
|
|
214
281
|
value: Record<string, string>;
|
|
215
282
|
}
|
|
216
|
-
interface
|
|
283
|
+
interface BaseButtonElement extends BaseElement<'button'> {
|
|
217
284
|
text: PlainTextElement;
|
|
218
|
-
type?: ButtonElement.Type;
|
|
219
285
|
size?: ButtonElement.Size;
|
|
220
|
-
width?: ButtonElement.Width;
|
|
221
286
|
icon?: IconElement;
|
|
222
|
-
hover_tips?: PlainTextElement;
|
|
223
287
|
disabled?: boolean;
|
|
288
|
+
behaviors?: ActionBehavior[];
|
|
289
|
+
}
|
|
290
|
+
interface ButtonElement extends BaseButtonElement {
|
|
291
|
+
type?: ButtonElement.Type;
|
|
292
|
+
width?: ButtonElement.Width;
|
|
293
|
+
hover_tips?: PlainTextElement;
|
|
224
294
|
disabled_tips?: PlainTextElement;
|
|
225
295
|
confirm?: {
|
|
226
296
|
title: PlainTextElement;
|
|
227
297
|
text: PlainTextElement;
|
|
228
298
|
};
|
|
229
|
-
behaviors?: ActionBehavior[];
|
|
230
299
|
name?: string;
|
|
231
300
|
required?: boolean;
|
|
232
301
|
action_type?: 'link' | 'request' | 'multi' | 'form_submit' | 'form_reset';
|
|
233
302
|
}
|
|
303
|
+
interface ConfirmElement {
|
|
304
|
+
title: PlainTextElement;
|
|
305
|
+
text: PlainTextElement;
|
|
306
|
+
}
|
|
307
|
+
interface InputElement extends BaseElement<'input'> {
|
|
308
|
+
name: string;
|
|
309
|
+
required?: boolean;
|
|
310
|
+
placeholder?: PlainTextElement;
|
|
311
|
+
default_value?: string;
|
|
312
|
+
disabled?: boolean;
|
|
313
|
+
width?: 'default' | 'fill' | string;
|
|
314
|
+
max_length?: number;
|
|
315
|
+
input_type?: 'text' | 'multiline_text' | 'password';
|
|
316
|
+
show_icon?: boolean;
|
|
317
|
+
rows?: number;
|
|
318
|
+
auto_resize?: boolean;
|
|
319
|
+
max_rows?: number;
|
|
320
|
+
label?: PlainTextElement;
|
|
321
|
+
label_position?: 'top' | 'left';
|
|
322
|
+
value?: string | object;
|
|
323
|
+
behaviors?: ActionBehavior[];
|
|
324
|
+
confirm?: ConfirmElement;
|
|
325
|
+
fallback?: {
|
|
326
|
+
tag?: string;
|
|
327
|
+
text?: PlainTextElement;
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
interface OverflowElement extends BaseElement<'overflow'> {
|
|
331
|
+
width?: 'default' | 'fill' | string;
|
|
332
|
+
options: OverflowElement.Option[];
|
|
333
|
+
value?: object;
|
|
334
|
+
confirm?: ConfirmElement;
|
|
335
|
+
}
|
|
336
|
+
namespace OverflowElement {
|
|
337
|
+
interface Option {
|
|
338
|
+
text?: PlainTextElement;
|
|
339
|
+
multi_url?: URLs;
|
|
340
|
+
value?: string;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
interface BaseSelectElement<T extends string = string> extends BaseElement<T> {
|
|
344
|
+
type?: 'default' | 'text';
|
|
345
|
+
name?: string;
|
|
346
|
+
required?: boolean;
|
|
347
|
+
disabled?: boolean;
|
|
348
|
+
placeholder?: PlainTextElement;
|
|
349
|
+
width?: 'default' | 'fill' | string;
|
|
350
|
+
confirm?: ConfirmElement;
|
|
351
|
+
}
|
|
352
|
+
interface OptionElement {
|
|
353
|
+
text: PlainTextElement;
|
|
354
|
+
icon?: IconElement;
|
|
355
|
+
value: string;
|
|
356
|
+
}
|
|
357
|
+
interface SelectElement extends BaseSelectElement<'select_static'> {
|
|
358
|
+
options: OptionElement[];
|
|
359
|
+
initial_option?: string;
|
|
360
|
+
}
|
|
361
|
+
interface MultiSelectElement extends BaseSelectElement<'multi_select_static'> {
|
|
362
|
+
options: OptionElement[];
|
|
363
|
+
selected_values?: string[];
|
|
364
|
+
}
|
|
365
|
+
interface SelectPersonElement extends BaseSelectElement<'select_person'> {
|
|
366
|
+
options?: {
|
|
367
|
+
value: string;
|
|
368
|
+
}[];
|
|
369
|
+
}
|
|
370
|
+
interface MultiSelectPersonElement extends BaseSelectElement<'multi_select_person'> {
|
|
371
|
+
options?: {
|
|
372
|
+
value: string;
|
|
373
|
+
}[];
|
|
374
|
+
selected_values?: string[];
|
|
375
|
+
}
|
|
376
|
+
interface DatePickerElement extends BaseSelectElement<'date_picker'> {
|
|
377
|
+
initial_date?: string;
|
|
378
|
+
value?: object;
|
|
379
|
+
}
|
|
380
|
+
interface TimePickerElement extends BaseSelectElement<'picker_time'> {
|
|
381
|
+
initial_time?: string;
|
|
382
|
+
value?: object;
|
|
383
|
+
}
|
|
384
|
+
interface DateTimePickerElement extends BaseSelectElement<'picker_datetime'> {
|
|
385
|
+
initial_datetime?: string;
|
|
386
|
+
value?: object;
|
|
387
|
+
}
|
|
388
|
+
interface CheckerElement extends BaseElement<'checker'> {
|
|
389
|
+
name?: string;
|
|
390
|
+
checked?: boolean;
|
|
391
|
+
disabled?: boolean;
|
|
392
|
+
text?: CheckerElement.TextElement;
|
|
393
|
+
overall_checkable?: boolean;
|
|
394
|
+
button_area?: {
|
|
395
|
+
pc_display_rule?: 'always' | 'on_hover';
|
|
396
|
+
buttons?: CheckerElement.ButtonElement[];
|
|
397
|
+
};
|
|
398
|
+
checked_style?: {
|
|
399
|
+
show_strikethrough?: boolean;
|
|
400
|
+
opacity?: number;
|
|
401
|
+
};
|
|
402
|
+
margin?: string;
|
|
403
|
+
padding?: string;
|
|
404
|
+
confirm?: ConfirmElement;
|
|
405
|
+
behaviors?: ActionBehavior[];
|
|
406
|
+
hover_tips?: PlainTextElement;
|
|
407
|
+
disable_tips?: PlainTextElement;
|
|
408
|
+
}
|
|
409
|
+
namespace CheckerElement {
|
|
410
|
+
interface TextElement extends PlainTextElement {
|
|
411
|
+
text_size?: 'normal' | 'heading' | 'notation';
|
|
412
|
+
text_color?: string;
|
|
413
|
+
text_align?: TextAlign;
|
|
414
|
+
}
|
|
415
|
+
interface ButtonElement extends BaseButtonElement {
|
|
416
|
+
type: 'text' | 'primary_text' | 'danger_text';
|
|
417
|
+
}
|
|
418
|
+
}
|
|
234
419
|
namespace ButtonElement {
|
|
235
420
|
type Size = 'tiny' | 'small' | 'medium' | 'large';
|
|
236
421
|
type Width = 'default' | 'fill' | string;
|
|
237
422
|
type Type = 'default' | 'primary' | 'danger' | 'text' | 'primary_text' | 'danger_text' | 'primary_filled' | 'danger_filled' | 'laser';
|
|
238
423
|
}
|
|
239
|
-
type Element = DivElement | MarkdownElement |
|
|
424
|
+
type Element = DivElement | MarkdownElement | HRElement | ActionElement | NoteElement | ChartElement | TableElement | ImageElement | FormElement | InputElement | ButtonElement;
|
|
240
425
|
}
|
|
241
426
|
interface Template {
|
|
242
427
|
type: 'template';
|
|
@@ -74,5 +74,21 @@ declare module '../event' {
|
|
|
74
74
|
open_chat_id: string;
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* 机器人自定义菜单事件
|
|
79
|
+
* @see https://open.feishu.cn/document/client-docs/bot-v3/events/menu
|
|
80
|
+
*/
|
|
81
|
+
'application.bot.menu_v6': {
|
|
82
|
+
operator: {
|
|
83
|
+
operator_name: string;
|
|
84
|
+
operator_id: {
|
|
85
|
+
union_id: string;
|
|
86
|
+
user_id: string;
|
|
87
|
+
open_id: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
event_key: string;
|
|
91
|
+
timestamp: number;
|
|
92
|
+
};
|
|
77
93
|
}
|
|
78
94
|
}
|
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.6.
|
|
4
|
+
"version": "3.6.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
],
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@cordisjs/plugin-server": "^0.2.4",
|
|
38
|
-
"@satorijs/core": "^4.2.
|
|
38
|
+
"@satorijs/core": "^4.2.10",
|
|
39
39
|
"cordis": "^3.18.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@satorijs/core": "^4.2.
|
|
42
|
+
"@satorijs/core": "^4.2.10"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/message.ts
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import { Context, h, MessageEncoder } from '@satorijs/core'
|
|
1
|
+
import { Context, Dict, h, MessageEncoder } from '@satorijs/core'
|
|
2
2
|
import { LarkBot } from './bot'
|
|
3
3
|
import { BaseResponse, Lark, MessageContent } from './types'
|
|
4
4
|
import { extractIdType } from './utils'
|
|
5
5
|
|
|
6
6
|
export class LarkMessageEncoder<C extends Context = Context> extends MessageEncoder<C, LarkBot<C>> {
|
|
7
|
-
private quote:
|
|
7
|
+
private quote: Dict | undefined
|
|
8
8
|
private textContent = ''
|
|
9
9
|
private richContent: MessageContent.RichText.Paragraph[] = []
|
|
10
|
-
private
|
|
11
|
-
private
|
|
10
|
+
private card: MessageContent.Card | undefined
|
|
11
|
+
private noteElements: MessageContent.Card.NoteElement.InnerElement[] | undefined
|
|
12
|
+
private actionElements: MessageContent.Card.Element[] = []
|
|
12
13
|
|
|
13
14
|
async post(data?: any) {
|
|
14
15
|
try {
|
|
15
16
|
let resp: BaseResponse & { data?: Lark.Message }
|
|
16
|
-
if (this.quote) {
|
|
17
|
-
resp = await this.bot.internal.replyImMessage(this.quote,
|
|
17
|
+
if (this.quote?.id) {
|
|
18
|
+
resp = await this.bot.internal.replyImMessage(this.quote.id, {
|
|
19
|
+
...data,
|
|
20
|
+
reply_in_thread: this.quote.replyInThread,
|
|
21
|
+
})
|
|
18
22
|
} else {
|
|
19
23
|
data.receive_id = this.channelId
|
|
20
|
-
resp = await this.bot.internal
|
|
24
|
+
resp = await this.bot.internal.createImMessage(data, {
|
|
21
25
|
receive_id_type: extractIdType(this.channelId),
|
|
22
26
|
})
|
|
23
27
|
}
|
|
@@ -41,27 +45,32 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
private flushText(
|
|
45
|
-
if ((this.textContent ||
|
|
46
|
-
this.
|
|
48
|
+
private flushText(button = false) {
|
|
49
|
+
if ((this.textContent || !button) && this.actionElements.length) {
|
|
50
|
+
this.card!.elements.push({ tag: 'action', actions: this.actionElements, layout: 'flow' })
|
|
47
51
|
this.actionElements = []
|
|
48
52
|
}
|
|
49
53
|
if (this.textContent) {
|
|
50
54
|
this.richContent.push([{ tag: 'md', text: this.textContent }])
|
|
51
|
-
|
|
55
|
+
if (this.noteElements) {
|
|
56
|
+
this.noteElements.push({ tag: 'plain_text', content: this.textContent })
|
|
57
|
+
} else if (this.card) {
|
|
58
|
+
this.card.elements.push({ tag: 'markdown', content: this.textContent })
|
|
59
|
+
}
|
|
52
60
|
this.textContent = ''
|
|
53
61
|
}
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
async flush() {
|
|
57
65
|
this.flushText()
|
|
58
|
-
if (!this.
|
|
66
|
+
if (!this.card && !this.richContent.length) return
|
|
59
67
|
|
|
60
|
-
if (this.
|
|
68
|
+
if (this.card) {
|
|
69
|
+
this.bot.logger.debug('card', JSON.stringify(this.card.elements))
|
|
61
70
|
await this.post({
|
|
62
71
|
msg_type: 'interactive',
|
|
63
72
|
content: JSON.stringify({
|
|
64
|
-
elements: this.
|
|
73
|
+
elements: this.card.elements,
|
|
65
74
|
}),
|
|
66
75
|
})
|
|
67
76
|
} else {
|
|
@@ -79,7 +88,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
79
88
|
this.quote = undefined
|
|
80
89
|
this.textContent = ''
|
|
81
90
|
this.richContent = []
|
|
82
|
-
this.
|
|
91
|
+
this.card = undefined
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
async createImage(url: string) {
|
|
@@ -124,6 +133,27 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
124
133
|
})
|
|
125
134
|
}
|
|
126
135
|
|
|
136
|
+
private createBehavior(attrs: Dict) {
|
|
137
|
+
const behaviors: MessageContent.Card.ActionBehavior[] = []
|
|
138
|
+
if (attrs.type === 'link') {
|
|
139
|
+
behaviors.push({
|
|
140
|
+
type: 'open_url',
|
|
141
|
+
default_url: attrs.href,
|
|
142
|
+
})
|
|
143
|
+
} else if (attrs.type === 'input') {
|
|
144
|
+
behaviors.push({
|
|
145
|
+
type: 'callback',
|
|
146
|
+
value: {
|
|
147
|
+
_satori_type: 'command',
|
|
148
|
+
content: attrs.text,
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
} else if (attrs.type === 'action') {
|
|
152
|
+
// TODO
|
|
153
|
+
}
|
|
154
|
+
return behaviors.length ? behaviors : undefined
|
|
155
|
+
}
|
|
156
|
+
|
|
127
157
|
async visit(element: h) {
|
|
128
158
|
const { type, attrs, children } = element
|
|
129
159
|
if (type === 'text') {
|
|
@@ -147,7 +177,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
147
177
|
// platform does not support sharp
|
|
148
178
|
} else if (type === 'quote') {
|
|
149
179
|
await this.flush()
|
|
150
|
-
this.quote = attrs
|
|
180
|
+
this.quote = attrs
|
|
151
181
|
} else if (type === 'img' || type === 'image') {
|
|
152
182
|
const image_key = await this.createImage(attrs.src || attrs.url)
|
|
153
183
|
this.textContent += ``
|
|
@@ -162,26 +192,41 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
162
192
|
} else if (type === 'hr') {
|
|
163
193
|
this.flushText()
|
|
164
194
|
this.richContent.push([{ tag: 'hr' }])
|
|
165
|
-
this.
|
|
166
|
-
} else if (type === '
|
|
195
|
+
this.card?.elements.push({ tag: 'hr' })
|
|
196
|
+
} else if (type === 'form') {
|
|
167
197
|
this.flushText()
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
type: 'callback',
|
|
177
|
-
value: {
|
|
178
|
-
_satori_type: 'command',
|
|
179
|
-
content: attrs.text,
|
|
180
|
-
},
|
|
198
|
+
const length = this.card?.elements.length
|
|
199
|
+
await this.render(children)
|
|
200
|
+
if (this.card?.elements.length > length) {
|
|
201
|
+
const elements = this.card?.elements.slice(length)
|
|
202
|
+
this.card.elements.push({
|
|
203
|
+
tag: 'form',
|
|
204
|
+
name: attrs.name || 'Form',
|
|
205
|
+
elements,
|
|
181
206
|
})
|
|
182
|
-
} else if (attrs.type === 'action') {
|
|
183
|
-
// TODO
|
|
184
207
|
}
|
|
208
|
+
} else if (type === 'input') {
|
|
209
|
+
this.flushText()
|
|
210
|
+
this.card?.elements.push({
|
|
211
|
+
tag: 'action',
|
|
212
|
+
actions: [{
|
|
213
|
+
tag: 'input',
|
|
214
|
+
name: attrs.name,
|
|
215
|
+
width: attrs.width,
|
|
216
|
+
label: attrs.label && {
|
|
217
|
+
tag: 'plain_text',
|
|
218
|
+
content: attrs.label,
|
|
219
|
+
},
|
|
220
|
+
placeholder: attrs.placeholder && {
|
|
221
|
+
tag: 'plain_text',
|
|
222
|
+
content: attrs.placeholder,
|
|
223
|
+
},
|
|
224
|
+
behaviors: this.createBehavior(attrs),
|
|
225
|
+
}],
|
|
226
|
+
})
|
|
227
|
+
} else if (type === 'button') {
|
|
228
|
+
this.card ??= { elements: [] }
|
|
229
|
+
this.flushText(true)
|
|
185
230
|
await this.render(children)
|
|
186
231
|
this.actionElements.push({
|
|
187
232
|
tag: 'button',
|
|
@@ -189,13 +234,14 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
189
234
|
tag: 'plain_text',
|
|
190
235
|
content: this.textContent,
|
|
191
236
|
},
|
|
192
|
-
|
|
237
|
+
disabled: attrs.disabled,
|
|
238
|
+
behaviors: this.createBehavior(attrs),
|
|
193
239
|
})
|
|
194
240
|
this.textContent = ''
|
|
195
241
|
} else if (type === 'button-group') {
|
|
196
|
-
this.flushText(
|
|
242
|
+
this.flushText()
|
|
197
243
|
await this.render(children)
|
|
198
|
-
this.flushText(
|
|
244
|
+
this.flushText()
|
|
199
245
|
} else if (type.startsWith('lark:') || type.startsWith('feishu:')) {
|
|
200
246
|
const tag = type.slice(type.split(':', 1)[0].length + 1)
|
|
201
247
|
if (tag === 'share-chat') {
|
|
@@ -224,18 +270,51 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
224
270
|
this.textContent = ''
|
|
225
271
|
} else if (tag === 'card') {
|
|
226
272
|
await this.flush()
|
|
227
|
-
this.
|
|
273
|
+
this.card = {
|
|
274
|
+
elements: [],
|
|
275
|
+
header: attrs.title && {
|
|
276
|
+
template: attrs.color,
|
|
277
|
+
ud_icon: attrs.icon && {
|
|
278
|
+
tag: 'standard_icon',
|
|
279
|
+
token: attrs.icon,
|
|
280
|
+
},
|
|
281
|
+
title: {
|
|
282
|
+
tag: 'plain_text',
|
|
283
|
+
content: attrs.title,
|
|
284
|
+
},
|
|
285
|
+
subtitle: attrs.subtitle && {
|
|
286
|
+
tag: 'plain_text',
|
|
287
|
+
content: attrs.subtitle,
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
}
|
|
228
291
|
await this.render(children, true)
|
|
229
292
|
} else if (tag === 'div') {
|
|
230
293
|
this.flushText()
|
|
231
294
|
await this.render(children)
|
|
232
|
-
this.
|
|
295
|
+
this.card?.elements.push({
|
|
233
296
|
tag: 'markdown',
|
|
234
297
|
text_align: attrs.align,
|
|
235
298
|
text_size: attrs.size,
|
|
236
299
|
content: this.textContent,
|
|
237
300
|
})
|
|
238
301
|
this.textContent = ''
|
|
302
|
+
} else if (tag === 'note') {
|
|
303
|
+
this.flushText()
|
|
304
|
+
this.noteElements = []
|
|
305
|
+
await this.render(children)
|
|
306
|
+
this.flushText()
|
|
307
|
+
this.card?.elements.push({
|
|
308
|
+
tag: 'note',
|
|
309
|
+
elements: this.noteElements,
|
|
310
|
+
})
|
|
311
|
+
this.noteElements = undefined
|
|
312
|
+
} else if (tag === 'icon') {
|
|
313
|
+
this.flushText()
|
|
314
|
+
this.noteElements?.push({
|
|
315
|
+
tag: 'standard_icon',
|
|
316
|
+
token: attrs.token,
|
|
317
|
+
})
|
|
239
318
|
}
|
|
240
319
|
} else {
|
|
241
320
|
await this.render(children)
|
package/src/types/api.ts
CHANGED
|
@@ -16681,6 +16681,8 @@ export interface ReplyImMessageRequest {
|
|
|
16681
16681
|
content: string
|
|
16682
16682
|
/** 消息类型,包括:text、post、image、file、audio、media、sticker、interactive、share_card、share_user */
|
|
16683
16683
|
msg_type: string
|
|
16684
|
+
/** 是否以话题形式回复。取值为 true 时将以话题形式回复。注意:如果要回复的消息已经是话题形式的消息,则默认以话题形式进行回复。 */
|
|
16685
|
+
reply_in_thread?: boolean
|
|
16684
16686
|
/** 由开发者生成的唯一字符串序列,用于回复消息请求去重;持有相同uuid的请求1小时内至多成功执行一次 */
|
|
16685
16687
|
uuid?: string
|
|
16686
16688
|
}
|