rez_core 2.2.250 → 2.2.252

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.2.250",
3
+ "version": "2.2.252",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -21,6 +21,7 @@ import { TwilioStrategy } from './strategies/sms/twilio.strategy';
21
21
  import { KnowlarityStrategy as KnowlaritySMSStrategy } from './strategies/sms/knowlarity.strategy';
22
22
  import { WhatsAppCloudStrategy } from './strategies/whatsapp/whatsapp-cloud.strategy';
23
23
  import { KnowlarityVoiceStrategy } from './strategies/telephone/knowlarity-voice.strategy';
24
+ import { OzonetelVoiceStrategy } from './strategies/telephone/ozonetel-voice.strategy';
24
25
 
25
26
  // New unified strategies
26
27
  import { OutlookStrategy } from './strategies/email/outlook.strategy';
@@ -73,6 +74,7 @@ import { WebhookController } from './controller/webhook.controller';
73
74
  KnowlaritySMSStrategy,
74
75
  WhatsAppCloudStrategy,
75
76
  KnowlarityVoiceStrategy,
77
+ OzonetelVoiceStrategy,
76
78
 
77
79
  // New unified strategies
78
80
  OutlookStrategy,
@@ -2,10 +2,14 @@ import { Injectable } from '@nestjs/common';
2
2
  import { BaseFactory } from './base.factory';
3
3
  import { CommunicationStrategy } from '../strategies/communication.strategy';
4
4
  import { KnowlarityStrategy as TelephoneKnowlarityStrategy } from '../strategies/telephone/knowlarity-multi.strategy';
5
+ import { OzonetelVoiceStrategy } from '../strategies/telephone/ozonetel-voice.strategy';
5
6
 
6
7
  @Injectable()
