尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Activepieces Human Input 模块深度解析:基于 Form / Chat 触发器构建公开交互流程

Activepieces Human Input 模块深度解析:基于 Form / Chat 触发器构建公开交互流程 Activepieces Human Input 模块深度解析基于 Form / Chat 触发器构建公开交互流程【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces导读Human Input 是 Activepieces 中负责让人与流程交互的后端服务模块它对外暴露两组只读的公开 HTTP 端点把以activepieces/piece-forms片段作为触发器的流程渲染为**表单Forms或对话界面Chat**两种 UI供外部用户通过 URL 直接访问。本文以该模块的知识笔记为骨架结合仓库源码后端控制器与服务、共享 zod 契约、前端渲染与路由逐层拆解其端点设计、触发器校验、草稿保护、白标品牌化与前端渲染链路帮助读者理解如何基于 flow ID 安全地暴露交互式 UI以及useDraft、waitForResponse等关键参数的真实行为。一、模块定位两种模式一个后端Human Input 的核心思路是流程本身作为业务逻辑Human Input 只负责把流程的触发器定义翻译成浏览器可渲染的 UI 元数据。它支持两种交互模式Forms表单结构化输入字段text、text_area、toggle、file用户填写后提交Chat对话会话式 UI气泡、输入框、消息列表用户与流程往返对话。两者都由触发器为activepieces/piece-forms片段的流程支撑。后端端点只读且公开——它们只返回 UI 元数据标题、输入 schema、品牌信息真正的提交动作走的是 webhook 端点即流程触发端点的路径。浏览器 ── GET /v1/human-input/form/:flowId ── 返回 FormResponseUI 元数据 浏览器 ── GET /v1/human-input/chat/:flowId ── 返回 ChatUIResponseUI 元数据 浏览器 ── POST webhook 端点 ──────────────── 触发流程执行从源码结构看后端整块逻辑集中在一个目录下packages/server/api/src/app/flows/flow/human-input/包含四个文件文件职责form-controller.ts注册GET /v1/human-input/form/:flowIdchat-controller.ts注册GET /v1/human-input/chat/:flowIdhuman-input.service.ts核心逻辑解析流程、校验触发器类型、构建响应human-input.module.ts模块装配统一挂载两个控制器模块装配代码human-input.module.ts以FastifyPluginAsyncZod形式注册两个控制器共用/v1/human-input前缀export const humanInputModule: FastifyPluginAsyncZod async (app) { await app.register(formController, { prefix: /v1/human-input }) await app.register(chatController, { prefix: /v1/human-input }) }二、端点契约与公开访问控制2.1 表单端点GET /v1/human-input/form/:flowId由 form-controller.ts 定义。它接收路径参数flowIdApId类型以及可选的useDraft查询参数然后委托给服务app.get(/form/:flowId, GetFormRequest, async (request) { return humanInputService(request.log).getFormByFlowIdOrThrow( request.params.flowId, request.query.useDraft ?? false ) })2.2 对话端点GET /v1/human-input/chat/:flowId由 chat-controller.ts 定义结构与表单端点完全对称仅把服务方法换成getChatUIByFlowIdOrThrow。2.3 公开访问securityAccess.public()两个端点都在请求配置中声明security: securityAccess.public()这意味着无需任何登录态或 API Key 即可访问。这是 Human Input 能作为外部用户通过 URL 打开的交互入口的前提——但也要注意公开的只是 UI 元数据流程执行本身仍由独立的 webhook 端点承载。OptionalBooleanFromQuery用于把useDraft解析为布尔值缺失时默认false这正是草稿保护机制的入口下文第三节详述。三、服务层核心逻辑humanInputService服务的完整实现在 human-input.service.ts它定义了关键的常量与两个对外方法。3.1 关键常量与触发器白名单const FORMS_PIECE_NAME activepieces/piece-forms const FORM_TRIIGGER form_submission const FILE_TRIGGER file_submission const FORMS_TRIGGER_NAMES [FORM_TRIIGGER, FILE_TRIGGER]注意表单模式的白名单只包含form_submission与file_submission两个触发器chat_submission触发器虽然同样来自piece-forms片段但只被 Chat 端点接受见 3.3。isFormTrigger辅助函数用两个条件判定流程是否合法settings.pieceName FORMS_PIECE_NAME且triggerName在白名单内human-input.service.ts。3.2getFormByFlowIdOrThrow表单元数据解析处理流程分四步human-input.service.ts加载流程调用getPopulatedFlowById(log, flowId, useDraft)见 3.4校验触发器isFormTrigger不通过则抛ActivepiecesErrorENTITY_NOT_FOUNDentityType 为flow_form解析片段精确版本通过pieceMetadataService.resolveExactVersion结合平台 ID 解析出piece-forms片段在触发器中声明的精确版本号pieceVersion构建响应根据触发器类型返回不同 props——file_submission返回硬编码的单文件 schemaSIMPLE_FILE_PROPSform_submission返回trigger.settings.input即用户在流程构建器里配置的表单字段。SIMPLE_FILE_PROPS的定义如下它固定为一个必填的file类型输入且waitForResponse恒为truehuman-input.service.tsconst SIMPLE_FILE_PROPS { inputs: [ { displayName: File, description: , type: FormInputType.FILE, required: true, }, ], waitForResponse: true, }FormResponse最终结构为{ id, title, props, projectId, version }其中title取自流程版本的displayNameversion是解析出的片段精确版本供前端按需加载对应版本的渲染逻辑。3.3getChatUIByFlowIdOrThrow对话 UI 与白标品牌化处理逻辑human-input.service.ts校验触发器必须满足triggerName chat_submission且pieceName FORMS_PIECE_NAME否则抛ENTITY_NOT_FOUND解析平台信息通过projectService.getPlatformId(flow.projectId)拿到平台 ID再用platformService.getOneOrThrow(platformId)读取平台记录构建响应返回ChatUIResponse其中包含platformLogoUrl来自platform.logoIconUrl与platformName来自platform.name。这正是Chat 界面支持白标white-label的实现基础前端把平台 Logo 与名称嵌入聊天界面头部不同平台的对话页可展示各自的品牌形象而不是统一的 Activepieces 品牌。3.4getPopulatedFlowById草稿保护的核心async function getPopulatedFlowById(log, id, useDraft): PromisePopulatedFlow | null { const flow await flowRepo().findOneBy({ id }) if (isNil(flow) || (isNil(flow.publishedVersionId) !useDraft)) { return null } const flowVersion await flowVersionService(log).getFlowVersionOrThrow({ flowId: id, versionId: useDraft ? undefined : flow.publishedVersionId!, }) return { ...flow, version: flowVersion } }逻辑要点未发布保护若流程从未发布publishedVersionId为空且未传useDrafttrue直接返回null→ 上层抛出 404。这防止未发布表单被意外暴露给外部用户版本选择useDrafttrue时读取草稿版本versionId为undefined否则强制读取已发布版本publishedVersionId版本一致性返回的是流程行 指定版本的组装体PopulatedFlow后续所有触发器判断都基于该版本。四、共享数据契约zod schemaHuman Input 的前后端共享契约定义在 packages/core/execution/src/lib/flows/form.ts。注意该文件此前位于packages/core/shared/src/lib/automation/flows/form.ts后来迁移到packages/core/execution下引用时以当前路径为准。4.1 表单输入类型FormInputTypeexport enum FormInputType { TEXT text, FILE file, TEXT_AREA text_area, TOGGLE toggle, }四种字段类型单行文本、文件、多行文本、开关。FormInput对象由displayName、required、description、type四个字段组成form.ts。4.2 表单与对话响应契约FormProps{ inputs: FormInput[], waitForResponse: boolean }——waitForResponse声明该表单提交后是否等待返回值FormResponse{ id, title, props, projectId, version }——表单端点的完整返回体ChatUIProps{ botName: string }——对话 UI 的个性化属性机器人名称ChatUIResponse{ id, title, props, projectId, platformLogoUrl, platformName }——对话端点的完整返回体含平台品牌字段USE_DRAFT_QUERY_PARAM_NAME值为useDraft作为查询参数名常量被前后端共用。waitForResponse的行为值得单独说明当它为true时流程运行会在触发后暂停pause前端等待一个值回显给提交者。这适合提交表单 → 流程处理后把结果展示回页面的双向交互场景为false时则是单向提交fire-and-forget。五、前端渲染链路从 URL 到 UI前端将 Human Input 渲染为两个公开路由均不要求登录模式路由前端代码位置表单/forms/flowIdpackages/web/src/app/routes/forms/index.tsx对话/chat/flowIdpackages/web/src/app/routes/chat/5.1 表单前端表单渲染涉及三个文件packages/web/src/features/forms/api/human-input-api.tsx调用GET /v1/human-input/form/:flowId的 API 客户端hooks/forms-hooks.ts查询 hooks管理加载/错误/数据状态components/ap-form.tsx根据FormInputType渲染对应输入控件文本、多行文本、开关、文件上传的表单组件。公开路由页拿到FormResponse后把props.inputs交给ap-form渲染用户提交后请求流程的 webhook 端点完成触发若waitForResponse为真则等待并展示流程返回值。5.2 对话前端Chat 是比表单更重的 UI组件拆分也更细packages/web/src/features/chat/chat-bubble / chat-input / chat-message / chat-message-list气泡、输入框含文件上传预览、消息文本/图片/文件、消息列表含错误气泡等基础组件lib/状态与数据层包括chat-api.tsAPI 调用、chat-store.ts会话状态、use-chat.ts交互逻辑、use-streaming-reducer.ts流式消息合并、use-tts.ts与use-voice-input.ts语音能力等chat-intro.tsx对话起始介绍页use-cases/默认用例卡片用于空状态引导。此外构建器Builder侧为测试chat_submission流程提供了配套实现可复用的聊天外壳与内嵌 Drawer 包装器位于 packages/web/src/app/routes/chat/配套的构建器聊天状态在 packages/web/src/app/builder/state/chat-state.ts。这意味着开发者可以在流程构建器里直接预览对话体验而无需先发布并打开公开 URL。六、易踩坑点Gotchas结合源码可以确认以下三个边界行为对自建集成或排查问题至关重要端点完全公开任何人只要知道flowId就能读取表单/对话的 UI 元数据securityAccess.public()。这仅暴露 UI 定义并不能执行流程——执行必须通过 webhook 端点。设计公开页面时应注意 flow ID 本身不属于敏感信息但不要依赖ID 保密作为安全手段。未发布流程默认 404没有发布版本的流程在未传useDrafttrue时返回 404human-input.service.ts 中的isNil(flow.publishedVersionId) !useDraft分支。这保护了未发布表单不被意外暴露需要调试草稿时显式传?useDrafttrue即可。端点只返回 UI 定义GET /v1/human-input/form/:flowId与/chat/:flowId都不是触发端点它们只回答这个流程长什么样。流程的实际触发由 webhook 端点承担前端在用户提交表单或发送消息时才发起触发请求。七、版本与可用性版本范围Human Input 功能在 CE社区版/ EE企业版/ Cloud云版中完全可用无需任何 plan flag属于基础能力而非付费门槛功能代码位置速查后端整块packages/server/api/src/app/flows/flow/human-input/控制器 服务 模块共享契约packages/core/execution/src/lib/flows/form.tsFormInputType、FormProps、FormResponse、ChatUIProps、ChatUIResponse、USE_DRAFT_QUERY_PARAM_NAME前端表单packages/web/src/features/forms/前端对话packages/web/src/features/chat/公开路由packages/web/src/app/routes/forms/与packages/web/src/app/routes/chat/构建器内聊天状态packages/web/src/app/builder/state/chat-state.ts。结语Human Input 模块是 Activepieces 中流程即应用理念的缩影后端只暴露只读的 UI 元数据端点通过isFormTrigger/chat_submission的严格校验把触发器约束在piece-forms片段上用useDraft与已发布版本机制守住草稿边界再用waitForResponse支撑提交—暂停—回显的双向交互前端则分别在/forms/flowId与/chat/flowId完成渲染Chat 模式还借助平台 Logo 与名称实现白标品牌化。理解这条从 flow ID 到浏览器 UI 的链路就能准确地把 Activepieces 流程嵌入到任意面向用户的 Web 场景中。【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表