From fd08a5d5dbde198f647ef3d8391dad6eac37c565 Mon Sep 17 00:00:00 2001 From: saridsa2 Date: Tue, 24 Mar 2026 15:22:19 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20Ozonetel=20token=20=E2=80=94=2010min=20c?= =?UTF-8?q?ache,=20invalidate=20on=20401,=20refresh=20on=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reduced token cache from 55min to 10min (Ozonetel expires in ~15min) - All API methods invalidate cached token on 401 response - Force-refresh token on CC agent login - Removed unused withTokenRetry wrapper Co-Authored-By: Claude Opus 4.6 (1M context) --- src/auth/auth.controller.ts | 5 +++++ src/ozonetel/ozonetel-agent.service.ts | 19 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 8e3494a..7c931b6 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -139,6 +139,11 @@ export class AuthController { // Lock session in Redis with IP await this.sessionService.lockSession(agentConfig.ozonetelAgentId, memberId, clientIp); + // Force-refresh Ozonetel API token on login + this.ozonetelAgent.refreshToken().catch(err => { + this.logger.warn(`Ozonetel token refresh on login failed: ${err.message}`); + }); + // Login to Ozonetel with agent-specific credentials const ozAgentPassword = process.env.OZONETEL_AGENT_PASSWORD ?? 'Test123$'; this.ozonetelAgent.loginAgent({ diff --git a/src/ozonetel/ozonetel-agent.service.ts b/src/ozonetel/ozonetel-agent.service.ts index 8267b1d..789d6e3 100644 --- a/src/ozonetel/ozonetel-agent.service.ts +++ b/src/ozonetel/ozonetel-agent.service.ts @@ -22,6 +22,10 @@ export class OzonetelAgentService { return this.cachedToken; } + return this.refreshToken(); + } + + async refreshToken(): Promise { const url = `https://${this.apiDomain}/ca_apis/CAToken/generateToken`; this.logger.log('Generating CloudAgent API token'); @@ -32,7 +36,7 @@ export class OzonetelAgentService { const data = response.data; if (data.token) { this.cachedToken = data.token; - this.tokenExpiry = Date.now() + 55 * 60 * 1000; + this.tokenExpiry = Date.now() + 10 * 60 * 1000; // 10 min cache (Ozonetel expires in ~15 min) this.logger.log('CloudAgent token generated successfully'); return data.token; } @@ -40,6 +44,12 @@ export class OzonetelAgentService { throw new Error(data.message ?? 'Token generation failed'); } + private invalidateToken(): void { + this.cachedToken = null; + this.tokenExpiry = 0; + } + + async loginAgent(params: { agentId: string; password: string; @@ -83,6 +93,7 @@ export class OzonetelAgentService { this.logger.log(`Agent login response: ${JSON.stringify(data)}`); return data; } catch (error: any) { + if (error?.response?.status === 401) this.invalidateToken(); this.logger.error(`Agent login failed: ${error.message}`); throw error; } @@ -111,10 +122,10 @@ export class OzonetelAgentService { 'Content-Type': 'application/json', }, }); - this.logger.log(`Manual dial response: ${JSON.stringify(response.data)}`); return response.data; } catch (error: any) { + if (error?.response?.status === 401) this.invalidateToken(); const responseData = error?.response?.data ? JSON.stringify(error.response.data) : ''; this.logger.error(`Manual dial failed: ${error.message} ${responseData}`); throw error; @@ -304,6 +315,7 @@ export class OzonetelAgentService { } return []; } catch (error: any) { + if (error?.response?.status === 401) this.invalidateToken(); this.logger.error(`Abandon calls failed: ${error.message}`); return []; } @@ -393,6 +405,7 @@ export class OzonetelAgentService { } return null; } catch (error: any) { + if (error?.response?.status === 401) this.invalidateToken(); this.logger.error(`Agent summary failed: ${error.message}`); return null; } @@ -422,6 +435,7 @@ export class OzonetelAgentService { } return '00:00:00'; } catch (error: any) { + if (error?.response?.status === 401) this.invalidateToken(); this.logger.error(`AHT failed: ${error.message}`); return '00:00:00'; } @@ -459,6 +473,7 @@ export class OzonetelAgentService { this.logger.log(`Agent logout response: ${JSON.stringify(response.data)}`); return response.data; } catch (error: any) { + if (error?.response?.status === 401) this.invalidateToken(); this.logger.error(`Agent logout failed: ${error.message}`); throw error; }