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

如何在Apps Script服务器函数中为单个Web用户设置全局属性?

问题原因

你遇到的UserProperties失效问题,核心是Web应用的执行身份设置:如果部署时选择了"以开发者身份执行",所有服务器端函数都会以你的账号运行,此时getUserProperties()获取的是你的个人属性,而非当前登录用户的。

解决方案

方案1:修正Web应用部署设置(首选)

如果业务允许,将Web应用部署为**"以访问者身份执行"**:

  • 部署时,在"执行身份"下拉框选择"用户访问Web应用时"
  • 权限设置选择"任何人,甚至匿名"或"域内任何人"(根据你的需求)

修改后,服务器端函数会以当前登录用户的身份运行,UserProperties就能正确存储每个用户的专属设置。同时需要修正代码里的判断逻辑(你当前设置的是TRUE/FALSE,但判断的是enabled,两者不匹配):

修改frontend_toggleSlack:

function frontend_toggleSlack(form) {
  const slackToggle = form.slackToggle; // 'enable' or 'disable'
  const userProperties = PropertiesService.getUserProperties();
  if (slackToggle === 'enable') {
    userProperties.setProperty('SLACK_POST', 'enabled');
  } else if (slackToggle === 'disable') {
    userProperties.setProperty('SLACK_POST', 'disabled');
  } else {
    throw new Error(`Invalid Slack posting setting applied!`);
  }
}

sendSlackString保持原逻辑即可,现在每个用户的设置会独立存储。

方案2:用全局属性存储用户专属配置(强制以开发者身份执行时用)

如果必须以开发者身份执行(比如需要调用只有管理员权限的API),可以用ScriptProperties(全局属性存储),但给每个用户的键加上邮箱前缀,确保唯一性:

修改frontend_toggleSlack:

function frontend_toggleSlack(form) {
  const slackToggle = form.slackToggle;
  const userEmail = Session.getActiveUser().getEmail();
  const scriptProperties = PropertiesService.getScriptProperties();
  const key = `SLACK_POST_${userEmail}`;
  
  if (slackToggle === 'enable') {
    scriptProperties.setProperty(key, 'enabled');
  } else if (slackToggle === 'disable') {
    scriptProperties.setProperty(key, 'disabled');
  } else {
    throw new Error(`Invalid Slack posting setting applied!`);
  }
}

修改sendSlackString:

function sendSlackString(slackBody) {
  const userEmail = Session.getActiveUser().getEmail();
  const scriptProperties = PropertiesService.getScriptProperties();
  const SLACK_POST = scriptProperties.getProperty(`SLACK_POST_${userEmail}`) || 'enabled'; // 默认开启
  
  if (SLACK_POST === 'enabled') {
    const template = {
      "blocks": [
        {
          "type": "section",
          "text": {
            "type": "mrkdwn",
            "text": `${slackBody}`
          }
        }
      ]
    };
    sendSlackMessage(template);
  } else {
    console.info(`Slack posting disabled for message\n\n${slackBody}`);
  }
}

方案3:从前端传递开关状态

如果不想用属性存储,可以在前端保存开关状态(比如用localStorage),每次调用后端函数时把状态作为参数传递:

前端JS修改:

// 保存开关状态到localStorage
function toggleSlackSuccess() {
  const slackToggle = document.querySelector('input[name="slackToggle"]:checked').value;
  localStorage.setItem('SLACK_POST', slackToggle);
}

// 调用后端函数时带上状态
function callModifyFunction(formData) {
  const slackEnabled = localStorage.getItem('SLACK_POST') || 'enable';
  google.script.run
    .withFailureHandler(showFail)
    .frontend_modifyForwardingDelegation({
      ...formData,
      slackEnabled: slackEnabled
    });
}

后端frontend_modifyForwardingDelegation修改:

function frontend_modifyForwardingDelegation(formObject) {
  // ...其他逻辑
  modifyGmailACLs(raw_sourceUser, raw_targetUser, option, action, formObject.slackEnabled);
}

function modifyGmailACLs(raw_sourceUser, raw_targetUser, option, action, slackEnabled) {
  // ...其他逻辑
  sendSlackString(message, slackEnabled);
}

function sendSlackString(slackBody, slackEnabled) {
  if (slackEnabled === 'enable') {
    const template = {
      "blocks": [
        {
          "type": "section",
          "text": {
            "type": "mrkdwn",
            "text": `${slackBody}`
          }
        }
      ]
    };
    sendSlackMessage(template);
  } else {
    console.info(`Slack posting disabled for message\n\n${slackBody}`);
  }
}
注意事项
  • 方案1需要确保用户有足够权限调用AdminDirectory等API,如果普通用户不需要这些权限,建议用此方案。
  • 方案2的ScriptProperties有存储上限(总存储量不超过9KB),如果用户量较大或存储其他配置,需要注意容量。
  • 方案3的状态存在前端,用户清除浏览器缓存后会丢失,适合临时设置或对持久化要求不高的场景。

内容的提问来源于stack exchange,提问作者Ian Hyzy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:04:56