Firebase的云功能:HTTP触发器 - Promise / Async

时间:2017-06-20 07:53:39

标签: node.js firebase google-cloud-functions

我正在开发一个Facebook聊天机器人,它连接到Cloud Functions for Firebase。

伪代码:

  1. 收到用户留言
  2. 检查这是否是有效的网址
  3. 从URL(使用节点库read-art
  4. 检索内容/文章+ html
  5. 将数据存储到Firebase数据库
  6. 向用户发送回复(Facebook消息)
  7. 我写了所有5个零件并分别测试了所有零件,但是我把所有零件都链接起来了。我想问几个问题。

    1. 我应该在何时/何时致电response.sendStatus(200);?在我调用response.sendStatus(200);后,firebase功能是否立即终止? (根据firebase文档,答案似乎是肯定的)。所以我尝试将此行放在promise块中,firebase在日志文件中提示timeout消息

    2. 有任何解决问题的建议吗?我应该如何构建我的功能?

    3. exports.messengerWebhook = functions.https.onRequest((request, response) => {
          var data = request.body;
          // Make sure this is a page subscription
          if (data.object === "page") {
              // Iterate over each entry - there may be multiple if batched
             data.entry.forEach(function(entry) {
                 var pageID = entry.id;
                 var timeOfEvent = entry.time;
      
                 // Iterate over each messaging event
                 entry.messaging.forEach(function(event) {
                     if (event.message) {
                         receivedMessage(event);
                     } else {
                         console.log("Webhook received unknown event: ", event);
                     }
                 });
             });
             response.sendStatus(200);
          }
      });
      
      function receivedMessage(event) {
        // Putting a stub for now, we'll expand it in the following steps
        var senderID = event.sender.id;
        var recipientID = event.recipient.id;
        var timeOfMessage = event.timestamp;
        var message = event.message;
      
        console.log(
          "Received message for user %d and page %d at %d with message:",
          senderID,
          recipientID,
          timeOfMessage
        );
        console.log(JSON.stringify(message));
      
        var messageId = message.mid;
      
        var messageText = message.text;
        var messageAttachments = message.attachments;
      
        if (validUrl.isHttpUri(messageText) || validUrl.isHttpsUri(messageText)) {
          // If we receive a text message, check to see if it matches a keyword
          // and send back the example. Otherwise, just echo the text we received.
          switch (messageText) {
            case "generic":
              extractContentAndSave(messageText);
              break;
            default:
              sendTextMessage(senderID, messageText);
          }
        } else {
          sendTextMessage(senderID, "This is not a url");
        }
      }
      
      function extractContentAndSave(url) {
        read(url, function(err, art, options, resp) {
          if (err) {
            throw err;
          }
          var title = art.title, // title of article
            content = art.content, // content of article
            html = art.html; // whole original innerHTML
      
          admin
            .database()
            .ref("webpage")
            .push({
              url: url,
              title: title,
              content: content,
              rawHtml: html
              //cachedPageUrl:
            })
            .then(
              {
                //Send response to user via Facebook Messenger
              }
            );
          console.log("[STATUS CODE]", resp && resp.statusCode);
          // sendTextMessage(senderID, title);
        });
      }
      

1 个答案:

答案 0 :(得分:0)

我不知道这是否有资格作为答案(因为我没有时间修改你的代码),但正如你所说的,你应该只在完成所有事情之后调用response.sendStatus(200);,我所说的一切你开始的每一个承诺都已完成。

因此,您的函数extractContentAndSave必须返回Promise(您的Firebase推送),此函数的调用者即receivedMessage必须处理从extractContentAndSave收到的Promise,并且在每种情况下都应返回的承诺。

最后messengerWebhook必须处理receivedMessage返回的Promise。你必须确保你的承诺成为你架构的顶级功能。