export default async function create()

in packages/directlinespeech/src/createAdapters.js [20:257]


export default async function create({
  audioConfig,
  audioContext,
  audioInputDeviceId,
  enableInternalHTTPSupport,
  enableTelemetry,
  fetchCredentials,
  speechRecognitionEndpointId,
  speechRecognitionLanguage = (typeof window !== 'undefined' &&
    typeof window.navigator !== 'undefined' &&
    window.navigator.language) ||
    'en-US',
  speechSynthesisDeploymentId,
  speechSynthesisOutputFormat,
  textNormalization,
  userID,
  username
}) {
  if (!fetchCredentials) {
    throw new Error('"fetchCredentials" must be specified.');
  }

  const { authorizationToken, directLineToken, directLineSpeechHostname, region, subscriptionKey } =
    await resolveFunctionOrReturnValue(fetchCredentials);

  if (
    (!authorizationToken && !subscriptionKey) ||
    (authorizationToken && subscriptionKey) ||
    (authorizationToken && typeof authorizationToken !== 'string') ||
    (subscriptionKey && typeof subscriptionKey !== 'string') ||
    (enableInternalHTTPSupport && !directLineToken)
  ) {
    throw new Error(
      '"fetchCredentials" must return either "authorizationToken" or "subscriptionKey" as a non-empty string only. If enableInternalHTTPSupport is set to true, then it should also return a non-empty "directLineToken"'
    );
  }

  if (typeof enableTelemetry !== 'undefined') {
    console.warn(
      'botframework-directlinespeech: Telemetry options are not yet supported. Please refer to Cognitive Services documentation for details.'
    );
  }

  if ((directLineSpeechHostname && region) || (!directLineSpeechHostname && !region)) {
    throw new Error(
      '"fetchCredentials" must return either "directLineSpeechHostname" or "region" and it must not be an empty string.'
    );
  }

  if (directLineSpeechHostname) {
    if (typeof directLineSpeechHostname !== 'string') {
      throw new Error('"fetchCredentials" must return "directLineSpeechHostname" as a string.');
    }

    if (enableInternalHTTPSupport) {
      throw new Error(
        '"fetchCredentials" must not return "directLineSpeechHostname" if "enableInternalHTTPSupport" is set.'
      );
    }
  } else {
    if (typeof region !== 'string') {
      throw new Error('"fetchCredentials" must return "region" as a string.');
    }
  }

  if (audioConfig && audioInputDeviceId) {
    console.warn(
      'botframework-directlinespeech-sdk: Only "audioConfig" or "audioInputDeviceId" can be specified, but not both; ignoring "audioInputDeviceId".'
    );
  } else if (!audioConfig) {
    if (audioInputDeviceId) {
      audioConfig = AudioConfig.fromMicrophoneInput(audioInputDeviceId);
    } else {
      audioConfig = AudioConfig.fromDefaultMicrophoneInput();
    }
  }

  if (speechRecognitionEndpointId) {
    console.warn(
      'botframework-directlinespeech: Custom Speech is currently not supported; ignoring "speechRecognitionEndpointId".'
    );
  }

  if (speechSynthesisDeploymentId) {
    console.warn(
      'botframework-directlinespeech: Custom Voice is currently not supported; ignoring "speechSynthesisDeploymentId".'
    );
  }

  if (speechSynthesisOutputFormat) {
    console.warn(
      'botframework-directlinespeech: Synthesis output format is currently not supported; ignoring "speechSynthesisOutputFormat".'
    );
  }

  if (textNormalization) {
    console.warn(
      'botframework-directlinespeech: Text normalization is currently not supported; ignoring "textNormalization".'
    );
  }

  if (userID || username) {
    console.warn(
      'botframework-directlinespeech: Custom "userId" and "username" are currently not supported and are ignored.'
    );
  }

  let config;

  if (directLineSpeechHostname) {
    if (authorizationToken) {
      config = BotFrameworkConfig.fromHost(new URL(`wss://${directLineSpeechHostname}`));

      config.setProperty(PropertyId.SpeechServiceAuthorization_Token, authorizationToken);
    } else {
      config = BotFrameworkConfig.fromHost(new URL(`wss://${directLineSpeechHostname}`), subscriptionKey);
    }
  } else {
    if (authorizationToken) {
      config = BotFrameworkConfig.fromAuthorizationToken(authorizationToken, region);
    } else {
      config = BotFrameworkConfig.fromSubscription(subscriptionKey, region);
    }

    // If internal HTTP support is enabled, switch the endpoint to Direct Line on Direct Line Speech service.
    if (enableInternalHTTPSupport) {
      config.setProperty(
        PropertyId.SpeechServiceConnection_Endpoint,
        `wss://${encodeURI(region)}.convai.speech.microsoft.com/directline/api/v1`
      );

      config.setProperty(PropertyId.Conversation_Agent_Connection_Id, directLineToken);
    }
  }

  // Supported options can be found in DialogConnectorFactory.js.

  // Set the language used for recognition.
  config.setProperty(PropertyId.SpeechServiceConnection_RecoLanguage, speechRecognitionLanguage);

  // The following code sets the output format.
  // As advised by the Speech team, this API may be subject to future changes.
  // We are not enabling output format option because it does not send detailed output format to the bot, rendering this option useless.
  // config.setProperty(PropertyId.SpeechServiceResponse_OutputFormatOption, OutputFormat[OutputFormat.Detailed]);

  // Set the user ID for starting the conversation.
  userID && config.setProperty(PropertyId.Conversation_From_Id, userID);

  // Set Custom Speech and Custom Voice.
  // The following code is copied from C#, and it is not working yet.
  // https://github.com/Azure-Samples/Cognitive-Services-Direct-Line-Speech-Client/blob/master/DLSpeechClient/MainWindow.xaml.cs
  // speechRecognitionEndpointId && config.setServiceProperty('cid', speechRecognitionEndpointId, ServicePropertyChannel.UriQueryParameter);
  // speechSynthesisDeploymentId && config.setProperty(PropertyId.conversation_Custom_Voice_Deployment_Ids, speechSynthesisDeploymentId);

  const dialogServiceConnector = patchDialogServiceConnectorInline(new DialogServiceConnector(config, audioConfig));

  // Renew token per interval.
  if (authorizationToken) {
    const interval = setInterval(async () => {
      // #2660 If the connector has been disposed, we should stop renewing the token.

      // TODO: We should use a public implementation if Speech SDK has one related to "privIsDisposed".
      if (dialogServiceConnector.privIsDisposed) {
        clearInterval(interval);
      }

      const {
        authorizationToken,
        directLineSpeechHostname: nextDirectLineSpeechHostname,
        region: nextRegion
      } = await resolveFunctionOrReturnValue(fetchCredentials);

      if (!authorizationToken) {
        return console.warn(
          'botframework-directlinespeech-sdk: Renew token failed because "fetchCredentials" call returned no authorization token.'
        );
      }

      if (directLineSpeechHostname) {
        if (directLineSpeechHostname !== nextDirectLineSpeechHostname) {
          return console.warn(
            'botframework-directlinespeech-sdk: "directLineSpeechHostname" change is not supported for renewed token. Authorization token is not renewed.'
          );
        }
      } else {
        if (region !== nextRegion) {
          return console.warn(
            'botframework-directlinespeech-sdk: Region change is not supported for renewed token. Authorization token is not renewed.'
          );
        }
      }

      dialogServiceConnector.authorizationToken = authorizationToken; // eslint-disable-line require-atomic-updates
    }, TOKEN_RENEWAL_INTERVAL);
  }

  // Renew token per interval.
  if (enableInternalHTTPSupport) {
    const interval = setInterval(async () => {
      // #2660 If the connector has been disposed, we should stop renewing the token.

      // TODO: We should use a public implementation if Speech SDK has one related to "privIsDisposed".
      if (dialogServiceConnector.privIsDisposed) {
        clearInterval(interval);
      }

      const refreshedDirectLineToken = await refreshDirectLineToken(directLineToken);

      if (!refreshedDirectLineToken) {
        return console.warn(
          'botframework-directlinespeech-sdk: Renew token failed because call to refresh token Direct Line API did not return a new token.'
        );
      }

      config.setProperty(PropertyId.Conversation_Agent_Connection_Id, refreshedDirectLineToken);

      dialogServiceConnector.properties.setProperty(
        PropertyId.Conversation_Agent_Connection_Id,
        refreshedDirectLineToken
      );
      dialogServiceConnector.connect();
    }, DIRECT_LINE_TOKEN_RENEWAL_INTERVAL);
  }

  const directLine = new DirectLineSpeech({ dialogServiceConnector });

  const webSpeechPonyfillFactory = createWebSpeechPonyfillFactory({
    audioContext,
    enableTelemetry,
    recognizer: dialogServiceConnector,
    textNormalization
  });

  return {
    directLine,
    webSpeechPonyfillFactory
  };
}