Skip to content

Commit

Permalink
Update speech options to use credentials (#2759)
Browse files Browse the repository at this point in the history
* Update to latest fetch credentials signature

* Prettier

* Refactor

* Apply suggestions from code review

Co-Authored-By: Corina <14900841+corinagum@users.noreply.github.com>

Co-authored-by: Corina <14900841+corinagum@users.noreply.github.com>
  • Loading branch information
compulim and corinagum committed Jan 15, 2020
1 parent 6addf73 commit b9612d5
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 176 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixes [#2510](https://github.com/microsoft/BotFramework-WebChat/issues/2510). Host hybrid-react and clear-after-idle samples, by [@corinagum](https://github.com/corinagum) in PR [#2798](https://github.com/microsoft/BotFramework-WebChat/pull/2798)
- Fixes [#2772](https://github.com/microsoft/BotFramework-WebChat/issues/2772). Updated Adaptive Cards HostConfig to include container styles, by [@tdurnford](https://github.com/tdurnford) in PR [#28XX](https://github.com/microsoft/BotFramework-WebChat/pull/2810)
- Fixes [#2145](https://github.com/microsoft/BotFramework-WebChat/issues/2145). Updated Adaptive Cards styles to include action styles, by [@tdurnford](https://github.com/tdurnford) in PR [#2810](https://github.com/microsoft/BotFramework-WebChat/pull/2810)
- Fixes [#2459](https://github.com/microsoft/BotFramework-WebChat/issues/2459). Updated Cognitive Services Speech Services to use latest fetch credentials signature, by [@compulim](https://github.com/compulim) in PR [#2740](https://github.com/microsoft/BotFramework-WebChat/pull/2759)

### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { AudioConfig } from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig';
import createPonyfill from 'web-speech-cognitive-services/lib/SpeechServices';

async function resolveFunction(fnOrValue) {
return await (typeof fnOrValue === 'function' ? fnOrValue() : fnOrValue);
}

export default function createCognitiveServicesSpeechServicesPonyfillFactory({
audioConfig,
authorizationToken,
credentials,
enableTelemetry,
region,
speechRecognitionEndpointId,
Expand All @@ -12,6 +17,26 @@ export default function createCognitiveServicesSpeechServicesPonyfillFactory({
subscriptionKey,
textNormalization
}) {
if (!credentials && (authorizationToken || region || subscriptionKey)) {
console.warn(
'botframework-webchat: "authorizationToken", "region", and "subscriptionKey" are being deprecated and will be removed on or after 2020-12-17. Please use "credentials" instead.'
);

credentials = async () => {
if (authorizationToken) {
return {
authorizationToken: resolveFunction(authorizationToken),
region
};
} else {
return {
region,
subscriptionKey: resolveFunction(subscriptionKey)
};
}
};
}

// HACK: We should prevent AudioContext object from being recreated because they may be blessed and UX-wise expensive to recreate.
// In Cognitive Services SDK, if they detect the "end" function is falsy, they will not call "end" but "suspend" instead.
// And on next recognition, they will re-use the AudioContext object.
Expand All @@ -35,14 +60,12 @@ export default function createCognitiveServicesSpeechServicesPonyfillFactory({
return ({ referenceGrammarID }) => {
const ponyfill = createPonyfill({
audioConfig,
authorizationToken,
credentials,

This comment has been minimized.

Copy link
@HamdBilalTahir-PwC

HamdBilalTahir-PwC Jan 16, 2020

These credentials don't work

This comment has been minimized.

Copy link
@HamdBilalTahir-PwC

This comment has been minimized.

Copy link
@HamdBilalTahir-PwC

This comment has been minimized.

Copy link
@HamdBilalTahir-PwC
enableTelemetry,
referenceGrammars: [`luis/${referenceGrammarID}-PRODUCTION`],
region,
speechRecognitionEndpointId,
speechSynthesisDeploymentId,
speechSynthesisOutputFormat,
subscriptionKey,
textNormalization
});

Expand Down
25 changes: 8 additions & 17 deletions samples/03.speech/b.cognitive-speech-services-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,17 @@ Cognitive Services Speech Services has published a new API to provide speech rec
+ let lastPromise;
+
+ return () => {
+ if (Date.now() > expireAfter) {
+ const speechServicesTokenResPromise = fetch(
+ const now = Date.now();
+
+ if (now > expireAfter) {
+ expireAfter = now + 300000;
+ lastPromise = fetch(
+ 'https://webchat-mockbot.azurewebsites.net/speechservices/token',
+ { method: 'POST' }
+ );
+
+ expireAfter = Date.now() + 300000;
+ lastPromise = speechServicesTokenResPromise.then(
+ ).then(
+ res => res.json(),
+ err => {
+ lastPromise = null;
+ expireAfter = 0;
+
+ return Promise.reject(err);
+ }
Expand All @@ -82,22 +82,13 @@ Cognitive Services Speech Services has published a new API to provide speech rec
+ }
+
+ const fetchSpeechServicesCredentials = createFetchSpeechServicesCredentials();
+
+ async function fetchSpeechServicesRegion() {
+ return (await fetchSpeechServicesCredentials()).region;
+ }
+
+ async function fetchSpeechServicesToken() {
+ return (await fetchSpeechServicesCredentials()).token;
+ }

(async function () {
const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
const { token } = await res.json();

+ const webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
+ authorizationToken: fetchSpeechServicesToken,
+ region: await fetchSpeechServicesRegion()
+ credentials: fetchSpeechServicesCredentials
+ });

window.WebChat.renderWebChat({
Expand Down
32 changes: 10 additions & 22 deletions samples/03.speech/b.cognitive-speech-services-js/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,20 @@
let lastPromise;

return () => {
const now = Date.now();

// Fetch a new token if the existing one is expiring.
// The following article mentioned the token is only valid for 10 minutes.
// We will invalidate the token after 5 minutes.
// https://docs.microsoft.com/en-us/azure/cognitive-services/authentication#authenticate-with-an-authentication-token
if (Date.now() > expireAfter) {
const speechServicesTokenResPromise = fetch(
'https://webchat-mockbot.azurewebsites.net/speechservices/token',
{ method: 'POST' }
);

expireAfter = Date.now() + 300000;
lastPromise = speechServicesTokenResPromise.then(
if (now > expireAfter) {
expireAfter = now + 300000;
lastPromise = fetch('https://webchat-mockbot.azurewebsites.net/speechservices/token', {
method: 'POST'
}).then(
res => res.json(),
err => {
lastPromise = null;
expireAfter = 0;

return Promise.reject(err);
}
Expand All @@ -62,14 +61,6 @@

const fetchSpeechServicesCredentials = createFetchSpeechServicesCredentials();

async function fetchSpeechServicesRegion() {
return (await fetchSpeechServicesCredentials()).region;
}

async function fetchSpeechServicesToken() {
return (await fetchSpeechServicesCredentials()).token;
}

(async function() {
// In this demo, we are using Direct Line token from MockBot.
// Your client code must provide either a secret or a token to talk to your bot.
Expand All @@ -81,12 +72,9 @@

// Create the ponyfill factory function, which can be called to create a concrete implementation of the ponyfill.
const webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
// We are passing the Promise function to the authorizationToken field.
// We are passing the Promise function to the "credentials" field.
// This function will be called every time the token is being used.
authorizationToken: fetchSpeechServicesToken,

// In contrast, we are only fetching the region once.
region: await fetchSpeechServicesRegion()
credentials: fetchSpeechServicesCredentials
});

// Pass a Web Speech ponyfill factory to renderWebChat.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,20 @@
let lastPromise;

return () => {
const now = Date.now();

// Fetch a new token if the existing one is expiring.
// The following article mentioned the token is only valid for 10 minutes.
// We will invalidate the token after 5 minutes.
// https://docs.microsoft.com/en-us/azure/cognitive-services/authentication#authenticate-with-an-authentication-token
if (Date.now() > expireAfter) {
const speechServicesTokenResPromise = fetch(
'https://webchat-mockbot.azurewebsites.net/speechservices/token',
{ method: 'POST' }
);

expireAfter = Date.now() + 300000;
lastPromise = speechServicesTokenResPromise.then(
if (now > expireAfter) {
expireAfter = now + 300000;
lastPromise = fetch('https://webchat-mockbot.azurewebsites.net/speechservices/token', {
method: 'POST'
}).then(
res => res.json(),
err => {
lastPromise = null;
expireAfter = 0;

return Promise.reject(err);
}
Expand All @@ -62,14 +61,6 @@

const fetchSpeechServicesCredentials = createFetchSpeechServicesCredentials();

async function fetchSpeechServicesRegion() {
return (await fetchSpeechServicesCredentials()).region;
}

async function fetchSpeechServicesToken() {
return (await fetchSpeechServicesCredentials()).token;
}

(async function() {
// In this demo, we are using Direct Line token from MockBot.
// Your client code must provide either a secret or a token to talk to your bot.
Expand All @@ -81,12 +72,9 @@

// Create the ponyfill factory function, which can be called to create a concrete implementation of the ponyfill.
const webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
// We are passing the Promise function to the authorizationToken field.
// We are passing the Promise function to the "credentials" field.
// This function will be called every time the token is being used.
authorizationToken: fetchSpeechServicesToken,

// In contrast, we are only fetching the region once.
region: await fetchSpeechServicesRegion(),
credentials: fetchSpeechServicesCredentials,
textNormalization: 'lexical'
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,17 @@ Here is the finished `index.html`:
let lastPromise;

return () => {
if (Date.now() > expireAfter) {
const speechServicesTokenResPromise = fetch(
const now = Date.now();

if (now > expireAfter) {
expireAfter = now + 300000;
lastPromise = fetch(
'https://webchat-mockbot.azurewebsites.net/speechservices/token',
{ method: 'POST' }
);

expireAfter = Date.now() + 300000;
lastPromise = speechServicesTokenResPromise.then(
).then(
res => res.json(),
err => {
lastPromise = null;
expireAfter = 0;

return Promise.reject(err);
}
Expand All @@ -135,14 +135,6 @@ Here is the finished `index.html`:

const fetchSpeechServicesCredentials = createFetchSpeechServicesCredentials();

async function fetchSpeechServicesRegion() {
return (await fetchSpeechServicesCredentials()).region;
}

async function fetchSpeechServicesToken() {
return (await fetchSpeechServicesCredentials()).token;
}

(async function() {
const directLineTokenRes = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', {
method: 'POST'
Expand All @@ -151,15 +143,13 @@ Here is the finished `index.html`:
const { token } = await directLineTokenRes.json();

- const webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
- authorizationToken: fetchSpeechServicesToken,
- region: await fetchSpeechServicesRegion()
- credentials: fetchSpeechServicesCredentials
- });

+ async function createSpeechRecognitionOnlyPonyfillFactory() {
+ const speechServicesPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory(
+ {
+ authorizationToken: fetchSpeechServicesToken,
+ region: await fetchSpeechServicesRegion()
+ credentials: fetchSpeechServicesCredentials
+ }
+ );
+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,20 @@
let lastPromise;

return () => {
const now = Date.now();

// Fetch a new token if the existing one is expiring.
// The following article mentioned the token is only valid for 10 minutes.
// We will invalidate the token after 5 minutes.
// https://docs.microsoft.com/en-us/azure/cognitive-services/authentication#authenticate-with-an-authentication-token
if (Date.now() > expireAfter) {
const speechServicesTokenResPromise = fetch(
'https://webchat-mockbot.azurewebsites.net/speechservices/token',
{ method: 'POST' }
);

expireAfter = Date.now() + 300000;
lastPromise = speechServicesTokenResPromise.then(
if (now > expireAfter) {
expireAfter = now + 300000;
lastPromise = fetch('https://webchat-mockbot.azurewebsites.net/speechservices/token', {
method: 'POST'
}).then(
res => res.json(),
err => {
lastPromise = null;
expireAfter = 0;

return Promise.reject(err);
}
Expand All @@ -62,14 +61,6 @@

const fetchSpeechServicesCredentials = createFetchSpeechServicesCredentials();

async function fetchSpeechServicesRegion() {
return (await fetchSpeechServicesCredentials()).region;
}

async function fetchSpeechServicesToken() {
return (await fetchSpeechServicesCredentials()).token;
}

(async function() {
// In this demo, we are using Direct Line token from MockBot.
// Your client code must provide either a secret or a token to talk to your bot.
Expand All @@ -87,12 +78,9 @@
// Create the ponyfill factory function, which can be called to create a concrete implementation of the ponyfill.
const speechServicesPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory(
{
// We are passing the Promise function to the authorizationToken field.
// We are passing the Promise function to the "credentials" field.
// This function will be called every time the token is used.
authorizationToken: fetchSpeechServicesToken,

// In contrast, we are only fetching the region once.
region: await fetchSpeechServicesRegion()
credentials: fetchSpeechServicesCredentials
}
);

Expand Down
Loading

0 comments on commit b9612d5

Please sign in to comment.