microsoft / BotFramework-WebChat

A highly-customizable web-based client for Azure Bot Services.
https://www.botframework.com/
MIT License
1.58k stars 1.53k forks source link

Need a way to stop webchat. #2835

Closed prashanthsridhar closed 4 years ago

prashanthsridhar commented 4 years ago

Feature Request

Is your feature request related to a problem? Please describe.

webchat.renderwebchat is being called multiple times. The result is that when the bot talks back,we can hear multiple voices. This is because there are multiple instances running at the same time.

Describe the suggestion or request in detail Need a webchat.disconnect() which de-allocates all resources held and stops the speech recognition/synthesis.

Additional context Using webchat.js 4.7.0 Using it in angular

stevkan commented 4 years ago

Can you please provide the code for your Angular html page? Be sure to hide any sensitive data before doing so.

prashanthsridhar commented 4 years ago

The code is spread across multiple files. The gist of it is: there is a bot icon,when clicked a bot component is activated and onInit of that component. RenderWebchat is inside onInit of that component.

window.WebChat.renderWebChat(
            {
                directLine: this.commonService.directLine,
                userID: sessionStorage.getItem('email'),
                username: sessionStorage.getItem('username'),
                locale: 'en-GB',
                //styleSet,
                styleOptions: this.commonService.styleOptions,
                groupTimestamp,
                selectVoice: () => ({ voiceURI: 'sample }),
                webSpeechPonyfillFactory: options => {
                    var { SpeechGrammarList, SpeechRecognition } = speechToTextPonyfillFactory(options);
                    var { speechSynthesis, SpeechSynthesisUtterance } = textToSpeechPonyfillFactory(options);
                    return {
                        SpeechGrammarList,
                        SpeechRecognition,
                        speechSynthesis,
                        SpeechSynthesisUtterance
                    };
                }

            },
            this.botWindowElement.nativeElement
        );

when close bot icon is clicked,i need a way to disconnect from bot.

Virtual-Josh commented 4 years ago

@stevkan can you provide an update on this ticket? Thanks.

stevkan commented 4 years ago

Hi @prashanthsridhar,

First, you will want to fix a single closing quote that is missing in the following line: selectVoice: () => ({ voiceURI: 'sample }).

Regarding the various parameters / variables (speechToTextPonyfillFactory, SpeechGrammarList, etc.) you include in webSpeechPonyfillFactory, are you able to post the definitions you are using for these? In order to repro the issue, I'd like to model my Web Chat setup as closely to your as is possible.

Also, would you be willing to post your package.json? Similar to the above, I want to match the installed packages as closely to yours as I can.

prashanthsridhar commented 4 years ago

Hi @stevkan Here is the package.json

{
  "name": "test",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "clean": "rm -rf dist",
    "hmr": "ng serve --configuration hmr",
    "ng": "ng",
    "start": "node --max_old_space_size=8048 ./node_modules/@angular/cli/bin/ng serve --configuration hmr --hmrWarning=false",
    "build": "node --max_old_space_size=20480 node_modules/@angular/cli/bin/ng build  --prod",
    "postbuild": "gulp compress",
    "dev": "lite-server",
    "build:ssr": "npm run build -- --app=ssr --output-hashing=media",
    "test": "ng test",
    "lint": "ng lint",
    "prod-build-prod": "ng build --prod=true  --configuration=production",
    "e2e": "ng e2e",
    "postinstall": "node patch.js"
  },
  "private": true,
  "dependencies": {
    "@angular-devkit/build-angular": "^0.803.21",
    "@angular/animations": "^8.2.14",
    "@angular/cdk": "^8.2.3",
    "@angular/common": "^8.2.14",
    "@angular/compiler": "^8.2.14",
    "@angular/core": "^8.2.14",
    "@angular/forms": "^8.2.14",
    "@angular/material": "^8.2.3",
    "@angular/platform-browser": "^8.2.14",
    "@angular/platform-browser-dynamic": "^8.2.14",
    "@angular/platform-server": "^8.2.14",
    "@angular/pwa": "^0.803.21",
    "@angular/router": "^8.2.14",
    "@angular/service-worker": "^8.2.14",
    "@aspnet/signalr": "^1.1.4",
    "@azure/msal-angular": "^0.1.4",
    "@nguniversal/express-engine": "^8.2.6",
    "@nguniversal/module-map-ngfactory-loader": "^8.2.6",
    "@ngxs/logger-plugin": "^3.6.0",
    "@ngxs/store": "^3.6.0",
    "@progress/kendo-angular-buttons": "^5.1.0",
    "@progress/kendo-angular-common": "^1.2.1",
    "@progress/kendo-angular-conversational-ui": "^2.0.0",
    "@progress/kendo-angular-dateinputs": "^4.2.0",
    "@progress/kendo-angular-dialog": "^4.1.0",
    "@progress/kendo-angular-dropdowns": "^4.2.3",
    "@progress/kendo-angular-editor": "^0.11.0",
    "@progress/kendo-angular-excel-export": "^3.1.0",
    "@progress/kendo-angular-grid": "^4.6.3",
    "@progress/kendo-angular-inputs": "^6.3.1",
    "@progress/kendo-angular-intl": "^2.0.0",
    "@progress/kendo-angular-l10n": "^2.0.1",
    "@progress/kendo-angular-label": "^2.0.2",
    "@progress/kendo-angular-layout": "^4.1.5",
    "@progress/kendo-angular-menu": "^2.0.1",
    "@progress/kendo-angular-notification": "2.0.0",
    "@progress/kendo-angular-pdf-export": "^2.0.0",
    "@progress/kendo-angular-popup": "^3.0.4",
    "@progress/kendo-angular-scheduler": "^1.1.1",
    "@progress/kendo-angular-scrollview": "^3.0.0",
    "@progress/kendo-angular-sortable": "3.0.1",
    "@progress/kendo-angular-toolbar": "^2.2.1",
    "@progress/kendo-angular-tooltip": "^2.1.1",
    "@progress/kendo-angular-upload": "^5.1.0",
    "@progress/kendo-data-query": "^1.5.2",
    "@progress/kendo-date-math": "^1.5.1",
    "@progress/kendo-drawing": "^1.6.0",
    "@progress/kendo-recurrence": "^1.0.0",
    "@progress/kendo-theme-bootstrap": "^4.8.0",
    "@progress/kendo-theme-default": "4.10.0",
    "@syncfusion/ej2": "^17.4.40",
    "@syncfusion/ej2-angular-buttons": "^17.4.39",
    "@syncfusion/ej2-angular-calendars": "^17.4.40",
    "@syncfusion/ej2-angular-circulargauge": "^17.4.39",
    "@syncfusion/ej2-angular-diagrams": "^17.4.40",
    "@syncfusion/ej2-angular-dropdowns": "^17.4.40",
    "@syncfusion/ej2-angular-grids": "^17.4.40",
    "@syncfusion/ej2-angular-inputs": "^17.4.39",
    "@syncfusion/ej2-angular-maps": "^17.4.40",
    "@syncfusion/ej2-angular-notifications": "^17.4.40",
    "@syncfusion/ej2-angular-splitbuttons": "^17.4.39",
    "@syncfusion/ej2-data": "^17.4.39",
    "@syncfusion/ej2-diagrams": "^17.4.40",
    "@syncfusion/ej2-inputs": "^17.4.39",
    "@syncfusion/ej2-maps": "^17.4.40",
    "@teachablemachine/image": "^0.8.4",
    "@tensorflow/tfjs": "^1.2.8",
    "@thisissoon/angular-image-loader": "^5.1.0",
    "@types/dom-mediacapture-record": "^1.0.2",
    "ajv": "^6.10.2",
    "angular-epic-spinners": "^2.0.0",
    "applicationinsights-js": "^1.0.20",
    "artyom.js": "^1.0.6",
    "aspnet-prerendering": "^3.0.1",
    "awesome-typescript-loader": "^5.2.1",
    "base-64": "^0.1.0",
    "bootstrap": "^4.4.1",
    "botframework-directlinejs": "^0.11.6",
    "compression-webpack-plugin": "^3.0.1",
    "core-js": "^3.6.3",
    "core-util-is": "^1.0.2",
    "ej-angular2": "17.4.39",
    "eslint": "^6.8.0",
    "guid-typescript": "^1.0.9",
    "gulp": "^4.0.2",
    "gulp-gzip": "^1.4.2",
    "gulp-sass": "^4.0.2",
    "hammerjs": "^2.0.8",
    "handtrackjs": "0.0.13",
    "html2canvas": "^1.0.0-rc.5",
    "html-to-text": "^5.1.1",
    "i": "^0.3.6",
    "image-to-base64": "^2.0.1",
    "increase-memory-limit": "^1.0.7",
    "install": "^0.13.0",
    "jquery": "^3.4.1",
    "jwt-decode": "^2.2.0",
    "lodash": "^4.17.15",
    "mat-progress-buttons": "^8.0.7",
    "metro4": "^4.3.4",
    "microsoft-cognitiveservices-speech-sdk": "1.8.1",
    "moment": "^2.24.0",
    "moment-timezone": "^0.5.27",
    "ng-artyom": "0.0.1-alpha",
    "ng-drag-drop": "^5.0.0",
    "ng2-search-filter": "^0.5.1",
    "ngx-color": "^4.1.0",
    "ngx-color-picker": "^8.2.0",
    "ngx-export-as": "^1.4.0",
    "ngx-moment": "^3.5.0",
    "ngx-pagination": "^5.0.0",
    "ngx-permissions": "^7.0.3",
    "ngx-pinch-zoom": "^2.2.4",
    "ngx-powerbi": "^2.0.0",
    "ngx-quicklink": "^0.1.5",
    "npm": "^6.13.4",
    "npm-check-updates": "^4.0.1",
    "observable-webworker": "^3.2.3",
    "offline-plugin": "^5.0.7",
    "popper.js": "^1.16.0",
    "popups": "^1.1.3",
    "powerbi-client": "^2.8.0",
    "purgecss-webpack-plugin": "^1.6.0",
    "qtip2": "^3.0.3",
    "recorder-js": "^1.0.7",
    "recordrtc": "^5.5.8",
    "rxjs": "^6.5.3",
    "rxjs-compat": "^6.5.3",
    "speak-tts": "^2.0.8",
    "survey-angular": "^1.1.26",
    "survey-creator": "^1.1.26",
    "surveyjs-widgets": "^1.1.26",
    "syncfusion-javascript": "17.4.39",
    "typescript": "~3.4.5",
    "uglifyjs-webpack-plugin": "^1.0.0-rc.0",
    "utf8": "^3.0.0",
    "uuid": "^3.3.3",
    "vis": "^4.21.0",
    "webpack": "^4.41.5",
    "webpack-bundle-analyzer": "^3.6.0",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.1",
    "yfiles": "./lib/es-modules/yfiles-22.0.3.tgz",
    "zone.js": "^0.10.2"
  },
  "devDependencies": {
    "@angular-builders/custom-webpack": "^8.4.1",
    "@angular/cli": "^8.3.21",
    "@angular/compiler-cli": "^8.2.14",
    "@angular/language-service": "^8.2.14",
    "@angularclass/hmr": "^2.1.3",
    "@ngxs/hmr-plugin": "^3.6.0",
    "@types/ej.web.all": "^17.3.2",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.8",
    "@types/jquery": "^3.3.31",
    "@types/lodash": "^4.14.149",
    "@types/node": "^12.12.22",
    "angular2-template-loader": "^0.6.2",
    "codelyzer": "^5.2.1",
    "css-loader": "^3.4.2",
    "guess-parser": "^0.4.12",
    "guess-webpack": "^0.4.12",
    "html-loader": "^0.5.5",
    "html-webpack-injector": "^1.1.2",
    "html-webpack-plugin": "^3.2.0",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.4.1",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "^2.1.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.5.1",
    "protractor": "~5.4.2",
    "scss-loader": "0.0.1",
    "style-loader": "^1.1.2",
    "to-string-loader": "^1.1.6",
    "ts-loader": "^6.2.1",
    "ts-node": "~8.5.4",
    "tslint": "^5.20.1",
    "webpack-dashboard": "^3.2.0"
  },
  "optionalDependencies": {
    "grunt-usemin": "^3.1.1",
    "http-server": "^0.6.1",
    "node-sass": "^4.13.0"
  },
  "browserslist": [
    "last 1 version",
    "> 1%",
    "maintained node versions",
    "not dead"
  ]
}
prashanthsridhar commented 4 years ago

@stevkan On further testing, i noticed that,for every input i give there is one activities call to /v3/directline/conversations and multiple calls to /cognitiveservices/v1

Additional info:

                                               directline           cognitiveservices
open bot once:                                   1                               1
close bot open again                             1                               2
close bot open again                             1                               3

and so on. Find screenshot below The renderWebchat function is listed in the first comment Capture

prashanthsridhar commented 4 years ago

Hi @compulim , is this something within the scope of how the cognitiveservices call is happening via webChat.

stevkan commented 4 years ago

@prashanthsridhar, I'm still unable to reproduce the issue. Furthermore, I'm not seeing any calls coming thru that match or even look similar to the ones you have identified up above (i.e. v1?deploymentId...). I'm inclined to think that there is some other process in your code that is resulting in those calls being made. I'm also inclined to think that these additional calls are interrupting your speech service from functioning properly, however it's hard for me to know since I can't see all of your code.

Can you check for any other processes that may be calling Cognitive Services? Or, can you provide any additional code (and the file it's living in) that is associated to Web Chat being implemented?

This is the code I'm using for connecting speech. It is taken from the 03.speech/g.hybrid-speech sample. You'll notice that the "README.md" file demonstrates how to pass the authorizationToken and region while the "index.html" file demonstrates how to pass credentials. As you can see, there aren't any "v1" calls being made.

image

prashanthsridhar commented 4 years ago

Hi @stevkan ,i am using custom speech and voice. I think the "v1?deploymentId" call is for custom speech.

const speechToTextPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
            // We are passing the Promise function to the authorizationToken field.
            // This function will be called every time the token is being used.
            subscriptionKey: 'blabla',
            region: 'westus2',
            speechRecognitionEndpointId: 'blabla',
        })
        const textToSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
            // We are passing the Promise function to the authorizationToken field.
            // This function will be called every time the token is being used.
            subscriptionKey: 'blabla',
            region: 'westus2',
            speechSynthesisDeploymentId: 'blabla'
        });

