These are some, in-general I suggest to reach out to PS team who can help you better in setting up all these.
Original Message:
Sent: 06-17-2025 07:29
From: Arash Fattahi
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi @Ranjith Manikante Sai,
Thanks for your reply.
I have updated my JavaScript code based on your recommendation, but unfortunately, it didn't resolve the issue. The Messenger SDK still does not automatically refresh the JWT.
Please find below the screenshot I captured from my browser's console logs:
- Yellow Section: Opened my website for the very first time.
- Blue Section: Clicked the "Sign in" button on the Messenger and completed the authentication process.
- Red Section: The IdP redirected me back to the web page, the JavaScript code executed, and the Authenticated event appeared to trigger successfully. However, immediately afterward, the reAuthenticate command was triggered, initiating a second authentication process. What I expected was for the Messenger SDK to automatically refresh the JWT.
- Green Section: Same as the Yellow and Blue sections. The only difference was that I did not need to enter my credentials, and the authentication process was noticeably quicker.
I have also shared my JavaScript code for your reference.
Please note that the AuthProvider.publish('signInFailed') command is not required, as the second "Sign in" event is automatically triggered when the authCode is present.
Thanks.

console.log("GC Starting Authentication Process ...");let gc_jwt;let currentURL = window.location.origin + window.location.pathname;const authUrl = new URL("authEndpointURL");authUrl.searchParams.set("response_type", "code");authUrl.searchParams.set("response_mode", "query");authUrl.searchParams.set("client_id", "clientId");authUrl.searchParams.set("audience", "genesys");authUrl.searchParams.set("redirect_uri", currentURL);authUrl.searchParams.set("scope", "openid offline_access");let AuthorizationURL = decodeURIComponent(authUrl.toString());let authCode;let urlParams;urlParams = new URLSearchParams(window.location.search);authCode = urlParams.get("code");let authData = { authCode: authCode, redirectUri: currentURL,};Genesys('registerPlugin', 'AuthProvider', (AuthProvider) => { AuthProvider.registerCommand('signIn', (e) => { console.log("GC signIn command received."); if (authCode) { AuthProvider.registerCommand('getAuthCode', (e) => { console.log("GC getAuthCode called."); e.resolve(authData); }); e.resolve(authData); AuthProvider.publish('signedIn', authData); const originalPath = window.location.pathname; history.replaceState(null, '', originalPath); } else { console.log("GC no authCode is available."); window.location.href = AuthorizationURL; } }); AuthProvider.registerCommand('reAuthenticate', (e) => { console.log("GC reAuthenticate command received."); window.location.href = AuthorizationURL; e.resolve(); }); AuthProvider.subscribe('Auth.signedIn', () => { console.log("GC Messenger Auth.signedIn."); }); AuthProvider.subscribe('Auth.signInFailed', () => { console.log("GC Messenger Auth.signInFailed."); }); AuthProvider.subscribe('Auth.authenticated', () => { console.log("GC Messenger is authenticated"); }); AuthProvider.subscribe('Auth.error', () => { console.log("GC Messenger Auth.error."); AuthProvider.publish('signInFailed'); }); AuthProvider.subscribe('Auth.loggedOut', () => { console.log("GC Messenger is loggedOut."); }); AuthProvider.subscribe('Auth.logoutError', () => { console.log("GC Messenger Auth.logoutError."); }); AuthProvider.subscribe('Auth.signInAvailable', () => { console.log("GC Messenger signInAvailable."); }); AuthProvider.subscribe('Auth.signingIn', () => { console.log("GC Messenger is signingIn."); window.location.href = AuthorizationURL; }); AuthProvider.subscribe('Auth.tokenError', () => { console.log("GC Messenger Auth.tokenError."); }); AuthProvider.subscribe('Auth.authError', () => { console.log("GC Messenger Auth.authError."); AuthProvider.publish('signInFailed'); }); AuthProvider.subscribe('Auth.authenticating', () => { console.log("GC Messenger is Auth.authenticating."); }); AuthProvider.subscribe('Auth.authProviderError', () => { console.log("GC Messenger is Auth.authProviderError."); AuthProvider.publish('signInFailed'); }); console.log("GC AuthProvider ready."); AuthProvider.ready();});if (authCode) { Genesys('command', "AuthProvider.Signin");}
------------------------------
Arash Fattahi
Original Message:
Sent: 06-17-2025 01:21
From: Ranjith Manikante Sai
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi @Arash Fattahi,
Appreciate sharing the code. Looking at it, I'm seeing couple of things are incorrect.
- In your `AuthProvider.registerCommand('signIn')` command, under the else condition you must publish `AuthProvider.signInFailed` event. See documentation related to that here.
} else { console.log("GC no authCode is available."); AuthProvider.publish('signInFailed', <your auth error data>); }
- Your `AuthProvider.reAuthenticate` command, is not doing anything. It is simply resolving which is incorrect. It MUST call your login function, typically the one that you use when you hit the login button. See documentation for that here. Refer to the sample blueprint code here.
AuthProvider.registerCommand('reAuthenticate', (e) => { // This command will be called when current refreshToken and/or authCode are no more valid. User needs to re-login here to provide us new authCode and/or refreshToken. ndAuthLoginBtn.click(); // simulate the login click. e.resolve();});
- Please remove the below code that is incorrect. What it is doing is registering a command `Auth.refreshToken` that is not asked in our documentation.
AuthProvider.registerCommand('Auth.refreshToken', () => { console.log("GC Auth.refreshToken command received."); });
Hopefully these should resolve for you. If not, suggest to reach out to our care team who can assist further in setting this up for you.
Thanks,
Ranjith Sai
------------------------------
Ranjith Manikante Sai
Senior Manager, Development
Original Message:
Sent: 06-16-2025 18:52
From: Arash Fattahi
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi @Ranjith Manikante Sai,
Thanks for your reply.
- No. We use native Messenger UI.
- Yes.
- I believe I do. I have included my JavaScript code below.
With our Identity Provider (IdP), the access token and refresh token lifetimes are configured as follows:
- Access Token Lifetime: 60 minutes
- Refresh Token Maximum Lifetime: 30 days
As a result, and according to the Genesys, the effective lifetimes of the tokens generated by Genesys Cloud will be as follows:
- JWT (Access Token) Lifetime: 15 minutes
- Refresh Token Maximum Lifetime: 24 hours
Thanks.
console.log("GC Starting Authentication Process ...");function generateCodeVerifier() { const array = new Uint8Array(64); crypto.getRandomValues(array); return btoa(String.fromCharCode(...array)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');}async function generateCodeChallenge(codeVerifier) { const data = new TextEncoder().encode(codeVerifier); const digest = await crypto.subtle.digest("SHA-256", data); return btoa(String.fromCharCode(...new Uint8Array(digest))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');}(async () => { let currentURL = window.location.origin + window.location.pathname; console.log("GC Redirect URL: ", currentURL); const authUrl = new URL("authEndpointURL"); authUrl.searchParams.set("response_type", "code"); authUrl.searchParams.set("response_mode", "query"); authUrl.searchParams.set("client_id", "clientId"); authUrl.searchParams.set("redirect_uri", currentURL); authUrl.searchParams.set("scope", "openid"); authUrl.searchParams.set("code_challenge", codeChallenge ); authUrl.searchParams.set("code_challenge_method", "S256"); let AuthorizationURL = decodeURIComponent(authUrl.toString()); console.log("GC Authorisation URL: ", AuthorizationURL); let authCode; let urlParams; urlParams = new URLSearchParams(window.location.search); authCode = urlParams.get("code"); console.log('GC Authorisation Code: ', authCode); let authData = { authCode: authCode, redirectUri: currentURL, codeVerifier: localStorage.getItem('gc_codeVerifier'), }; Genesys('registerPlugin', 'AuthProvider', (AuthProvider) => { AuthProvider.registerCommand('signIn', (e) => { console.log("GC signIn command received."); if (authCode) { AuthProvider.registerCommand('getAuthCode', (e) => { console.log("GC getAuthCode called."); e.resolve(authData); }); e.resolve(authData); console.log("GC Publishing signedIn event."); AuthProvider.publish('signedIn', authData); const originalPath = window.location.pathname; history.replaceState(null, '', originalPath); } else { console.log("GC no authCode is available."); } }); AuthProvider.registerCommand('reAuthenticate', (e) => { console.log("GC reAuthenticate command received."); e.resolve(); }); AuthProvider.registerCommand('Auth.refreshToken', () => { console.log("GC Auth.refreshToken command received."); }); AuthProvider.subscribe('Auth.signedIn', (data) => { console.log("GC Messenger Auth.signedIn.",data); }); AuthProvider.subscribe('Auth.signInFailed', (data) => { console.log("GC Messenger Auth.signInFailed.",data); }); AuthProvider.subscribe('Auth.authenticated', (data) => { console.log("GC Messenger is authenticated",data); }); AuthProvider.subscribe('Auth.error', () => { console.log("GC Messenger Auth.error."); AuthProvider.publish('signInFailed'); }); AuthProvider.subscribe('Auth.loggedOut', () => { console.log("GC Messenger is loggedOut."); }); AuthProvider.subscribe('Auth.logoutError', () => { console.log("GC Messenger Auth.logoutError."); }); AuthProvider.subscribe('Auth.signInAvailable', () => { console.log("GC Messenger signInAvailable."); }); AuthProvider.subscribe('Auth.signingIn', () => { console.log("GC Messenger is signingIn."); window.location.href = AuthorizationURL; }); AuthProvider.subscribe('Auth.tokenError', () => { console.log("GC Messenger Auth.tokenError."); }); AuthProvider.subscribe('Auth.authError', () => { console.log("GC Messenger Auth.authError."); AuthProvider.publish('signInFailed'); }); AuthProvider.subscribe('Auth.authenticating', () => { console.log("GC Messenger is Auth.authenticating."); }); AuthProvider.subscribe('Auth.authProviderError', () => { console.log("GC Messenger is Auth.authProviderError."); AuthProvider.publish('signInFailed'); }); console.log("GC AuthProvider ready."); AuthProvider.ready(); }); if (authCode) { Genesys('command', "AuthProvider.Signin"); }})();
------------------------------
Arash Fattahi
Original Message:
Sent: 06-16-2025 12:24
From: Ranjith Manikante Sai
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi @Arash Fattahi
You don't need to do all this. If your refreshToken is valid, Messenger will automatically get new JWT.
Couple of questions:
- Are you using Headless Messenger SDK with your own UI or using our native Messenger UI?
- Do you have `Allow end-users to upgrade an anonymous session to authenticated conversation.` enabled in your Messenger configuration?
- Do you have all the needed AuthProvider commands written as documented here, including AuthProvider.reAuthenticate command?
When the current authCode or refresh token is expired, Messenger will automatically call your `AuthProvider.reAuthenticate` command which will trigger your login process to get new one. Please make sure to have your login process trigger in this command.
See sample code - https://developer.genesys.cloud/commdigital/digital/webmessaging/messengersdk/authenticatedMessenger
Blueprint code - https://github.com/GenesysCloudBlueprints/messenger-authentication-okta-integration-blueprint/blob/main/docs/oauth.html
Thanks,
Ranjith Sai
------------------------------
Ranjith Manikante Sai
Senior Manager, Development
Original Message:
Sent: 06-16-2025 05:09
From: Arash Fattahi
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi @Frederic Thomas,
Thanks for your reply.
According to the Genesy documentation:
When web messaging authentication is enabled and current refreshToken and/or authCode are no more valid, user can re-login with this command. Login action will be triggered on Auth.reAuthenticate to receive new authCode and/or refreshToken.
However, in my scenario, the refresh token is valid, and I am able to manually refresh the JWT using the following Genesys SDK command:
Genesys("subscribe", "Auth.ready", function() { console.log("GC Auth plugin is ready."); Genesys('command', "Auth.refreshToken", {}, function() {console.log("GC Messenger JWT has been refreshed");}, function() { console.log("GC Messenger JWT refresh failed!"); Genesys('command', "Auth.reAuthenticate"); } ); });
The issue I am trying to resolve is why the Messenger SDK does not automatically refresh the JWT?!
My intention is not to refresh the JWT manually or enforce the re-authentication, but to understand why the automatic refresh mechanism isn't working as expected.
Thanks.
------------------------------
Arash Fattahi
Original Message:
Sent: 06-16-2025 03:23
From: Frederic Thomas
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi Arash,
AFAIK you should use the reAuthenticate function . You mentionned this term in your original message but I am not sure you are using this function
more details on the auth plugin can be found here https://developer.genesys.cloud/commdigital/digital/webmessaging/messengersdk/SDKCommandsEvents/authProviderPlugin#authprovider-reauthenticate
There is also this blueprint app https://developer.genesys.cloud/blueprints/messenger-authentication-okta-integration-blueprint/
regards
------------------------------
Frederic Thomas
Senior Manager, Development
Original Message:
Sent: 06-15-2025 22:20
From: Arash Fattahi
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi @Nick Tait,
Thanks for your reply.
The question is not about why we're using a 5-minute lifetime for the access token - this aligns with common security best practices for short-lived tokens.
The current issue is that the Messenger JavaScript SDK does not automatically refresh the access token internally, contrary to what has been stated by Genesys.
Thanks.
Regards,
------------------------------
Arash Fattahi
Original Message:
Sent: 06-15-2025 20:52
From: Nick Tait
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi Arash.
The only idea I have is increasing the IDP's access token's lifespan. E.g. I believe that 60 minutes is commonly used for access tokens, so is there any reason why you are using one as short as 5 minutes?
Nick.
------------------------------
Nick Tait
Genesys Consultant
Original Message:
Sent: 06-13-2025 08:31
From: Arash Fattahi
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi Developer Community,
I would really appreciate any guidance, suggestions, or shared experiences that could help me troubleshoot and resolve the above issue.
Thanks.
------------------------------
Arash Fattahi
Original Message:
Sent: 06-06-2025 09:33
From: Arash Fattahi
Subject: Authenticated Web Messaging - JavaScript SDK & Genesys JWT
Hi Team,
I am reaching out to the community for feedback on the following:
Summary:
According to the official Genesys documentation:
"Unless revoked, the JWT is valid for 15 minutes (or the access token age, whichever is the smallest) and the refresh token is valid for 24 hours."
Therefore, in my Genesys Cloud Authenticated Web Messaging deployment, the Identity Provider (IdP) issues an access token with a 5-minute lifetime and a refresh token valid for 30 days. Regardless, Genesys Cloud generates its own tokens as follows:
- Genesys JWT: 5-minute lifetime
- Genesys Refresh Token: 24-hour lifetime
This means the SDK is expected to refresh the Genesys JWT every 5 minutes using the refresh token to maintain an authenticated session.
Problem:
Five minutes after successfully authenticating with the Genesys Cloud Web Messenger, the Genesys JWT expires. Assuming the SDK automatically renews the JWT using the refresh token, I would expect that refreshing the brand's web page or opening it in a new browser tab would preserve the authenticated session.
However, what I am observing instead is that the "Re-authenticate" pop-up appears in the Messenger widget, and the session becomes unresponsive.
I have been able to resolve the issue by capturing the Genesys JWT and using a JavaScript function to refresh it 100 milliseconds before it expires:
function scheduleRefresh(jwt) { const payload = JSON.parse(atob(jwt.split('.')[1])); const expiry = payload.exp * 1000; const now = Date.now(); const refreshBefore = 0.1 * 1000; // Refresh JWT 100ms before expiry const delay = expiry - now - refreshBefore; const timeUntilExpiry = Math.floor((expiry - now)/1000); console.log("GC JWT expires in", timeUntilExpiry, "seconds"); if (delay > 0) { setTimeout(() => { Genesys('command', "Auth.refreshToken", {}, function() {console.log("GC Messenger JWT has been refreshed");}, function() {console.log("GC Messenger JWT refresh failed!");} ); }, delay); }}
However, this is not an ideal solution. I would prefer that the SDK handles this automatically as part of its session management.
I would appreciate your thoughts and any input you may have on this.
Thanks.
#PlatformSDK
#WebMessaging
------------------------------
Arash Fattahi
------------------------------