microsoft/BotFramework-DirectLineJS

How to capture DirectLine token refresh? Re ask of issue 302

scch1002 opened this issue · 4 comments

Hi,

I have a few questions related to the design of directline; related to the issue #302

  1. If DirectLine is automatically sending a request to refresh the token every 15 minutes then why is an additional custom endpoint and interval function necessary for refreshing tokens in webchat? From what I can tell, this would result in two separate calls occurring at roughly the same time. Also, from what I can tell there is no way to disable the token refresh feature of DirectLine. #302 (comment)

  2. Why is there no way to retrieve the refreshed token? The inability to retrieve the refreshed token severely limits the usability of DirectLineJs. What happens if the DirectLine object has to be reconstructed 30 minutes into the middle of a conversation? There is no way to reconnect to the conversation without calling to refresh the token manually. Which would result in a consist double call to the directline refresh endpoint every 15 minutes. The original token used to instantiate the directline object expires after 15 minutes, so that can't be used either.

Conclusion
The refreshed token should be made available through some form of subscription or callback. This would work similar to activity$ and connectionStatus$.

connectionStatus$: BehaviorSubject<ConnectionStatus>,

Or expose the token variable through a public property.

private token: string;

Another solution to this design issue; is to add a feature toggle for auto refreshing of the token through directline. This would allow for the implementation of third-party refresh logic without having a double call to the directline refresh endpoint.

Last Remark
The preferable solution, is to expose the refreshed token through a subscription; following the general design of directline.

@stevkan Can you take a look at this please?

@scch1002,

If DirectLine is automatically sending a request to refresh the token every 15 minutes then why is an additional custom endpoint and interval function necessary for refreshing tokens in webchat?

You are right. There have been improvements made to Web Chat, in this area, that I hadn't picked up on. At one point, the solution I presented was of use and can still prove useful to people wanting a bit more control. However, in some recent testing, I have verified that the token does get refreshed automatically without any additional calls having to be made nor the need for an interval function.

Also, from what I can tell there is no way to disable the token refresh feature of Direct Line.

Are you looking for a way to expire a conversation after a set amount of time? Or, are you wondering for some other reason?

Why is there no way to retrieve the refreshed token?

I'm investigating a possible method. Unsure if it will prove fruitful, but will keep you updated.

@stevkan do you have any updates on this issue?

@scch1002, thank you for your patience. When creating a Direct Line object, you can capture both the original and any refreshed tokens as they are generated by assigning the returned value to a variable. In the case of Web Chat, you can do the same with the returned value of createDirectLine().

In this example, I am running a "token server" that exchanges a Direct Line secret for a token. I also set the interval to check every 10 mins (600000 ms).

const res = await fetch( 'http://localhost:3500/directline/conversations', { method: 'POST' } );
const { token } = await res.json();

const directLine = window.WebChat.createDirectLine( {
  token
} )
sessionStorage.setItem( 'token', directLine.token );

setInterval( () => {
  let previousToken = sessionStorage.getItem( 'token');
  let newToken = directLine.token;
  if ( newToken !== previousToken ) {
    console.log( 'PREVIOUS TOKEN', previousToken );
    console.log( 'REFRESHED TOKEN ', newToken );
    sessionStorage.setItem( 'token', newToken );
  }
}, 600000 );

Console logged results

PREVIOUS TOKEN ew0KI...RL2nQ

REFRESHED TOKEN ew0KI...ADMEA