如何从外部服务向Google上的操作进行异步调用? [英] How to make asynchronous calls from external services to actions on google?

查看:103
本文介绍了如何从外部服务向Google上的操作进行异步调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过actionsdk将Google Home连接到外部聊天机器人。我有一个API,可以接收用户输入并通过webhook将其发送到我的聊天机器人,但是我的聊天机器人做出了响应,并以异步方式调用了我的API的另一个端点,因此我无法在Google或Google Home上的操作中显示该响应。

I'm trying to connect Google Home to an external chatbot with actionssdk. I have an API that take user inputs and send them to my chatbot with webhook, but my chatbot make a response calling another endpoint of my API in an async way, and I can't show the response in actions on Google or Google Home.

我创建一个actionsdkApp。

I create an actionssdkApp.

const {
  actionssdk,
  SimpleResponse,
  Image,
} = require('actions-on-google');
var app = actionssdk();
var express_app = express();

我的API有2个端点。其中之一是让Google上的操作将用户输入发送到我的聊天机器人:

My API has 2 endpoints. One of them is for actions on google to send user inputs to my chatbot:

app.intent('actions.intent.MAIN', conv => {
  console.log('entra en main');
  conv.ask('Hi, how is it going?');
});

app.intent('actions.intent.TEXT', (conv, input) => {
  var userId = conv.body.user.userId;
  console.log(userId);

  if(userId && input){
    textFound(conv, input, userId);
  }else{
    textnotFound(conv);
  }
});

TextFound函数使用webhook将用户输入发送到我的聊天机器人,但请求未收到响应。我的聊天机器人用文本答案呼叫另一个端点:

TextFound function send user inputs to my chatbot with webhook, but the request doesn't receive the response. My chatbot call another endpoint with the text answer:

express_app.post('/webhook', bodyParser.json(), (req, res)=>{
  console.log("Webhook");
  const userId = req.body.userId;
  if (!userId) {
    return res.status(400).send('Missing User ID');
  }
  console.log(req.body);
  res.sendStatus(200);
});

这是我要将答案发送到Google Home的地方。但是我需要conv对象才能在google主页中显示答案,或者在google或任何其他设备上显示操作。

And here is where I want to send the answer to Google Home. But I need the conv object to show the answer in google Home, or actions on google, or any other device.

编辑:

我的 textFound 函数:

webhook.messageToBot(metadata.channelUrl, metadata.channelSecretKey, userId, input, function(err){
        if(err){
            console.log('Error in sending message');
            conv.ask("Error in sending message");
        }else{
            conv.ask("some text");
        }
    });

在这里,我的api通过 messageToBot将用户输入信息发送到我的机器人函数:

From here my api send user inputs to my bot through messageToBot function:

request.post({
    uri: channelUrl,
    headers: headers,
    body: body,
    timeout: 60000,
    followAllRedirects: true,
    followOriginalHttpMethod: true,
    callback: function(err, res, body) {
        if (err) {                    
            console.log('err: '+err);
            callback(err);
        } else {
            console.log('Message sent');
            callback(null);
        }
    }
}); 

从现在开始,我的机器人没有发送响应,而是拨打了<$ c $我的api的c> / webhook 端点以及答案。但是在此功能中,我没有转换对象,也无法将答案发送给Google。我不知道如何访问该对象。也许有一个uri可以通过我的api在谷歌上与我的项目建立联系。

From now on, my bot doesn't send a response but makes a call to /webhook endpoint of my api with the answer. But in this function I haven't de conv object and I can't send the answer to google. I don't know how to access to this object. Maybe there is an uri to connect with my project in actions on google from my api.

推荐答案

通常,对Google的操作以请求-响应的方式工作。用户对操作说了些什么,然后该操作以响应进行回复。该回复大约需要5秒钟。如果您认为对/ webhook的调用可以很快到达,并且仅在用户说了几句话后才向用户发送消息,则可以让/ webhook将响应保存在该用户的队列中,并使Intent处理程序位于一个循环,检查此队列中是否有要答复的消息-如果在5秒钟内有消息,则用它答复;否则,则需要在5秒钟内答复。

Typically, Actions on Google works in a request-response way. The user says something to the Action, and the Action replies with a response. That reply needs to come within about 5 seconds. If you think the call to /webhook can come that quickly, and you will only deliver a message to the user after they say something, you can have /webhook save the response in a queue for the user, and have your Intent handler be in a loop that checks this queue for any messages to reply with - if there is a message within 5 seconds, you reply with it, if not, you need to reply before the 5 seconds are up.

但是,如果您不能保证将在5秒钟内完成操作,则有两种变通办法可能会根据您的需要而有用。

If you can't guarantee it will be done within 5 seconds, however, there are a couple of workarounds that might be useful depending on your needs.

首先,您可以使用通知。在这种情况下,您将发送来自用户的消息,然后关闭对话。触发/ webhook endpiont时,您将找到用户并将通知发送给其助手。不幸的是,这有点笨重,不会导致非常互动的聊天系统,并且智能扬声器也不支持通知。

The first is that you might be able to use notifications. In this scenario, you would send the message from the user and then close the conversation. When your /webhook endpiont is triggered, you would locate the user and send the notification to their Assistant. Unfortunately, this is a bit bulky, doesn't lead to a very interactive chat system, and notifications also aren't supported on smart speakers.

您还可以查看使用媒体响应设置一种轮询新消息的方式定期地。在这种方案下,您的用户将发送其消息。在对他们的答复中,您将包括一些音频播放的媒体响应,例如,播放时间为15秒。音频结束后,您的操作将再次被调用,您可以检查是否有任何消息排队等待传递给用户。如果是这样,则中继这些消息,然后中继媒体响应。否则,只需发送媒体回复。您对/ webhook的调用必须将消息放入队列中才能传递给用户。这更复杂,尤其是按比例缩放,但可以使其更具交互性。尝试在5秒内循环处理也是一种更普遍的情况。

You can also look into using a Media Response to set up a way for you to poll for new messages periodically. Under this scheme, your user would send their message. In your reply to them, you would include a Media Response for some audio that plays for, say, 15 seconds. When the audio finishes, your Action will be called again and you can check to see if any messages have been queued up to be delivered to the user. If so, you relay those messages, followed by a Media Response gain. Otherwise, just send a Media Response. Your call to /webhook would have to put messages in a queue to be delivered to the user. This is more complex, especially to scale, but can be made more interactive. It is also a more general case of trying to handle it in a loop inside 5 seconds.

这篇关于如何从外部服务向Google上的操作进行异步调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