These are the ponyfills used in renderWebchat

prashanthsridhar commented 4 years ago

Hi @stevkan ,implementing webchat with angular and custom web speech will be ideal to reproduce this issue.

deena0211 commented 4 years ago

I am also facing a similar issue.

prashanthsridhar commented 4 years ago

Hi @stevkan please find sample to reproduce this issue here : https://github.com/prashanthsridhar/WebchatSample substitute the keys as required. Once you are on localhost,click the "click me" button, say hi,click on it again to hide the chat window. Follow this three times. The third time the reply will be hello voiced out three times Please feel free to get back with doubts/recommendation on the implementation

prashanthsridhar commented 4 years ago

Hi @stevkan ,any update on this issue?

stevkan commented 4 years ago

Hi @prashanthsridhar, I was able to repro using your code and I believe the issue is your inclusion of two properties that shouldn't be supplied.

In both speechToTextPonyfillFactory and textToSpeechPonyfillFactory you only need to pass in the subscriptionKey and region. If you look at the available properties able to be passed in (see here), you'll notice that neither speechRecognitionEndpointId nor speechSynthesisDeploymentId are listed.

As soon as I removed those two properties, keeping only subscriptionKey and region in each, speech worked without issue with no repeating API calls being made. The below screenshot is after following your repro steps.

image

Please remove the errant properties and try again. Hopefully, this will resolve the issue for you.

As this appears to have resolved the problem, I am going to close this issue. If the problem persists, please feel free to reopen.

prashanthsridhar commented 4 years ago

Hi @stevkan the link you provided has those properties as seen below

image

Moreover the issue exists even after removing those properties.

Please reopen the issue.