【问题标题】:Gmail Add-on pass parameters to function triggered by card actionGmail 插件将参数传递给卡片操作触发的功能
【发布时间】:2020-02-06 11:50:53
【问题描述】:

我正在构建一个 Gmail 插件,它只用一个表单按钮创建一张卡片。单击后,我希望该按钮触发一个将打开的电子邮件内容发送到外部 API 的功能。

到目前为止,我有这样的事情:

function createCard(event) {
  var currentMessage = getCurrentMessage(event).getBody();
  var section = CardService.newCardSection();

  var submitForm = CardService.newAction()
    .setFunctionName('callAPI');

  var submitButton = CardService.newTextButton()
    .setText('Submit')
    .setOnClickAction(submitForm);

  section.addWidget(CardService.newButtonSet()
    .addButton(submitButton));

  var card = CardService.newCardBuilder()
    .setHeader(CardService.newCardHeader()
    .setTitle('Click this button'))
    .addSection(section)
    .build();

  return [card];
}

function callAPI(event) {
  var payload = { "msg": msg }; // msg is the parameter I need to get from the function call
  var options = {
        "method"  : "POST",
        "contentType": "application/json",
        "payload" : JSON.stringify(payload),
        "followRedirects" : true,
        "muteHttpExceptions": true
  };

  return UrlFetchApp.fetch('https://www.someAPI.com/api/endpoint', options);
}

如何将currentMessage 变量传递给callAPI 函数?根据文档,我们可以从动作函数中获得的唯一参数似乎是event,它只有表单字段数据。如果没有办法传递其他参数,有没有办法让那个函数直接在函数内部获取消息的上下文数据??

谢谢!

【问题讨论】:

  • 您的问题解决了吗?

标签: google-apps-script gmail-addons


【解决方案1】:

我相信将 currentMessage 内容传递给 callAPI 函数的正确方法是使用 this documentation 中描述的 setParameters

您的代码如下所示:

var submitForm = CardService.newAction()
    .setFunctionName('callAPI')
    .setParameters({message: currentMessage});

在回调中,您可以使用以下方式获取消息:

function callAPI(event) {
    var payload = event.parameters.message; 
    ...

提醒一下,键(消息)和值(currentMessage)都必须是字符串。

【讨论】:

    【解决方案2】:

    您可以使用Properties Service,它允许您将字符串存储为键值对。想法是将currentMessage 的值存储在函数createCard 的属性中,然后在callAPI 中使用它。

    • 首先,要存储变量,可以在声明currentMessage后在createCard中添加以下行:
    var userProperties = PropertiesService.getUserProperties();
    userProperties.setProperty("currentMessage", currentMessage);
    
    • 其次,要检索此变量,请将以下几行添加到callAPI
    var userProperties = PropertiesService.getUserProperties();
    var msg = userProperties.getProperty("currentMessage");
    

    更新:

    为了避免单个属性的字符数限制,您还可以根据需要将消息拆分为多个属性。

    • 您首先必须通过substring 将消息拆分为一个数组,并将该数组的每个元素存储在不同的属性中。在声明 currentMessage 之后,您必须将其添加到 createCard
    var messageArray = [];
    var i = 0;
    var k = 5000; // Character limit for one property (change accordingly)
    while (i < currentMessage.length) {
      var part = currentMessage.substring(i, i += k);
      messageArray.push(part); // Splitting string into an array of strings
    }
    var userProperties = PropertiesService.getUserProperties();
    userProperties.deleteAllProperties(); // Delete old properties
    for (var j = 0; j < messageArray.length; j++) { // Set a different property for each element in the array
      userProperties.setProperty('messagePart' + j, messageArray[j]);
    }
    
    • 然后,要检索消息正文,您可以先检索与消息对应的所有属性,然后将所有值与concat 连接在一个字符串中。将以下行添加到callAPI
    var userProperties = PropertiesService.getUserProperties();
    var keys = userProperties.getKeys(); // Get all property keys
    var j = 0;
    var currentMessage = "";
    do {
      var part = userProperties.getProperty('messagePart' + j);
      currentMessage = currentMessage.concat(part); // Concat each property value to a single string.
      j++;    
    } while (keys.indexOf('messagePart' + j) !== -1); // Check if property key exists
    

    参考:

    希望对你有帮助。

    【讨论】:

    • 谢谢@iamblichus!此解决方案的唯一问题是传递给 setProperty 的值的字符数有限制,因此我不能使用它来存储消息正文。
    • @uckc 在这种情况下,你可以将你的身体分成几个属性。这也有限制,但要高得多。这可以很容易地自动化。如果您认为这可能是一种有效的解决方法,我将使用相应的代码更新我的答案。
    • @uckc 我更新了我的答案。这样,我认为您可以避免字符限制问题。请告诉我这是否适合你。
    • 我尝试将字符串拆分为多个属性,但它使插件崩溃并返回超时。最后,我采用了不同的方法,使用 Gmail 的 API 来处理电子邮件内容的转发,而不是通过 API。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 2018-09-22
    相关资源
    最近更新 更多