@satorijs/adapter-lark 3.6.0 → 3.6.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/http.d.ts +5 -5
- package/lib/index.cjs +171 -101
- package/lib/index.cjs.map +2 -2
- package/lib/message.d.ts +7 -9
- package/lib/types/message/content.d.ts +201 -22
- package/lib/types/message/index.d.ts +2 -16
- package/lib/utils.d.ts +3 -3
- package/package.json +1 -1
- package/src/http.ts +6 -6
- package/src/message.ts +179 -111
- package/src/types/message/content.ts +266 -42
- package/src/types/message/index.ts +2 -19
- package/src/utils.ts +6 -6
package/src/message.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { Context, h, MessageEncoder } from '@satorijs/core'
|
|
2
2
|
import { LarkBot } from './bot'
|
|
3
|
-
import { BaseResponse, Lark, MessageContent
|
|
3
|
+
import { BaseResponse, Lark, MessageContent } from './types'
|
|
4
4
|
import { extractIdType } from './utils'
|
|
5
5
|
|
|
6
|
-
export interface Addition {
|
|
7
|
-
file: MessageContent.MediaContents
|
|
8
|
-
type: MessageType
|
|
9
|
-
}
|
|
10
|
-
|
|
11
6
|
export class LarkMessageEncoder<C extends Context = Context> extends MessageEncoder<C, LarkBot<C>> {
|
|
12
7
|
private quote: string | undefined
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
private
|
|
8
|
+
private textContent = ''
|
|
9
|
+
private richContent: MessageContent.RichText.Paragraph[] = []
|
|
10
|
+
private cardElements: MessageContent.Card.Element[] | undefined
|
|
11
|
+
private actionElements: MessageContent.Card.ButtonElement[] = []
|
|
17
12
|
|
|
18
13
|
async post(data?: any) {
|
|
19
14
|
try {
|
|
@@ -46,131 +41,204 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
|
|
|
46
41
|
}
|
|
47
42
|
}
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
if (this.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (this.addition) {
|
|
54
|
-
message = {
|
|
55
|
-
...message,
|
|
56
|
-
...this.addition.file,
|
|
57
|
-
}
|
|
44
|
+
private flushText(flushAction = false) {
|
|
45
|
+
if ((this.textContent || flushAction) && this.actionElements.length) {
|
|
46
|
+
this.cardElements?.push({ tag: 'action', actions: this.actionElements })
|
|
47
|
+
this.actionElements = []
|
|
58
48
|
}
|
|
59
|
-
if (this.
|
|
60
|
-
|
|
49
|
+
if (this.textContent) {
|
|
50
|
+
this.richContent.push([{ tag: 'md', text: this.textContent }])
|
|
51
|
+
this.cardElements?.push({ tag: 'markdown', content: this.textContent })
|
|
52
|
+
this.textContent = ''
|
|
61
53
|
}
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async flush() {
|
|
57
|
+
this.flushText()
|
|
58
|
+
if (!this.cardElements && !this.richContent.length) return
|
|
59
|
+
|
|
60
|
+
if (this.cardElements) {
|
|
61
|
+
await this.post({
|
|
62
|
+
msg_type: 'interactive',
|
|
63
|
+
content: JSON.stringify({
|
|
64
|
+
elements: this.cardElements,
|
|
65
|
+
}),
|
|
66
|
+
})
|
|
67
|
+
} else {
|
|
68
|
+
await this.post({
|
|
69
|
+
msg_type: 'post',
|
|
70
|
+
content: JSON.stringify({
|
|
71
|
+
zh_cn: {
|
|
72
|
+
content: this.richContent,
|
|
73
|
+
},
|
|
74
|
+
}),
|
|
75
|
+
})
|
|
64
76
|
}
|
|
65
|
-
await this.post({
|
|
66
|
-
msg_type: this.richText ? 'post' : this.addition ? this.addition.type : 'text',
|
|
67
|
-
content: JSON.stringify(message),
|
|
68
|
-
})
|
|
69
77
|
|
|
70
78
|
// reset cached content
|
|
71
79
|
this.quote = undefined
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
80
|
+
this.textContent = ''
|
|
81
|
+
this.richContent = []
|
|
82
|
+
this.cardElements = undefined
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
async
|
|
85
|
+
async createImage(url: string) {
|
|
86
|
+
const { filename, type, data } = await this.bot.assetsQuester.file(url)
|
|
78
87
|
const payload = new FormData()
|
|
88
|
+
payload.append('image', new Blob([data], { type }), filename)
|
|
89
|
+
payload.append('image_type', 'message')
|
|
90
|
+
const { data: { image_key } } = await this.bot.internal.createImImage(payload)
|
|
91
|
+
return image_key
|
|
92
|
+
}
|
|
79
93
|
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
payload
|
|
94
|
+
async sendFile(_type: 'video' | 'audio' | 'file', attrs: any) {
|
|
95
|
+
const url = attrs.src || attrs.url
|
|
96
|
+
const payload = new FormData()
|
|
97
|
+
const { filename, type, data } = await this.bot.assetsQuester.file(url)
|
|
98
|
+
payload.append('file', new Blob([data], { type }), filename)
|
|
99
|
+
payload.append('file_name', filename)
|
|
83
100
|
|
|
84
|
-
if (
|
|
85
|
-
payload.append('
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
if (attrs.duration) {
|
|
102
|
+
payload.append('duration', attrs.duration)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (_type === 'audio') {
|
|
106
|
+
// FIXME: only support opus
|
|
107
|
+
payload.append('file_type', 'opus')
|
|
108
|
+
} else if (_type === 'video') {
|
|
109
|
+
// FIXME: only support mp4
|
|
110
|
+
payload.append('file_type', 'mp4')
|
|
93
111
|
} else {
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
payload.append('file_type', 'opus')
|
|
98
|
-
msgType = 'audio'
|
|
99
|
-
} else if (type === 'video') {
|
|
100
|
-
// FIXME: only support mp4
|
|
101
|
-
payload.append('file_type', 'mp4')
|
|
102
|
-
msgType = 'media'
|
|
112
|
+
const ext = filename.split('.').pop()
|
|
113
|
+
if (['doc', 'xls', 'ppt', 'pdf'].includes(ext)) {
|
|
114
|
+
payload.append('file_type', ext)
|
|
103
115
|
} else {
|
|
104
|
-
|
|
105
|
-
if (['xls', 'ppt', 'pdf'].includes(ext)) {
|
|
106
|
-
payload.append('file_type', ext)
|
|
107
|
-
} else {
|
|
108
|
-
payload.append('file_type', 'stream')
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
payload.append('file_name', filename)
|
|
112
|
-
const { data } = await this.bot.internal.createImFile(payload)
|
|
113
|
-
return {
|
|
114
|
-
type: msgType,
|
|
115
|
-
file: {
|
|
116
|
-
file_key: data.file_key,
|
|
117
|
-
},
|
|
116
|
+
payload.append('file_type', 'stream')
|
|
118
117
|
}
|
|
119
118
|
}
|
|
119
|
+
|
|
120
|
+
const { data: { file_key } } = await this.bot.internal.createImFile(payload)
|
|
121
|
+
await this.post({
|
|
122
|
+
msg_type: _type === 'video' ? 'media' : _type,
|
|
123
|
+
content: JSON.stringify({ file_key }),
|
|
124
|
+
})
|
|
120
125
|
}
|
|
121
126
|
|
|
122
127
|
async visit(element: h) {
|
|
123
128
|
const { type, attrs, children } = element
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.content += `<at user_id="all">${attrs.name ?? '所有人'}</at>`
|
|
132
|
-
} else {
|
|
133
|
-
this.content += `<at user_id="${attrs.id}">${attrs.name}</at>`
|
|
134
|
-
}
|
|
135
|
-
break
|
|
129
|
+
if (type === 'text') {
|
|
130
|
+
this.textContent += attrs.content
|
|
131
|
+
} else if (type === 'at') {
|
|
132
|
+
if (attrs.type === 'all') {
|
|
133
|
+
this.textContent += `<at user_id="all">${attrs.name ?? '所有人'}</at>`
|
|
134
|
+
} else {
|
|
135
|
+
this.textContent += `<at user_id="${attrs.id}">${attrs.name}</at>`
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
137
|
+
} else if (type === 'a') {
|
|
138
|
+
await this.render(children)
|
|
139
|
+
if (attrs.href) this.textContent += ` (${attrs.href})`
|
|
140
|
+
} else if (type === 'p') {
|
|
141
|
+
if (!this.textContent.endsWith('\n')) this.textContent += '\n'
|
|
142
|
+
await this.render(children)
|
|
143
|
+
if (!this.textContent.endsWith('\n')) this.textContent += '\n'
|
|
144
|
+
} else if (type === 'br') {
|
|
145
|
+
this.textContent += '\n'
|
|
146
|
+
} else if (type === 'sharp') {
|
|
147
|
+
// platform does not support sharp
|
|
148
|
+
} else if (type === 'quote') {
|
|
149
|
+
await this.flush()
|
|
150
|
+
this.quote = attrs.id
|
|
151
|
+
} else if (type === 'img' || type === 'image') {
|
|
152
|
+
const image_key = await this.createImage(attrs.src || attrs.url)
|
|
153
|
+
this.textContent += ``
|
|
154
|
+
this.flushText()
|
|
155
|
+
this.richContent.push([{ tag: 'img', image_key }])
|
|
156
|
+
} else if (['video', 'audio', 'file'].includes(type)) {
|
|
157
|
+
await this.flush()
|
|
158
|
+
await this.sendFile(type as any, attrs)
|
|
159
|
+
} else if (type === 'figure' || type === 'message') {
|
|
160
|
+
await this.flush()
|
|
161
|
+
await this.render(children, true)
|
|
162
|
+
} else if (type === 'hr') {
|
|
163
|
+
this.flushText()
|
|
164
|
+
this.richContent.push([{ tag: 'hr' }])
|
|
165
|
+
this.cardElements?.push({ tag: 'hr' })
|
|
166
|
+
} else if (type === 'button') {
|
|
167
|
+
this.flushText()
|
|
168
|
+
const behaviors: MessageContent.Card.ActionBehavior[] = []
|
|
169
|
+
if (attrs.type === 'link') {
|
|
170
|
+
behaviors.push({
|
|
171
|
+
type: 'open_url',
|
|
172
|
+
default_url: attrs.href,
|
|
173
|
+
})
|
|
174
|
+
} else if (attrs.type === 'input') {
|
|
175
|
+
behaviors.push({
|
|
176
|
+
type: 'callback',
|
|
177
|
+
value: {
|
|
178
|
+
_satori_type: 'command',
|
|
179
|
+
content: attrs.text,
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
} else if (attrs.type === 'action') {
|
|
183
|
+
// TODO
|
|
184
|
+
}
|
|
185
|
+
await this.render(children)
|
|
186
|
+
this.actionElements.push({
|
|
187
|
+
tag: 'button',
|
|
188
|
+
text: {
|
|
189
|
+
tag: 'plain_text',
|
|
190
|
+
content: this.textContent,
|
|
191
|
+
},
|
|
192
|
+
behaviors,
|
|
193
|
+
})
|
|
194
|
+
this.textContent = ''
|
|
195
|
+
} else if (type === 'button-group') {
|
|
196
|
+
this.flushText(true)
|
|
197
|
+
await this.render(children)
|
|
198
|
+
this.flushText(true)
|
|
199
|
+
} else if (type.startsWith('lark:') || type.startsWith('feishu:')) {
|
|
200
|
+
const tag = type.slice(type.split(':', 1)[0].length + 1)
|
|
201
|
+
if (tag === 'share-chat') {
|
|
153
202
|
await this.flush()
|
|
154
|
-
this.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
203
|
+
await this.post({
|
|
204
|
+
msg_type: 'share_chat',
|
|
205
|
+
content: JSON.stringify({ chat_id: attrs.chatId }),
|
|
206
|
+
})
|
|
207
|
+
} else if (tag === 'share-user') {
|
|
208
|
+
await this.flush()
|
|
209
|
+
await this.post({
|
|
210
|
+
msg_type: 'share_user',
|
|
211
|
+
content: JSON.stringify({ user_id: attrs.userId }),
|
|
212
|
+
})
|
|
213
|
+
} else if (tag === 'system') {
|
|
214
|
+
await this.flush()
|
|
215
|
+
await this.render(children)
|
|
216
|
+
await this.post({
|
|
217
|
+
msg_type: 'system',
|
|
218
|
+
content: JSON.stringify({
|
|
219
|
+
type: 'divider',
|
|
220
|
+
params: { divider_text: { text: this.textContent } },
|
|
221
|
+
options: { need_rollup: attrs.needRollup },
|
|
222
|
+
}),
|
|
223
|
+
})
|
|
224
|
+
this.textContent = ''
|
|
225
|
+
} else if (tag === 'card') {
|
|
169
226
|
await this.flush()
|
|
227
|
+
this.cardElements = []
|
|
170
228
|
await this.render(children, true)
|
|
171
|
-
|
|
172
|
-
|
|
229
|
+
} else if (tag === 'div') {
|
|
230
|
+
this.flushText()
|
|
173
231
|
await this.render(children)
|
|
232
|
+
this.cardElements?.push({
|
|
233
|
+
tag: 'markdown',
|
|
234
|
+
text_align: attrs.align,
|
|
235
|
+
text_size: attrs.size,
|
|
236
|
+
content: this.textContent,
|
|
237
|
+
})
|
|
238
|
+
this.textContent = ''
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
await this.render(children)
|
|
174
242
|
}
|
|
175
243
|
}
|
|
176
244
|
}
|
|
@@ -1,23 +1,35 @@
|
|
|
1
|
-
// https://open.larksuite.com/document/
|
|
1
|
+
// https://open.larksuite.com/document/server-docs/im-v1/message-content-description/create_json
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
declare global {
|
|
4
|
+
namespace JSX {
|
|
5
|
+
interface IntrinsicElements {
|
|
6
|
+
'lark:share-chat': {
|
|
7
|
+
'chat-id': string
|
|
8
|
+
}
|
|
9
|
+
'lark:share-user': {
|
|
10
|
+
'user-id': string
|
|
11
|
+
}
|
|
12
|
+
'lark:system': {
|
|
13
|
+
'need-rollup'?: boolean
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface MessageContent {
|
|
20
|
+
text: MessageContent.Text
|
|
21
|
+
post: MessageContent.RichText
|
|
22
|
+
image: MessageContent.Image
|
|
23
|
+
file: MessageContent.File
|
|
24
|
+
audio: MessageContent.Audio
|
|
25
|
+
media: MessageContent.Media
|
|
26
|
+
sticker: MessageContent.Sticker
|
|
27
|
+
share_chat: MessageContent.ShareChat
|
|
28
|
+
share_user: MessageContent.ShareUser
|
|
29
|
+
system: MessageContent.System
|
|
30
|
+
}
|
|
20
31
|
|
|
32
|
+
export namespace MessageContent {
|
|
21
33
|
export interface Text {
|
|
22
34
|
text: string
|
|
23
35
|
}
|
|
@@ -40,7 +52,7 @@ export namespace MessageContent {
|
|
|
40
52
|
|
|
41
53
|
export interface Media {
|
|
42
54
|
file_key: string
|
|
43
|
-
image_key
|
|
55
|
+
image_key?: string
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
export interface File {
|
|
@@ -51,52 +63,264 @@ export namespace MessageContent {
|
|
|
51
63
|
file_key: string
|
|
52
64
|
}
|
|
53
65
|
|
|
66
|
+
export interface System {
|
|
67
|
+
type: 'divider'
|
|
68
|
+
params: {
|
|
69
|
+
divider_text: {
|
|
70
|
+
text: string
|
|
71
|
+
i18n_text?: Record<string, string>
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
options?: {
|
|
75
|
+
need_rollup?: boolean
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
54
79
|
export interface RichText {
|
|
55
80
|
[locale: string]: {
|
|
56
|
-
title
|
|
81
|
+
title?: string
|
|
57
82
|
content: RichText.Paragraph[]
|
|
58
83
|
}
|
|
59
84
|
}
|
|
60
85
|
|
|
61
86
|
export namespace RichText {
|
|
62
|
-
export
|
|
87
|
+
export type Style = 'bold' | 'italic' | 'underline' | 'lineThrough'
|
|
63
88
|
|
|
64
|
-
export interface
|
|
65
|
-
tag:
|
|
89
|
+
export interface BaseElement<T extends string = string> {
|
|
90
|
+
tag: T
|
|
66
91
|
}
|
|
67
92
|
|
|
68
|
-
export interface
|
|
69
|
-
tag: 'text'
|
|
93
|
+
export interface TextElement extends BaseElement<'text'> {
|
|
70
94
|
text: string
|
|
71
95
|
un_escape?: boolean
|
|
96
|
+
style?: Style[]
|
|
72
97
|
}
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
|
|
99
|
+
export interface LinkElement extends BaseElement<'a'> {
|
|
75
100
|
text: string
|
|
76
101
|
href: string
|
|
102
|
+
style?: Style[]
|
|
77
103
|
}
|
|
78
|
-
|
|
79
|
-
|
|
104
|
+
|
|
105
|
+
export interface AtElement extends BaseElement<'at'> {
|
|
80
106
|
user_id: string
|
|
81
|
-
|
|
107
|
+
style?: Style[]
|
|
108
|
+
// user_name?: string
|
|
82
109
|
}
|
|
83
|
-
|
|
84
|
-
|
|
110
|
+
|
|
111
|
+
export interface ImageElement extends BaseElement<'img'> {
|
|
85
112
|
image_key: string
|
|
86
|
-
height?: number
|
|
87
|
-
width?: number
|
|
113
|
+
// height?: number
|
|
114
|
+
// width?: number
|
|
88
115
|
}
|
|
89
|
-
|
|
90
|
-
|
|
116
|
+
|
|
117
|
+
export interface MediaElement extends BaseElement<'media'> {
|
|
91
118
|
file_key: string
|
|
92
119
|
image_key?: string
|
|
93
120
|
}
|
|
94
121
|
|
|
95
|
-
export
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
122
|
+
export interface EmotionElement extends BaseElement<'emoji'> {
|
|
123
|
+
emoji_type: string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface CodeBlockElement extends BaseElement<'code_block'> {
|
|
127
|
+
language?: string
|
|
128
|
+
text: string
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface HRElement extends BaseElement<'hr'> {}
|
|
132
|
+
|
|
133
|
+
export interface MarkdownElement extends BaseElement<'md'> {
|
|
134
|
+
text: string
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export type InlineElement =
|
|
138
|
+
| TextElement
|
|
139
|
+
| LinkElement
|
|
140
|
+
| AtElement
|
|
141
|
+
| EmotionElement
|
|
142
|
+
| MarkdownElement
|
|
143
|
+
|
|
144
|
+
export type BlockElement =
|
|
145
|
+
| ImageElement
|
|
146
|
+
| MediaElement
|
|
147
|
+
| CodeBlockElement
|
|
148
|
+
| HRElement
|
|
149
|
+
|
|
150
|
+
export type Paragraph =
|
|
151
|
+
| InlineElement[]
|
|
152
|
+
| [BlockElement]
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface Card {
|
|
156
|
+
config: Card.Config
|
|
157
|
+
card_link?: Card.URLs
|
|
158
|
+
elements?: Card.Element[]
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export namespace Card {
|
|
162
|
+
/** @see https://open.larksuite.com/document/common-capabilities/message-card/getting-started/card-structure/card-configuration */
|
|
163
|
+
export interface Config {
|
|
164
|
+
enable_forward?: boolean
|
|
165
|
+
update_multi?: boolean
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface URLs {
|
|
169
|
+
url: string
|
|
170
|
+
pc_url?: string
|
|
171
|
+
ios_url?: string
|
|
172
|
+
android_url?: string
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** @see https://open.larksuite.com/document/common-capabilities/message-card/message-cards-content/card-header */
|
|
176
|
+
export interface Header {
|
|
177
|
+
title: I18nPlainTextElement
|
|
178
|
+
subtitle?: I18nPlainTextElement
|
|
179
|
+
template?: Header.Template
|
|
180
|
+
icon?: CustomIconElement
|
|
181
|
+
ud_icon?: StandardIconElement
|
|
182
|
+
text_tag_list?: TextTagElement[]
|
|
183
|
+
i18n_text_tag_list?: Record<string, TextTagElement[]>
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export namespace Header {
|
|
187
|
+
export type Template = 'blue' | 'wathet' | 'turquoise' | 'green' | 'yellow' | 'orange' | 'red' | 'carmine' | 'violet' | 'purple' | 'indigo' | 'grey' | 'default'
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface BaseElement<T extends string = string> {
|
|
191
|
+
tag: T
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export type TextSize =
|
|
195
|
+
| 'heading-0' | 'heading-1' | 'heading-2' | 'heading-3' | 'heading-4' | 'heading'
|
|
196
|
+
| 'normal' | 'notation' | 'xxxx-large' | 'xxx-large' | 'xx-large' | 'x-large' | 'large' | 'medium' | 'small' | 'x-small'
|
|
197
|
+
|
|
198
|
+
export type TextAlign = 'left' | 'center' | 'right'
|
|
199
|
+
|
|
200
|
+
export interface PlainTextElement extends BaseElement<'plain_text'> {
|
|
201
|
+
content: string
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface I18nPlainTextElement extends PlainTextElement {
|
|
205
|
+
i18n?: Record<string, string>
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface DivPlainTextElement extends PlainTextElement {
|
|
209
|
+
text_size?: TextSize
|
|
210
|
+
text_color?: string
|
|
211
|
+
text_align?: TextAlign
|
|
212
|
+
lines?: number
|
|
213
|
+
icon?: IconElement
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export type IconElement = StandardIconElement | CustomIconElement
|
|
217
|
+
|
|
218
|
+
export interface CustomIconElement extends BaseElement<'custom_icon'> {
|
|
219
|
+
img_key: string
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface StandardIconElement extends BaseElement<'standard_icon'> {
|
|
223
|
+
token: string
|
|
224
|
+
color?: string
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export interface TextTagElement extends BaseElement<'text_tag'> {
|
|
228
|
+
text: PlainTextElement
|
|
229
|
+
color: TextTagElement.Color
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export namespace TextTagElement {
|
|
233
|
+
export type Color = 'neutral' | 'blue' | 'torqoise' | 'lime' | 'orange' | 'violet' | 'indigo' | 'wathet' | 'green' | 'yellow' | 'red' | 'purple' | 'carmine'
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface ImageElement extends BaseElement<'image'> {
|
|
237
|
+
img_key: string
|
|
238
|
+
alt?: PlainTextElement
|
|
239
|
+
title?: PlainTextElement
|
|
240
|
+
custom_width?: number
|
|
241
|
+
compact_width?: boolean
|
|
242
|
+
mode?: 'crop_center' | 'fit_horizontal' | 'large' | 'medium' | 'small' | 'tiny'
|
|
243
|
+
preview?: boolean
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface HorizontalRuleElement extends BaseElement<'hr'> {}
|
|
247
|
+
|
|
248
|
+
export interface DivElement extends BaseElement<'div'> {
|
|
249
|
+
text?: DivPlainTextElement
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface MarkdownElement extends BaseElement<'markdown'> {
|
|
253
|
+
content: string
|
|
254
|
+
text_size?: TextSize
|
|
255
|
+
text_align?: TextAlign
|
|
256
|
+
href?: Record<string, URLs>
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface HorizontalRuleElement extends BaseElement<'hr'> {}
|
|
260
|
+
|
|
261
|
+
export interface ActionModule extends BaseElement<'action'> {
|
|
262
|
+
actions: ActionElement[]
|
|
263
|
+
layout?: 'bisected' | 'trisection' | 'flow'
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export type ActionElement =
|
|
267
|
+
| ButtonElement
|
|
268
|
+
|
|
269
|
+
export type ActionBehavior =
|
|
270
|
+
| OpenURLBehavior
|
|
271
|
+
| CallbackBehavior
|
|
272
|
+
|
|
273
|
+
export interface OpenURLBehavior {
|
|
274
|
+
type: 'open_url'
|
|
275
|
+
default_url: string
|
|
276
|
+
pc_url?: string
|
|
277
|
+
ios_url?: string
|
|
278
|
+
android_url?: string
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface CallbackBehavior {
|
|
282
|
+
type: 'callback'
|
|
283
|
+
value: Record<string, string>
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface ButtonElement extends BaseElement<'button'> {
|
|
287
|
+
text: PlainTextElement
|
|
288
|
+
type?: ButtonElement.Type
|
|
289
|
+
size?: ButtonElement.Size
|
|
290
|
+
width?: ButtonElement.Width
|
|
291
|
+
icon?: IconElement
|
|
292
|
+
hover_tips?: PlainTextElement
|
|
293
|
+
disabled?: boolean
|
|
294
|
+
disabled_tips?: PlainTextElement
|
|
295
|
+
confirm?: {
|
|
296
|
+
title: PlainTextElement
|
|
297
|
+
text: PlainTextElement
|
|
298
|
+
}
|
|
299
|
+
behaviors?: ActionBehavior[]
|
|
300
|
+
// form-related fields
|
|
301
|
+
name?: string
|
|
302
|
+
required?: boolean
|
|
303
|
+
action_type?: 'link' | 'request' | 'multi' | 'form_submit' | 'form_reset'
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export namespace ButtonElement {
|
|
307
|
+
export type Size = 'tiny' | 'small' | 'medium' | 'large'
|
|
308
|
+
export type Width = 'default' | 'fill' | string
|
|
309
|
+
export type Type = 'default' | 'primary' | 'danger' | 'text' | 'primary_text' | 'danger_text' | 'primary_filled' | 'danger_filled' | 'laser'
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export type Element =
|
|
313
|
+
| DivElement
|
|
314
|
+
| MarkdownElement
|
|
315
|
+
| HorizontalRuleElement
|
|
316
|
+
| ActionModule
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface Template {
|
|
320
|
+
type: 'template'
|
|
321
|
+
data: {
|
|
322
|
+
template_id: string
|
|
323
|
+
template_variable: object
|
|
324
|
+
}
|
|
101
325
|
}
|
|
102
326
|
}
|