You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Google Apps Script开发Google Sheets GUI应用的配置界面需求

嘿,我来帮你搞定这个Google Sheets上的GUI配置工具!结合你给出的getGmail2GDriveConfig()函数,咱们一步步实现可视化配置功能:

构建Google Sheets GUI编辑Gmail转GDrive配置

先拆解你的配置结构,这样咱们能对应每个配置项设计合适的GUI控件:
你的配置函数返回的对象包含这些核心项:

  • processedLabel: Gmail已处理对话的标签(字符串类型)
  • sleepTime: 处理间隔的休眠时间(数字,单位毫秒)
  • maxRuntime: 脚本最大运行时长(数字,单位秒,上限280对应Google脚本5分钟限制)
  • timezone: 日期/时间操作的时区(字符串)
  • rules: 处理规则数组,每个规则包含filter等自定义属性

接下来分两部分实现:后端配置读写逻辑和前端GUI表单

1. 后端:配置的持久化读写

首先把配置从硬编码的函数里抽离出来,用Google Apps Script的PropertiesService存储,这样用户修改后的配置能永久保存:

// 获取配置:优先读已保存的,无则返回默认值
function getGmail2GDriveConfig() {
  const scriptProps = PropertiesService.getScriptProperties();
  const savedConfig = scriptProps.getProperty('GMAIL2GDRIVE_CONFIG');
  
  if (savedConfig) {
    return JSON.parse(savedConfig);
  }
  
  // 你的默认配置
  return {
    "processedLabel": "✉ ➔ ▲",
    "sleepTime": 100,
    "maxRuntime": 280,
    "timezone": "GMT",
    "rules": [
      {
        "filter": "from:example@domain.com"
        // 后续可以补充更多规则属性,比如附件匹配规则、目标文件夹ID等
      }
    ]
  };
}

// 保存配置到Script Properties
function saveGmail2GDriveConfig(config) {
  const scriptProps = PropertiesService.getScriptProperties();
  scriptProps.setProperty('GMAIL2GDRIVE_CONFIG', JSON.stringify(config));
}

2. 前端:构建可视化配置表单

用HtmlService创建一个模态对话框,包含所有配置项的输入控件,还支持动态添加/删除处理规则:

创建HTML表单文件

