2017-01-16 79 views
0

我正在嘗試使用wit.ai quickstart example。該示例適用於硬編碼值,但是當我使用第三方天氣API並嘗試向用戶提供響應時,它不起作用。wit.ai和Node.js入門

工作代碼:

const actions = { 
     send(request, response) { 
      const {sessionId, context, entities} = request; 
      const {text, quickreplies} = response; 
      console.log('sending...', JSON.stringify(response)); 
     }, 
     getForecast({context, entities}) { 
      var location = firstEntityValue(entities, 'location'); 
      if (location) { 
      context.forecast = 'sunny in ' + location; // we should call a weather API here 
      delete context.missingLocation; 

      } else { 
      context.missingLocation = true; 
      delete context.forecast; 
      } 
      return context; 
     }, 
     }; 

現在我寫的函數的GetWeather({背景下,實體},位置)來調用第三方API天氣,並得到了用戶的地方的天氣信息。

非工作代碼:

var getWeather = function ({ context, entities }, location) { 
    console.log('Entities: ',entities) 
    var url = 'http://api.openweathermap.org/data/2.5/weather?q=' + location + '&appid=myAppID'; 
    request.get(url, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 
     console.log(typeof body) 
     var weatherObj = JSON.parse(body); 
     console.log('weather api res: ', weatherObj.weather[0].description); 
     context.forecast = weatherObj.weather[0].description + ' ' + location; // we should call a weather API here 
     delete context.missingLocation; 
    } 
    }) 
} 

const actions = { 
    send(request, response) { 
    const {sessionId, context, entities} = request; 
    const {text, quickreplies} = response; 
    console.log('sending...', JSON.stringify(response)); 
    }, 
    getForecast({context, entities}) { 
    var location = firstEntityValue(entities, 'location'); 
    if (location) { 
     //Call a function which calls the third party weather API and then handles the response message. 
     getWeather({ context, entities }, location); 
    } else { 
     context.missingLocation = true; 
     delete context.forecast; 
    } 
    return context; 
    }, 
}; 

另外,如果我改變的GetWeather()函數略微並移動context.forecast = +位置 '在晴天';刪除context.missingLocation;的request.GET中的回調機能的研究外()調用它會再次工作,但在這一點上我沒有來自第三方API天氣信息:

工作代碼:

var getWeather = function ({ context, entities }, location) { 
    //Keeping context.forecast outside the request.get() callback function is useless as we yet to get the weather info from the API 
    context.forecast = 'sunny in ' + location; 
    delete context.missingLocation; 
    console.log('Entities: ',entities) 
    var url = 'http://api.openweathermap.org/data/2.5/weather?q=' + location + '&appid=myAppID'; 
    request.get(url, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 
     console.log(typeof body) 
     var weatherObj = JSON.parse(body); 
     console.log('weather api res: ', weatherObj.weather[0].description); 
    } 
    }) 
} 

那麼如何make context.forecast = apiRes + location;線內工作的http調用回調?我在這裏做錯了什麼?

注: 錯誤響應我從wit.ai得到:

Error: Oops, I don't know what to do.

at F:\..\node-wit\lib\wit.js:87:15 
at process._tickCallback (internal/process/next_tick.js:103:7) 

我使用NPM包request,使內部節點HTTP調用。

回答

1

通過妥善解決承諾解決了這個問題。以下是完整的代碼:

'use strict'; 

let Wit = null; 
let interactive = null; 

var getWeather = function (location) { 
    var url = 'http://api.openweathermap.org/data/2.5/weather?q=' + location + '&appid=myAppID'; 
    return fetch(url, { 
    method: 'GET', 
    headers: { 
     'Content-Type': 'application/json', 
     'Accept': 'application/json', 
    } 
    }) 
    .then(rsp => { 
     var res = rsp.json(); 
     return res; 
    }) 
    .then(json => { 
     if (json.error && json.error.message) { 
     throw new Error(json.error.message); 
     } 
     return json; 
    }); 
} 

try { 
    // if running from repo 
    Wit = require('../').Wit; 
    interactive = require('../').interactive; 
} catch (e) { 
    Wit = require('node-wit').Wit; 
    interactive = require('node-wit').interactive; 
} 

const accessToken = (() => { 
    if (process.argv.length !== 3) { 
    console.log('usage: node examples/quickstart.js <wit-access-token>'); 
    process.exit(1); 
    } 
    return process.argv[2]; 
})(); 

// Quickstart example 
// See https://wit.ai/ar7hur/quickstart 

const firstEntityValue = (entities, entity) => { 
    const val = entities && entities[entity] && 
    Array.isArray(entities[entity]) && 
    entities[entity].length > 0 && 
    entities[entity][0].value; 
    if (!val) { 
    return null; 
    } 
    return typeof val === 'object' ? val.value : val; 
}; 

const actions = { 
    send(request, response) { 
    const {sessionId, context, entities} = request; 
    const {text, quickreplies} = response; 
    return new Promise(function (resolve, reject) { 
     console.log('sending...', JSON.stringify(response)); 
     return resolve(); 
    }); 
    }, 
    getForecast({context, entities}) { 
    var location = firstEntityValue(entities, 'location'); 
    if (location) { 
     return new Promise(function (resolve, reject) { 
     return getWeather(location).then(weatherJson => { 
      context.forecast = weatherJson.weather[0].description + ' in the ' + location; 
      delete context.missingLocation; 
      return resolve(context); 
     }) 
     }); 
    } else { 
     context.missingLocation = true; 
     delete context.forecast; 
     return Promise.reject(context); 
    } 
    return context; 
    }, 
}; 

const client = new Wit({ accessToken, actions }); 
interactive(client);