Skip to content

Commit

Permalink
Merge pull request #119 from amazon-connect/add-typing-throttle
Browse files Browse the repository at this point in the history
throttle typing event
  • Loading branch information
jiahaoyu6666 authored Feb 23, 2023
2 parents c2248bc + 4463477 commit 4cb7c38
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dist/amazon-connect-chat.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/amazon-connect-chat.js.map

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"json",
"html",
"cobertura",
"lcov"
"lcov",
"text"
]
},
"author": "Amazon Web Services",
Expand Down
42 changes: 29 additions & 13 deletions src/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
import { LogManager } from "../log";
//Note: this imports AWS instead from aws-sdk npm package - details in ReadMe
import { ConnectParticipant } from "./aws-sdk-connectparticipant";
import throttle from "lodash/throttle";
import { CONTENT_TYPE, TYPING_VALIDITY_TIME } from '../constants';

const DEFAULT_PREFIX = "Amazon-Connect-ChatJS-ChatClient";

Expand Down Expand Up @@ -227,21 +229,35 @@ class AWSChatClient extends ChatClient {
.catch(err => { return Promise.reject(err); });
}


sendEvent(connectionToken, contentType, content) {
let self = this;
var params = {
ConnectionToken: connectionToken,
ContentType: contentType,
Content: content
};
var sendEventRequest = self.chatClient.sendEvent(params);
const logContent = {contentType};
return self._sendRequest(sendEventRequest).then((res) => {
this.logger.debug("Successfully send event", {...logContent, id: res.data?.Id, });
return res;
}).catch((err) => {
return Promise.reject(err);
});
if(contentType === CONTENT_TYPE.typing) {
return self.throttleEvent(connectionToken, contentType, content)
}
return self._submitEvent(connectionToken, contentType, content);
}

throttleEvent = throttle((connectionToken, contentType, content) => {
return this._submitEvent(connectionToken, contentType, content);
}, TYPING_VALIDITY_TIME, { trailing: false, leading: true })

async _submitEvent(connectionToken, contentType, content) {
let self = this;
var params = {
ConnectionToken: connectionToken,
ContentType: contentType,
Content: content
};
var sendEventRequest = self.chatClient.sendEvent(params);
const logContent = {contentType};
try {
const res = await self._sendRequest(sendEventRequest);
this.logger.debug("Successfully send event", { ...logContent, id: res.data?.Id, });
return res;
} catch (err) {
return await Promise.reject(err);
}
}

_sendRequest(request) {
Expand Down
54 changes: 54 additions & 0 deletions src/client/client.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { ChatClientFactory } from "./client";
import { CONTENT_TYPE } from "../constants";
import { jest } from "@jest/globals";

describe("client test cases", () => {
describe("event throttling test cases", () => {
const options = {};
const logMetaData = {};
const connectionToken = "connectionToken";
const content = "content";

var chatClient = ChatClientFactory.getCachedClient(options, logMetaData);

beforeEach(() => {
jest.spyOn(chatClient, "_submitEvent").mockImplementation(() => {});
jest.useFakeTimers();
jest.clearAllTimers();
jest.clearAllMocks();
});

test("typing event should be throttled if content type is typing", () => {
let count = 0;
let typingInterval = setInterval(() => {
if (count > 8) {
clearInterval(typingInterval);
}
count++;
chatClient.sendEvent(connectionToken, CONTENT_TYPE.typing, content);
}, 100);
jest.advanceTimersByTime(900);
expect(chatClient._submitEvent).toHaveBeenCalledTimes(1);
});

test("Other events should not be throttled", () => {
for (let key in CONTENT_TYPE) {
jest.clearAllTimers();
jest.clearAllMocks();
if (key === "typing") {
continue;
}
let count = 0;
let typingInterval = setInterval(() => {
if (count > 8) {
clearInterval(typingInterval);
}
count++;
chatClient.sendEvent(connectionToken, CONTENT_TYPE[key], content);
}, 100);
jest.advanceTimersByTime(900);
expect(chatClient._submitEvent).toHaveBeenCalledTimes(9);
}
});
});
});
4 changes: 3 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,6 @@ export const MOCK_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
export const SEND_EVENT_CONACK_THROTTLED = "SEND_EVENT_CONACK_THROTTLED";
export const CREATE_PARTICIPANT_CONACK_FAILURE = "CREATE_PARTICIPANT_CONACK_FAILURE";
export const SEND_EVENT_CONACK_FAILURE = "SEND_EVENT_CONACK_FAILURE";
export const CREATE_PARTICIPANT_CONACK_API_CALL_COUNT = "CREATE_PARTICIPANT_CONACK_CALL_COUNT";
export const CREATE_PARTICIPANT_CONACK_API_CALL_COUNT = "CREATE_PARTICIPANT_CONACK_CALL_COUNT";

export const TYPING_VALIDITY_TIME = 10000;

0 comments on commit 4cb7c38

Please sign in to comment.