在bot.use中设置event.textLocale(Node.js Microsoft Bot Framework)

时间:2018-02-08 15:47:26

标签: node.js azure locale botframework

我使用的是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"); 
    }
});

1 个答案:

答案 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中使用此变量。

如果我误解了您的要求,请随时告诉我。