wit.ai 和 Node.js 入门
Getting started with wit.ai and Node.js
我正在尝试使用 wit.ai quickstart example。该示例适用于硬编码值,但是当我使用第三方天气 API 并尝试向用户提供响应时,它不起作用。
工作代码:
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({ context, entities }, location) 来调用第三方天气 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 = 'sunny in ' + 位置;在 request.get() 的回调函数之外删除 context.missingLocation; 调用它将再次工作,但此时我没有来自第 3 方 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);
}
})
}
那么如何让context.forecast = apiRes + location; line work inside the callback of http call?我在这里做错了什么?
注意:
我从 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 在 Node 中进行 http 调用。
通过妥善解决承诺解决了问题。完整代码如下:
'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);
我正在尝试使用 wit.ai quickstart example。该示例适用于硬编码值,但是当我使用第三方天气 API 并尝试向用户提供响应时,它不起作用。
工作代码:
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({ context, entities }, location) 来调用第三方天气 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 = 'sunny in ' + 位置;在 request.get() 的回调函数之外删除 context.missingLocation; 调用它将再次工作,但此时我没有来自第 3 方 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);
}
})
}
那么如何让context.forecast = apiRes + location; line work inside the callback of http call?我在这里做错了什么?
注意: 我从 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 在 Node 中进行 http 调用。
通过妥善解决承诺解决了问题。完整代码如下:
'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);