在Google Apps Script编辑器中新建HTML文件(命名为ConfigForm.html),写入以下内容:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      .form-group { margin: 15px 0; }
      label { display: block; margin-bottom: 5px; font-weight: bold; }
      input, select { padding: 8px; width: 100%; max-width: 400px; }
      .rule-item { border: 1px solid #eee; padding: 10px; margin: 10px 0; position: relative; }
      .delete-rule { position: absolute; top: 10px; right: 10px; background: #ff4444; color: white; border: none; border-radius: 3px; cursor: pointer; }
      #add-rule { background: #00C851; color: white; border: none; padding: 10px 15px; border-radius: 3px; cursor: pointer; }
      #save-config { background: #33b5e5; color: white; border: none; padding: 10px 20px; border-radius: 3px; cursor: pointer; margin-top: 20px; }
      .message { margin-top: 15px; padding: 10px; border-radius: 3px; display: none; }
      .success { background: #dff0d8; color: #3c763d; }
      .error { background: #f2dede; color: #a94442; }
    </style>
  </head>
  <body>
    <h2>Gmail转GDrive配置</h2>
    
    <div class="form-group">
      <label for="processedLabel">已处理邮件标签</label>
      <input type="text" id="processedLabel" placeholder="例如:✉ ➔ ▲">
    </div>
    
    <div class="form-group">
      <label for="sleepTime">处理间隔休眠时间(毫秒)</label>
      <input type="number" id="sleepTime" min="10" max="1000">
    </div>
    
    <div class="form-group">
      <label for="maxRuntime">脚本最大运行时长(秒)</label>
      <input type="number" id="maxRuntime" min="60" max="280">
    </div>
    
    <div class="form-group">
      <label for="timezone">时区</label>
      <select id="timezone">
        <option value="GMT">GMT</option>
        <option value="America/New_York">美国东部时间</option>
        <option value="Asia/Shanghai">中国标准时间</option>
        <!-- 可以根据需求添加更多时区 -->
      </select>
    </div>
    
    <div class="form-group">
      <h3>处理规则</h3>
      <div id="rules-container">
        <!-- 规则项将动态生成 -->
      </div>
      <button id="add-rule">添加新规则</button>
    </div>
    
    <button id="save-config">保存配置</button>
    <div id="message" class="message"></div>

    <script>
      // 加载现有配置到表单
      google.script.run.withSuccessHandler((config) => {
        // 填充顶层配置项
        document.getElementById('processedLabel').value = config.processedLabel;
        document.getElementById('sleepTime').value = config.sleepTime;
        document.getElementById('maxRuntime').value = config.maxRuntime;
        document.getElementById('timezone').value = config.timezone;
        
        // 填充已有的处理规则
        const rulesContainer = document.getElementById('rules-container');
        config.rules.forEach((rule, index) => {
          addRuleItem(rule, index);
        });
        
        // 无规则则添加一个默认空规则
        if (config.rules.length === 0) {
          addRuleItem({}, 0);
        }
      }).getGmail2GDriveConfig();
      
      // 动态添加规则项
      function addRuleItem(rule = {}, index) {
        const rulesContainer = document.getElementById('rules-container');
        const ruleItem = document.createElement('div');
        ruleItem.className = 'rule-item';
        ruleItem.dataset.index = index;
        
        ruleItem.innerHTML = `
          <div class="form-group">
            <label>邮件过滤规则</label>
            <input type="text" class="rule-filter" placeholder="例如:from:example@domain.com" value="${rule.filter || ''}">
          </div>
          <!-- 这里可以扩展添加更多规则属性的输入框 -->
          <button class="delete-rule" onclick="deleteRule(${index})">删除</button>
        `;
        
        rulesContainer.appendChild(ruleItem);
      }
      
      // 删除指定规则项
      function deleteRule(index) {
        const rulesContainer = document.getElementById('rules-container');
        const ruleItems = rulesContainer.querySelectorAll('.rule-item');
        ruleItems.forEach((item, i) => {
          if (i === index) {
            item.remove();
          } else if (i > index) {
            item.dataset.index = i - 1;
            item.querySelector('.delete-rule').setAttribute('onclick', `deleteRule(${i - 1})`);
          }
        });
      }
      
      // 保存配置到后端
      document.getElementById('save-config').addEventListener('click', () => {
        // 收集顶层配置
        const config = {
          processedLabel: document.getElementById('processedLabel').value,
          sleepTime: parseInt(document.getElementById('sleepTime').value),
          maxRuntime: parseInt(document.getElementById('maxRuntime').value),
          timezone: document.getElementById('timezone').value,
          rules: []
        };
        
        // 收集所有处理规则
        const ruleItems = document.querySelectorAll('.rule-item');
        ruleItems.forEach(item => {
          const rule = {
            filter: item.querySelector('.rule-filter').value
            // 收集其他规则属性
          };
          config.rules.push(rule);
        });
        
        // 调用后端保存函数
        google.script.run.withSuccessHandler(() => {
          showMessage('配置保存成功!', 'success');
        }).withFailureHandler((error) => {
          showMessage('保存失败:' + error.message, 'error');
        }).saveGmail2GDriveConfig(config);
      });
      
      // 添加新规则按钮事件
      document.getElementById('add-rule').addEventListener('click', () => {
        const rulesContainer = document.getElementById('rules-container');
        const ruleCount = rulesContainer.querySelectorAll('.rule-item').length;
        addRuleItem({}, ruleCount);
      });
      
      // 显示提示消息
      function showMessage(text, type) {
        const messageEl = document.getElementById('message');
        messageEl.textContent = text;
        messageEl.className = `message ${type}`;
        messageEl.style.display = 'block';
        
        // 3秒后自动隐藏
        setTimeout(() => {
          messageEl.style.display = 'none';
        }, 3000);
      }
    </script>
  </body>
</html>

添加Sheet菜单栏入口

在主脚本文件(比如Code.gs)中添加以下代码,让用户能通过Sheet菜单栏打开配置表单:

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('Gmail转GDrive')
    .addItem('打开配置', 'showConfigForm')
    .addToUi();
}

function showConfigForm() {
  const html = HtmlService.createHtmlOutputFromFile('ConfigForm')
    .setWidth(500)
    .setHeight(600);
  SpreadsheetApp.getUi().showModalDialog(html, 'Gmail转GDrive配置');
}

使用步骤

  1. 在Google Apps Script编辑器中创建对应文件:Code.gs(包含配置读写和菜单代码)、ConfigForm.html(GUI表单)
  2. 保存脚本后,运行onOpen函数,刷新Sheet就能看到顶部的「Gmail转GDrive」菜单
  3. 点击菜单里的「打开配置」,就能在模态对话框中编辑所有配置项,保存后配置会自动持久化

内容的提问来源于stack exchange,提问作者Thomas Chirwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:17:13