Skip to content

Commit

Permalink
Merge pull request #327 from customer-dynamics/release-v2.2.0
Browse files Browse the repository at this point in the history
release: v3.0.0
  • Loading branch information
hendrickson-tyler committed Aug 26, 2024
2 parents 31093c9 + 80de411 commit 4cf3b84
Show file tree
Hide file tree
Showing 33 changed files with 2,986 additions and 1,992 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
"instanceArn": "placeholder",
"securityKeyId": "placeholder",
"securityKeyCertificateContent": "-----BEGIN CERTIFICATE-----\\n-----END CERTIFICATE-----\\n",
"workspaceApp": true,
"addAppsToWorkspace": true,
"receiptQueueArn": "placeholder"
},
"c3": {
Expand All @@ -48,7 +48,8 @@ jobs:
"agentAssistedIVR": true,
"agentAssistedLink": true,
"selfServiceIVR": true,
"subjectLookup": "required-editable"
"subjectLookup": "required-editable",
"receiptApp": true
},
"options": {
"codeSigning": true,
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"Popout",
"Runtimes",
"Softphone",
"SSML",
"Tokenizes",
"Visualforce",
"Zift"
Expand Down
2 changes: 1 addition & 1 deletion bin/c3-amazon-connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async function getMostRecentGitTag(): Promise<string> {
return stdout.trim();
} catch (error) {
console.error('Error fetching the most recent git tag:', error);
return 'v2.1.0';
return 'v3.0.0';
}
}

Expand Down
5 changes: 3 additions & 2 deletions cdk.context.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"instanceArn": "",
"securityKeyId": "",
"securityKeyCertificateContent": "",
"workspaceApp": true,
"addAppsToWorkspace": true,
"receiptQueueArn": ""
},
"c3": {
Expand All @@ -16,7 +16,8 @@
"agentAssistedIVR": true,
"agentAssistedLink": true,
"selfServiceIVR": true,
"subjectLookup": ""
"subjectLookup": "",
"receiptApp": true
},
"options": {
"codeSigning": true,
Expand Down
2 changes: 1 addition & 1 deletion docs/ALTERNATIVE_IMPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ It might be necessary to use the alternative import method in the following inst
- This prevents even your _root_ user from having ECR permissions and they cannot be added.

> [!TIP]
> If you are using Salesforce Service Cloud Voice, ensure that the `amazonConnect.workspaceApp` and `options.codeSigning` values are set to `false` in your `cdk.context.json` file. Your account will not have the necessary permissions for these items.
> If you are using Salesforce Service Cloud Voice, ensure that the `amazonConnect.addAppsToWorkspace` and `options.codeSigning` values are set to `false` in your `cdk.context.json` file. Your account will not have the necessary permissions for these items.
## Initial Deployment

Expand Down
5 changes: 4 additions & 1 deletion docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Before getting started with C3 for Amazon Connect, please ensure the following:
- You have a current C3 vendor account
- You have an AWS account
- You have an Amazon Connect instance
- You are able to run commands from a bash terminal
- If you are using Windows, you can use the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install) to run bash commands.
- You have Node.js (v20+) and npm (v10+) installed on your machine
- You have [installed and configured the AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_auth) on your machine

