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

如何在Gmail插件中持久化用户特定值:避免重复询问信息

嘿,我懂你遇上的麻烦了——明明想用Property Service存用户的基础信息,结果每次打开新邮件还是要重复填,太闹心了对吧?我帮你分析下问题大概率出在哪,再给你调整后的代码方案。

首先,你得搞清楚Property Service的三种类型,别用错了:

  • UserProperties:用户专属,每个用户的数据单独存储,跨插件的所有运行实例生效,这才是你应该用的
  • ScriptProperties:所有使用这个插件的用户共享数据,绝对不能用来存单个用户的设置
  • DocumentProperties:和特定文档绑定,Gmail插件里用不上

我猜你要么是用错了属性类型,要么是没在buildAddOn里正确判断是否已经保存过信息。下面是修正后的完整代码思路:

核心逻辑

每次插件启动时(也就是buildAddOn运行时),先检查用户属性里有没有「已完成设置」的标记:

  1. 如果没有,弹出基础信息收集表单
  2. 如果有,直接显示正常的插件界面
  3. 用户提交表单后,把信息存到UserProperties,再刷新界面切换到主卡片

完整代码示例

var MAX_THREADS = 5;

/**
 * 返回当前电子邮件线程应渲染的卡片数组
 * @param {Object} e Gmail UI提供的数据
 * @returns {Card[]}
 */
function buildAddOn(e) {
  // 获取当前用户专属的属性存储
  const userProps = PropertiesService.getUserProperties();
  const hasCompletedSetup = userProps.getProperty('hasCompletedSetup');

  // 未完成设置,返回收集信息的卡片
  if (!hasCompletedSetup) {
    return buildSetupCard();
  }

  // 已完成设置,返回主功能卡片
  return buildMainCard(e);
}

/**
 * 构建基础信息收集卡片
 */
function buildSetupCard() {
  const card = CardService.newCardBuilder()
    .setHeader(CardService.newCardHeader().setTitle('欢迎使用插件,请完成基础设置'))
    .addSection(CardService.newCardSection()
      .addWidget(CardService.newTextInput()
        .setFieldName('username')
        .setTitle('您的姓名'))
      .addWidget(CardService.newTextInput()
        .setFieldName('workEmail')
        .setTitle('工作邮箱'))
      .addWidget(CardService.newButtonSet()
        .addButton(CardService.newTextButton()
          .setText('提交')
          .setOnClickAction(CardService.newAction()
            .setFunctionName('saveUserInfo'))))
    );
  return [card.build()];
}

/**
 * 保存用户提交的基础信息
 * @param {Object} e 表单提交的数据
 */
function saveUserInfo(e) {
  const userProps = PropertiesService.getUserProperties();
  // 获取表单输入值
  const username = e.formInput.username;
  const workEmail = e.formInput.workEmail;

  // 保存信息,并标记已完成设置
  userProps.setProperty('hasCompletedSetup', 'true');
  userProps.setProperty('username', username);
  userProps.setProperty('workEmail', workEmail);

  // 刷新插件界面,切换到主卡片
  return CardService.newActionResponseBuilder()
    .setNavigation(CardService.newNavigation().updateCard(buildMainCard()[0]))
    .build();
}

/**
 * 构建插件主功能卡片(这里替换成你原来的业务逻辑)
 * @param {Object} e Gmail UI提供的数据
 */
function buildMainCard(e) {
  const userProps = PropertiesService.getUserProperties();
  const username = userProps.getProperty('username');
  
  // 这里写你原来的卡片渲染逻辑,比如展示邮件相关功能
  const card = CardService.newCardBuilder()
    .setHeader(CardService.newCardHeader().setTitle(`欢迎回来,${username}!`))
    .addSection(CardService.newCardSection()
      .addWidget(CardService.newTextParagraph().setText('这是您的插件主界面,可进行邮件相关操作')));
  
  return [card.build()];
}

你之前可能踩的坑

  1. 用错了属性类型:比如误把ScriptProperties当UserProperties用,导致所有用户共享同一个设置标记
  2. 没设置判断标记:只存了用户信息,但没加hasCompletedSetup这种开关,导致每次都判断为未设置
  3. 权限配置问题:确保插件清单里的authorizationScopes包含必要范围,比如https://www.googleapis.com/auth/gmail.addons.execute和https://www.googleapis.com/auth/script.storage(后者是操作Property Service需要的)

如果测试时想重置用户数据,可以运行这个函数清空属性:

function resetUserProps() {
  PropertiesService.getUserProperties().deleteAllProperties();
}

这样改完后,用户第一次打开收件箱会看到设置表单,提交后不管打开多少封邮件,都只会显示主界面啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:15:55