如何在Gmail插件中持久化用户特定值:避免重复询问信息
嘿,我懂你遇上的麻烦了——明明想用Property Service存用户的基础信息,结果每次打开新邮件还是要重复填,太闹心了对吧?我帮你分析下问题大概率出在哪,再给你调整后的代码方案。
首先,你得搞清楚Property Service的三种类型,别用错了:
UserProperties:用户专属,每个用户的数据单独存储,跨插件的所有运行实例生效,这才是你应该用的ScriptProperties:所有使用这个插件的用户共享数据,绝对不能用来存单个用户的设置DocumentProperties:和特定文档绑定,Gmail插件里用不上
我猜你要么是用错了属性类型,要么是没在buildAddOn里正确判断是否已经保存过信息。下面是修正后的完整代码思路:
核心逻辑
每次插件启动时(也就是buildAddOn运行时),先检查用户属性里有没有「已完成设置」的标记:
- 如果没有,弹出基础信息收集表单
- 如果有,直接显示正常的插件界面
- 用户提交表单后,把信息存到
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()]; }
你之前可能踩的坑
- 用错了属性类型:比如误把
ScriptProperties当UserProperties用,导致所有用户共享同一个设置标记 - 没设置判断标记:只存了用户信息,但没加
hasCompletedSetup这种开关,导致每次都判断为未设置 - 权限配置问题:确保插件清单里的
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
相关产品推荐
相关产品推荐