Expand Down Expand Up @@ -53,7 +55,7 @@ In order to facilitate this process, you will need to provide some values to the
| `instanceArn` | The full ARN of your Amazon Connect Instance. You can find this in the AWS console and it should look something like `"arn:aws:connect:us-west-2:815407490078:instance/5c1f1fba-d5f1-4155-9e09-496456e58912"`. |
| `securityKeyId` | The ID of the security key that you configured for your Amazon Connect instance. You can find this in the AWS console. |
| `securityKeyCertificateContent` | The full content of the certificate associated with your Amazon Connect security key. Begins with `-----BEGIN CERTIFICATE-----` and ends with`-----END CERTIFICATE-----`. **Note**: This must be contained within a single string with newlines denoted with `\\n`. |
| `workspaceApp` | Whether to create the C3 Payment Request app for the Amazon Connect agent workspace. Defaults to `true`. You may want to set this to `false` if you plan to use the workspace through another interface, like Salesforce. **Note**: This option does nothing if no agent-assisted features are enabled. |
| `addAppsToWorkspace` | Whether to add third-party apps to the Amazon Connect agent workspace. Defaults to `true`. You may want to set this to `false` if you plan to use the workspace apps through another interface, like Salesforce. |
| `receiptQueueArn` | **Optional**. The full ARN of the Amazon Connect queue to transfer to when there is no email present for the customer and they would like a receipt. This is only valid for self-service payments. If not provided, the customer will not be asked to transfer to an agent and will simply not receive a receipt. |

##### C3
Expand All @@ -72,6 +74,7 @@ In order to facilitate this process, you will need to provide some values to the
| `agentAssistedLink` | **Currently unsupported**. This feature will be coming soon. |
| `selfServiceIVR` | Determines whether or not to deploy resources necessary to support a self-service payment IVR. Defaults to `true`. If set to `false`, some resources will not be deployed.<br><br>For more information, see the [self-service payment IVR](./features/SELF_SERVICE_PAYMENT_IVR.md) documentation. |
| `subjectLookup` | **Optional**. Additional feature for agent-assisted IVR payments. If set, this will allow the agent to pull details about the subject to pre-fill information in the payment request (contact name, contact email, and amount due). Valid options are `"required-fixed"`, `"required-editable"`, and `"optional-editable"`. Leave blank if you don't want to support subject lookup.<br><br>For more information, see the [subject lookup](./features/SUBJECT_LOOKUP.md) documentation. |
| `receiptApp` | Determines whether or not to deploy resources to allow agents to send a receipt. Defaults to `true`. If set to `false`, some resources will not be deployed, and agents will not be able to send a receipt to a customer if the email was not already provided. |

##### Options

Expand Down
21 changes: 18 additions & 3 deletions docs/features/SALESFORCE_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ C3 for Amazon connect can be used within Salesforce to provide agents with a sea
When you deployed resources to your AWS account through this project, a unique URL was generated for your agent workspace. After running `npm run synth` or `npm run deploy`, you will see this URL output in the console. It will look something like:

```bash
🌐 Your C3 Payment Request app URL is:
💰 Your C3 Payment Request app URL is:

https://some-vendor.call2action.link/agent-workspace?contactCenter=amazon&instanceId=some-guid&region=some-region&externalRoleArn=${Token[TOKEN.261]}&subjectLookup=required-editable&customEmbed=true
🌐https://some-vendor.call2action.link/agent-workspace/payment-request?contactCenter=amazon&instanceId=some-guid&region=some-region&externalRoleArn=${Token[TOKEN.261]}&subjectLookup=required-editable&customEmbed=true
```

> [!TIP]
> You can also find this URL at any time by looking at the `exports/C3WorkspaceAppUrl.txt` file.
> You can also find this URL at any time by looking at the `exports/C3PaymentRequestAppUrl.txt` file.
Replace the `${Token[TOKEN.261]}` value with the ARN of the IAM role that was created when you deployed the stack. Look in IAM for a role named "AmazonConnectExternalRole", copy the ARN, and replace the placeholder in the URL.

Expand Down Expand Up @@ -73,6 +73,21 @@ Optionally, you can repeat the same steps on the "Mobile Navigation" tab to add

Your app page is now ready for use! Verify that your agents can see the new app page in their navigation items.

### Create Receipt App

If you enabled the receipt app feature, you will need to create a second Visualforce page and app page for the receipt app. Follow the same steps as above, but use the receipt app URL instead of the payment request app URL.

