2017-08-27 104 views
0

所以我刚开始为Google智能助理创建api代理。我遵循https://api.ai/docs/getting-started/basic-fulfillment-conversation的api.ai文档中的所有内容,以便下面的代理获取天气并返回响应。这是一个有效的代码,但我希望通过回复获得创意。我想要做的是从反应中得到国家,并决定是否显示返回温度的摄氏或华氏相当于摄氏或华氏。但是在控制台测试它时,它会继续使用摄氏温度。 我还希望根据稍后添加的温度返回友好提醒。Google智能助理和WorldWeatherOnline API混淆

'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); 
    }); 
}); 
}); 
} 
+1

欢迎来到Stack Overflow!这些类型的问题(评论)更适合[codereview.se]。除非有特定问题,否则我会推荐在那里发帖(请参阅[如何提问](https://stackoverflow.com/help/how-to-ask))。 –

+0

嗨!对于那个很抱歉。那么我会在那里移动这篇文章。谢谢! – user2658763

+1

看起来你实际上并不是在寻求代码审查,而是为了帮助修复你没有做到你想要的代码。您应该[编辑]您的标题以更好地反映这一点,并帮助防止您的问题被关闭。 –

回答

1

虽然您已经使用api.ai和google-on-action标记了此代码,并且您的代码似乎来自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. 谷歌助理指定他们资本化国家的名字(可能,但不能保证)。

  4. 如果这个国家是美国,就用“美国”这个确切的字符串来代替,而不是像“美国”或“美国”那样较短的东西(但仍然是可识别的)。

此外,还有逻辑问题是询问信息的人可能希望它在所熟悉的他们单位,而不是传统的是对该国单位。一位美国人询问西班牙的天气可能仍然需要华氏。

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

我不确定是否有直接和好的方法来处理你想要做的事情。一些想法:

  • 你可以尝试寻找国家作为查询字符串的任何地方不区分大小写字符串,但可能给你一些误报。尽管如此,这可能是您最简单的解决方案。

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

  • 您也可以询问用户的当前位置(同样,如果您使用的是Google操作),然后使用Geolocator找出它们的位置。但那真是太麻烦了。

  • 你可以把它当作对话的一部分 - 扩展Intent短语,让他们指定“华氏温度”或其他可能的短语并进行转换。或者在上下文中存储一些信息,并且如果他们提供后续短语,例如“华氏度是什么”,则提供更新的,转换的信息。 (如果你真的很漂亮,你会将这个人的userId存储在某种数据库中,下一次他们访问你时,你只需以他们选择的单位提供它)。

我第一个想到的是最简单的,随着最后一个是最自然的交谈中,但是这一切都取决于什么样的location['query']价值实际上可以。

+0

嘿,囚徒,你的第一个建议的解决方案正是我所要做的。位置['query']从响应数据中返回[城市,国家]。所以在我的代码中,我得到了国家并以此为基础来显示是否显示摄氏或华氏。但你是对的,我应该把它当作对话的一部分。还有很多东西需要学习。 – user2658763

+0

这是一种全新的思考方式,我们都在试图找出最适合的方式。一条基本原则 - 思考人们实际上说了些什么。如果答案有帮助 - 接受或提高答案总是赞赏。 – Prisoner

1

,而不是试图获取用户是来自哪个国家,你可以使用getUserLocale用户的区域,用户可以按照自己的意愿改变,独立于它们的位置可以更好地反映其温度刻度他们喜欢。

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

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