如何从外部服务异步调用 google 上的操作?
How to make asynchronous calls from external services to actions on google?
我正在尝试使用 actionssdk 将 Google 主页连接到外部聊天机器人。我有一个 API 接受用户输入并使用 webhook 将它们发送到我的聊天机器人,但我的聊天机器人做出响应以异步方式调用我的 API 的另一个端点,我无法显示响应在 Google 或 Google 主页上的操作中。
我创建了一个actionssdkApp。
const {
actionssdk,
SimpleResponse,
Image,
} = require('actions-on-google');
var app = actionssdk();
var express_app = express();
我的 API 有 2 个端点。其中之一是针对 google 的操作,将用户输入发送到我的聊天机器人:
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 主页的地方。但我需要 conv 对象在 google 主页中显示答案,或在 google 或任何其他设备上显示操作。
编辑:
我的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 对象,我不能将答案发送到 google。我不知道如何访问这个对象。也许有一个 uri 可以连接到我的 google 上的项目,来自我的 api。
通常,Google 上的操作以请求-响应方式工作。用户对 Action 说了些什么,Action 回复了一个响应。该回复需要在大约 5 秒内到达。如果您认为对 /webhook 的调用可以那么快,并且您只会在用户说些什么后向用户发送消息,您可以让 /webhook 将响应保存在用户的队列中,并让您的 Intent 处理程序在一个循环,检查此队列中是否有任何要回复的消息 - 如果 5 秒内有消息,你就回复它,如果没有,你需要在 5 秒结束之前回复。
如果您不能保证它会在 5 秒内完成,但是,根据您的需要,有一些可能有用的解决方法。
首先是您可以使用 notifications。在这种情况下,您将发送来自用户的消息,然后关闭对话。当你的 /webhook endpiont 被触发时,你会找到用户并将通知发送给他们的助手。不幸的是,这有点笨重,不会导致非常互动的聊天系统,并且智能扬声器也不支持通知。
您还可以考虑使用 Media Response 来设置一种方法,以便您定期轮询新消息。在此方案下,您的用户将发送他们的消息。在您对他们的回复中,您会为某些播放了 15 秒的音频添加媒体响应。当音频结束时,您的 Action 将再次被调用,您可以检查是否有任何消息排队等待发送给用户。如果是这样,您将转发这些消息,然后是媒体响应增益。否则,只需发送媒体响应。您对 /webhook 的调用必须将消息放入队列中以传递给用户。这更复杂,尤其是在规模上,但可以使其更具交互性。这也是一个更一般的情况,试图在 5 秒内循环处理它。
我正在尝试使用 actionssdk 将 Google 主页连接到外部聊天机器人。我有一个 API 接受用户输入并使用 webhook 将它们发送到我的聊天机器人,但我的聊天机器人做出响应以异步方式调用我的 API 的另一个端点,我无法显示响应在 Google 或 Google 主页上的操作中。
我创建了一个actionssdkApp。
const {
actionssdk,
SimpleResponse,
Image,
} = require('actions-on-google');
var app = actionssdk();
var express_app = express();
我的 API 有 2 个端点。其中之一是针对 google 的操作,将用户输入发送到我的聊天机器人:
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 主页的地方。但我需要 conv 对象在 google 主页中显示答案,或在 google 或任何其他设备上显示操作。
编辑:
我的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 对象,我不能将答案发送到 google。我不知道如何访问这个对象。也许有一个 uri 可以连接到我的 google 上的项目,来自我的 api。
通常,Google 上的操作以请求-响应方式工作。用户对 Action 说了些什么,Action 回复了一个响应。该回复需要在大约 5 秒内到达。如果您认为对 /webhook 的调用可以那么快,并且您只会在用户说些什么后向用户发送消息,您可以让 /webhook 将响应保存在用户的队列中,并让您的 Intent 处理程序在一个循环,检查此队列中是否有任何要回复的消息 - 如果 5 秒内有消息,你就回复它,如果没有,你需要在 5 秒结束之前回复。
如果您不能保证它会在 5 秒内完成,但是,根据您的需要,有一些可能有用的解决方法。
首先是您可以使用 notifications。在这种情况下,您将发送来自用户的消息,然后关闭对话。当你的 /webhook endpiont 被触发时,你会找到用户并将通知发送给他们的助手。不幸的是,这有点笨重,不会导致非常互动的聊天系统,并且智能扬声器也不支持通知。
您还可以考虑使用 Media Response 来设置一种方法,以便您定期轮询新消息。在此方案下,您的用户将发送他们的消息。在您对他们的回复中,您会为某些播放了 15 秒的音频添加媒体响应。当音频结束时,您的 Action 将再次被调用,您可以检查是否有任何消息排队等待发送给用户。如果是这样,您将转发这些消息,然后是媒体响应增益。否则,只需发送媒体响应。您对 /webhook 的调用必须将消息放入队列中以传递给用户。这更复杂,尤其是在规模上,但可以使其更具交互性。这也是一个更一般的情况,试图在 5 秒内循环处理它。