```bash
🧾 Your C3 Receipt app URL is:

🌐https://some-vendor.call2action.link/agent-workspace/receipt?contactCenter=amazon&instanceId=some-guid&region=some-region&externalRoleArn=${Token[TOKEN.261]}&customEmbed=true
```

> [!TIP]
> You can also find this URL at any time by looking at the `exports/C3ReceiptAppUrl.txt` file.
Replace the `${Token[TOKEN.261]}` value with the ARN of the IAM role that was created when you deployed the stack. Look in IAM for a role named "AmazonConnectExternalRole", copy the ARN, and replace the placeholder in the URL.

### Configure Amazon Connect Integration

This step will vary depending on how you have Amazon Connect integrated with Salesforce. Please follow the appropriate guide below:
Expand Down
59 changes: 44 additions & 15 deletions lib/c3-amazon-connect-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
validateOptionsContext,
} from './models';
import { writeFileToExports } from './helpers/file';
import { ReceiptApp } from './features/receipt-app';

export class C3AmazonConnectStack extends Stack {
private c3BaseUrl: string;
Expand Down Expand Up @@ -142,9 +143,25 @@ export class C3AmazonConnectStack extends Stack {
this.featuresContext.agentAssistedIVR ||
this.featuresContext.agentAssistedLink
) {
const appUrl = this.getAppUrl(!this.amazonConnectContext.workspaceApp);
if (this.amazonConnectContext.workspaceApp) {
this.create3rdPartyApp(appUrl);
const paymentRequestAppUrl = this.getPaymentRequestAppUrl(
!this.amazonConnectContext.addAppsToWorkspace,
);
if (this.amazonConnectContext.addAppsToWorkspace) {
this.createPaymentRequestApp(paymentRequestAppUrl);
}

// Create resources needed for agent-assisted receipt app.
if (this.featuresContext.receiptApp) {
new ReceiptApp(
this,
this.stackLabel,
this.amazonConnectContext,
this.sendReceiptFunction,
this.agentAssistedIVRResources?.sendAgentMessageFunction,
this.agentAssistedIVRResources?.hoursOfOperation,
this.agentAssistedIVRResources?.iamRole?.roleArn,
this.c3AppUrlFragment,
);
}
}
}
Expand Down Expand Up @@ -471,16 +488,16 @@ export class C3AmazonConnectStack extends Stack {
* This app is required in order for an agent to initiate a payment while on a call with a customer. Once created, it will show as
* an app in the agent workspace. NOTE: You will also have to enable this app to viewed on the security profile for your agents.
*/
private create3rdPartyApp(appUrl: string): void {
console.log('Creating 3rd party application...');
private createPaymentRequestApp(appUrl: string): void {
console.log('Creating payment request application...');

// Create the app.
const stackLabelTitleCase =
this.stackLabel.charAt(0).toUpperCase() + this.stackLabel.slice(1);
const appLabel = this.stackLabel ? ` - ${stackLabelTitleCase}` : '';
const application = new CfnApplication(
this,
`C3ConnectApp${stackLabelTitleCase}`,
`C3ConnectPaymentRequestApp${stackLabelTitleCase}`,
{
name: 'Payment Request' + appLabel, // App name is unfortunately required to be unique to create.
namespace: `c3-payment-${this.stackLabel}`,
Expand All @@ -495,12 +512,24 @@ export class C3AmazonConnectStack extends Stack {
},
);

// Workaround to delete the existing associations. Necessary when the naming format changes.
const skipAssociations =
this.node.tryGetContext('options').skipAssociations;
if (skipAssociations) {
console.log('⚠️ Skipping Amazon Connect associations! ⚠️');
return;
}

// Associate the app with the Amazon Connect instance.
new CfnIntegrationAssociation(this, `C3ConnectIntegrationApp`, {
instanceId: this.amazonConnectContext.instanceArn,
integrationType: 'APPLICATION',
integrationArn: application.attrApplicationArn,
});
new CfnIntegrationAssociation(
this,
`C3ConnectPaymentRequestIntegrationApp`,
{
instanceId: this.amazonConnectContext.instanceArn,
integrationType: 'APPLICATION',
integrationArn: application.attrApplicationArn,
},
);
}

/**
Expand All @@ -509,7 +538,7 @@ export class C3AmazonConnectStack extends Stack {
* @param customEmbed Whether to use a custom embed URL for the app.
* @returns The URL for the app.
*/
private getAppUrl(customEmbed: boolean): string {
private getPaymentRequestAppUrl(customEmbed: boolean): string {
const instanceId = this.amazonConnectContext.instanceArn.split('/')[1];

// Set params for IVR features.
Expand All @@ -535,10 +564,10 @@ export class C3AmazonConnectStack extends Stack {
configuredFeatureParams += '&customEmbed=true';
}

const appUrl = `https://${this.c3Context.vendorId}.${this.c3AppUrlFragment}/agent-workspace?contactCenter=amazon&instanceId=${instanceId}&region=${region}${agentAssistedIVRParams}${configuredFeatureParams}`;
const appUrl = `https://${this.c3Context.vendorId}.${this.c3AppUrlFragment}/agent-workspace/payment-request?contactCenter=amazon&instanceId=${instanceId}&region=${region}${agentAssistedIVRParams}${configuredFeatureParams}`;
writeFileToExports(
'C3WorkspaceAppUrl.txt',
`🌐 Your C3 Payment Request app URL is:\n\n${appUrl}\n`,
'C3PaymentRequestAppUrl.txt',
`💰 Your C3 Payment Request app URL is:\n\n🌐 ${appUrl}\n`,
);
return appUrl;
}
Expand Down
39 changes: 38 additions & 1 deletion lib/connect/content-transformations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Function } from 'aws-cdk-lib/aws-lambda';
import * as flowModuleJson from './flows/modules/c3-payment-ivr-flow-module.json';
import * as agentAssistedPaymentIVRFlowJson from './flows/c3-agent-assisted-payment-ivr-flow.json';
import * as subjectLookupFlow from './flows/c3-subject-lookup-flow.json';
import * as receiptFlow from './flows/c3-receipt-flow.json';
import { IvrSpeakingContext } from '../models';

/**
Expand Down Expand Up @@ -73,7 +74,7 @@ export function getPaymentIVRFlowModuleContent(
}
transformedContent = transformedContent.replace(
/<<receiptQueueId>>/g,
queueId,
queueId ?? '',
);

transformedContent = transformedContent.replace(
Expand Down Expand Up @@ -186,3 +187,39 @@ export function getSubjectLookupFlowContent(
);
return transformedContent;
}

/**
* Gets the content for the receipt flow.
*
* @param sendReceiptLambdaArn The Lambda function that sends a receipt.
* @param sendAgentMessageFunction The Lambda function that sends messages to the agent.
* @param ivrSpeakingContext The speaking context for the IVR.
* @returns A string representing the content for the receipt flow.
*/
export function getReceiptFlowContent(
sendReceiptLambdaFunction: Function,
sendAgentMessageFunction: Function,
ivrSpeakingContext: IvrSpeakingContext,
): string {
let transformedContent = JSON.stringify(receiptFlow);

// Replace the placeholders with the actual values.
transformedContent = transformedContent.replace(
/<<sendReceiptLambdaArn>>/g,
sendReceiptLambdaFunction.functionArn,
);
transformedContent = transformedContent.replace(
/<<sendAgentMessageLambdaArn>>/g,
sendAgentMessageFunction.functionArn,
);

transformedContent = transformedContent.replace(
/<<speakingRate>>/g,
ivrSpeakingContext.rate,
);
transformedContent = transformedContent.replace(
/<<speakingVolume>>/g,
ivrSpeakingContext.volume,
);
return transformedContent;
}
Loading

0 comments on commit 4cf3b84

Please sign in to comment.