Skip to content

Commit

Permalink
feat(lark): support lark:note and lark:icon
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Oct 31, 2024
1 parent 3f0b3bd commit f00c1b9
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 28 deletions.
70 changes: 54 additions & 16 deletions adapters/lark/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
private quote: string | undefined
private textContent = ''
private richContent: MessageContent.RichText.Paragraph[] = []
private cardElements: MessageContent.Card.Element[] | undefined
private actionElements: MessageContent.Card.ButtonElement[] = []
private card: MessageContent.Card | undefined
private noteElements: MessageContent.Card.NoteElement.InnerElement[] | undefined
private actionElements: MessageContent.Card.ActionElement.InnerElement[] = []

async post(data?: any) {
try {
Expand Down Expand Up @@ -41,27 +42,31 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
}
}

private flushText(flushAction = false) {
if ((this.textContent || flushAction) && this.actionElements.length) {
this.cardElements?.push({ tag: 'action', actions: this.actionElements })
private flushText(button = false) {
if ((this.textContent || !button) && this.actionElements.length) {
this.card?.elements.push({ tag: 'action', actions: this.actionElements })
this.actionElements = []
}
if (this.textContent) {
this.richContent.push([{ tag: 'md', text: this.textContent }])
this.cardElements?.push({ tag: 'markdown', content: this.textContent })
if (this.noteElements) {
this.noteElements.push({ tag: 'plain_text', content: this.textContent })
} else if (this.card) {
this.card.elements.push({ tag: 'markdown', content: this.textContent })
}
this.textContent = ''
}
}

async flush() {
this.flushText()
if (!this.cardElements && !this.richContent.length) return
if (!this.card.elements && !this.richContent.length) return

if (this.cardElements) {
if (this.card) {
await this.post({
msg_type: 'interactive',
content: JSON.stringify({
elements: this.cardElements,
elements: this.card.elements,
}),
})
} else {
Expand All @@ -79,7 +84,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
this.quote = undefined
this.textContent = ''
this.richContent = []
this.cardElements = undefined
this.card = undefined
}

async createImage(url: string) {
Expand Down Expand Up @@ -162,9 +167,9 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
} else if (type === 'hr') {
this.flushText()
this.richContent.push([{ tag: 'hr' }])
this.cardElements?.push({ tag: 'hr' })
this.card?.elements.push({ tag: 'hr' })
} else if (type === 'button') {
this.flushText()
this.flushText(true)
const behaviors: MessageContent.Card.ActionBehavior[] = []
if (attrs.type === 'link') {
behaviors.push({
Expand Down Expand Up @@ -193,9 +198,9 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
})
this.textContent = ''
} else if (type === 'button-group') {
this.flushText(true)
this.flushText()
await this.render(children)
this.flushText(true)
this.flushText()
} else if (type.startsWith('lark:') || type.startsWith('feishu:')) {
const tag = type.slice(type.split(':', 1)[0].length + 1)
if (tag === 'share-chat') {
Expand Down Expand Up @@ -224,18 +229,51 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
this.textContent = ''
} else if (tag === 'card') {
await this.flush()
this.cardElements = []
this.card = {
elements: [],
header: attrs.title && {
template: attrs.color,
ud_icon: attrs.icon && {
tag: 'standard_icon',
token: attrs.icon,
},
title: {
tag: 'plain_text',
content: attrs.title,
},
subtitle: attrs.subtitle && {
tag: 'plain_text',
content: attrs.subtitle,
},
},
}
await this.render(children, true)
} else if (tag === 'div') {
this.flushText()
await this.render(children)
this.cardElements?.push({
this.card?.elements.push({
tag: 'markdown',
text_align: attrs.align,
text_size: attrs.size,
content: this.textContent,
})
this.textContent = ''
} else if (tag === 'note') {
this.flushText()
this.noteElements = []
await this.render(children)
this.flushText()
this.card?.elements.push({
tag: 'note',
elements: this.noteElements,
})
this.noteElements = undefined
} else if (tag === 'icon') {
this.flushText()
this.noteElements?.push({
tag: 'standard_icon',
token: attrs.token,
})
}
} else {
await this.render(children)
Expand Down
99 changes: 87 additions & 12 deletions adapters/lark/src/types/message/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,10 @@ export namespace MessageContent {
}

export interface Card {
config: Card.Config
config?: Card.Config
card_link?: Card.URLs
elements?: Card.Element[]
header?: Card.Header
elements: Card.Element[]
}

export namespace Card {
Expand Down Expand Up @@ -233,17 +234,27 @@ export namespace MessageContent {
export type Color = 'neutral' | 'blue' | 'torqoise' | 'lime' | 'orange' | 'violet' | 'indigo' | 'wathet' | 'green' | 'yellow' | 'red' | 'purple' | 'carmine'
}

export interface ImageElement extends BaseElement<'image'> {
export interface BaseImageElement extends BaseElement<'image'> {
img_key: string
alt?: PlainTextElement
}

export interface ImageElement extends BaseImageElement {
title?: PlainTextElement
transparent?: string
preview?: boolean
corner_radius?: string
scale_type?: 'crop_center' | 'fit_horizontal' | 'crop_top'
size?: 'large' | 'medium' | 'small' | 'tiny' | 'stretch_without_padding' | 'stretch' | string
/** @deprecated */
custom_width?: number
/** @deprecated */
compact_width?: boolean
/** @deprecated */
mode?: 'crop_center' | 'fit_horizontal' | 'large' | 'medium' | 'small' | 'tiny'
preview?: boolean
}

export interface HorizontalRuleElement extends BaseElement<'hr'> {}
export interface HRElement extends BaseElement<'hr'> {}

export interface DivElement extends BaseElement<'div'> {
text?: DivPlainTextElement
Expand All @@ -256,15 +267,75 @@ export namespace MessageContent {
href?: Record<string, URLs>
}

export interface HorizontalRuleElement extends BaseElement<'hr'> {}
export interface PersonElement extends BaseElement<'person'> {
user_id: string
size?: 'large' | 'medium' | 'small' | 'extra_small'
}

export interface PersonListElement extends BaseElement<'person_list'> {
persons: { id: string }[]
size?: 'large' | 'medium' | 'small' | 'extra_small'
show_name?: boolean
show_avatar?: boolean
}

export interface ChartElement extends BaseElement<'chart'> {
chart_spec: {} // TODO
aspect_ratio?: '1:1' | '2:1' | '4:3' | '16:9'
color_theme?: 'brand' | 'rainbow' | 'complementary' | 'converse' | 'primary'
preview?: boolean
height?: 'auto' | string
}

export interface TableElement extends BaseElement<'table'> {
page_size?: number
row_height?: 'low' | 'medium' | 'high' | string
header_style?: TableElement.HeaderStyle
columns: TableElement.Column[]
rows: object[]
}

export namespace TableElement {
export interface HeaderStyle {
text_align?: TextAlign
text_size?: TextSize
background_style?: 'grey' | 'none'
text_color?: 'default' | 'grey'
bold?: boolean
lines?: number
}

export interface ActionModule extends BaseElement<'action'> {
actions: ActionElement[]
export interface Column {
name: string
display_name?: string
width?: 'auto' | string
horizontal_align?: 'left' | 'center' | 'right'
data_type?: 'text' | 'lark_md' | 'options' | 'number' | 'persons' | 'date' | 'markdown'
format?: {
percision?: number
symbol?: string
separator?: string
}
date_format?: string
}
}

export interface NoteElement extends BaseElement<'note'> {
elements: NoteElement.InnerElement[]
}

export namespace NoteElement {
export type InnerElement = IconElement | PlainTextElement | BaseImageElement
}

export interface ActionElement extends BaseElement<'action'> {
actions: ActionElement.InnerElement[]
layout?: 'bisected' | 'trisection' | 'flow'
}

export type ActionElement =
| ButtonElement
export namespace ActionElement {
export type InnerElement = ButtonElement
}

export type ActionBehavior =
| OpenURLBehavior
Expand Down Expand Up @@ -312,8 +383,12 @@ export namespace MessageContent {
export type Element =
| DivElement
| MarkdownElement
| HorizontalRuleElement
| ActionModule
| HRElement
| ActionElement
| NoteElement
| ChartElement
| TableElement
| ImageElement
}

export interface Template {
Expand Down

0 comments on commit f00c1b9

Please sign in to comment.