Как совершать асинхронные звонки из внешних сервисов на действия в гугле?
Я пытаюсь подключить Google Home к внешнему чат-боту с помощью actionssdk. У меня есть API, который принимает пользовательские входные данные и отправляет их в мой чат-бот с помощью webhook, но мой чат-бот отвечает асинхронно, вызывая другую конечную точку моего API, и я не могу показать ответ в действиях в Google или Google Home.
Я создаю 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 Home. Но мне нужен объект conv, чтобы показать ответ в Google Home, или действия в 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);
}
}
});
С этого момента мой бот не отправляет ответ, а звонит /webhook
Конечная точка моего API с ответом. Но в этой функции у меня нет объекта de conv, и я не могу отправить ответ в Google. Я не знаю, как получить доступ к этому объекту. Может быть, есть URI для подключения к моему проекту в действиях на Google из моего API.
1 ответ
Как правило, действия в Google работают в режиме запрос-ответ. Пользователь что-то говорит Действию, и Действие отвечает ответом. Этот ответ должен прийти в течение 5 секунд. Если вы считаете, что вызов /webhook может происходить так быстро, и вы доставите сообщение пользователю только после того, как он что-то скажет, вы можете /webhook сохранить ответ в очереди для пользователя, и ваш обработчик Intent будет в цикл, который проверяет эту очередь на наличие сообщений для ответа - если в течение 5 секунд есть сообщение, вы отвечаете им, если нет, вам нужно ответить до истечения 5 секунд.
Если вы не можете гарантировать, что это будет сделано в течение 5 секунд, однако, есть несколько обходных путей, которые могут быть полезны в зависимости от ваших потребностей.
Во-первых, вы можете использовать уведомления. В этом случае вы отправите сообщение от пользователя, а затем закроете диалог. Когда ваш /webhook endpiont запущен, вы должны найти пользователя и отправить уведомление его помощнику. К сожалению, это немного громоздко, не приводит к очень интерактивной системе чата, а уведомления на интеллектуальных колонках также не поддерживаются.
Вы также можете использовать Media Response, чтобы настроить периодический опрос новых сообщений. По этой схеме ваш пользователь отправит свое сообщение. В своем ответе на них вы включили бы Media Response для некоторого звука, который воспроизводится, скажем, в течение 15 секунд. Когда аудио закончится, ваше Действие будет вызвано снова, и вы можете проверить, были ли какие-либо сообщения поставлены в очередь для доставки пользователю. Если это так, вы ретранслируете эти сообщения, после чего получаете усиление Media Response. В противном случае просто отправьте медиа-ответ. Ваш вызов /webhook должен был бы поместить сообщения в очередь для доставки пользователю. Это сложнее, особенно в масштабе, но можно сделать более интерактивным. Это также более общий случай попытки обработать его в цикле за 5 секунд.