fix: Ozonetel token — 10min cache, invalidate on 401, refresh on login

- 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) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 15:22:19 +05:30
parent 2e4f97ff1a
commit fd08a5d5db
2 changed files with 22 additions and 2 deletions

View File

@@ -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({

View File

@@ -22,6 +22,10 @@ export class OzonetelAgentService {
return this.cachedToken;
}
return this.refreshToken();
}
async refreshToken(): Promise<string> {
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;
}