Я использую инструменты графического интерфейса, предоставляемые API AI, для создания действий. Можно ли получить местоположение устройства? Я слышал, что это возможно, запросив разрешения. Это где-нибудь задокументировано? Пример/фрагмент кода будет очень полезен.
Как получить местоположение устройства с помощью API AI?
Ответы (5)
Документация немного неясна. Я надеюсь, что это может помочь кому-то.
Все, что вам нужно сделать, это создать дочернее резервное намерение для намерения, у которого вы запрашиваете разрешения.
- Для этого вам нужно нажать на ссылку «Добавить последующее намерение» в вашем намерении. Обратите внимание, что ссылка будет отображаться только при наведении на нее курсора. Выберите резервный вариант из раскрывающегося списка, и для вас будет создано дочернее резервное намерение.
Снимок экрана, показывающий, как создать дочернее резервное намерение
- Нажмите на дочернее резервное намерение и включите «Использовать веб-перехватчик».
Снимок экрана, на котором показано, как настроить дочернее резервное намерение
Вот и все. Теперь, как только разрешение будет запрошено, ответ пользователя будет отправлен вам обратно с действием, которое настроено в вашем дочернем резервном намерении.
См. ниже пример кода веб-перехватчика.
'use strict';
const express = require('express')();
const router = require('express').Router();
const bodyParser = require('body-parser');
const ActionsSdkApp = require('actions-on-google').ActionsSdkApp;
const ApiAiApp = require('actions-on-google').ApiAiApp;
express.use(bodyParser.json({type: 'application/json'}));
// In aip.ai console, under Fulfillment set webhook url to
// https://[YOUR DOMAIN]/example/location
// don't forget to select "Enable webhook for all domains" for the DOMAIN field
router.post('/location', (req, res) => {
const app = new ApiAiApp({request: req, response: res});
const intent = app.getIntent();
switch(intent){
case 'input.welcome':
// you are able to request for multiple permissions at once
const permissions = [
app.SupportedPermissions.NAME,
app.SupportedPermissions.DEVICE_PRECISE_LOCATION
];
app.askForPermissions('Your own reason', permissions);
break;
case 'DefaultWelcomeIntent.DefaultWelcomeIntent-fallback':
if (app.isPermissionGranted()) {
// permissions granted.
let displayName = app.getUserName().displayName;
//NOTE: app.getDeviceLocation().address always return undefined for me. not sure if it is a bug.
// app.getDeviceLocation().coordinates seems to return a correct values
// so i have to use node-geocoder to get the address out of the coordinates
let coordinates = app.getDeviceLocation().address;
app.tell('Hi ' + app.getUserName().givenName + '! Your address is ' + address);
}else{
// permissions are not granted. ask them one by one manually
app.ask('Alright. Can you tell me you address please?');
}
break;
}
});
express.use('/example', router);
express.listen('8081', function () {
console.log('Example app is running')
})
В этом есть три части:
- Спрашивая разрешения
- Указание API.AI обработать ответ
- Обработка информации, пересылаемой API.AI
Запрос разрешения
Многие люди не упоминают тело JSON, которое необходимо сделать для запроса разрешений в первую очередь. Это (плохо) задокументировано в действия > помощник > помощники > информация о пользователе, поскольку на самом деле он не охватывает то, что нужно отправить, если вы используете API.AI.
Короче говоря, ваш JSON должен выглядеть примерно так:
{
"speech": "PLACEHOLDER_FOR_PERMISSION",
"data": {
"google": {
"expectUserResponse": true,
"isSsml": false,
"noInputPrompts": [],
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To pick you up",
"permissions": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
}
}
}
}
}
Указание API.AI обработать ответ
API.AI необходимо знать, какое намерение обрабатывает информацию о разрешениях. Вы делаете это, устанавливая событие на actions_intent_PERMISSION
.
Это будет выглядеть примерно так:
Вы можете установить действие на все, что имеет смысл для вашего веб-перехватчика, и обязательно включите выполнение веб-перехватчика для намерения.
Если вам нужно отслеживать, откуда был инициирован запрос разрешения, и обрабатывать его с помощью другого действия, вы можете установить контекст и иметь разные намерения обработки на основе разных настроек контекста.
Метод резервного намерения работает, потому что на тот момент нет лучшего совпадения, поскольку вы не указали обычное намерение с помощью actions_intent_PERMISSION
. Однако это не лучший выбор, поскольку он может соответствовать другим ситуациям вашего пользователя.
Получите информацию в свой веб-перехватчик
Ваш веб-хук получит объект JSON в теле.
Имя пользователя и связанная с ним информация будут находиться по пути к объекту originalRequest.data.user.profile
.
Их местонахождение указано по адресу originalRequest.data.device.location
.
См. Обзор > Действия в Google позволяют расширить функциональность для справки.
Да, можно получить местоположение устройства и некоторую другую информацию (имя) после того, как пользователь даст разрешение.
Это уже хорошо задокументировано Google, поэтому я не думаю, что это необходимо мне повторить это здесь.
Если вопрос заключается в том, возможно ли получить информацию о местоположении без пользовательской реализации веб-перехватчика, которая вызывается через выполнение API.AI, то ответ будет отрицательным: сам API.AI изначально не предоставляет эту возможность, вам нужно использовать расширение API.AI. механизм, то есть вебхук.
Как вы можете видеть здесь Api.Ai doc в ответе есть поле data
. Вам необходимо создать ответ в формате json, который Google ожидает именно от веб-перехватчика (см. Google docs), но если вы используете Api.Ai, вам нужно вложить элемент Google json в поле данных.
Я так долго с этим боролся. Я нашел этот форум и что-то щелкнуло. Оказывается, это действительно не так уж и сложно.
В вашем веб-перехватчике php ваше первоначальное намерение должно возвращать это как json - или json_encode
этот массив:
array(
'data' =>
array(
'google' =>
array(
'expectUserResponse' => true,
'systemIntent' =>
array(
'intent' => 'actions.intent.PERMISSION',
'data' =>
array(
'@type' =>
'type.googleapis.com/google.actions.v2.PermissionValueSpec',
'optContext' => 'To find the closest site ',
'permissions' =>
'DEVICE_PRECISE_LOCATION'
,
),
),
),
),
)
затем создайте другое намерение с событием: actions_intent_PERMISSION
Теперь в вашем веб-перехватчике php для вновь созданного намерения вам будет возвращено местоположение. Это в ответе: ["originalRequest"]['data']['device']['location']['coordinates']
Очень просто...