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

如何通过AppScript将登录回调Token传回Gmail插件

解决Gmail插件登录回调中Token传回与存储问题

核心问题分析

现有代码存在三个关键缺陷:

  • getCallbackURL中state是字符串而非实际生成的有效Token,导致回调无法触发指定方法
  • 缺少处理回调URL中Token的服务器端逻辑
  • 回调页面未实现向父窗口(插件登录弹窗)传递Token的机制

修复方案

1. 修正State Token生成逻辑

将getCallbackURL中的字符串形式代码改为实际执行Token生成:

var SCRIPT_ID = "MY_SCRIPT_ID";

// get a callback url to render in popup
function getAuthURL() {  
  var authorizeURL = getCallbackURL('testCallback');
  return authorizeURL;
}

// generate a user callback url
function getCallbackURL(callback) {
  // 实际生成State Token,而非字符串
  var state = ScriptApp.newStateToken()
    .withTimeout(3600)
    .withMethod(callback)
    .createToken();
  return 'https://script.google.com/macros/d/'+SCRIPT_ID+'/usercallback?state='+state;
}

2. 实现回调处理函数testCallback

该函数负责提取URL中的Token、存储到UserProperties,并向父窗口发送登录成功通知:

function testCallback(e) {
  // 从回调请求中获取Token参数
  const token = e.parameter.token;
  
  // 将Token存入用户属性
  if (token) {
    PropertiesService.getUserProperties().setProperty('USER_LOGIN_TOKEN', token);
  }

  // 返回用于传递消息的HTML页面
  return HtmlService.createHtmlOutput(`
    <script>
      // 向父窗口发送Token消息
      window.opener.postMessage({
        action: 'loginSuccess',
        value: '${token}'
      }, '*');
      // 自动关闭回调弹窗
      window.close();
    </script>
  `);
}

3. 调整前端消息监听与处理逻辑

修改doGet中的前端代码,确保收到Token后完成后续流程:

// generate login 
function doGet(e){
  return HtmlService.createTemplate(`
    <!DOCTYPE html>
    <html>
      <head>
        <script>
          function openSeparatePopup() {
            var url = encodeURIComponent('<?= getAuthURL() ?>');
            var popupOptions = "width=500,height=600";
            var separatePopup = window.open('https://url.com/addon_login/?client=gmailaddon&redirect_url=' + url, "SeparatePopupWindow", popupOptions);
          }

          // 监听回调弹窗的消息
          window.addEventListener("message", function(event) {
            if (event.data.action === 'loginSuccess') {
              console.log('登录Token已获取:', event.data.value);
              // 可选:调用服务器端函数确认存储状态
              google.script.run.withSuccessHandler(() => {
                alert('登录完成');
                // 此处可添加通知Gmail插件主逻辑更新状态的代码
              }).confirmTokenStorage();
            }
          });
        </script>
      </head>
      <body>
        <button onclick="openSeparatePopup()">Login</button>
      </body>
    </html>
  `).evaluate();
}

4. 可选:添加Token存储确认函数

如果需要在前端验证Token是否成功存储,可添加以下服务器端函数:

function confirmTokenStorage() {
  const storedToken = PropertiesService.getUserProperties().getProperty('USER_LOGIN_TOKEN');
  return storedToken ? true : false;
}

流程说明

  1. 用户点击插件登录按钮,打开第三方登录弹窗
  2. 第三方登录成功后,跳转到Web App的usercallback地址,携带token参数
  3. testCallback函数提取Token并存入UserProperties,同时生成页面向父窗口发送消息
  4. 插件登录弹窗收到消息后,可触发后续逻辑(如关闭弹窗、通知插件主界面登录完成)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:52:52