Skip to main content
Glama

create_sign_flow

Initiate and manage electronic signing workflows for various file formats (PDF, Word, Excel, PPT, WPS, images) with automatic PDF conversion. Requires file path, name, and recipient phone number.

Instructions

创建签署流程,支持多种文件格式,包括:PDF、Word、Excel、PPT、WPS、图片等。非PDF格式会自动转换为PDF。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fileNameYes文件名,必须包含文件扩展名(例如:合同.pdf、文档.docx),扩展名要与实际文件格式一致
filePathYes文件路径,支持本地文件路径或 HTTP(S) 远程文件下载链接。支持的格式:PDF(.pdf)、Word(.docx/.doc/.rtf)、Excel(.xlsx/.xls)、PPT(.pptx/.ppt)、WPS(.wps/.et/.dps)、图片(.jpg/.png/.bmp等)、HTML(.html/.htm)
receiverPhoneYes签署人手机号,用于接收签署通知短信
usernameNo签署人姓名,非必填,默认为空字符串,如果对方没有在e签宝注册过, 则必须提供姓名; 如果对应用户已存在个人信息,则不需要添加姓名

Implementation Reference

  • The main handler logic for the 'create_sign_flow' tool within the CallToolRequestSchema handler. It orchestrates file upload, waits for file processing, creates the sign flow, generates a sign URL, and returns the result.
    case "create_sign_flow": { try { const args = request.params.arguments as unknown as SignRequest; const {filePath, fileName, receiverPhone, username} = args; logToFile(`uploadFile filePath: ${filePath} fileName: ${fileName}`); const fileId = await uploadFile(filePath, fileName); // 等待文件处理完成 await waitForFileProcessing(fileId); const flowId = await createSignFlow(fileId, receiverPhone, fileName, username); const signUrl = await getSignUrl(flowId, receiverPhone); return { content: [{ type: "text", text: `Success!\nFlow ID: ${flowId}\nSign URL: ${signUrl}` }] }; } catch (err: any) { return { content: [{ type: "text", text: `Error: ${err.message}` }] }; } }
  • src/index.ts:162-187 (registration)
    Tool registration in the ListToolsRequestSchema handler, defining name, description, and input schema for 'create_sign_flow'.
    { name: "create_sign_flow", description: "创建签署流程,支持多种文件格式,包括:PDF、Word、Excel、PPT、WPS、图片等。非PDF格式会自动转换为PDF。", inputSchema: { type: "object", properties: { filePath: { type: "string", description: "文件路径,支持本地文件路径或 HTTP(S) 远程文件下载链接。支持的格式:PDF(.pdf)、Word(.docx/.doc/.rtf)、Excel(.xlsx/.xls)、PPT(.pptx/.ppt)、WPS(.wps/.et/.dps)、图片(.jpg/.png/.bmp等)、HTML(.html/.htm)" }, fileName: { type: "string", description: "文件名,必须包含文件扩展名(例如:合同.pdf、文档.docx),扩展名要与实际文件格式一致" }, receiverPhone: { type: "string", description: "签署人手机号,用于接收签署通知短信" }, username: { type: "string", description: "签署人姓名,非必填,默认为空字符串,如果对方没有在e签宝注册过, 则必须提供姓名; 如果对应用户已存在个人信息,则不需要添加姓名" } }, required: ["filePath", "fileName", "receiverPhone"] } },
  • Helper function that performs the actual API call to create the sign flow using the provided fileId, receiver phone, file name, and username.
    async function createSignFlow(fileId: string, receiverPhone: string, fileName: string, username : string): Promise<string> { const requestPath = '/v3/sign-flow/create-by-file'; const requestBody = JSON.stringify({ docs: [{ fileId: fileId, fileName: fileName }], signFlowConfig: { signFlowTitle: "待签署文件", signFlowDesc: "请签署文件", signFlowEffectiveTime: Date.now(), signFlowExpireTime: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7天后过期 signOrder: false, // 无序签署 notifyType: "1", // 短信通知 redirectUrl: "", // 可以为空 autoFinish: true }, signers: [{ signConfig: { signOrder: 1, forcedReadingTime: "10" // 强制阅读时间10秒 }, noticeConfig: { noticeTypes: "1" // 短信通知 }, signerType: 0, // 个人签署 psnSignerInfo: { psnAccount: receiverPhone, psnInfo: username === "" || username === undefined ? undefined : { psnName: username === "" ? undefined : username } }, signFields: [{ fileId: fileId, signFieldType: 0, normalSignFieldConfig: { autoSign: false, freeMode: false, movableSignField: false, signFieldStyle: 1, signFieldSize: "96", signFieldPosition: { positionPage: "1", positionX: 100, positionY: 100 } }, signDateConfig: { dateFormat: "yyyy-MM-dd", showSignDate: 1, signDatePositionX: 100, signDatePositionY: 150 } }] }], autoStart: true }); debugger const headers = getCommonHeaders('POST', requestPath, requestBody); const response = await fetch(`${config.host}${requestPath}`, { method: 'POST', headers: headers, body: requestBody }); const result = await response.json() as ApiResponse<SignFlowResponse>; if (result.code === 0) { return result.data.signFlowId; } throw new Error(`Sign flow creation failed: ${result.message}`); }
  • Helper function that handles file upload to the eSign service, including downloading remote files if necessary, obtaining upload URL, and uploading the file to get fileId.
    async function uploadFile(filePath: string, fileName: string): Promise<string> { // 检查文件格式是否支持 if (!isFileSupported(fileName)) { throw new Error(`不支持的文件格式。支持的格式包括:${SUPPORTED_FILE_EXTENSIONS.join(', ')}`); } let actualFilePath = filePath; let cleanup: (() => void) | undefined; try { // 检查是否是远程文件 if (filePath.startsWith('http://') || filePath.startsWith('https://')) { logToFile(`检测到远程文件链接: ${filePath}`); const downloadResult = await downloadFile(filePath); actualFilePath = downloadResult.filePath; cleanup = downloadResult.cleanup; logToFile(`远程文件已下载到本地: ${actualFilePath}`); } // 步骤一:获取文件上传地址 const fileSize = fs.statSync(actualFilePath).size; const fileBuffer = fs.readFileSync(actualFilePath); const contentMd5 = calculateContentMd5(fileBuffer); const isPDF = fileName.toLowerCase().endsWith('.pdf'); const isHTML = fileName.toLowerCase().match(/\.(html|htm)$/); const requestPath = '/v3/files/file-upload-url'; const requestBody = JSON.stringify({ contentMd5, contentType: isPDF ? 'application/pdf' : 'application/octet-stream', fileName, fileSize, convertToPDF: !isPDF, convertToHTML: isHTML ? false : undefined }); logToFile(`上传文件请求参数:\ncontentMd5=${contentMd5}\nfileSize=${fileSize}`); const headers = getCommonHeaders('POST', requestPath, requestBody, 'application/json; charset=UTF-8'); logToFile("headers " + JSON.stringify(headers)) const response = await fetch(`${config.host}${requestPath}`, { method: 'POST', headers: headers, body: requestBody }); const responseText = await response.text(); logToFile(`上传文件响应:\n${responseText}`); const result = JSON.parse(responseText) as ApiResponse<{ fileId: string; fileUploadUrl: string; }>; if (result.code !== 0) { throw new Error(`Failed to get upload URL: ${result.message}`); } // 步骤二:上传文件流 const uploadResponse = await fetch(result.data.fileUploadUrl, { method: 'PUT', headers: { 'Content-Type': isPDF ? 'application/pdf' : 'application/octet-stream', 'Content-MD5': contentMd5 }, body: fileBuffer }); if (!uploadResponse.ok) { throw new Error(`Failed to upload file: ${uploadResponse.statusText}`); } // 返回文件ID return result.data.fileId; } finally { // 如果是远程文件,清理临时文件 if (cleanup) { cleanup(); } } }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/esign-cn-open-source/mcp-server-esign'

If you have feedback or need assistance with the MCP directory API, please join our Discord server