Google智能助理和WorldWeatherOnline API混淆

时间:2017-08-27 01:51:45

标签: node.js dialogflow actions-on-google weather-api

所以我刚开始为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);
  });
});
 });
}

2 个答案:

答案 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];

此行获取您在查询中提供的值。在其中,您承担了许多事情,例如:

  1. 用户指定国家/地区(如果区分足够的话,WWO只能占用一个城市)。

  2. 该国家被指定为第二个字段(在谈论美国城市时,指定州是常见的,这将使该国成为第三个字段)。

  3. Google智能助理指定他们将该国家的名字大写(可能,但不能保证)。

  4. 如果该国家/地区是美国,则使用确切的字符串"美利坚合众国"而不是更短(但仍然可识别)的东西,如" US"或"美国"。

  5. 此外还有一个逻辑问题,即要求提供信息的人可能希望以他们所熟悉的单位,而不是那个国家的传统单位。一位美国人询问西班牙的天气可能仍然需要华氏温度。

    无论如何 - 调试此方法的一个好方法是实际打印出location['query']的值,以查看各种输入的值,并相应地进行调整。

    我不确定是否有直接而好的方法来处理您尝试做的事情。一些想法:

    • 您可以尝试在查询字符串中的任何位置查找这些国家/地区作为不区分大小写的子字符串,但这可能会让您产生误报。仍然......这可能是你最简单的解决方案。

    • @Shuyang的建议很好 - 但语言区域设置并不总是最佳方式,您需要对通过API.AI提供的数据使用Google Actions扩展。

    • 您还可以询问用户的当前位置(再次,如果您正在使用Google操作),然后使用Geolocator确定他们的位置。但那真是一团糟。

    • 您可以将其视为对话的一部分 - 扩展意图短语,让他们在华氏温度中指定""或与其他可能的短语,并进行转换。或者在一个上下文中存储一些信息,如果它们构成一个后续短语,例如"华氏温度是什么"提供更新的转换信息。

      (如果你真的很光滑,你将这个人的userId存储在某种数据库中,下次他们访问你时,你只需在单位中提供它他们的选择。)

    我认为第一个是最简单的,最后一个是最自然的,但这完全取决于location['query']的实际价值。