Feishu MCP Server

by cso1z
Verified
// 定义块类型接口 export interface FeishuBlock { block_type: number; [key: string]: any; } // 定义文本样式接口 export interface TextElementStyle { bold?: boolean; // 是否加粗 italic?: boolean; // 是否斜体 underline?: boolean; // 是否下划线 strikethrough?: boolean; // 是否删除线 inline_code?: boolean; // 是否行内代码 text_color?: number; // 文本颜色 } // 定义文本内容接口 export interface TextContent { text: string; // 文本内容 style?: TextElementStyle; // 文本样式 } // 定义文本块接口 export interface TextBlock extends FeishuBlock { block_type: 2; // 文本块类型固定为2 text: { elements: Array<{ text_run: { content: string; text_element_style: TextElementStyle; } }>; style: { align: number; // 对齐方式:1左对齐,2居中,3右对齐 } }; } // 定义代码块接口 export interface CodeBlock extends FeishuBlock { block_type: 14; // 代码块类型固定为14 code: { elements: Array<{ text_run: { content: string; text_element_style: TextElementStyle; } }>; style: { language: number; // 语言类型代码 wrap: boolean; // 是否自动换行 } }; } // 定义标题块接口 export interface HeadingBlock extends FeishuBlock { block_type: number; // 标题块类型:3-11(对应标题级别1-9) [headingKey: string]: any; // 动态属性名,如heading1, heading2等 } // 定义批量创建块的请求数据接口 export interface CreateBlocksRequest { children: FeishuBlock[]; index: number; } /** * 构建批量创建块的请求数据 * @param blocks 块内容数组 * @param index 插入位置索引 * @returns 请求数据对象 */ export function buildCreateBlocksRequest(blocks: FeishuBlock[], index: number = 0): CreateBlocksRequest { return { children: blocks, index }; } /** * 创建文本块内容 * @param text 文本内容 * @param style 文本样式 * @param align 对齐方式:1左对齐,2居中,3右对齐 * @returns 文本块内容对象 */ export function createTextBlockContent(textContents: Array<{text: string, style?: any}>, align: number = 1): FeishuBlock { return { block_type: 2, // 2表示文本块 text: { elements: textContents.map(content => ({ text_run: { content: content.text, text_element_style: content.style || {} } })), style: { align: align // 1 居左,2 居中,3 居右 } } }; } /** * 创建代码块内容 * @param code 代码内容 * @param language 语言类型代码 * @param wrap 是否自动换行 * @returns 代码块内容对象 */ export function createCodeBlockContent(code: string, language: number = 0, wrap: boolean = false): FeishuBlock { return { block_type: 14, // 14表示代码块 code: { elements: [ { text_run: { content: code, text_element_style: { bold: false, inline_code: false, italic: false, strikethrough: false, underline: false } } } ], style: { language: language, wrap: wrap } } }; } /** * 创建标题块内容 * @param text 标题文本 * @param level 标题级别(1-9) * @param align 对齐方式:1左对齐,2居中,3右对齐 * @returns 标题块内容对象 */ export function createHeadingBlockContent(text: string, level: number = 1, align: number = 1): FeishuBlock { // 确保标题级别在有效范围内(1-9) const safeLevel = Math.max(1, Math.min(9, level)); // 根据标题级别设置block_type和对应的属性名 // 飞书API中,一级标题的block_type为3,二级标题为4,以此类推 const blockType = 2 + safeLevel; // 一级标题为3,二级标题为4,以此类推 const headingKey = `heading${safeLevel}`; // heading1, heading2, ... // 构建块内容 const blockContent: any = { block_type: blockType }; // 设置对应级别的标题属性 blockContent[headingKey] = { elements: [ { text_run: { content: text, text_element_style: {} } } ], style: { align: align, folded: false } }; return blockContent; } /** * 处理Markdown语法转换 * @param textContents 文本内容数组 * @returns 处理后的文本内容数组 */ export function processMarkdownSyntax(textContents: Array<{text: string, style?: any}>): Array<{text: string, style: any}> { return textContents.map(content => { let { text, style = {} } = content; // 创建一个新的style对象,避免修改原始对象 const newStyle = { ...style }; // 处理粗体 **text** if (text.match(/\*\*([^*]+)\*\*/g)) { text = text.replace(/\*\*([^*]+)\*\*/g, "$1"); newStyle.bold = true; } // 处理斜体 *text* if (text.match(/(?<!\*)\*([^*]+)\*(?!\*)/g)) { text = text.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, "$1"); newStyle.italic = true; } // 处理删除线 ~~text~~ if (text.match(/~~([^~]+)~~/g)) { text = text.replace(/~~([^~]+)~~/g, "$1"); newStyle.strikethrough = true; } // 处理行内代码 `code` if (text.match(/`([^`]+)`/g)) { text = text.replace(/`([^`]+)`/g, "$1"); newStyle.inline_code = true; } return { text, style: newStyle }; }); }