Skip to content

Commit

Permalink
feat(lark): support buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Oct 30, 2024
1 parent 7b30ac1 commit 22e736b
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 12 deletions.
65 changes: 58 additions & 7 deletions adapters/lark/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
private textContent = ''
private richContent: MessageComponent.RichText.Paragraph[] = []
private cardElements: MessageComponent.Card.Element[] | undefined
private actionElements: MessageComponent.Card.ActionElement[] = []

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

private flushText() {
if (!this.textContent) return
this.richContent.push([{ tag: 'md', text: this.textContent }])
this.cardElements?.push({ tag: 'markdown', content: this.textContent })
this.textContent = ''
private flushText(flushAction = false) {
if ((this.textContent || flushAction) && this.actionElements.length) {
this.cardElements?.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 })
this.textContent = ''
}
}

async flush() {
Expand All @@ -54,7 +60,9 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
if (this.cardElements) {
await this.post({
msg_type: 'interactive',
elements: this.cardElements,
content: JSON.stringify({
elements: this.cardElements,
}),
})
} else {
await this.post({
Expand Down Expand Up @@ -147,10 +155,43 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
} else if (type === 'figure' || type === 'message') {
await this.flush()
await this.render(children, true)
} else if (type === 'hr' || type === 'lark:hr' || type === 'feishu:hr') {
} else if (type === 'hr') {
this.flushText()
this.richContent.push([{ tag: 'hr' }])
this.cardElements?.push({ tag: 'hr' })
} else if (type === 'button') {
this.flushText()
const behaviors: MessageComponent.Card.ActionBehavior[] = []
if (attrs.type === 'link') {
behaviors.push({
type: 'open_url',
default_url: attrs.href,
})
} else if (attrs.type === 'input') {
behaviors.push({
type: 'callback',
value: {
_satori_type: 'command',
content: attrs.text,
},
})
} else if (attrs.type === 'action') {
// TODO
}
await this.render(children)
this.actionElements.push({
tag: 'button',
text: {
tag: 'plain_text',
content: this.textContent,
},
behaviors,
})
this.textContent = ''
} else if (type === 'button-group') {
this.flushText(true)
await this.render(children)
this.flushText(true)
} 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 @@ -181,6 +222,16 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
await this.flush()
this.cardElements = []
await this.render(children, true)
} else if (tag === 'div') {
this.flushText()
await this.render(children)
this.cardElements?.push({
tag: 'markdown',
text_align: attrs.align,
text_size: attrs.size,
content: this.textContent,
})
this.textContent = ''
}
} else {
await this.render(children)
Expand Down
68 changes: 63 additions & 5 deletions adapters/lark/src/types/message/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ export namespace MessageComponent {

/** @see https://open.larksuite.com/document/common-capabilities/message-card/message-cards-content/card-header */
export interface Header {
title: PlainTextElement
subtitle?: PlainTextElement
title: I18nPlainTextElement
subtitle?: I18nPlainTextElement
template?: Header.Template
icon?: CustomIconElement
ud_icon?: StandardIconElement
Expand All @@ -186,7 +186,13 @@ export namespace MessageComponent {

export interface PlainTextElement extends BaseElement<'plain_text'> {
content: string
}

export interface I18nPlainTextElement extends PlainTextElement {
i18n?: Record<string, string>
}

export interface DivPlainTextElement extends PlainTextElement {
text_size?: TextSize
text_color?: string
text_align?: TextAlign
Expand Down Expand Up @@ -226,8 +232,8 @@ export namespace MessageComponent {

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

export interface ParagraphElement extends BaseElement<'div'> {
text?: PlainTextElement
export interface DivElement extends BaseElement<'div'> {
text?: DivPlainTextElement
}

export interface MarkdownElement extends BaseElement<'markdown'> {
Expand All @@ -239,10 +245,62 @@ export namespace MessageComponent {

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

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

export type ActionElement =
| ButtonElement

export type ActionBehavior =
| OpenURLBehavior
| CallbackBehavior

export interface OpenURLBehavior {
type: 'open_url'
default_url: string
pc_url?: string
ios_url?: string
android_url?: string
}

export interface CallbackBehavior {
type: 'callback'
value: Record<string, string>
}

export interface ButtonElement extends BaseElement<'button'> {
text: PlainTextElement
type?: ButtonElement.Type
size?: ButtonElement.Size
width?: ButtonElement.Width
icon?: IconElement
hover_tips?: PlainTextElement
disabled?: boolean
disabled_tips?: PlainTextElement
confirm?: {
title: PlainTextElement
text: PlainTextElement
}
behaviors?: ActionBehavior[]
// form-related fields
name?: string
required?: boolean
action_type?: 'link' | 'request' | 'multi' | 'form_submit' | 'form_reset'
}

export namespace ButtonElement {
export type Size = 'tiny' | 'small' | 'medium' | 'large'
export type Width = 'default' | 'fill' | string
export type Type = 'default' | 'primary' | 'danger' | 'text' | 'primary_text' | 'danger_text' | 'primary_filled' | 'danger_filled' | 'laser'
}

export type Element =
| ParagraphElement
| DivElement
| MarkdownElement
| HorizontalRuleElement
| ActionModule
}

export interface Template {
Expand Down

0 comments on commit 22e736b

Please sign in to comment.