语音服务令牌时长延长问题

问题描述 投票:0回答:1

我需要保持一个语音服务的长期活力。语音服务默认为10分钟,因此需要延长服务时间。因此需要延长服务时间。我想了以下几种方法。1-用户令牌生成参数,允许其持续时间延长。2-在我的代码中捕捉到令牌到期异常,并请求新的令牌留白,迫使我的机器人重新启动。不过还没有找到解决方案。我的机器人应用程序总是在 failed: HTTP Authentication failed; no valid credentials available 代币过期后的消息。这是我的机器人代码。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>FTD Bit_Bot</title>
</head>
<body style="background-color: #fff; background-image: url('img/FTDBackground.jpg');">
    <div id="chatbot" role="main"
         data-cb-width="320px"
         data-cb-height="400px"
         data-cb-border="1px solid #ededed"
         data-cb-border-radius="0px"
         data-cb-background-color="white"
         data-cb-position="fixed"
         data-cb-right="40px"
         data-cb-bottom="100px"
         data-cb-zIndex="1"
         data-cb-bubble-background="rgba(217, 217, 217, 0.15)"
         data-cb-bubble-from-user-background="#e22e2c"
         data-cb-bubble-from-user-text-color="white"
         data-cb-bubble-max-width="600"
         data-cb-bot-avatar-image="http://demo.radical-thinking.net/bella/microsoft/chat-assets/img/Chat-in-day-Workshop-Icon.png"
         data-cb-hide-send-box="false"
         data-cb-hide-upload-button="true"
         data-cb-send-box-button-color="#e22e2c"
         data-cb-send-box-button-color-on-disabled="#CCC"
         data-cb-send-box-button-color-on-focus="#333"
         data-cb-send-box-button-color-on-hover="#333"
         data-cb-send-box-height="30"
         data-cb-suggested-action-text-color="black"
         data-cb-suggested-action-border="solid 2px #e22e2c"
         data-cb-suggested-action-height="30">
    </div>
    <!-- Include ajax library for speech service token request call -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <!-- Include webchat client functionality (https://github.com/Microsoft/BotFramework-WebChat) -->
    <!-- Change to the latest directory to stop the 'No renderer for this activity' error. However the avatar won't show -->
    <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js" charset="utf-8"></script>
    <script>
        var chatbot = document.getElementById('chatbot');

        // Style modifications
        const styleOptions = {

            // Colors
            bubbleBackground: chatbot.dataset.cbBubbleBackground,
            bubbleFromUserBackground: chatbot.dataset.cbBubbleFromUserBackground,
            bubbleFromUserTextColor: chatbot.dataset.cbBubbleFromUserTextColor,
            bubbleMaxWidth: parseInt(chatbot.dataset.cbBubbleMaxWidth), // maximum width of text message

            // Avatar
            botAvatarImage: chatbot.dataset.cbBotAvatarImage,
            userAvatarInitials: '',

            // Send box
            hideSendBox: JSON.parse(chatbot.dataset.cbHideSendBox),
            hideUploadButton: JSON.parse(chatbot.dataset.cbHideUploadButton),
            sendBoxButtonColor: chatbot.dataset.cbSendBoxButtonColor,
            sendBoxButtonColorOnDisabled: chatbot.dataset.cbSendBoxButtonColorOnDisabled,
            sendBoxButtonColorOnFocus: chatbot.dataset.cbSendBoxButtonColorOnFocus,
            sendBoxButtonColorOnHover: chatbot.dataset.cbSendBoxButtonColorOnHover,
            sendBoxHeight: parseInt(chatbot.dataset.cbSendBoxHeight),

            // Suggested actions
            suggestedActionTextColor: chatbot.dataset.cbSuggestedActionTextColor,
            suggestedActionBorder: chatbot.dataset.cbSuggestedActionBorder,
            suggestedActionHeight: parseInt(chatbot.dataset.cbSuggestedActionHeight),

        }
    </script>
    <script>
        var chatbot = document.getElementById("chatbot");

        //style tag start
        var script = {
            id: 'chatbotStyle',
            type: 'text/css',
            style: document.createElement('style'),
            content: '@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,600"); ::-webkit-scrollbar{width:10px}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#555} #chatbot{ font-family: Roboto, sans-serif; font-weight: 400; position: fixed; right: 10px; bottom: 20px; text-align: center; } #chatbot img{ margin: auto; } #chatbot small{ display: block; font-size: 9px; } .initLaunchPad{ cursor: pointer; text-align: center; transition: .4s all; } .botHeader{min-height:40px;background:#ededed;border-radius:6px 6px 0 0;display:flex;justify-content:space-between;align-items:center;padding:4px} .botHeader img{float:left;width:32px;height:32px; border-radius:50%;background-color:#f9f9f9}.botHeader h5{float:left;padding:0!important;margin:4px 0 3px 6px} .botHeader h5 small{font-size: 12px;} .botHeader > div{width:40%;display:flex;align-items:center;text-align:left;height:32px} #botClose{cursor:pointer;font-size:12px;font-weight:600;padding:6px 8px;border-radius:4px;background-color:#e22e2c;color:#fff; } #botContainer{ display: none; border-radius: 8px; border:1px solid #cbcbcb; transition:.4s all; width: 310px; height: 420px; max-width:420px; max-height: 420px; margin-bottom: 4px; } #botBody{ height: 366px; } ',
            append: function () {
                this.style.type = this.type;
                this.style.appendChild(document.createTextNode(this.content));
                document.head.appendChild(this.style);
            }
        }; script.append();
        //style tag end

        //initLaunchPad started
        var initLaunchPad = document.createElement('div');
        initLaunchPad.classList.add('initLaunchPad');
        var initBotIcon = document.createElement('img');
        initBotIcon.src = "https://farm5.staticflickr.com/4876/39891228293_13c532f352_o.gif";
        initBotIcon.width = 86;
        initLaunchPad.appendChild(initBotIcon);
        chatbot.appendChild(initLaunchPad);

        $(function getSpeechAuthToken() {
            var params = {
                // Request parameters
            };

            $.ajax({
                url: "https://brazilsouth.api.cognitive.microsoft.com/sts/v1.0/issuetoken" + $.param(params),
                beforeSend: function (xhrObj) {
                    // Request headers
                    xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", "XXXXXX");
                },
                type: "POST",
                // Request body
                data: "{body}",
            })
                .done(function (data) {
                    speechAuthToken = data;
                })
                .fail(function () {
                    alert("error");
                });
        });
        initBotIcon.addEventListener('click', function (e) {
            e.preventDefault();
            initLaunchPad.style.display = "none";
            botContainer.style.display = "block";

            /*Call bot API*/
            (async function () {

                const searchParams = new URLSearchParams(window.location.search);

                //Speech Service Token Generation
                const subscriptionKey = 'XXXXXX';
                const region = 'brazilsouth';
                let webSpeechPonyfillFactory;

                //Speech Service Setting
                webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
                    credentials: {
                        authorizationToken: speechAuthToken,
                        region: region
                    }
                });

                //Direct-Line BotToken Generation
                const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { method: 'POST', headers: { Authorization: 'Bearer ' + 'XXXXXX' } });
                const { token } = await res.json();

                window.WebChat.renderWebChat({
                    directLine: window.WebChat.createDirectLine({ token }),
                    store,
                    userID: "User",
                    styleOptions,
                    locale: 'pt-BR',
                    selectVoice: (voices, activity) =>
                        activity.locale === 'pt-BR'
                            ? voices.find(({ name }) => /Daniel/iu.test(name))
                            : voices.find(({ name }) => /Daniel/iu.test(name)) ||
                            voices.find(({ name }) => /Daniel/iu.test(name)),
                    webSpeechPonyfillFactory
                }, document.getElementById('botBody'));
                document.querySelector('#botBody > *').focus();

                var mainTag = chatbot.getElementsByClassName('main')[0];
                mainTag.style.borderTop = chatbot.dataset.cbBorder;
            })().catch(err => console.error(err));

            //Bot Message Exchange Setting 
            const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
                if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
                    dispatch({
                        type: 'WEB_CHAT/SEND_EVENT',
                        payload: {
                            name: 'userName',
                            value: Paul
                        }
                    });                    
                }
                return next(action);
            });

        //initLaunchPad ended

        var botContainer = document.createElement('div');
        botContainer.id = "botContainer";

        var botHeader = document.createElement('div');
        botHeader.classList.add('botHeader');

        var botClose = document.createElement('a');
        botClose.id = "botClose";
        botClose.innerText = "X";
        botClose.title = "Close";
        botHeader.innerHTML = "<div><img src='" + chatbot.dataset.cbBotAvatarImage + "'/> <h5>Bit_Bot <small>FTD Educação</small> </div></h5>";
        botHeader.appendChild(botClose);

        botClose.addEventListener('click', function (e) {
            e.preventDefault();
            initLaunchPad.style.display = "";
            botContainer.style.display = "none";
            return false;
        });

        botContainer.appendChild(botHeader);

        var botBody = document.createElement('div');
        botBody.id = "botBody";
        botContainer.appendChild(botBody);

        var poweredBy = document.createElement('div');
        poweredBy.innerHTML = "<small>Powered by <img src='http://ainetw.com/img/icon.png' width=12 /> AI Networks</small>";

        chatbot.appendChild(botContainer);
        chatbot.appendChild(poweredBy);
    </script>
