2017-01-16 4 views
0

J'essaie d'utiliser wit.ai quickstart example. L'exemple fonctionne avec les valeurs codées en dur, mais lorsque j'utilise l'API de météo tierce et que j'essaie de donner la réponse à l'utilisateur, cela ne fonctionne pas.Premiers pas avec wit.ai et Node.js

Code de travail:

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; 
     }, 
     }; 

Maintenant, je l'ai écrit fonction getWeather ({contexte, entités}, emplacement) pour appeler l'API météo tiers et obtenir les informations météorologiques pour l'emplacement donné de l'utilisateur.

Code chômés:

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; 
    }, 
}; 

Aussi, si je change la fonction getWeather() légèrement et déplacer context.forecast = 'ensoleillé' + emplacement; delete context.missingLocation; en dehors du fuction de rappel de request.GET() appeler travaillera à nouveau, mais à ce stade, je n'ai pas d'info météo de api 3ème partie:

Code de travail:

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); 
    } 
    }) 
} 

Alors, comment make context.forecast = apiRes + emplacement; ligne de travail à l'intérieur du rappel de l'appel http? Qu'est-ce que je fais mal ici?

REMARQUE: réponse d'erreur que je reçois de 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) 

J'utilise paquet NPM request pour faire des appels http à l'intérieur du nœud.

Répondre

1

Résolu le problème en résolvant correctement la promesse. Voici le code complet:

'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);