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

Google Sheets Add-on共享后custom functions执行及API密钥归属问题咨询

解决Google Sheets Add-on自定义函数共享权限与API Key隔离问题

问题根源分析

  1. 未安装插件用户可执行自定义函数并使用原用户API Key:Google Sheets自定义函数默认以函数创建者身份运行,即使表格被共享,未安装插件的用户调用函数时,仍会使用原用户的授权上下文(包括User Properties中的API Key)。
  2. 已安装插件用户侧边栏无法读取自身API Key:PropertiesService.getUserProperties()是用户级别的存储,每个用户的属性完全独立,原用户的API Key不会同步到共享用户的属性中,因此新用户打开侧边栏时读取的是空值。

解决方案

一、限制未安装插件用户执行自定义函数

在自定义函数开头添加授权状态验证,未安装/未授权插件的用户无法通过验证,会返回明确错误提示:

/**
 * @OnlyCurrentDoc
 * 获取Similarweb网站数据
 * @param {string} url 目标网址
 * @return {object} 网站分析数据
 * @customfunction
 */
function GET_SIMILARWEB_DATA(url) {
  // 验证用户是否已授权插件(未安装插件无法通过此验证)
  const authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL);
  if (authInfo.getAuthorizationStatus() !== ScriptApp.AuthorizationStatus.REQUIRED) {
    return "⚠️ 请先安装并授权《The Official Similarweb For Google Sheets™》插件";
  }

  // 后续逻辑...
}
  • @OnlyCurrentDoc注释限制插件权限仅作用于当前文档,降低用户授权门槛;
  • 未安装插件的用户无法获取插件的授权权限,验证失败后无法执行后续API调用逻辑。

二、确保自定义函数调用当前用户的API Key

核心是改变自定义函数的运行身份,让其以当前执行用户的身份运行,从而读取自身的User Properties:

  1. 完善自定义函数的身份验证与API Key读取逻辑:
function GET_SIMILARWEB_DATA(url) {
  // 授权验证(同上)
  const authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL);
  if (authInfo.getAuthorizationStatus() !== ScriptApp.AuthorizationStatus.REQUIRED) {
    return "⚠️ 请先安装并授权插件";
  }

  // 读取当前用户的API Key
  const userProps = PropertiesService.getUserProperties();
  const apiKey = userProps.getProperty('SIMILARWEB_API_KEY');
  
  if (!apiKey) {
    return "⚠️ 请先在插件侧边栏设置你的API Key";
  }

  // 调用Similarweb API并返回结果
  const apiResponse = UrlFetchApp.fetch(`https://api.similarweb.com/v1/...?key=${apiKey}&url=${url}`);
  return JSON.parse(apiResponse.getContentText());
}
  1. 插件安装与侧边栏逻辑优化:
    添加onInstall触发器确保用户首次安装时初始化自身属性,同时侧边栏只读取当前用户的API Key:
// 插件安装时触发
function onInstall(e) {
  onOpen(e);
  // 初始化当前用户的API Key属性(避免空值报错)
  const userProps = PropertiesService.getUserProperties();
  if (!userProps.getProperty('SIMILARWEB_API_KEY')) {
    userProps.setProperty('SIMILARWEB_API_KEY', '');
  }
}

// 打开表格时添加插件菜单
function onOpen(e) {
  SpreadsheetApp.getUi()
    .createMenu('Similarweb')
    .addItem('打开API设置', 'showSidebar')
    .addToUi();
}

// 显示侧边栏
function showSidebar() {
  const html = HtmlService.createHtmlOutputFromFile('sidebar')
    .setTitle('Similarweb API 设置');
  SpreadsheetApp.getUi().showSidebar(html);
}

// 侧边栏调用:读取当前用户API Key
function getUserApiKey() {
  const userProps = PropertiesService.getUserProperties();
  return userProps.getProperty('SIMILARWEB_API_KEY') || '';
}

// 侧边栏调用:保存当前用户API Key
function saveUserApiKey(key) {
  const userProps = PropertiesService.getUserProperties();
  userProps.setProperty('SIMILARWEB_API_KEY', key.trim());
}

侧边栏HTML示例(仅读取当前用户数据):

<script>
  window.onload = () => {
    // 加载当前用户的API Key
    google.script.run.withSuccessHandler(key => {
      document.getElementById('apiKey').value = key;
    }).getUserApiKey();
  };

  function saveKey() {
    const key = document.getElementById('apiKey').value;
    google.script.run.withSuccessHandler(() => {
      alert('API Key已保存');
    }).saveUserApiKey(key);
  }
</script>

<div style="padding: 1rem;">
  <input type="text" id="apiKey" placeholder="输入你的Similarweb API Key" style="width: 100%; padding: 0.5rem;">
  <button onclick="saveKey()" style="margin-top: 1rem; padding: 0.5rem 1rem;">保存</button>
</div>

关键注意事项

  • 用户首次运行自定义函数时会弹出授权提示,需引导用户完成授权(可通过插件菜单触发授权流程,降低用户操作门槛);
  • User Properties完全隔离,不会跨用户共享数据,确保每个用户的API Key仅自己可见和使用;
  • 未安装插件的用户无法通过授权验证,自然无法执行自定义函数,彻底解决权限泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 00:23:15