</body>
</html>

我未能成功地在代码的以下部分捕捉到这个错误。1) 在语音服务设置中。

 //Speech Service Setting
        try {
           webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
           credentials: {
               authorizationToken: speechAuthToken,
               region: region
           }
        });
        } catch (error) {
            console.log('Error Speech Service');
            console.log(error);
            //Refreshes token
            getSpeechAuthToken();
            webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
                credentials: {
                    authorizationToken: speechAuthToken,
                    region: region
                }
            });
        }

2) 在Webchat设置中。

window.WebChat.renderWebChat({
            directLine: window.WebChat.createDirectLine({ token }),
            store,
            //userID: "Randomly Generated by the Webchat",
            styleOptions,
            locale: 'pt-BR',
            selectVoice: (voices, activity) =>
                activity.locale === 'pt-BR'
                    ? voices.find(({ name }) => /Daniel/iu.test(name))
                    : voices.find(({ name }) => /Daniel/iu.test(name)) ||
                    voices.find(({ name }) => /Daniel/iu.test(name)),
            webSpeechPonyfillFactory
        }, document.getElementById('botBody'));
        document.querySelector('#botBody > *').focus();

        var mainTag = chatbot.getElementsByClassName('main')[0];
        mainTag.style.borderTop = chatbot.dataset.cbBorder;
    })().catch(err =>
        {
            console.log('Error Webchat');
        console.log(error);
        //Refreshes token
        getSpeechAuthToken();
            if (err && err.status === 401) {
                speechAuthToken = speechAuthToken();
                webSpeechPonyfillFactory = window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
                    credentials: {
                        authorizationToken: speechAuthToken,
                        region: region
                    }
                 });
            }
        }
    );

