Google Chat Apps脚本:表单输入变更时不关闭对话框更新任务列表
解决Google Chat任务对话框下拉框变更时自动关闭的问题
问题核心
你遇到的问题根源是:Google Chat对话框中触发onChangeAction后,系统默认会关闭对话框。要实现变更后不关闭对话框并更新任务列表,关键是在action的响应中返回一个新的对话框实例,替换原有对话框,而非依赖系统默认行为。
解决方案步骤
1. 实现onStatusChange函数,返回更新后的对话框
当用户修改状态下拉框时,该函数需要完成:获取变更的任务ID与新状态、更新任务数据、重新生成带最新状态的对话框并返回。
function onStatusChange(event) { // 从输入组件名称中提取任务ID(例如"status_123" → "123") const taskId = event.commonWidgetSelection.inputName.replace("status_", ""); // 获取选中的新状态值 const newStatus = event.commonWidgetSelection.selectedValues[0]; // 获取当前用户的任务列表并更新对应任务状态 const userEmail = event.message.sender.email; let tasks = fetchOpenTasks(userEmail); tasks = tasks.map(task => { if (task.id === taskId) { return {...task, status: newStatus}; } return task; }); // 重新构建对话框(复用原有逻辑,后续可封装为公共函数) const statusIcons = { "Not Started": "🔴", "In Progress": "🟡", "Completed": "🟢" }; const taskWidgets = tasks.map(task => ({ widgets: [ { decoratedText: { topLabel: task.title, text: task.description, wrapText : true, bottomLabel: `Due: ${task.dueDate}`, } }, { columns: { columnItems: [ { horizontalSizeStyle : "FILL_MINIMUM_SPACE", widgets: [ { selectionInput: { name: `status_${task.id}`, label: "Status", type: "DROPDOWN", onChangeAction: { actionMethodName: "onStatusChange" }, items: [ { text: `${statusIcons["Not Started"]} Not Started`, value: "Not Started", selected: task.status === "Not Started" }, { text: `${statusIcons["In Progress"]} In Progress`, value: "In Progress", selected: task.status === "In Progress" }, { text: `${statusIcons["Completed"]} Completed`, value: "Completed", selected: task.status === "Completed" } ], labelPosition: "TOP", buttonStyle: "PRIMARY" } } ] }, { widgets:[ { textInput: { name: `comments_${task.id}`, label: "Add Comments", type: "MULTIPLE_LINE", value: task.comments || "", // 给评论输入框添加onChangeAction,实现实时更新 onChangeAction: { actionMethodName: "onCommentChange" } } } ] } ] } } ] })); // 返回更新后的对话框,核心是指定actionResponse类型为DIALOG return { actionResponse: { type: "DIALOG", dialogAction: { dialog: { body: { sections: [...taskWidgets], "fixedFooter": { "primaryButton": { "text": "Save changes", "color": { "red": 0, "green": 0.5, "blue": 1, "alpha": 1 }, "onClick": { "action": { "function": "updateTasks" } } }, } } } } } }; }
2. 实现评论输入框的onCommentChange函数
和状态变更逻辑一致,更新对应任务的评论内容后返回新对话框:
function onCommentChange(event) { const taskId = event.commonWidgetTextInput.inputName.replace("comments_", ""); const newComment = event.commonWidgetTextInput.value; const userEmail = event.message.sender.email; let tasks = fetchOpenTasks(userEmail); tasks = tasks.map(task => { if (task.id === taskId) { return {...task, comments: newComment}; } return task; }); // 复用对话框构建逻辑(推荐封装为公共函数) return buildTaskDialog(tasks, userEmail); }
3. 封装公共对话框构建函数(可选但推荐)
将重复的对话框构建逻辑抽离,减少冗余代码:
function buildTaskDialog(tasks, userEmail) { const statusIcons = { "Not Started": "🔴", "In Progress": "🟡", "Completed": "🟢" }; const taskWidgets = tasks.map(task => ({ widgets: [ { decoratedText: { topLabel: task.title, text: task.description, wrapText : true, bottomLabel: `Due: ${task.dueDate}`, } }, { columns: { columnItems: [ { horizontalSizeStyle : "FILL_MINIMUM_SPACE", widgets: [ { selectionInput: { name: `status_${task.id}`, label: "Status", type: "DROPDOWN", onChangeAction: { actionMethodName: "onStatusChange" }, items: [ { text: `${statusIcons["Not Started"]} Not Started`, value: "Not Started", selected: task.status === "Not Started" }, { text: `${statusIcons["In Progress"]} In Progress`, value: "In Progress", selected: task.status === "In Progress" }, { text: `${statusIcons["Completed"]} Completed`, value: "Completed", selected: task.status === "Completed" } ], labelPosition: "TOP", buttonStyle: "PRIMARY" } } ] }, { widgets:[ { textInput: { name: `comments_${task.id}`, label: "Add Comments", type: "MULTIPLE_LINE", value: task.comments || "", onChangeAction: { actionMethodName: "onCommentChange" } } } ] } ] } } ] })); return { actionResponse: { type: "DIALOG", dialogAction: { dialog: { body: { sections: [...taskWidgets], "fixedFooter": { "primaryButton": { "text": "Save changes", "color": { "red": 0, "green": 0.5, "blue": 1, "alpha": 1 }, "onClick": { "action": { "function": "updateTasks" } } }, } } } } } }; } // 简化原showUpdateTaskDialog函数 function showUpdateTaskDialog(event) { const userEmail = event.message.sender.email; const tasks = fetchOpenTasks(userEmail); if (tasks.length === 0) { return { actionResponse: { type: "NEW_MESSAGE" }, text: `You have no tasks assigned to you, ${event.message.sender.displayName}.` }; } return buildTaskDialog(tasks, userEmail); }
关键注意事项
- 所有对话框内的变更action(
onStatusChange、onCommentChange)必须返回actionResponse.type = "DIALOG",携带更新后的对话框结构,这样Google Chat会用新对话框替换旧的,而非关闭。 - 确保在action中正确提取任务ID和新值,准确更新任务数据。
- 封装公共构建函数可大幅降低代码冗余,提升维护效率。
内容的提问来源于stack exchange,提问作者PriyankaJ
相关产品推荐
相关产品推荐

