【问题标题】:Google Assistant and WorldWeatherOnline API confusionGoogle Assistant 和 WorldWeatherOnline API 混淆
【发布时间】:2018-02-04 15:57:55
【问题描述】:

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

【问题讨论】:

  • 欢迎来到 Stack Overflow!这些类型的问题(复习)更适合Code Review。除非您有特定问题,否则我建议您在那里发帖(请参阅How to Ask)。
  • 嗨!对于那个很抱歉。那我把这个帖子移到那里去。谢谢!
  • 看来您实际上并不是在要求进行代码审查,而是在寻求帮助修复您不符合您要求的代码。您应该 edit 您的标题以更好地反映这一点,并帮助防止您的问题被关闭。

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


【解决方案1】:

虽然您已使用 api.ai 和 actions-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”或“United States”这样更短(但仍可识别)的字符串。

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

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

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

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

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

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

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

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

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

【讨论】:

  • 嘿,囚犯,您提出的第一个解决方案正是我想要的。 location['query'] 从响应数据中返回 [city, country]。所以在我的代码中,我得到了国家,并以此为基础显示摄氏度还是华氏度。但你是对的,我可能应该把它当作谈话的一部分。还有很多东西要学。
  • 这是一种全新的思考方式,我们仍在努力找出最有效的方法。一个基本规则——想想人们实际上说了什么。如果答案有帮助 - 接受或支持答案总是值得赞赏的。
【解决方案2】:

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

使用该方法,您将收到类似'en-US''en-GB' 的字符串,这些字符串与一个国家/地区相关联,因此您可以映射到某个温度标度。可以在here 找到使用本地化的示例。

在 Google 控制台模拟器上的操作中,您可以使用语言下拉菜单更改语言环境,以便使用不同的语言环境测试您的应用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    相关资源
    最近更新 更多