我们如何避免令牌过期的问题? 谢谢

botframework speech
1个回答
0
投票

从认知服务的语音服务 文件,

每个访问令牌的有效期为10分钟。你可以在任何时候获得一个新的令牌,但是,为了最大限度地减少网络流量和延迟,我们建议在9分钟内使用同一个令牌。

在我的设置中,我在本地运行一个 "令牌 "服务器(也可以部署),运行Restify,我通过它进行各种生成令牌的API服务调用。在Restify令牌服务器中,我设置了自己的API,我可以从Web Chat中调用。当我调用我的令牌服务器API时,服务API被调用,获取令牌,并将其返回给Web Chat。

这样一来,我一下子解决了两个问题。一,我的服务的秘密在服务器端是安全的;二,我可以在服务器端设置一个 setInterval() 在令牌过期前调用Web Chat中的API。


tokenServer.js

const path = require('path');
const restify = require('restify');
const request = require('request');

const bodyParser = require('body-parser');
const corsMiddleware = require('restify-cors-middleware');

const cors = corsMiddleware({
    origins: ['*']
});

const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });

// Create HTTP server.
const server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.use(bodyParser.json({
    extended: false
}));

server.post('/speechservices/token', async (req, res) => {
    const options = {
        // method: 'POST',
        uri: `https://${ process.env.SPEECH_SERVICES_REGION }.api.cognitive.microsoft.com/sts/v1.0/issueToken`,
        headers: {
            'Ocp-Apim-Subscription-Key': process.env.SPEECH_SERVICES_SUBSCRIPTION_KEY
        }
    };
    request.post(options, (error, response, body) => {
        if (!error && response.statusCode < 300) {
            body = { region: process.env.SPEECH_SERVICES_REGION, authorizationToken: body };
            res.send({
                authorizationToken: body.authorizationToken,
                region: body.region
            });
            console.log(`Someone requested a speech token...(${ response.statusCode })`);
        } else if (response.statusCode >= 400 && response.statusCode < 500) {
            res.send({ statusCode: response.statusCode, error: "CS's speech token API returned error" });
        } else if (response.statusCode >= 500) {
            res.status(response.statusCode);
            res.send({ statusCode: response.statusCode, error: "CS's speech token API couldn't be reached" });
        }
    });
});

网络聊天 - 我在服务端设置了区域值,用令牌返回即可。

setInterval(() => {
  const fetchPromise =  fetch( 
  `http://localhost:3500/speechservices/token`, { method: 'POST' } );

  return fetchPromise.then(async res => {
    if ( res.status === 200 ) {
      const { authorizationToken, region, error: error } = await res.json();
      credentials['authorizationToken'] = authorizationToken;
      credentials['region'] = region;

      return credentials;
    } else {
      console.log( `Speech Services: ${ error }` )
    }
  });
}, 540000); // Is set to 9 minutes

希望能得到帮助

© www.soinside.com 2019 - 2024. All rights reserved.