我使用的是Azure Web App Bot(Node v 6.9.1),当初始化Test in Web Chat界面时,text和textLocale为null。但是当从用户收到第一个输入时,会为event.textLocale分配一个默认的' en'因此我在执行语言检测后无法从bot.use(接收)中重置一次(因为在此阶段它不是null)。
是否有另一种重置event.textLocale的方法,因为我无法通过从bot.use(receive)到bot.use(send)事件的任何全局node.js变量传播语言环境值要么?请帮助,谢谢
app.js代码段
bot.use({
receive: function (event, next) {
var text = '';
async.waterfall([
function(callback) {
text= event.text;
textLocale = event.textLocale;
request.get(
'http://<<<hostname>>>/translateIntent?intent='+text.toString()+'&textLocale='+(textLocale).toString(),
function (error, response, body) {
if (!error && response.statusCode == 200) {
var jsonStr = JSON.parse(body);
event.text=jsonStr.outputText;
// Storing the user's text locale if not already set
// - does not execute as event.textLocale is set by default and global variables are not propagating from receive to send
if(!event.textLocale && (jsonStr.inputLanguageContext != "(Unknown)")) {
event.textLocale = jsonStr.inputLanguageContext;
console.log("Rewriting event text locale to :" + jsonStr.inputLanguageContext);
}
callback(null, event);
}
}
);
},
function(event, callback) {
console.log("Rec after modification:");
console.log("event.textLocale: " + event.textLocale);
next();
callback(null, 'done');
}
]);
},
send: function (event, next) {
// translate response using event.textLocale as languageTo {event.text, languageFrom='en', event.textLocale}
}
});
翻译api:
app.get("/translateIntent", function(request, response) {
var inputText = request.param('intent');
if(inputText) {
var textLocale = ''; var outputText = '';
// If locale is already set, languageDetectHelper does not need to be called
if(request.param('textLocale')) {
textLocale = request.param('textLocale');
if(textLocale == 'en') {
// No translation required, just send back the inputText
response.end({outputText:inputText, inputLanguageContext:languageCodeDetected});
} else {
// Call translate, with languageFrom as textLocale, and languageTo = 'en'
translateHelper.GetTranslation(inputText, textLocale, languageTo).then(jsonStr => {
response.end(jsonStr);
}).catch(error => {
console.log("Error: " + error);
})
}
} else {
// Locale not yet set, call detectLanguage
languageDetectHelper.GetTextLanguage(inputText).then(languageCodeDetected => {
var languageTo = 'en';
if(languageCodeDetected == 'en' || languageCodeDetected == '(Unknown)') {
// Send back without translation
response.end({outputText:inputText, inputLanguageContext:languageCodeDetected});
} else {
// Translate to English
translateHelper.GetTranslation(inputText, languageCodeDetected, languageTo).then(jsonStr => {
console.log("JSON stringify output in server: " + JSON.stringify(jsonStr));
response.end(jsonStr);
}).catch(error => {
console.log("Error: " + error);
})
}
}).catch(error=> {
console.log("Error: " + error);
});
}
} else {
console.log("No translation required, waiting for the next event");
}
});
答案 0 :(得分:1)
根据我的理解,您正在尝试检测用户的输入语言,如果它不是英语,请将其翻译为英语,以便您的后端如LUIS服务可以处理它,并在处理后您的机器人默认会向您的用户发送英文回复,但您希望将响应再次转换回用户的输入语言。
由于我无法使用您的代码构建复杂的演示,因此我在这里使用azure认知服务来创建此演示:
var tokenHandler = require('./tokenHandler');
tokenHandler.init();
var TOLOCALE = 'en';
var FROMLOCALE;
bot.use({
receive: function (event, next) {
var token = tokenHandler.token();
//text ayalytics
if(event.text != ""){
var options = {
method: 'POST',
url: 'https://westcentralus.api.cognitive.microsoft.com/text/analytics/v2.0/languages',
body: { documents: [{ id: 'message', text: event.text }]},
json: true,
headers: {
'Ocp-Apim-Subscription-Key': 'YOUR-KEY'
}
};
request(options, function (error, response, body) {
if (!error && body) {
if (body.documents && body.documents.length > 0) {
var languages = body.documents[0].detectedLanguages;
if (languages && languages.length > 0) {
event.textLocale = languages[0].iso6391Name;
FROMLOCALE = event.textLocale;
}
}
}
//text translations
if (token && token !== ""){ //not null or empty string
var urlencodedtext = urlencode(event.text); // convert foreign characters to utf8
var options = {
method: 'GET',
url: 'http://api.microsofttranslator.com/v2/Http.svc/Translate'+'?text=' + urlencodedtext + '&from=' + FROMLOCALE +'&to=' + TOLOCALE,
headers: {
'Authorization': 'Bearer ' + token
}
};
request(options, function (error, response, body){
//Check for error
if(error){
return console.log('Error:', error);
}
else if(response.statusCode !== 200){
return console.log('Invalid Status Code Returned:', response.statusCode);
}
else {
parseString(body, function (err, result) {
console.log(result.string._);
event.text = result.string._;
next();
});
}
});
}
else{
console.log("No token");
next();
}
});
}
else{
next();
}
},
send: function (event, next) {
// translate response using event.textLocale as languageTo {event.text, languageFrom='en', event.textLocale}
var token = tokenHandler.token();
if (token && token !== ""){
var options = {
method: 'GET',
url: 'http://api.microsofttranslator.com/v2/Http.svc/Translate'+'?text=' + event.text + '&from=' + TOLOCALE +'&to=' + FROMLOCALE,
headers: {
'Authorization': 'Bearer ' + token
}
};
request(options, function (error, response, body){
//Check for error
if(error){
return console.log('Error:', error);
}
else if(response.statusCode !== 200){
return console.log('Invalid Status Code Returned:', response.statusCode);
}
else {
parseString(body, function (err, result) {
console.log(result.string._);
event.text = result.string._;
next();
});
}
});
}
}
});
//=========================================================
// Bots Dialogs
//=========================================================
var luisAppUrl = 'YOUR-LUIS-ENDPOINT';
var recognizer = new builder.LuisRecognizer(luisAppUrl);
var intents = new builder.IntentDialog({ recognizers: [recognizer] });
bot.dialog('/', intents);
//Route the luis intents to the various dialogs
intents.matches('greeting', (session)=>{
session.send('You reached Greeting intent, you said \'%s\'.', session.message.text);
}).onDefault((session)=>{
session.send('Sorry, I did not understand \'%s\'.', session.message.text);
});
tokenhandler
的代码是这样的:
var request = require('request');
var token = "";
var tokeninterval;
var TRANSLATIONKEY = 'YOUR-KEY';
function getToken() {
var options = {
method: 'POST',
url: 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key=' + TRANSLATIONKEY
};
request(options, function (error, response, body){
//Check for error
if(error){
return console.log('Error:', error);
} else if(response.statusCode !== 200){
return console.log('Invalid Status Code Returned:', response.statusCode);
} else {
//Token gets returned as string in the body
token = body;
}
});
interval = setTimeout(getToken, 540000); // runs once every 9 minutes, token lasts for 10
}
// Stop the token generation
function stopInterval() {
clearTimeout(tokeninterval);
}
module.exports = {
init: function() {
getToken();
},
stop: function() {
stopInterval();
},
token: function () {
return token;
}
};
此演示适用于我的一方,但对于您的演示,如果您想使用receive
中设置的区域设置,您可以在我的代码中直接定义类似FROMLOCALE
的变量,设置receive
中的值,并在send
中使用此变量。
如果我误解了您的要求,请随时告诉我。