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

Gmail Add-on撰写触发器报错:事件对象属性缺失无法读取

Gmail Add-on 撰写/回复界面无法获取邮件内容问题

开发了一个简单的Gmail Add-on,在邮件侧边栏点击插件图标可正常获取并展示邮件内容,但在撰写/回复界面点击插件图标时,无法获取内容,仅返回默认值。报错信息如下:

Error Info Event object: undefined, Error TypeError: Cannot read properties of undefined (reading 'gmail')

尝试修改manifest文件和权限配置后,问题仍未解决。


相关代码

/**
 * Function to build the compose UI.
 *
 * @param {Object} e The event object.
 * @return {CardService.Card[]} The card to show to the user.
 */
function getComposeUI(e) {
  Logger.log('getComposeUI event: ' + JSON.stringify(e));

  var subject = 'No Subject';
  var sender = 'Unknown Sender';
  var body = 'No content available';

  // Check if the compose action is triggered
  if (e && e.action && e.action.compose) {
    var action = e.action.compose;
    var actionParameters = action.parameters;

    // Check if the action type is "REPLY" or "FORWARD"
    if (actionParameters && actionParameters.action == 'REPLY' || actionParameters.action == 'FORWARD') {
      // Get the message ID of the original email
      var messageId = actionParameters.messageId;
      var message = GmailApp.getMessageById(messageId);

      subject = message.getSubject() || 'No Subject';
      sender = message.getFrom() || 'Unknown Sender';
      body = message.getPlainBody() || 'No content available';
      Logger.log('Reply or Forward action. Subject: ' + subject + ', Sender: ' + sender + ', Body: ' + body);
    } else {
      Logger.log('New message action.');
    }
  } else {
    Logger.log('No relevant event data found.');
  }

  var card = buildComposeCard(subject, sender, body);
  return [card];
}

/**
 * Function to build the compose card.
 *
 * @param {string} subject The subject of the email.
 * @param {string} sender The sender of the email.
 * @param {string} body The body of the email.
 * @return {CardService.Card}
 */
function buildComposeCard(subject, sender, body) {
  Logger.log('Building compose card with subject: ' + subject + ', sender: ' + sender + ', body: ' + body);

  var card = CardService.newCardBuilder()
    .setHeader(CardService.newCardHeader().setTitle('Email Content'))
    .addSection(CardService.newCardSection()
      .addWidget(CardService.newTextParagraph().setText('Subject: ' + subject))
      .addWidget(CardService.newTextParagraph().setText('Sender: ' + sender))
      .addWidget(CardService.newTextParagraph().setText('Body: ' + body)))
    .build();

  return card;
}

/**
 * Trigger function when a Gmail message is opened.
 * Constructs the add-on's user interface for the message.
 */
function onGmailMessageOpen(e) {
  Logger.log('onGmailMessageOpen event: ' + JSON.stringify(e));

  var subject = 'No Subject';
  var sender = 'Unknown Sender';
  var body = 'No content available';

  if (e && e.gmail && e.gmail.messageId) {
    var messageId = e.gmail.messageId;
    var message = GmailApp.getMessageById(messageId);

    subject = message.getSubject() || 'No Subject';
    sender = message.getFrom() || 'Unknown Sender';
    body = message.getPlainBody() || 'No content available';
  } else {
    Logger.log('No relevant event data found.');
  }

  var card = buildComposeCard(subject, sender, body);
  return [card];
}

manifest配置文件

{
  "timeZone": "America/Los_Angeles",
  "dependencies": {
    "enabledAdvancedServices": []
  },
  "exceptionLogging": "STACKDRIVER",
  "oauthScopes": [
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.readonly"
  ],
  "gmail": {
    "name": "Email Content Viewer",
    "logoUrl": "https://example.com/logo.png",
    "contextualTriggers": [
      {
        "unconditional": {},
        "onTriggerFunction": "onGmailMessageOpen"
      }
    ],
    "composeTrigger": {
      "selectActions": [
        {
          "text": "Get Email Content",
          "runFunction": "getComposeUI"
        }
      ]
    },
    "openLinkUrlPrefixes": [
      "https://"
    ],
    "primaryColor": "#4285F4",
    "secondaryColor": "#D2E3FC"
  }
}

修复方案

1. 更新manifest配置

添加草稿访问权限并补充必要的OAuth范围,确保插件能访问撰写界面的相关数据:

{
  "timeZone": "America/Los_Angeles",
  "dependencies": {
    "enabledAdvancedServices": []
  },
  "exceptionLogging": "STACKDRIVER",
  "oauthScopes": [
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.readonly",
    "https://www.googleapis.com/auth/gmail.compose"
  ],
  "gmail": {
    "name": "Email Content Viewer",
    "logoUrl": "https://example.com/logo.png",
    "contextualTriggers": [
      {
        "unconditional": {},
        "onTriggerFunction": "onGmailMessageOpen"
      }
    ],
    "composeTrigger": {
      "selectActions": [
        {
          "text": "Get Email Content",
          "runFunction": "getComposeUI"
        }
      ],
      "draftAccess": "WRITE"
    },
    "openLinkUrlPrefixes": [
      "https://"
    ],
    "primaryColor": "#4285F4",
    "secondaryColor": "#D2E3FC"
  }
}

2. 修正getComposeUI函数的事件处理逻辑

撰写界面的事件对象结构与邮件详情页不同,需调整判断逻辑以正确获取原始邮件信息:

function getComposeUI(e) {
  Logger.log('getComposeUI event: ' + JSON.stringify(e));

  var subject = 'No Subject';
  var sender = 'Unknown Sender';
  var body = 'No content available';

  // 检查是否为撰写界面触发的事件
  if (e && e.gmail && e.gmail.composeAction) {
    var composeAction = e.gmail.composeAction;
    // 仅在回复/转发时存在原始邮件ID
    if (composeAction.type === 'REPLY' || composeAction.type === 'FORWARD') {
      if (composeAction.messageId) {
        try {
          var message = GmailApp.getMessageById(composeAction.messageId);
          subject = message.getSubject() || 'No Subject';
          sender = message.getFrom() || 'Unknown Sender';
          body = message.getPlainBody() || 'No content available';
          Logger.log('Reply or Forward action. Subject: ' + subject + ', Sender: ' + sender + ', Body: ' + body);
        } catch (err) {
          Logger.log('Error fetching message: ' + err.message);
        }
      }
    } else {
      Logger.log('New message action.');
    }
  } else {
    Logger.log('No relevant event data found.');
  }

  var card = buildComposeCard(subject, sender, body);
  return [card];
}

3. 重新部署插件

修改完成后,重新部署Gmail Add-on,确保新配置和代码生效。


关键说明

  • 撰写界面的事件对象结构为e.gmail.composeAction,而非原代码中的e.action.compose,这是无法获取数据的核心原因。
  • 添加draftAccess和gmail.compose权限是为了让插件正常访问撰写界面的草稿及原始邮件数据。
  • 增加try-catch块可捕获获取邮件时的异常,避免插件崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:15:00