Skip to content

Commit

Permalink
1.0.0 - Connect Cloudwatch Dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
mcosicaws committed Sep 9, 2021
1 parent bedb15f commit b3b57a3
Show file tree
Hide file tree
Showing 8 changed files with 20,610 additions and 34 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Change Log
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2021-09-09
### Added
- CHANGELOG.md
- Connect Cloudwatch Dashboard
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ Feel free to add more languages. Please follow the requirements in each subdirec
| LastAgentRouting | This project shows how to potentially implement last agent routing for customers using a voice channel.| [CloudFormation](projects/LastAgentRouting) |
| RoutingFeatureRouting | This project shows how to capture a routing feature and use that to dynamically route a caller in a contact flow.| [CloudFormation](projects/RoutingFeatureRouting) |
| LambdaAlias | This project shows how to provide access to an AWS Lambda function Alias from Amazon Connect.| [CloudFormation](projects/LambdaAlias) |
| ContextRouting | This project demonstrates how you can use contact trace record processing, Lambda, and DynamoDB to track a callers progress through an IVR task, such as making a payment, and return them to that task should they be disonnected.| [CloudFormation](projects/ContextRouting) |
| ContextRouting | This project demonstrates how you can use contact trace record processing, Lambda, and DynamoDB to track a callers progress through an IVR task, such as making a payment, and return them to that task should they be disconnected.| [CloudFormation](projects/ContextRouting) |
| Rate Limiter | The rate limiter project utilizes AWS Lambda and Amazon DynamoDB dynamically to add rate limiting a caller to a Amazon Connect queue based on their phone number and/or IP address.| [CloudFormation](projects/RateLimiter) |
| CCP Log Parser| A visualisation tool to visualise CCP logs to help troubleshoot client side errors | [link](tools/CCPLogParser) |
| Connectivity Test Tool | This tool checks which web browser the agent is running, the network configuration from the client side and whether the microphone has required permissions. | [link](tools/CCPConnectivityTestTools) |
| Dynamic Contact Center | This project demonstrates how you can use persistent session attributes to develop modular, repeatable and dynamic contact flows | [CloudFormation](projects/DynamicContactCenter)
| Connect Cloudwatch Dashboard | This project automates the creation and deployment of a Cloudwatch Dashboard to monitor critical metrics for an Amazon Connect instance | [link](tools/ConnectCloudwatchDashboard/README.md)


## Contributions

Expand Down
19,981 changes: 19,981 additions & 0 deletions javascript/customAgentDesktop-AzureSSO/webApp/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion javascript/customAgentDesktop-AzureSSO/webApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@
"last 1 safari version"
]
}
}
}
64 changes: 32 additions & 32 deletions javascript/customAgentDesktop-AzureSSO/webApp/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { Auth, Hub } from 'aws-amplify';
import Logger from './util/logger/logger';
import Logger from './util/logger/logger';
import OAuthButton from './components/OAuthButton/OAuthButton';
import ErrorBoundary from './components/ErrorBoundary/ErrorBoundary';
import Ccp from './components/Ccp/Ccp';
Expand Down Expand Up @@ -36,54 +36,54 @@ class App extends Component<Props, State> {
username: '',
jwtToken: ''
};

private readonly _ccpRef = React.createRef<Ccp>();

constructor(props: Props) {
super(props);
this._logger.debug(this._name + ': constructor');
this.state = {

this.state = {
isLoaded: false,
user: this._unauthenticatedUser
};
}

render() {
this._logger.debug(this._name + ': render');
let control = <Text variant='p'>Loading...</Text>;
if (this.state.isLoaded){
if (this.state.user.isAuthenticated){
control = (
<Container>

let control = <Text variant='p'>Loading...</Text>;
if (this.state.isLoaded) {
if (this.state.user.isAuthenticated) {
control = (
<Container>
<Stack>
<Ccp ref={this._ccpRef} />
<UserAttributes user={this.state.user} />
<Ccp ref={this._ccpRef} />
<UserAttributes user={this.state.user} />
<MockApi user={this.state.user} />
<Button variant="primary" onClick={ async () => await this.signOut() }>Logout</Button>
<Button variant="primary" onClick={async () => await this.signOut()}>Logout</Button>
</Stack>
</Container>
);
} else {
control = <OAuthButton />;
}
}

return (
<div className="App">
<ErrorBoundary>
<div className="App">
<ErrorBoundary>
<NorthStarThemeProvider>
{control}
{control}
</NorthStarThemeProvider>
</ErrorBoundary>
</div>
);
}

async componentDidMount() {
this._logger.debug(this._name + ': componentDidMount');

let myCognitoUser = this._unauthenticatedUser;
try {
const user = await Auth.currentAuthenticatedUser();
Expand All @@ -95,43 +95,43 @@ class App extends Component<Props, State> {
} catch {
// currentAuthenticatedUser throws an Error if not signed in so do nothing since myCognitoUser is already set
} finally {
this.setState({
this.setState({
isLoaded: true,
user: myCognitoUser
});
}

Hub.listen("auth", async (data) => {
this._logger.debug(this._name + `: Auth listen ${data.payload.event}`);

switch (data.payload.event) {
case "oAuthSignOut":
if (this._ccpRef.current){
if (this._ccpRef.current) {
// Finished Signing out of main app so let's logout of the Ccp
await this._ccpRef.current.logout();
} else {
throw new Error ('_ccpRef is null. This should never happen');
throw new Error('_ccpRef is null. This should never happen');
}
break;
default:
//Do nothing
}
//Do nothing
}
}
);
}

signOut = async () => {
this._logger.debug(this._name + ': signOut');

try {
await Auth.signOut({ global: true });
} catch (error) {
if (error instanceof Error) {
throw new Error(`signOut error: ${error.message}`);
} else {
throw(error);
throw (error);
}
}
}
}
}

Expand Down
34 changes: 34 additions & 0 deletions tools/ConnectCloudwatchDashboard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## Purpose
This project's intent is to automate the creation and deployment of a Cloudwatch dashboard to monitor critical metrics for an Amazon Connect instance.

It is made of two parts:
- a Cloudformation stack
- a Lambda

The Cloudformation stack will take care of creating the dashboard by triggering the Lambda as a custom resource. The deletion of the dashboard is also handled when the stack is deleted.
The Lamdba is gathering the Amazon Connect instance necessary objects (queues, contact flows, etc...) and responds to Cloudformation events to create the relevant dashboard.

The dashboard created allows to monitor:
- Concurrent Calls (%)
- Concurrent Calls (number)
- Throttled Calls (number)
- Contact Flow Errors
- Contact Flows Fatal Errors
- Longest Queue Wait Time
- Packet Loss Rate
- Calls Per Interval
- Call Recording Upload Error
- Misconfigured Phone Numbers
- Calls Breaching Quota


## How-to use
Zip index.js, and upload the archive to S3.
Create the Cloudformation stack using the template that takes a few input parameters:
- the name of the dashboard that will be created (without spaces or special characters)
- the Amazon Connect instance id
- the S3 bucket where the Lambda package is located
- the name of the Lambda package object in S3

## Feedback
If you would like to give some feedback, please get in touch with <a href="mailto:plancqua@amazon">me</a>!
Loading

0 comments on commit b3b57a3

Please sign in to comment.