Node.js 谷歌助手和WorldWeatherOnline API混淆

Node.js 谷歌助手和WorldWeatherOnline API混淆,node.js,dialogflow-es,actions-on-google,weather-api,Node.js,Dialogflow Es,Actions On Google,Weather Api,所以我刚开始为谷歌助手创建api代理。我跟踪了api.ai文档中的所有内容,以便下面的代理获取天气并返回响应。这是一个有效的代码,但我想对响应进行创新。我的目标是从回复中了解国家,并决定是否显示返回温度的摄氏度或华氏度。但在控制台中测试后,它继续使用摄氏度。 我还想返回基于温度的友好提醒,稍后我会添加 'use strict'; const http = require('http'); const host = 'api.worldweatheronline.com'; const wwoAp

所以我刚开始为谷歌助手创建api代理。我跟踪了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);
  });
});
 });
}

您不需要尝试获取用户来自哪个国家,而是可以获取用户的区域设置,用户可以使用该区域设置根据自己的意愿进行更改,并且与他们的位置无关,这样可以更好地反映他们喜欢的温度标度

使用该方法,您将收到一个字符串,如
'en-US'
'en-GB'
,它们与一个国家相关,因此您可以映射到特定的温度标度。可以找到使用本地化的示例


在Google Console Simulator上的操作中,您可以使用语言下拉菜单更改区域设置,以便使用不同的区域设置测试应用程序。

而不是尝试获取用户来自哪个国家,您可以获取用户的区域设置,用户可以根据自己的意愿进行更改,并且与他们的位置无关,这可以更好地反映他们喜欢的温度等级

使用该方法,您将收到一个字符串,如
'en-US'
'en-GB'
,它们与一个国家相关,因此您可以映射到特定的温度标度。可以找到使用本地化的示例


在谷歌控制台模拟器上的操作中,您可以使用语言下拉菜单更改区域设置,以便使用不同的区域设置测试您的应用程序。

尽管您在谷歌上用api.ai和操作标记了它,并且您的代码似乎来自于此,但操作api本身并不存在问题。这似乎与您如何处理来自WorldWeatherOnline(WWO)API的结果以及您对Google助手提供的输入的期望有关

您有一些问题,所有这些问题都集中在这一行:

let country = location['query'].split(",")[1];
此行获取您在查询中提供的值。在其中,您假设了许多事情,例如:

  • 用户指定国家(WWO可以只选择一个城市,如果它足够区分的话)

  • 国家被指定为第二个领域(当谈到美国城市时,指定国家是常见的,这将使国家成为第三个领域)

  • GoogleAssistant指定他们将国家的名字大写(很可能,但不能保证)

  • 如果国家是美国,则会使用确切的字符串“美利坚合众国”来指定,而不是使用较短的字符串(但仍然可以识别),如“US”或“United States”

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

    不管怎样-调试的一个好方法是实际打印出
    location['query']
    的值,查看各种输入的值,并进行相应调整

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

    • 您可以尝试在查询字符串中的任何位置将国家作为不区分大小写的子字符串查找,但这可能会导致一些误报。还是。。。这可能是最简单的解决方案

    • @Shuyang的建议很好,但是语言环境并不总是最好的方法,你需要使用Google Actions扩展来扩展通过API.AI提供的数据

    • 您还可以询问用户的当前位置(同样,如果您使用的是Google Actions),然后使用地理定位器确定用户的位置。但这真的很混乱

    • 您可以将其视为对话的一部分-扩展意图短语,让它们指定“华氏度”或其他可能的短语,并进行转换。或者将一些信息存储在上下文中,如果它们提出了后续短语,如“What is that in Fahrenheit”,则提供更新、转换的信息

      (如果你真的很精明,你会将此人的用户ID存储在某种数据库中,下次他们访问你时,你只需以他们选择的单位提供。)


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

    尽管您在google上用api.ai和actions标记了它,并且您的代码似乎来自于此,但actions api本身并没有什么问题。这似乎与您如何处理来自WorldWeatherOnline(WWO)API的结果以及您对Google助手提供的输入的期望有关

    您有一些问题,所有这些问题都集中在这一行:

    let country = location['query'].split(",")[1];
    
    此行获取您在查询中提供的值。在其中,您假设了许多事情,例如:

  • 用户指定国家(WWO可以只选择一个城市,如果它足够区分的话)

  • 国家被指定为第二个领域(当谈到美国城市时,指定国家是常见的,这将使国家成为第三个领域)

  • GoogleAssistant指定他们将国家的名字大写(很可能,但不能保证)

  • 如果国家是美国,则会使用确切的字符串“美利坚合众国”来指定,而不是使用较短的字符串(但仍然可以识别),如“US”或“United States”