所以我刚开始为Google智能助理创建api代理。我在https://api.ai/docs/getting-started/basic-fulfillment-conversation的api.ai文档中跟踪了所有内容,以便下面的代理获取天气并返回响应。这是一个有效的代码,但我希望通过响应获得创意。我的目的是从响应中获取国家,并决定是否显示相当于返回温度的摄氏或华氏温度。但是在控制台上测试它时,它会继续使用摄氏温度。 我还希望根据我稍后会添加的温度返回友好提醒。
'use strict';
const http = require('http');
const host = 'api.worldweatheronline.com';
const wwoApiKey = '[api key]';
exports.weatherWebhook = (req, res) => {
// Get the city and date from the request
let city = req.body.result.parameters['geo-city']; // city is a required param
// Get the date for the weather forecast (if present)
let date = '';
if (req.body.result.parameters['date']) {
date = req.body.result.parameters['date'];
console.log('Date: ' + date);
}
// Call the weather API
callWeatherApi(city, date).then((output) => {
// Return the results of the weather API to API.AI
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ 'speech': output, 'displayText': output }));
}).catch((error) => {
// If there is an error let the user know
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ 'speech': error, 'displayText': error }));
});
};
function callWeatherApi (city, date) {
return new Promise((resolve, reject) => {
// Create the path for the HTTP request to get the weather
let path = '/premium/v1/weather.ashx?format=json&num_of_days=1' +
'&q=' + encodeURIComponent(city) + '&key=' + wwoApiKey + '&date=' + date;
console.log('API Request: ' + host + path);
// Make the HTTP request to get the weather
http.get({host: host, path: path}, (res) => {
let body = ''; // var to store the response chunks
res.on('data', (d) => { body += d; }); // store each response chunk
res.on('end', () => {
// After all the data has been received parse the JSON for desired data
let response = JSON.parse(body);
let forecast = response['data']['weather'][0];
let minTemp = forecast['mintempC'];
let maxTemp = forecast['maxtempC'];
let unit = '°C';
let location = response['data']['request'][0];
//get country
let country = location['query'].split(",")[1];
let conditions = response['data']['current_condition'][0];
let currentConditions = conditions['weatherDesc'][0]['value'];
if(country == "Liberia" || country == "Myanmar" || country == "United States of America")
{
minTemp = forecast['mintempF'];
maxTemp = forecast['maxtempF'];
unit = '°F';
}
// Create response
let output =
`Current conditions in the ${location['type']}
${location['query']} are ${currentConditions} with a projected high of
${maxTemp} ${unit} and a low of
${minTemp}${unit} on
${forecast['date']} in ${country}`;
// Resolve the promise with the output text
console.log(output);
resolve(output);
});
res.on('error', (error) => {
reject(error);
});
});
});
}
答案 0 :(得分:1)
您可以使用getUserLocale来获取用户所在的区域,而不是尝试获取用户来自哪个国家/地区,用户可以根据自己的意愿进行更改,并且可以更好地反映他们的温度范围偏爱。
使用该方法,您将收到与国家/地区相关联的字符串'en-US'
或'en-GB'
,因此您可以映射到特定的温度范围。可以找到使用本地化的示例here。
在Google操作系统模拟器上的操作中,您可以使用语言下拉菜单更改区域设置,以便您可以使用不同的区域设置测试您的应用。
答案 1 :(得分:1)
虽然您已使用api.ai和action-on-google对此进行了标记,并且您的代码似乎来自https://api.ai/docs/getting-started/basic-fulfillment-conversation#setup_weather_api,但这对Actions API本身来说并不是一个问题。看起来它与您如何处理WorldWeatherOnline(WWO)API的结果以及您对Google智能助理提供的输入的预期有关。
你有一些问题,所有问题都集中在这一行:
let country = location['query'].split(",")[1];
此行获取您在查询中提供的值。在其中,您承担了许多事情,例如:
用户指定国家/地区(如果区分足够的话,WWO只能占用一个城市)。
该国家被指定为第二个字段(在谈论美国城市时,指定州是常见的,这将使该国成为第三个字段)。
Google智能助理指定他们将该国家的名字大写(可能,但不能保证)。
如果该国家/地区是美国,则使用确切的字符串"美利坚合众国"而不是更短(但仍然可识别)的东西,如" US"或"美国"。
此外还有一个逻辑问题,即要求提供信息的人可能希望以他们所熟悉的单位,而不是那个国家的传统单位。一位美国人询问西班牙的天气可能仍然需要华氏温度。
无论如何 - 调试此方法的一个好方法是实际打印出location['query']
的值,以查看各种输入的值,并相应地进行调整。
我不确定是否有直接而好的方法来处理您尝试做的事情。一些想法:
您可以尝试在查询字符串中的任何位置查找这些国家/地区作为不区分大小写的子字符串,但这可能会让您产生误报。仍然......这可能是你最简单的解决方案。
@Shuyang的建议很好 - 但语言区域设置并不总是最佳方式,您需要对通过API.AI提供的数据使用Google Actions扩展。
您还可以询问用户的当前位置(再次,如果您正在使用Google操作),然后使用Geolocator确定他们的位置。但那真是一团糟。
您可以将其视为对话的一部分 - 扩展意图短语,让他们在华氏温度中指定""或与其他可能的短语,并进行转换。或者在一个上下文中存储一些信息,如果它们构成一个后续短语,例如"华氏温度是什么"提供更新的转换信息。
(如果你真的很光滑,你将这个人的userId存储在某种数据库中,下次他们访问你时,你只需在单位中提供它他们的选择。)
我认为第一个是最简单的,最后一个是最自然的,但这完全取决于location['query']
的实际价值。