genesys-cloud-streaming-client 19.6.0 → 19.6.1-develop.17

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.
@@ -33,6 +33,27 @@ export interface ICustomHeader {
33
33
  export declare enum AlertableInteractionTypes {
34
34
  voice = "voice"
35
35
  }
36
+ /** The alerting status for an interaction type */
37
+ export interface IAlertingStatus {
38
+ /**
39
+ * Indicates whether this client should be alerting. This can be because this client is the alerting
40
+ * leader for this interaction type, alerting leader functionality is not configured by an admin,
41
+ * or because setup for alerting leader failed and we fallback to `alerting: true` so interactions
42
+ * don't go unnoticed.
43
+ */
44
+ alerting: boolean;
45
+ /**
46
+ * Indicates if alerting leader functionality is configured by an admin. This will also be `false`
47
+ * if setup for alerting leader failed.
48
+ */
49
+ configured: boolean;
50
+ /** A string representing the client type of the alerting leader, based on OAuth client ID. */
51
+ clientType?: string;
52
+ }
53
+ /** The alerting leader status for this client. Currently only `voice` interactions are supported. */
54
+ export interface ILeaderStatus {
55
+ voice?: IAlertingStatus;
56
+ }
36
57
  export interface IClientConfig {
37
58
  host: string;
38
59
  apiHost: string;
@@ -67,6 +88,7 @@ export declare type RequestApiOptions = {
67
88
  requestTimeout?: number;
68
89
  customHeaders?: ICustomHeader;
69
90
  maxAttempts?: number;
91
+ signal?: AbortSignal;
70
92
  };
71
93
  export interface IAxiosResponseError extends AxiosError {
72
94
  text: string;
@@ -1,13 +1,13 @@
1
1
  {
2
- "version": "19.6.0",
3
- "build": "7",
4
- "buildDate": "2026-04-17T16:20:47.432Z",
2
+ "version": "19.6.1-develop",
3
+ "build": "17",
4
+ "buildDate": "2026-04-29T14:55:47.312Z",
5
5
  "indexFiles": [
6
6
  {
7
- "file": "v19.6.0/streaming-client.browser.js"
7
+ "file": "v19.6.1/streaming-client.browser.js"
8
8
  },
9
9
  {
10
- "file": "v19.6.0/streaming-client.browser.js.LICENSE.txt"
10
+ "file": "v19.6.1/streaming-client.browser.js.LICENSE.txt"
11
11
  },
12
12
  {
13
13
  "file": "v19/streaming-client.browser.js"
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  # [Unreleased](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.6.0...HEAD)
8
+ * [STREAM-1155](https://inindca.atlassian.net/browse/STREAM-1155) - Allow clients to become the alerting leader and listen for alerting leader events.
8
9
 
9
10
  # [v19.6.0](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.6.0...HEAD)
10
11
  ### Added
@@ -1,14 +1,26 @@
1
- import { IClientOptions, StreamingClientExtension } from './types/interfaces';
1
+ /// <reference types="node" />
2
+ import { IClientOptions, ILeaderStatus, StreamingClientExtension } from './types/interfaces';
2
3
  import { Client } from './client';
4
+ import { EventEmitter } from 'events';
3
5
  import { NamedAgent } from './types/named-agent';
4
- export declare class AlertingLeaderExtension implements StreamingClientExtension {
6
+ export declare class AlertingLeaderExtension extends EventEmitter implements StreamingClientExtension {
5
7
  private client;
6
8
  private connectionId?;
7
9
  private alertableInteractionTypes;
10
+ private abortController?;
11
+ private leaderStatus;
8
12
  constructor(client: Client, options: IClientOptions);
9
13
  handleStanzaInstanceChange(stanzaInstance: NamedAgent): void;
14
+ private setupAlertingLeader;
15
+ private subscribeToAlertingLeader;
10
16
  private markAsAlertable;
17
+ private getAlertingLeader;
18
+ private claimAlertingLeader;
11
19
  get expose(): AlertingLeaderApi;
12
20
  }
13
21
  export interface AlertingLeaderApi {
22
+ on: (event: string, handler: (...args: any) => void) => void;
23
+ off: (event: string, handler: (...args: any) => void) => void;
24
+ claimAlertingLeader(): Promise<void>;
25
+ leaderStatus: ILeaderStatus;
14
26
  }
@@ -1,20 +1,58 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AlertingLeaderExtension = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const axios_1 = tslib_1.__importDefault(require("axios"));
6
+ const interfaces_1 = require("./types/interfaces");
7
+ const events_1 = require("events");
4
8
  const utils_1 = require("./utils");
5
- class AlertingLeaderExtension {
9
+ class AlertingLeaderExtension extends events_1.EventEmitter {
6
10
  constructor(client, options) {
7
11
  var _a;
12
+ super();
8
13
  this.client = client;
14
+ this.leaderStatus = {};
9
15
  this.alertableInteractionTypes = (_a = options.alertableInteractionTypes) !== null && _a !== void 0 ? _a : [];
10
16
  }
11
17
  handleStanzaInstanceChange(stanzaInstance) {
12
18
  var _a, _b;
13
19
  this.connectionId = (_b = (_a = stanzaInstance.transport) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.id;
20
+ this.setupAlertingLeader();
21
+ }
22
+ async setupAlertingLeader() {
14
23
  if (this.alertableInteractionTypes.length !== 0) {
15
- this.markAsAlertable();
24
+ try {
25
+ await this.subscribeToAlertingLeader();
26
+ await this.markAsAlertable();
27
+ await this.getAlertingLeader();
28
+ }
29
+ catch (err) {
30
+ this.client.logger.warn('Failed to setup alerting leader; falling back to the default of acting as the alerting leader');
31
+ // Fail 'open' so users don't miss calls
32
+ this.leaderStatus = { voice: { alerting: true, configured: false } };
33
+ this.emit('alertingLeaderChanged', this.leaderStatus);
34
+ }
16
35
  }
17
36
  }
37
+ async subscribeToAlertingLeader() {
38
+ const topic = `v2.users.${this.client.config.userId}.alertingleader`;
39
+ this.client.on(`notify:${topic}`, (event) => {
40
+ var _a, _b;
41
+ (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
42
+ if ((_b = event.eventBody) === null || _b === void 0 ? void 0 : _b.connectionId) {
43
+ // We should alert if our connection is the alerting leader connection
44
+ const alerting = event.eventBody.connectionId === this.connectionId;
45
+ const clientType = event.eventBody.clientType;
46
+ let voice = { alerting, configured: true };
47
+ if (clientType) {
48
+ voice = { ...voice, clientType };
49
+ }
50
+ this.leaderStatus = { voice };
51
+ this.emit('alertingLeaderChanged', this.leaderStatus);
52
+ }
53
+ });
54
+ return this.client._notifications._subscribeInternal(topic);
55
+ }
18
56
  async markAsAlertable() {
19
57
  const userId = this.client.config.userId;
20
58
  const connectionsRequestOptions = {
@@ -44,8 +82,61 @@ class AlertingLeaderExtension {
44
82
  this.client.logger.warn('Could not mark this connection as alertable; this client may not alert for incoming interactions');
45
83
  });
46
84
  }
85
+ async getAlertingLeader() {
86
+ this.abortController = new AbortController();
87
+ const leaderRequestOptions = {
88
+ method: 'get',
89
+ host: this.client.config.apiHost,
90
+ authToken: this.client.config.authToken,
91
+ logger: this.client.logger,
92
+ signal: this.abortController.signal
93
+ };
94
+ try {
95
+ const currentLeader = await this.client.http.requestApi('users/alertingleader', leaderRequestOptions);
96
+ // We should alert if our connection is the alerting leader connection
97
+ const alerting = currentLeader.data.connectionId === this.connectionId;
98
+ const clientType = currentLeader.data.clientType;
99
+ let voice = { alerting, configured: true };
100
+ if (clientType) {
101
+ voice = { ...voice, clientType };
102
+ }
103
+ this.leaderStatus = { voice };
104
+ this.emit('alertingLeaderChanged', this.leaderStatus);
105
+ }
106
+ catch (err) {
107
+ if (axios_1.default.isCancel(err)) {
108
+ return;
109
+ }
110
+ throw err;
111
+ }
112
+ }
113
+ async claimAlertingLeader() {
114
+ if (this.alertableInteractionTypes.length === 0) {
115
+ this.client.logger.info('This client is not configured for any alertable interactions and will not attempt to claim alerting leader');
116
+ throw new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.generic, 'Unable to claim alerting leader; this client is not configured for any alertable interactions');
117
+ }
118
+ const leaderRequestOptions = {
119
+ method: 'put',
120
+ host: this.client.config.apiHost,
121
+ authToken: this.client.config.authToken,
122
+ logger: this.client.logger,
123
+ data: {
124
+ connectionId: this.connectionId
125
+ }
126
+ };
127
+ return this.client.http.requestApi('users/alertingleader', leaderRequestOptions)
128
+ .catch((err) => {
129
+ this.client.logger.warn('Unable to claim alerting leader; this client may not alert for incoming interactions');
130
+ throw new utils_1.StreamingClientError(interfaces_1.StreamingClientErrorTypes.generic, 'Unable to claim alerting leader', err);
131
+ });
132
+ }
47
133
  get expose() {
48
- return {};
134
+ return {
135
+ on: this.on.bind(this),
136
+ off: this.off.bind(this),
137
+ claimAlertingLeader: this.claimAlertingLeader.bind(this),
138
+ leaderStatus: this.leaderStatus
139
+ };
49
140
  }
50
141
  }
51
142
  exports.AlertingLeaderExtension = AlertingLeaderExtension;
@@ -670,7 +670,7 @@ class Client extends events_1.default {
670
670
  return Client.version;
671
671
  }
672
672
  static get version() {
673
- return '19.6.0';
673
+ return '19.6.1';
674
674
  }
675
675
  }
676
676
  exports.Client = Client;
@@ -64,7 +64,8 @@ class HttpClient {
64
64
  data: opts.data,
65
65
  responseType: opts.responseType,
66
66
  timeout: opts.requestTimeout || 30000,
67
- headers
67
+ headers,
68
+ signal: opts.signal
68
69
  };
69
70
  // default to include auth header
70
71
  if (!opts.noAuthHeader) {
@@ -33,6 +33,27 @@ export interface ICustomHeader {
33
33
  export declare enum AlertableInteractionTypes {
34
34
  voice = "voice"
35
35
  }
36
+ /** The alerting status for an interaction type */
37
+ export interface IAlertingStatus {
38
+ /**
39
+ * Indicates whether this client should be alerting. This can be because this client is the alerting
40
+ * leader for this interaction type, alerting leader functionality is not configured by an admin,
41
+ * or because setup for alerting leader failed and we fallback to `alerting: true` so interactions
42
+ * don't go unnoticed.
43
+ */
44
+ alerting: boolean;
45
+ /**
46
+ * Indicates if alerting leader functionality is configured by an admin. This will also be `false`
47
+ * if setup for alerting leader failed.
48
+ */
49
+ configured: boolean;
50
+ /** A string representing the client type of the alerting leader, based on OAuth client ID. */
51
+ clientType?: string;
52
+ }
53
+ /** The alerting leader status for this client. Currently only `voice` interactions are supported. */
54
+ export interface ILeaderStatus {
55
+ voice?: IAlertingStatus;
56
+ }
36
57
  export interface IClientConfig {
37
58
  host: string;
38
59
  apiHost: string;
@@ -67,6 +88,7 @@ export declare type RequestApiOptions = {
67
88
  requestTimeout?: number;
68
89
  customHeaders?: ICustomHeader;
69
90
  maxAttempts?: number;
91
+ signal?: AbortSignal;
70
92
  };
71
93
  export interface IAxiosResponseError extends AxiosError {
72
94
  text: string;