7
8
  export class TelephoneFactory implements BaseFactory {
8
- constructor(private knowlarityStrategy: TelephoneKnowlarityStrategy) {}
9
+ constructor(
10
+ private knowlarityStrategy: TelephoneKnowlarityStrategy,
11
+ private ozonetelVoiceStrategy: OzonetelVoiceStrategy,
12
+ ) {}
9
13
 
10
14
  createProvider(service: string, provider: string): CommunicationStrategy {
11
15
  const key = `${service.toLowerCase()}_${provider.toLowerCase()}`;
@@ -13,6 +17,8 @@ export class TelephoneFactory implements BaseFactory {
13
17
  switch (key) {
14
18
  case 'third_party_knowlarity':
15
19
  return this.knowlarityStrategy;
20
+ case 'third_party_ozonetel':
21
+ return this.ozonetelVoiceStrategy;
16
22
 
17
23
  default:
18
24
  throw new Error(
@@ -22,7 +28,10 @@ export class TelephoneFactory implements BaseFactory {
22
28
  }
23
29
 
24
30
  getSupportedCombinations(): Array<{ service: string; provider: string }> {
25
- return [{ service: 'THIRD_PARTY', provider: 'knowlarity' }];
31
+ return [
32
+ { service: 'THIRD_PARTY', provider: 'knowlarity' },
33
+ { service: 'THIRD_PARTY', provider: 'ozonetel' }
34
+ ];
26
35
  }
27
36
 
28
37
  validateCombination(service: string, provider: string): boolean {
@@ -455,6 +455,11 @@ export class CommunicationService {
455
455
  ? `Knowlarity Voice: ${configJson.callerNumber}`
456
456
  : 'Knowlarity voice number not configured';
457
457
 
458
+ case 'telephone_third_party_ozonetel':
459
+ return configJson?.userName
460
+ ? `Ozonetel Voice: ${configJson.userName}`
461
+ : 'Ozonetel voice not configured';
462
+
458
463
  // AWS SES configurations
459
464
  case 'email_api_aws-ses':
460
465
  case 'email_api_ses':
@@ -563,6 +568,14 @@ export class CommunicationService {
563
568
  hasApiSecret: !!configJson?.apiSecret,
564
569
  };
565
570
 
571
+ case 'telephone_third_party_ozonetel':
572
+ return {
573
+ userName: configJson?.userName,
574
+ agentID: configJson?.agentID,
575
+ campaignName: configJson?.campaignName,
576
+ hasApiKey: !!configJson?.apiKey,
577
+ };
578
+
566
579
  // AWS SES configurations
567
580
  case 'email_api_aws-ses':
568
581
  case 'email_api_ses':
@@ -0,0 +1,127 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import axios from 'axios';
3
+ import {
4
+ CommunicationResult,
5
+ CommunicationStrategy,
6
+ } from '../communication.strategy';
7
+
8
+ interface OzonetelVoiceConfig {
9
+ apiKey: string;
10
+ userName: string;
11
+ agentID: string;
12
+ campaignName: string;
13
+ }
14
+
15
+ @Injectable()
16
+ export class OzonetelVoiceStrategy implements CommunicationStrategy {
17
+ private readonly baseUrl = 'https://in1-ccaas-api.ozonetel.com';
18
+
19
+ async sendMessage(
20
+ to: string,
21
+ message: string,
22
+ config: OzonetelVoiceConfig,
23
+ ): Promise<CommunicationResult> {
24
+ if (!this.validateConfig(config)) {
25
+ return {
26
+ success: false,
27
+ provider: 'ozonetel',
28
+ service: 'THIRD_PARTY',
29
+ error: 'Invalid Ozonetel Voice configuration',
30
+ timestamp: new Date(),
31
+ };
32
+ }
33
+
34
+ try {
35
+ // First, get JWT token
36
+ const token = await this.generateToken(config);
37
+ if (!token) {
38
+ return {
39
+ success: false,
40
+ provider: 'ozonetel',
41
+ service: 'THIRD_PARTY',
42
+ error: 'Failed to generate Ozonetel authentication token',
43
+ timestamp: new Date(),
44
+ };
45
+ }
46
+
47
+ // Then make the manual dial call
48
+ const url = `${this.baseUrl}/ca_apis/AgentManualDial`;
49
+ await axios.post(
50
+ url,
51
+ {
52
+ userName: config.userName,
53
+ agentID: config.agentID,
54
+ campaignName: config.campaignName,
55
+ customerNumber: to,
56
+ UCID: true,
57
+ uui: message,
58
+ },
59
+ {
60
+ headers: {
61
+ 'Content-Type': 'application/json',
62
+ Authorization: `Bearer ${token}`,
63
+ apiKey: config.apiKey,
64
+ },
65
+ },
66
+ );
67
+
68
+ return {
69
+ success: true,
70
+ messageId: `ozonetel-voice-${Date.now()}`,
71
+ provider: 'ozonetel',
72
+ service: 'THIRD_PARTY',
73
+ timestamp: new Date(),
74
+ };
75
+ } catch (error) {
76
+ let errorMsg = 'Unknown error';
77
+ if (axios.isAxiosError(error)) {
78
+ errorMsg = error.response?.data?.message || error.message;
79
+ } else if (error instanceof Error) {
80
+ errorMsg = error.message;
81
+ }
82
+ return {
83
+ success: false,
84
+ provider: 'ozonetel',
85
+ service: 'THIRD_PARTY',
86
+ error: errorMsg,
87
+ timestamp: new Date(),
88
+ };
89
+ }
90
+ }
91
+
92
+ private async generateToken(
93
+ config: OzonetelVoiceConfig,
94
+ ): Promise<string | null> {
95
+ try {
96
+ const response = await axios.post(
97
+ `${this.baseUrl}/ca_apis/CAToken/generateToken`,
98
+ {
99
+ userName: config.userName,
100
+ },
101
+ {
102
+ headers: {
103
+ apiKey: config.apiKey,
104
+ 'Content-Type': 'application/json',
105
+ },
106
+ },
107
+ );
108
+
109
+ // Extract token from response - safely handle any response structure
110
+ const data = response.data as { token?: string; accessToken?: string };
111
+ return data?.token || data?.accessToken || null;
112
+ } catch (error) {
113
+ console.error('Failed to generate Ozonetel token:', error);
114
+ return null;
115
+ }
116
+ }
117
+
118
+ validateConfig(config: Partial<OzonetelVoiceConfig>): boolean {
119
+ return !!(
120
+ config &&
121
+ config.apiKey &&
122
+ config.userName &&
123
+ config.agentID &&
124
+ config.campaignName
125
+ );
126
+ }
127
+ }