如何从外部服务到谷歌上的操作进行异步调用?



我正在尝试使用actionssdk将Google Home连接到外部聊天机器人。我有一个 API,它接受用户输入并使用 webhook 将它们发送到我的聊天机器人,但我的聊天机器人以异步方式调用我的 API 的另一个端点做出响应,我无法在 Google 或 Google Home 上的操作中显示响应。

我创建了一个actionssdkApp。

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

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

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 将用户输入发送到我的聊天机器人,但请求没有收到响应。我的聊天机器人调用另一个端点,并给出文本答案:

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 对象在谷歌主页中显示答案,或者在谷歌或任何其他设备上显示操作。

编辑:

我的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函数将用户输入发送到我的机器人:

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);
}
}
}); 

从现在开始,我的机器人不会发送响应,而是使用答案调用我的 api/webhook终结点。但是在这个函数中,我没有 de conv 对象,我无法将答案发送给谷歌。我不知道如何访问这个对象。也许有一个 uri 可以从我的 API 在谷歌上的操作中与我的项目连接。

通常,Google 上的操作以请求-响应方式工作。用户对操作说些什么,操作回复响应。该回复需要在大约 5 秒内完成。如果您认为对/webhook 的调用可以如此之快,并且您只会在用户说出某事后向用户传递消息,则可以让/webhook 将响应保存在用户的队列中,并让您的 Intent 处理程序处于循环中,该循环检查此队列是否有任何要回复的消息 - 如果在 5 秒内有消息, 你回复它,如果没有,你需要在 5 秒结束之前回复。

但是,如果您不能保证它会在 5 秒内完成,则根据您的需要,有一些解决方法可能很有用。

首先是您可能能够使用通知。在此方案中,您将从用户发送消息,然后关闭对话。当您的/webhook endpiont 被触发时,您将找到用户并将通知发送给他们的助手。不幸的是,这有点笨重,不会导致非常互动的聊天系统,并且智能扬声器也不支持通知。

您还可以考虑使用媒体响应来设置一种定期轮询新消息的方法。在此方案下,您的用户将发送他们的消息。在回复中,您将包括某些播放时间(例如 15 秒(的音频的媒体响应。音频完成后,将再次调用您的操作,您可以检查是否有任何消息已排队等待传递给用户。如果是这样,则转发这些消息,然后获得媒体响应增益。否则,只需发送媒体响应。对/webhook 的调用必须将消息放入队列中才能传递给用户。这更复杂,尤其是缩放,但可以提高交互性。这也是尝试在 5 秒内循环处理它的更普遍的情况。

最新更新