├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── amplify.yml ├── amplify ├── .config │ └── project-config.json ├── README.md ├── backend │ ├── api │ │ └── amazonTranslateAPI │ │ │ ├── amazonTranslateAPI-cloudformation-template.json │ │ │ ├── api-params.json │ │ │ └── parameters.json │ ├── auth │ │ └── connecttranslateblog690eb6d1 │ │ │ └── cli-inputs.json │ ├── backend-config.json │ ├── custom │ │ └── environmentIntegration │ │ │ ├── custom-environmentIntegration-parameters.json │ │ │ └── custom-environmentIntegration-template.json │ ├── function │ │ ├── amazonTranslateLambda │ │ │ ├── amazonTranslateLambda-cloudformation-template.json │ │ │ ├── amplify.state │ │ │ ├── function-parameters.json │ │ │ ├── parameters.json │ │ │ └── src │ │ │ │ ├── event.json │ │ │ │ ├── index.js │ │ │ │ ├── package-lock.json │ │ │ │ └── package.json │ │ └── postInstallScript │ │ │ ├── amplify.state │ │ │ ├── function-parameters.json │ │ │ ├── postInstallScript-cloudformation-template.json │ │ │ └── src │ │ │ ├── event.json │ │ │ ├── index.js │ │ │ ├── package-lock.json │ │ │ └── package.json │ ├── hosting │ │ └── amplifyhosting │ │ │ └── amplifyhosting-template.json │ ├── predictions │ │ ├── interpretTextcabd9d8d │ │ │ ├── interpretTextcabd9d8d-template.json │ │ │ └── parameters.json │ │ └── translateText0519c50f │ │ │ ├── parameters.json │ │ │ └── translateText0519c50f-template.json │ ├── tags.json │ └── types │ │ └── amplify-dependent-resources-ref.d.ts └── cli.json ├── artifacts ├── Arch.png ├── Environment variables.png ├── TranslateDemo.gif ├── Web app deployed.png ├── Web app deploying.png ├── connectChatTranslate.png └── customTerminologySample.csv ├── craco.config.js ├── customHttp.yml ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── .env ├── App.css ├── App.js ├── App.test.js ├── components │ ├── ccp.js │ ├── chat.js │ ├── chatroom.css │ ├── chatroom.js │ ├── detectText.js │ ├── message.js │ ├── translate.js │ └── translateAPI.js ├── index.css ├── index.js ├── logo.svg ├── reportWebVitals.js ├── semantic-ui │ ├── site │ │ ├── collections │ │ │ ├── breadcrumb.overrides │ │ │ ├── breadcrumb.variables │ │ │ ├── form.overrides │ │ │ ├── form.variables │ │ │ ├── grid.overrides │ │ │ ├── grid.variables │ │ │ ├── menu.overrides │ │ │ ├── menu.variables │ │ │ ├── message.overrides │ │ │ ├── message.variables │ │ │ ├── table.overrides │ │ │ └── table.variables │ │ ├── elements │ │ │ ├── button.overrides │ │ │ ├── button.variables │ │ │ ├── container.overrides │ │ │ ├── container.variables │ │ │ ├── divider.overrides │ │ │ ├── divider.variables │ │ │ ├── flag.overrides │ │ │ ├── flag.variables │ │ │ ├── header.overrides │ │ │ ├── header.variables │ │ │ ├── icon.overrides │ │ │ ├── icon.variables │ │ │ ├── image.overrides │ │ │ ├── image.variables │ │ │ ├── input.overrides │ │ │ ├── input.variables │ │ │ ├── label.overrides │ │ │ ├── label.variables │ │ │ ├── list.overrides │ │ │ ├── list.variables │ │ │ ├── loader.overrides │ │ │ ├── loader.variables │ │ │ ├── rail.overrides │ │ │ ├── rail.variables │ │ │ ├── reveal.overrides │ │ │ ├── reveal.variables │ │ │ ├── segment.overrides │ │ │ ├── segment.variables │ │ │ ├── step.overrides │ │ │ └── step.variables │ │ ├── globals │ │ │ ├── reset.overrides │ │ │ ├── reset.variables │ │ │ ├── site.overrides │ │ │ └── site.variables │ │ ├── modules │ │ │ ├── accordion.overrides │ │ │ ├── accordion.variables │ │ │ ├── chatroom.overrides │ │ │ ├── chatroom.variables │ │ │ ├── checkbox.overrides │ │ │ ├── checkbox.variables │ │ │ ├── dimmer.overrides │ │ │ ├── dimmer.variables │ │ │ ├── dropdown.overrides │ │ │ ├── dropdown.variables │ │ │ ├── embed.overrides │ │ │ ├── embed.variables │ │ │ ├── modal.overrides │ │ │ ├── modal.variables │ │ │ ├── nag.overrides │ │ │ ├── nag.variables │ │ │ ├── popup.overrides │ │ │ ├── popup.variables │ │ │ ├── progress.overrides │ │ │ ├── progress.variables │ │ │ ├── rating.overrides │ │ │ ├── rating.variables │ │ │ ├── search.overrides │ │ │ ├── search.variables │ │ │ ├── shape.overrides │ │ │ ├── shape.variables │ │ │ ├── sidebar.overrides │ │ │ ├── sidebar.variables │ │ │ ├── sticky.overrides │ │ │ ├── sticky.variables │ │ │ ├── tab.overrides │ │ │ ├── tab.variables │ │ │ ├── transition.overrides │ │ │ └── transition.variables │ │ └── views │ │ │ ├── ad.overrides │ │ │ ├── ad.variables │ │ │ ├── card.overrides │ │ │ ├── card.variables │ │ │ ├── comment.overrides │ │ │ ├── comment.variables │ │ │ ├── feed.overrides │ │ │ ├── feed.variables │ │ │ ├── item.overrides │ │ │ ├── item.variables │ │ │ ├── statistic.overrides │ │ │ └── statistic.variables │ └── theme.config ├── setupTests.js └── store │ └── state.js └── yarn.lock /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Translate CCP Demo for Amazon Connect 2 | 3 | **NOTE: This is a fork of [VoiceFoundry's GitHub repository](https://github.com/voicefoundry-cloud-public/Amazon-Connect-Chat-Translate-Demo) that addresses deployment issues reported by users and provides ability to address any future user concerns.** 4 | 5 | This is a sample project that demonstrates using Amazon Translate with Amazon Connect chat to perform real-time translation on chat messages, allowing a user to support dozens of languages. The web app supports multi-chat allow an Amazon Connect Chat user to support multiple languages concurrently. Deployment is using the Amplify UI (No CLI access required) and is using serverless architecture. Deployment takes about 10 minutes. 6 | 7 | Read the Amazon blog: https://www.amazon.com/livechattranslate 8 | 9 | ### Demo 10 | 11 | 12 | 13 | ### Architecture 14 | 15 | 16 | 17 | 18 | ### Pre-Reqs 19 | 20 | - Existing Amazon Connect Instance ([Create an instance in 3 easy steps](https://docs.aws.amazon.com/connect/latest/adminguide/tutorial1-set-up-your-instance.html)) 21 | - Github account ([Create a free GitHub account](https://github.com/join)) 22 | 23 | 24 | ### Deploy 25 | 26 | - Fork this repository in your Github account 27 | - Navigate to [Amplify Console](https://console.aws.amazon.com/amplify/) 28 | - Get Started with Amplify Hosting 29 | - Connect to Github 30 | - Select repository - `amazon-connect-chat-translate` 31 | - Click on 'Create new role' then `Next: Permissions` > `Next: Tags` > `Next: Review` finally `Create role` 32 | - Click `Create new environment` for backend 33 | - Expand `Environment variables` and add the following: 34 | - `REACT_APP_CONNECT_REGION` = `AWS Region` (Example `eu-west-2`) 35 | - `REACT_APP_CONNECT_INSTANCE_URL` = `Amazon Connect URL` (Example `https://<>.awsapps.com` or `https://<>.my.connect.aws`) 36 | 37 | [Important, if you copy and paste, ensure there are no trailing whitespaces in the above 2 variable keys, or values. This will cause the web app to not load CCP and a rebuild will be required] 38 | 39 | 40 | 41 | It will take about 10 minutes for the application to deploy. After successful deployment, add the hosting URL to the Amazon Connect Approved Origin list to allow the web application to embed the CCP as an iFrame. 42 | 43 | 44 | 45 | * Navigate to the Amazon Connect console (AWS), and select on your Amazon Connect instance name 46 | * Goto `Approved origins` then `+ Add origin` 47 | * Enter the Amplify hosting URL, then click `Add` (Example URL `https://main.d13aaabbbccc.amplifyapp.com`; remove the trailing '/') 48 | 49 | ### Testing 50 | 51 | * Log in to the Amplify web app, create an account, then login to Amazon Connect 52 | * Start a customer chat (Go to `https:///connect/test-chat`) 53 | * Connect through to your agent that's running the new WebApp 54 | * As the customer type some text in French and you'll see the agent translate app show 'Translate - (fr) French' 55 | * As the agent type in English into the translate textbox and press enter. This will be converted to french and sent back to the customer as french 56 | 57 | 58 | ### Custom Terminologies 59 | 60 | * Custom Terminologies is supported by the web app, and a file is created upon installation which can be updated by following the steps below: 61 | * Update the provided Custom Terminologies files 62 | * Go to https://console.aws.amazon.com/translate/home?#terminology 63 | * Click on the radio button next to `connectChatTranslate` 64 | * Download the CSV 65 | * Edit the CSV, by adding additional rows. 'en' as the source language and using the columns for the destination language (Feel free to add additional languages in column D onwards) 66 | * 67 | * Update the `connectChatTranslate` custom terminologies with the updated CSV 68 | * For more information visit: https://docs.aws.amazon.com/transcribe/latest/dg/how-vocabulary.html 69 | 70 | 71 | ### Features 72 | 73 | * The web app looks for a contact attribute of `x_lang` if set then the language will be set accordingly. (Supported languages for translation: https://docs.aws.amazon.com/translate/latest/dg/what-is.html) 74 | * If no `x_lang` contact attribute is set, the FIRST message from the customer will be used to perform language detection using Amazon Comprehend. (Supported languages for detection: https://docs.aws.amazon.com/comprehend/latest/dg/how-languages.html) 75 | * Agent side is hardcoded to `'en'` 76 | 77 | 78 | ### Costs 79 | 80 | All the services used are included within the [AWS Free tier](https://aws.amazon.com/free/) offer. However, should you exceed this you will be charged for the services consumed. Please see the [clean up](https://github.com/aws-samples/amazon-connect-chat-translate#clean-up) section to delete all deployed infrastructure. 81 | 82 | Outside of free tier you will be charged for the consumption of the services used. For example. 83 | 84 | [Amazon Connect Pricing](https://aws.amazon.com/connect/pricing/) for chat is : $0.004 per message 85 | [Amazon Translate Pricing](https://aws.amazon.com/translate/pricing/) : $15 per million characters 86 | [Amazon API Gateway](https://aws.amazon.com/api-gateway/pricing/) : $1 per per million requests 87 | [AWS Lambda](https://aws.amazon.com/lambda/pricing/) : $0.20 per million requests 88 | [AWS Amplify ](https://aws.amazon.com/amplify/pricing/?nc=sn&loc=3) : $0.01 per build minute and $0.23 per GB stored per month and $0.15 per GB served 89 | 90 | Therefore a very approximate cost for 100 users for a month, handling 59 chats per day each for 21 days (a month) we have: 91 | 92 | | Service | Costs (Month) | 93 | |---------------------|---------------| 94 | | Amacon Connect Chat | $8,400.00 | 95 | | Amazon Translate | $425.25 | 96 | | Amazon Comprehend | $63.00 | 97 | | Amazon API Gateway | $2.10 | 98 | | AWS Lambda | $0.22 | 99 | | Amplify Build | $0.08 | 100 | | Amplify Hosting | $0.01 | 101 | | Amplify Served | $0.37 | 102 | | | | 103 | | Total (124k chats) | $8,891.03 | 104 | 105 | Assumptions. 106 | 107 | - 30% of messages are translated 108 | - 15% of the chats require language detection 109 | - 10 Page loads per user per day 110 | - 150 characters average message size for translation 111 | - Average messages per chat 17 112 | 113 | 114 | ### Todo 115 | 116 | * More testing & code clean up 117 | * Enable language selection for the customer side 118 | * Enable language section for the agent side 119 | * Translate message prior connect to an agent 120 | * Store state locally to survive page refresh 121 | * Prevent translation attempt for same language pairs 122 | 123 | 124 | ### Clean up 125 | 126 | Within the amplify UI navigate to your app, on the top right select `Actions` and then `Delete app`. 127 | 128 | ### Contributors 129 | - Daniel Bloy 130 | - Bob Strahan 131 | - Vishal Nayak 132 | - EJ Ferrell 133 | - Kishore Dhamodaran 134 | -------------------------------------------------------------------------------- /amplify.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | backend: 3 | phases: 4 | build: 5 | commands: 6 | - '# Execute Amplify CLI with the helper script' 7 | - REACT_APP_CONNECT_INSTANCE_ID=$REACT_APP_CONNECT_INSTANCE_ID 8 | - amplifyPush --simple 9 | frontend: 10 | phases: 11 | preBuild: 12 | commands: 13 | - yarn install 14 | build: 15 | commands: 16 | - REACT_APP_CONNECT_REGION=${REACT_APP_CONNECT_REGION} 17 | - REACT_APP_CONNECT_INSTANCE_ID=${REACT_APP_CONNECT_INSTANCE_ID} 18 | - yarn run build 19 | artifacts: 20 | baseDirectory: build 21 | files: 22 | - '**/*' 23 | cache: 24 | paths: 25 | - node_modules/**/* 26 | -------------------------------------------------------------------------------- /amplify/.config/project-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "ConnectTranslateBlog", 3 | "version": "3.1", 4 | "frontend": "javascript", 5 | "javascript": { 6 | "framework": "react", 7 | "config": { 8 | "SourceDir": "src", 9 | "DistributionDir": "build", 10 | "BuildCommand": "npm run-script build", 11 | "StartCommand": "npm run-script start" 12 | } 13 | }, 14 | "providers": [ 15 | "awscloudformation" 16 | ] 17 | } -------------------------------------------------------------------------------- /amplify/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Amplify CLI 2 | This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli). 3 | 4 | Helpful resources: 5 | - Amplify documentation: https://docs.amplify.aws 6 | - Amplify CLI documentation: https://docs.amplify.aws/cli 7 | - More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files 8 | - Join Amplify's community: https://amplify.aws/community/ 9 | -------------------------------------------------------------------------------- /amplify/backend/api/amazonTranslateAPI/amazonTranslateAPI-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"api-API Gateway\",\"metadata\":{}}", 4 | "Parameters": { 5 | "env": { 6 | "Type": "String" 7 | }, 8 | "functionamazonTranslateLambdaName": { 9 | "Type": "String", 10 | "Default": "functionamazonTranslateLambdaName" 11 | }, 12 | "functionamazonTranslateLambdaArn": { 13 | "Type": "String", 14 | "Default": "functionamazonTranslateLambdaArn" 15 | } 16 | }, 17 | "Conditions": { 18 | "ShouldNotCreateEnvResources": { 19 | "Fn::Equals": [ 20 | { 21 | "Ref": "env" 22 | }, 23 | "NONE" 24 | ] 25 | } 26 | }, 27 | "Resources": { 28 | "amazonTranslateAPI": { 29 | "Type": "AWS::ApiGateway::RestApi", 30 | "Properties": { 31 | "Description": "", 32 | "Name": "amazonTranslateAPI", 33 | "Body": { 34 | "swagger": "2.0", 35 | "info": { 36 | "version": "2018-05-24T17:52:00Z", 37 | "title": "amazonTranslateAPI" 38 | }, 39 | "host": { 40 | "Fn::Join": [ 41 | "", 42 | [ 43 | "apigateway.", 44 | { 45 | "Ref": "AWS::Region" 46 | }, 47 | ".amazonaws.com" 48 | ] 49 | ] 50 | }, 51 | "basePath": { 52 | "Fn::If": [ 53 | "ShouldNotCreateEnvResources", 54 | "/Prod", 55 | { 56 | "Fn::Join": [ 57 | "", 58 | [ 59 | "/", 60 | { 61 | "Ref": "env" 62 | } 63 | ] 64 | ] 65 | } 66 | ] 67 | }, 68 | "schemes": [ 69 | "https" 70 | ], 71 | "paths": { 72 | "/translate": { 73 | "options": { 74 | "consumes": [ 75 | "application/json" 76 | ], 77 | "produces": [ 78 | "application/json" 79 | ], 80 | "responses": { 81 | "200": { 82 | "description": "200 response", 83 | "headers": { 84 | "Access-Control-Allow-Origin": { 85 | "type": "string" 86 | }, 87 | "Access-Control-Allow-Methods": { 88 | "type": "string" 89 | }, 90 | "Access-Control-Allow-Headers": { 91 | "type": "string" 92 | } 93 | } 94 | } 95 | }, 96 | "x-amazon-apigateway-integration": { 97 | "responses": { 98 | "default": { 99 | "statusCode": "200", 100 | "responseParameters": { 101 | "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", 102 | "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", 103 | "method.response.header.Access-Control-Allow-Origin": "'*'" 104 | } 105 | } 106 | }, 107 | "requestTemplates": { 108 | "application/json": "{\"statusCode\": 200}" 109 | }, 110 | "passthroughBehavior": "when_no_match", 111 | "type": "mock" 112 | } 113 | }, 114 | "x-amazon-apigateway-any-method": { 115 | "consumes": [ 116 | "application/json" 117 | ], 118 | "produces": [ 119 | "application/json" 120 | ], 121 | "parameters": [ 122 | { 123 | "in": "body", 124 | "name": "RequestSchema", 125 | "required": false, 126 | "schema": { 127 | "$ref": "#/definitions/RequestSchema" 128 | } 129 | } 130 | ], 131 | "responses": { 132 | "200": { 133 | "description": "200 response", 134 | "schema": { 135 | "$ref": "#/definitions/ResponseSchema" 136 | } 137 | } 138 | }, 139 | "security": [ 140 | { 141 | "sigv4": [] 142 | } 143 | ], 144 | "x-amazon-apigateway-integration": { 145 | "responses": { 146 | "default": { 147 | "statusCode": "200" 148 | } 149 | }, 150 | "uri": { 151 | "Fn::Join": [ 152 | "", 153 | [ 154 | "arn:aws:apigateway:", 155 | { 156 | "Ref": "AWS::Region" 157 | }, 158 | ":lambda:path/2015-03-31/functions/", 159 | { 160 | "Ref": "functionamazonTranslateLambdaArn" 161 | }, 162 | "/invocations" 163 | ] 164 | ] 165 | }, 166 | "passthroughBehavior": "when_no_match", 167 | "httpMethod": "POST", 168 | "type": "aws_proxy" 169 | } 170 | } 171 | }, 172 | "/translate/{proxy+}": { 173 | "options": { 174 | "consumes": [ 175 | "application/json" 176 | ], 177 | "produces": [ 178 | "application/json" 179 | ], 180 | "responses": { 181 | "200": { 182 | "description": "200 response", 183 | "headers": { 184 | "Access-Control-Allow-Origin": { 185 | "type": "string" 186 | }, 187 | "Access-Control-Allow-Methods": { 188 | "type": "string" 189 | }, 190 | "Access-Control-Allow-Headers": { 191 | "type": "string" 192 | } 193 | } 194 | } 195 | }, 196 | "x-amazon-apigateway-integration": { 197 | "responses": { 198 | "default": { 199 | "statusCode": "200", 200 | "responseParameters": { 201 | "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", 202 | "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", 203 | "method.response.header.Access-Control-Allow-Origin": "'*'" 204 | } 205 | } 206 | }, 207 | "requestTemplates": { 208 | "application/json": "{\"statusCode\": 200}" 209 | }, 210 | "passthroughBehavior": "when_no_match", 211 | "type": "mock" 212 | } 213 | }, 214 | "x-amazon-apigateway-any-method": { 215 | "consumes": [ 216 | "application/json" 217 | ], 218 | "produces": [ 219 | "application/json" 220 | ], 221 | "parameters": [ 222 | { 223 | "in": "body", 224 | "name": "RequestSchema", 225 | "required": false, 226 | "schema": { 227 | "$ref": "#/definitions/RequestSchema" 228 | } 229 | } 230 | ], 231 | "responses": { 232 | "200": { 233 | "description": "200 response", 234 | "schema": { 235 | "$ref": "#/definitions/ResponseSchema" 236 | } 237 | } 238 | }, 239 | "security": [ 240 | { 241 | "sigv4": [] 242 | } 243 | ], 244 | "x-amazon-apigateway-integration": { 245 | "responses": { 246 | "default": { 247 | "statusCode": "200" 248 | } 249 | }, 250 | "uri": { 251 | "Fn::Join": [ 252 | "", 253 | [ 254 | "arn:aws:apigateway:", 255 | { 256 | "Ref": "AWS::Region" 257 | }, 258 | ":lambda:path/2015-03-31/functions/", 259 | { 260 | "Ref": "functionamazonTranslateLambdaArn" 261 | }, 262 | "/invocations" 263 | ] 264 | ] 265 | }, 266 | "passthroughBehavior": "when_no_match", 267 | "httpMethod": "POST", 268 | "type": "aws_proxy" 269 | } 270 | } 271 | } 272 | }, 273 | "securityDefinitions": { 274 | "sigv4": { 275 | "type": "apiKey", 276 | "name": "Authorization", 277 | "in": "header", 278 | "x-amazon-apigateway-authtype": "awsSigv4" 279 | } 280 | }, 281 | "definitions": { 282 | "RequestSchema": { 283 | "type": "object", 284 | "required": [ 285 | "request" 286 | ], 287 | "properties": { 288 | "request": { 289 | "type": "string" 290 | } 291 | }, 292 | "title": "Request Schema" 293 | }, 294 | "ResponseSchema": { 295 | "type": "object", 296 | "required": [ 297 | "response" 298 | ], 299 | "properties": { 300 | "response": { 301 | "type": "string" 302 | } 303 | }, 304 | "title": "Response Schema" 305 | } 306 | } 307 | }, 308 | "FailOnWarnings": true 309 | } 310 | }, 311 | "functionamazonTranslateLambdaPermissionamazonTranslateAPI": { 312 | "Type": "AWS::Lambda::Permission", 313 | "Properties": { 314 | "FunctionName": { 315 | "Ref": "functionamazonTranslateLambdaName" 316 | }, 317 | "Action": "lambda:InvokeFunction", 318 | "Principal": "apigateway.amazonaws.com", 319 | "SourceArn": { 320 | "Fn::Join": [ 321 | "", 322 | [ 323 | "arn:aws:execute-api:", 324 | { 325 | "Ref": "AWS::Region" 326 | }, 327 | ":", 328 | { 329 | "Ref": "AWS::AccountId" 330 | }, 331 | ":", 332 | { 333 | "Ref": "amazonTranslateAPI" 334 | }, 335 | "/*/*/*" 336 | ] 337 | ] 338 | } 339 | } 340 | }, 341 | "DeploymentAPIGWamazonTranslateAPI": { 342 | "Type": "AWS::ApiGateway::Deployment", 343 | "Properties": { 344 | "Description": "The Development stage deployment of your API.", 345 | "StageName": { 346 | "Fn::If": [ 347 | "ShouldNotCreateEnvResources", 348 | "Prod", 349 | { 350 | "Ref": "env" 351 | } 352 | ] 353 | }, 354 | "RestApiId": { 355 | "Ref": "amazonTranslateAPI" 356 | } 357 | } 358 | } 359 | }, 360 | "Outputs": { 361 | "RootUrl": { 362 | "Description": "Root URL of the API gateway", 363 | "Value": { 364 | "Fn::Join": [ 365 | "", 366 | [ 367 | "https://", 368 | { 369 | "Ref": "amazonTranslateAPI" 370 | }, 371 | ".execute-api.", 372 | { 373 | "Ref": "AWS::Region" 374 | }, 375 | ".amazonaws.com/", 376 | { 377 | "Fn::If": [ 378 | "ShouldNotCreateEnvResources", 379 | "Prod", 380 | { 381 | "Ref": "env" 382 | } 383 | ] 384 | } 385 | ] 386 | ] 387 | } 388 | }, 389 | "ApiName": { 390 | "Description": "API Friendly name", 391 | "Value": "amazonTranslateAPI" 392 | }, 393 | "ApiId": { 394 | "Description": "API ID (prefix of API URL)", 395 | "Value": { 396 | "Ref": "amazonTranslateAPI" 397 | } 398 | } 399 | } 400 | } -------------------------------------------------------------------------------- /amplify/backend/api/amazonTranslateAPI/api-params.json: -------------------------------------------------------------------------------- 1 | { 2 | "paths": [ 3 | { 4 | "name": "/translate", 5 | "lambdaFunction": "amazonTranslateLambda", 6 | "privacy": { 7 | "private": true, 8 | "auth": [ 9 | "/POST", 10 | "/GET", 11 | "/PUT", 12 | "/PATCH", 13 | "/DELETE" 14 | ] 15 | }, 16 | "policyResourceName": "/translate" 17 | } 18 | ], 19 | "resourceName": "amazonTranslateAPI", 20 | "apiName": "amazonTranslateAPI", 21 | "functionArns": [ 22 | { 23 | "lambdaFunction": "amazonTranslateLambda" 24 | } 25 | ], 26 | "privacy": { 27 | "auth": 1, 28 | "unauth": 0, 29 | "authRoleName": "amplify-vfgolddemo-dev-212450-authRole", 30 | "unAuthRoleName": "amplify-vfgolddemo-dev-212450-unauthRole" 31 | }, 32 | "dependsOn": [ 33 | { 34 | "category": "function", 35 | "resourceName": "amazonTranslateLambda", 36 | "attributes": [ 37 | "Name", 38 | "Arn" 39 | ] 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /amplify/backend/api/amazonTranslateAPI/parameters.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /amplify/backend/auth/connecttranslateblog690eb6d1/cli-inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "cognitoConfig": { 4 | "identityPoolName": "connecttranslateblog690eb6d1_identitypool_690eb6d1", 5 | "allowUnauthenticatedIdentities": false, 6 | "resourceNameTruncated": "connec690eb6d1", 7 | "userPoolName": "connecttranslateblog690eb6d1_userpool_690eb6d1", 8 | "autoVerifiedAttributes": [ 9 | "email" 10 | ], 11 | "mfaConfiguration": "OFF", 12 | "mfaTypes": [ 13 | "SMS Text Message" 14 | ], 15 | "smsAuthenticationMessage": "Your authentication code is {####}", 16 | "smsVerificationMessage": "Your verification code is {####}", 17 | "emailVerificationSubject": "Your verification code", 18 | "emailVerificationMessage": "Your verification code is {####}", 19 | "defaultPasswordPolicy": false, 20 | "passwordPolicyMinLength": 8, 21 | "passwordPolicyCharacters": [], 22 | "requiredAttributes": [ 23 | "email" 24 | ], 25 | "aliasAttributes": [], 26 | "userpoolClientGenerateSecret": false, 27 | "userpoolClientRefreshTokenValidity": 30, 28 | "userpoolClientWriteAttributes": [ 29 | "email" 30 | ], 31 | "userpoolClientReadAttributes": [ 32 | "email" 33 | ], 34 | "userpoolClientLambdaRole": "connec690eb6d1_userpoolclient_lambda_role", 35 | "userpoolClientSetAttributes": false, 36 | "authSelections": "identityPoolAndUserPool", 37 | "resourceName": "connecttranslateblog690eb6d1", 38 | "serviceName": "Cognito", 39 | "useDefault": "manual", 40 | "sharedId": "690eb6d1", 41 | "userPoolGroupList": [], 42 | "usernameAttributes": [ 43 | "email" 44 | ], 45 | "authRoleArn": { 46 | "Fn::GetAtt": [ 47 | "AuthRole", 48 | "Arn" 49 | ] 50 | }, 51 | "unauthRoleArn": { 52 | "Fn::GetAtt": [ 53 | "UnauthRole", 54 | "Arn" 55 | ] 56 | }, 57 | "breakCircularDependency": false, 58 | "useEnabledMfas": false, 59 | "dependsOn": [], 60 | "thirdPartyAuth": false, 61 | "userPoolGroups": false, 62 | "adminQueries": false, 63 | "triggers": {}, 64 | "hostedUI": false, 65 | "authProviders": [], 66 | "parentStack": { 67 | "Ref": "AWS::StackId" 68 | }, 69 | "permissions": [] 70 | } 71 | } -------------------------------------------------------------------------------- /amplify/backend/backend-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "api": { 3 | "amazonTranslateAPI": { 4 | "dependsOn": [ 5 | { 6 | "attributes": [ 7 | "Name", 8 | "Arn" 9 | ], 10 | "category": "function", 11 | "resourceName": "amazonTranslateLambda" 12 | } 13 | ], 14 | "providerPlugin": "awscloudformation", 15 | "service": "API Gateway" 16 | } 17 | }, 18 | "auth": { 19 | "connecttranslateblog690eb6d1": { 20 | "customAuth": false, 21 | "dependsOn": [], 22 | "frontendAuthConfig": { 23 | "mfaConfiguration": "OFF", 24 | "mfaTypes": [ 25 | "SMS" 26 | ], 27 | "passwordProtectionSettings": { 28 | "passwordPolicyCharacters": [], 29 | "passwordPolicyMinLength": 8 30 | }, 31 | "signupAttributes": [ 32 | "EMAIL" 33 | ], 34 | "socialProviders": [], 35 | "usernameAttributes": [ 36 | "EMAIL" 37 | ], 38 | "verificationMechanisms": [ 39 | "EMAIL" 40 | ] 41 | }, 42 | "providerPlugin": "awscloudformation", 43 | "service": "Cognito" 44 | } 45 | }, 46 | "custom": { 47 | "environmentIntegration": { 48 | "dependsOn": [ 49 | { 50 | "attributes": [ 51 | "Name", 52 | "Arn" 53 | ], 54 | "category": "function", 55 | "resourceName": "postInstallScript" 56 | }, 57 | { 58 | "category": "hosting", 59 | "resourceName": "amplifyhosting" 60 | } 61 | ], 62 | "providerPlugin": "awscloudformation", 63 | "service": "Custom::customhelper" 64 | } 65 | }, 66 | "function": { 67 | "amazonTranslateLambda": { 68 | "build": true, 69 | "dependsOn": [], 70 | "providerPlugin": "awscloudformation", 71 | "service": "Lambda" 72 | }, 73 | "postInstallScript": { 74 | "build": true, 75 | "providerPlugin": "awscloudformation", 76 | "service": "Lambda" 77 | } 78 | }, 79 | "hosting": { 80 | "amplifyhosting": { 81 | "providerPlugin": "awscloudformation", 82 | "service": "amplifyhosting", 83 | "type": "manual" 84 | } 85 | }, 86 | "parameters": { 87 | "AMPLIFY_function_amazonTranslateLambda_deploymentBucketName": { 88 | "usedBy": [ 89 | { 90 | "category": "function", 91 | "resourceName": "amazonTranslateLambda" 92 | } 93 | ] 94 | }, 95 | "AMPLIFY_function_amazonTranslateLambda_s3Key": { 96 | "usedBy": [ 97 | { 98 | "category": "function", 99 | "resourceName": "amazonTranslateLambda" 100 | } 101 | ] 102 | }, 103 | "AMPLIFY_function_postInstallScript_deploymentBucketName": { 104 | "usedBy": [ 105 | { 106 | "category": "function", 107 | "resourceName": "postInstallScript" 108 | } 109 | ] 110 | }, 111 | "AMPLIFY_function_postInstallScript_s3Key": { 112 | "usedBy": [ 113 | { 114 | "category": "function", 115 | "resourceName": "postInstallScript" 116 | } 117 | ] 118 | }, 119 | "AMPLIFY_hosting_amplifyhosting_appId": { 120 | "usedBy": [ 121 | { 122 | "category": "hosting", 123 | "resourceName": "amplifyhosting" 124 | } 125 | ] 126 | }, 127 | "AMPLIFY_hosting_amplifyhosting_type": { 128 | "usedBy": [ 129 | { 130 | "category": "hosting", 131 | "resourceName": "amplifyhosting" 132 | } 133 | ] 134 | } 135 | }, 136 | "predictions": { 137 | "interpretTextcabd9d8d": { 138 | "interpretType": "interpretText", 139 | "providerPlugin": "awscloudformation", 140 | "service": "Comprehend" 141 | }, 142 | "translateText0519c50f": { 143 | "convertType": "translateText", 144 | "providerPlugin": "awscloudformation", 145 | "service": "Translate" 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /amplify/backend/custom/environmentIntegration/custom-environmentIntegration-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "functionpostInstallScriptName": { 3 | "Fn::GetAtt": [ 4 | "functionpostInstallScript", 5 | "Outputs.Name" 6 | ] 7 | }, 8 | "functionpostInstallScriptArn": { 9 | "Fn::GetAtt": [ 10 | "functionpostInstallScript", 11 | "Outputs.Arn" 12 | ] 13 | } 14 | } -------------------------------------------------------------------------------- /amplify/backend/custom/environmentIntegration/custom-environmentIntegration-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"custom-Custom::customhelper\",\"metadata\":{}}", 4 | "Parameters": { 5 | "env": { 6 | "Type": "String" 7 | }, 8 | "functionpostInstallScriptName": { 9 | "Type": "String" 10 | }, 11 | "functionpostInstallScriptArn": { 12 | "Type": "String" 13 | } 14 | }, 15 | "Resources": { 16 | "environmentIntegration": { 17 | "Type": "Custom::customhelper", 18 | "Properties": { 19 | "ServiceToken": { 20 | "Ref": "functionpostInstallScriptArn" 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/amazonTranslateLambda-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"function-Lambda\",\"metadata\":{}}", 4 | "Parameters": { 5 | "CloudWatchRule": { 6 | "Type": "String", 7 | "Default": "NONE", 8 | "Description": " Schedule Expression" 9 | }, 10 | "deploymentBucketName": { 11 | "Type": "String" 12 | }, 13 | "env": { 14 | "Type": "String" 15 | }, 16 | "s3Key": { 17 | "Type": "String" 18 | } 19 | }, 20 | "Conditions": { 21 | "ShouldNotCreateEnvResources": { 22 | "Fn::Equals": [ 23 | { 24 | "Ref": "env" 25 | }, 26 | "NONE" 27 | ] 28 | } 29 | }, 30 | "Resources": { 31 | "LambdaFunction": { 32 | "Type": "AWS::Lambda::Function", 33 | "Metadata": { 34 | "aws:asset:path": "./src", 35 | "aws:asset:property": "Code" 36 | }, 37 | "Properties": { 38 | "Code": { 39 | "S3Bucket": { 40 | "Ref": "deploymentBucketName" 41 | }, 42 | "S3Key": { 43 | "Ref": "s3Key" 44 | } 45 | }, 46 | "Handler": "index.handler", 47 | "FunctionName": { 48 | "Fn::If": [ 49 | "ShouldNotCreateEnvResources", 50 | "amazonTranslateLambda", 51 | { 52 | "Fn::Join": [ 53 | "", 54 | [ 55 | "amazonTranslateLambda", 56 | "-", 57 | { 58 | "Ref": "env" 59 | } 60 | ] 61 | ] 62 | } 63 | ] 64 | }, 65 | "Environment": { 66 | "Variables": { 67 | "ENV": { 68 | "Ref": "env" 69 | }, 70 | "REGION": { 71 | "Ref": "AWS::Region" 72 | } 73 | } 74 | }, 75 | "Role": { 76 | "Fn::GetAtt": [ 77 | "LambdaExecutionRole", 78 | "Arn" 79 | ] 80 | }, 81 | "Runtime": "nodejs18.x", 82 | "Layers": [], 83 | "Timeout": "25" 84 | } 85 | }, 86 | "LambdaExecutionRole": { 87 | "Type": "AWS::IAM::Role", 88 | "Properties": { 89 | "RoleName": { 90 | "Fn::If": [ 91 | "ShouldNotCreateEnvResources", 92 | "vfgolddemoLambdaRole83f08017", 93 | { 94 | "Fn::Join": [ 95 | "", 96 | [ 97 | "vfgolddemoLambdaRole83f08017", 98 | "-", 99 | { 100 | "Ref": "env" 101 | } 102 | ] 103 | ] 104 | } 105 | ] 106 | }, 107 | "AssumeRolePolicyDocument": { 108 | "Version": "2012-10-17", 109 | "Statement": [ 110 | { 111 | "Effect": "Allow", 112 | "Principal": { 113 | "Service": [ 114 | "lambda.amazonaws.com" 115 | ] 116 | }, 117 | "Action": [ 118 | "sts:AssumeRole" 119 | ] 120 | } 121 | ] 122 | } 123 | } 124 | }, 125 | "lambdaexecutionpolicy": { 126 | "DependsOn": [ 127 | "LambdaExecutionRole" 128 | ], 129 | "Type": "AWS::IAM::Policy", 130 | "Properties": { 131 | "PolicyName": "lambda-execution-policy", 132 | "Roles": [ 133 | { 134 | "Ref": "LambdaExecutionRole" 135 | } 136 | ], 137 | "PolicyDocument": { 138 | "Version": "2012-10-17", 139 | "Statement": [ 140 | { 141 | "Effect": "Allow", 142 | "Action": [ 143 | "logs:CreateLogGroup", 144 | "logs:CreateLogStream", 145 | "logs:PutLogEvents" 146 | ], 147 | "Resource": { 148 | "Fn::Sub": [ 149 | "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", 150 | { 151 | "region": { 152 | "Ref": "AWS::Region" 153 | }, 154 | "account": { 155 | "Ref": "AWS::AccountId" 156 | }, 157 | "lambda": { 158 | "Ref": "LambdaFunction" 159 | } 160 | } 161 | ] 162 | } 163 | }, 164 | { 165 | "Effect": "Allow", 166 | "Action": [ 167 | "translate:TranslateText" 168 | ], 169 | "Resource": "*" 170 | } 171 | ] 172 | } 173 | } 174 | } 175 | }, 176 | "Outputs": { 177 | "Name": { 178 | "Value": { 179 | "Ref": "LambdaFunction" 180 | } 181 | }, 182 | "Arn": { 183 | "Value": { 184 | "Fn::GetAtt": [ 185 | "LambdaFunction", 186 | "Arn" 187 | ] 188 | } 189 | }, 190 | "Region": { 191 | "Value": { 192 | "Ref": "AWS::Region" 193 | } 194 | }, 195 | "LambdaExecutionRole": { 196 | "Value": { 197 | "Ref": "LambdaExecutionRole" 198 | } 199 | }, 200 | "LambdaExecutionRoleArn": { 201 | "Value": { 202 | "Fn::GetAtt": [ 203 | "LambdaExecutionRole", 204 | "Arn" 205 | ] 206 | } 207 | } 208 | } 209 | } -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/amplify.state: -------------------------------------------------------------------------------- 1 | { 2 | "pluginId": "amplify-nodejs-function-runtime-provider", 3 | "functionRuntime": "nodejs", 4 | "useLegacyBuild": true, 5 | "defaultEditorFile": "src/index.js", 6 | "scripts": { 7 | "build": "npm install --no-bin-links --production" 8 | } 9 | } -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/function-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "lambdaLayers": [] 3 | } -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/parameters.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/src/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "key1": "value1", 3 | "key2": "value2", 4 | "key3": "value3" 5 | } 6 | -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/src/index.js: -------------------------------------------------------------------------------- 1 | const AWS = require('aws-sdk'); 2 | 3 | const translate = new AWS.Translate({ apiVersion: '2017-07-01' }); // Fix API version (best practice) 4 | 5 | exports.handler = (event, context, callback) => { 6 | let payload = JSON.parse(event.body); 7 | console.log("event: ", event); 8 | //console.log("event: ", payload.terminologyNames); 9 | // body: '{"content":"hello","sourceLang":"en","targetLang":"en"}' 10 | 11 | let params = { 12 | SourceLanguageCode: payload.sourceLang, 13 | /* required */ 14 | TargetLanguageCode: payload.targetLang, 15 | /* required */ 16 | Text: payload.content, 17 | /* required */ 18 | //TerminologyNames: payload.terminologyNames 19 | }; 20 | console.log("parameters: " + JSON.stringify(params)); 21 | 22 | translate.translateText( 23 | params, 24 | function(error, response) { 25 | 26 | if (error) { 27 | console.log(error); 28 | callback(null, { "statusCode": 500, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*" }, "body": JSON.stringify((error)) }); 29 | } 30 | else { 31 | console.log('respoonse ' + JSON.stringify(response)); 32 | callback(null, { "statusCode": 200, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*" }, "body": JSON.stringify((response)) }); 33 | } 34 | } 35 | 36 | ); 37 | }; 38 | -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amazonTranslateLambda", 3 | "version": "2.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "amazonTranslateLambda", 9 | "version": "2.0.0", 10 | "license": "Apache-2.0", 11 | "dependencies": { 12 | "aws-sdk": "^2.1113.0" 13 | } 14 | }, 15 | "node_modules/available-typed-arrays": { 16 | "version": "1.0.5", 17 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", 18 | "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", 19 | "engines": { 20 | "node": ">= 0.4" 21 | }, 22 | "funding": { 23 | "url": "https://github.com/sponsors/ljharb" 24 | } 25 | }, 26 | "node_modules/aws-sdk": { 27 | "version": "2.1462.0", 28 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1462.0.tgz", 29 | "integrity": "sha512-gEcp/YWUp0zrM/LujI3cTLbOTK6XLwGSHWQII57jjRvjsIMacLomnIcd7fGKSfREAIHr5saexISRsnXhfI+Vgw==", 30 | "dependencies": { 31 | "buffer": "4.9.2", 32 | "events": "1.1.1", 33 | "ieee754": "1.1.13", 34 | "jmespath": "0.16.0", 35 | "querystring": "0.2.0", 36 | "sax": "1.2.1", 37 | "url": "0.10.3", 38 | "util": "^0.12.4", 39 | "uuid": "8.0.0", 40 | "xml2js": "0.5.0" 41 | }, 42 | "engines": { 43 | "node": ">= 10.0.0" 44 | } 45 | }, 46 | "node_modules/base64-js": { 47 | "version": "1.5.1", 48 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 49 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 50 | "funding": [ 51 | { 52 | "type": "github", 53 | "url": "https://github.com/sponsors/feross" 54 | }, 55 | { 56 | "type": "patreon", 57 | "url": "https://www.patreon.com/feross" 58 | }, 59 | { 60 | "type": "consulting", 61 | "url": "https://feross.org/support" 62 | } 63 | ] 64 | }, 65 | "node_modules/buffer": { 66 | "version": "4.9.2", 67 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 68 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 69 | "dependencies": { 70 | "base64-js": "^1.0.2", 71 | "ieee754": "^1.1.4", 72 | "isarray": "^1.0.0" 73 | } 74 | }, 75 | "node_modules/call-bind": { 76 | "version": "1.0.2", 77 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 78 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 79 | "dependencies": { 80 | "function-bind": "^1.1.1", 81 | "get-intrinsic": "^1.0.2" 82 | }, 83 | "funding": { 84 | "url": "https://github.com/sponsors/ljharb" 85 | } 86 | }, 87 | "node_modules/events": { 88 | "version": "1.1.1", 89 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 90 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", 91 | "engines": { 92 | "node": ">=0.4.x" 93 | } 94 | }, 95 | "node_modules/for-each": { 96 | "version": "0.3.3", 97 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 98 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 99 | "dependencies": { 100 | "is-callable": "^1.1.3" 101 | } 102 | }, 103 | "node_modules/function-bind": { 104 | "version": "1.1.1", 105 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 106 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 107 | }, 108 | "node_modules/get-intrinsic": { 109 | "version": "1.2.1", 110 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", 111 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", 112 | "dependencies": { 113 | "function-bind": "^1.1.1", 114 | "has": "^1.0.3", 115 | "has-proto": "^1.0.1", 116 | "has-symbols": "^1.0.3" 117 | }, 118 | "funding": { 119 | "url": "https://github.com/sponsors/ljharb" 120 | } 121 | }, 122 | "node_modules/gopd": { 123 | "version": "1.0.1", 124 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 125 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 126 | "dependencies": { 127 | "get-intrinsic": "^1.1.3" 128 | }, 129 | "funding": { 130 | "url": "https://github.com/sponsors/ljharb" 131 | } 132 | }, 133 | "node_modules/has": { 134 | "version": "1.0.3", 135 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 136 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 137 | "dependencies": { 138 | "function-bind": "^1.1.1" 139 | }, 140 | "engines": { 141 | "node": ">= 0.4.0" 142 | } 143 | }, 144 | "node_modules/has-proto": { 145 | "version": "1.0.1", 146 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 147 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 148 | "engines": { 149 | "node": ">= 0.4" 150 | }, 151 | "funding": { 152 | "url": "https://github.com/sponsors/ljharb" 153 | } 154 | }, 155 | "node_modules/has-symbols": { 156 | "version": "1.0.3", 157 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 158 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 159 | "engines": { 160 | "node": ">= 0.4" 161 | }, 162 | "funding": { 163 | "url": "https://github.com/sponsors/ljharb" 164 | } 165 | }, 166 | "node_modules/has-tostringtag": { 167 | "version": "1.0.0", 168 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 169 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 170 | "dependencies": { 171 | "has-symbols": "^1.0.2" 172 | }, 173 | "engines": { 174 | "node": ">= 0.4" 175 | }, 176 | "funding": { 177 | "url": "https://github.com/sponsors/ljharb" 178 | } 179 | }, 180 | "node_modules/ieee754": { 181 | "version": "1.1.13", 182 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 183 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 184 | }, 185 | "node_modules/inherits": { 186 | "version": "2.0.4", 187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 188 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 189 | }, 190 | "node_modules/is-arguments": { 191 | "version": "1.1.1", 192 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 193 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 194 | "dependencies": { 195 | "call-bind": "^1.0.2", 196 | "has-tostringtag": "^1.0.0" 197 | }, 198 | "engines": { 199 | "node": ">= 0.4" 200 | }, 201 | "funding": { 202 | "url": "https://github.com/sponsors/ljharb" 203 | } 204 | }, 205 | "node_modules/is-callable": { 206 | "version": "1.2.7", 207 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 208 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", 209 | "engines": { 210 | "node": ">= 0.4" 211 | }, 212 | "funding": { 213 | "url": "https://github.com/sponsors/ljharb" 214 | } 215 | }, 216 | "node_modules/is-generator-function": { 217 | "version": "1.0.10", 218 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", 219 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", 220 | "dependencies": { 221 | "has-tostringtag": "^1.0.0" 222 | }, 223 | "engines": { 224 | "node": ">= 0.4" 225 | }, 226 | "funding": { 227 | "url": "https://github.com/sponsors/ljharb" 228 | } 229 | }, 230 | "node_modules/is-typed-array": { 231 | "version": "1.1.12", 232 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", 233 | "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", 234 | "dependencies": { 235 | "which-typed-array": "^1.1.11" 236 | }, 237 | "engines": { 238 | "node": ">= 0.4" 239 | }, 240 | "funding": { 241 | "url": "https://github.com/sponsors/ljharb" 242 | } 243 | }, 244 | "node_modules/isarray": { 245 | "version": "1.0.0", 246 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 247 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" 248 | }, 249 | "node_modules/jmespath": { 250 | "version": "0.16.0", 251 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", 252 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", 253 | "engines": { 254 | "node": ">= 0.6.0" 255 | } 256 | }, 257 | "node_modules/punycode": { 258 | "version": "1.3.2", 259 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 260 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 261 | }, 262 | "node_modules/querystring": { 263 | "version": "0.2.0", 264 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 265 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", 266 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", 267 | "engines": { 268 | "node": ">=0.4.x" 269 | } 270 | }, 271 | "node_modules/sax": { 272 | "version": "1.2.1", 273 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 274 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" 275 | }, 276 | "node_modules/url": { 277 | "version": "0.10.3", 278 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 279 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", 280 | "dependencies": { 281 | "punycode": "1.3.2", 282 | "querystring": "0.2.0" 283 | } 284 | }, 285 | "node_modules/util": { 286 | "version": "0.12.5", 287 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", 288 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", 289 | "dependencies": { 290 | "inherits": "^2.0.3", 291 | "is-arguments": "^1.0.4", 292 | "is-generator-function": "^1.0.7", 293 | "is-typed-array": "^1.1.3", 294 | "which-typed-array": "^1.1.2" 295 | } 296 | }, 297 | "node_modules/uuid": { 298 | "version": "8.0.0", 299 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", 300 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", 301 | "bin": { 302 | "uuid": "dist/bin/uuid" 303 | } 304 | }, 305 | "node_modules/which-typed-array": { 306 | "version": "1.1.11", 307 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", 308 | "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", 309 | "dependencies": { 310 | "available-typed-arrays": "^1.0.5", 311 | "call-bind": "^1.0.2", 312 | "for-each": "^0.3.3", 313 | "gopd": "^1.0.1", 314 | "has-tostringtag": "^1.0.0" 315 | }, 316 | "engines": { 317 | "node": ">= 0.4" 318 | }, 319 | "funding": { 320 | "url": "https://github.com/sponsors/ljharb" 321 | } 322 | }, 323 | "node_modules/xml2js": { 324 | "version": "0.5.0", 325 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", 326 | "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", 327 | "dependencies": { 328 | "sax": ">=0.6.0", 329 | "xmlbuilder": "~11.0.0" 330 | }, 331 | "engines": { 332 | "node": ">=4.0.0" 333 | } 334 | }, 335 | "node_modules/xmlbuilder": { 336 | "version": "11.0.1", 337 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 338 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", 339 | "engines": { 340 | "node": ">=4.0" 341 | } 342 | } 343 | }, 344 | "dependencies": { 345 | "available-typed-arrays": { 346 | "version": "1.0.5", 347 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", 348 | "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" 349 | }, 350 | "aws-sdk": { 351 | "version": "2.1462.0", 352 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1462.0.tgz", 353 | "integrity": "sha512-gEcp/YWUp0zrM/LujI3cTLbOTK6XLwGSHWQII57jjRvjsIMacLomnIcd7fGKSfREAIHr5saexISRsnXhfI+Vgw==", 354 | "requires": { 355 | "buffer": "4.9.2", 356 | "events": "1.1.1", 357 | "ieee754": "1.1.13", 358 | "jmespath": "0.16.0", 359 | "querystring": "0.2.0", 360 | "sax": "1.2.1", 361 | "url": "0.10.3", 362 | "util": "^0.12.4", 363 | "uuid": "8.0.0", 364 | "xml2js": "0.5.0" 365 | } 366 | }, 367 | "base64-js": { 368 | "version": "1.5.1", 369 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 370 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 371 | }, 372 | "buffer": { 373 | "version": "4.9.2", 374 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 375 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 376 | "requires": { 377 | "base64-js": "^1.0.2", 378 | "ieee754": "^1.1.4", 379 | "isarray": "^1.0.0" 380 | } 381 | }, 382 | "call-bind": { 383 | "version": "1.0.2", 384 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 385 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 386 | "requires": { 387 | "function-bind": "^1.1.1", 388 | "get-intrinsic": "^1.0.2" 389 | } 390 | }, 391 | "events": { 392 | "version": "1.1.1", 393 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 394 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" 395 | }, 396 | "for-each": { 397 | "version": "0.3.3", 398 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 399 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 400 | "requires": { 401 | "is-callable": "^1.1.3" 402 | } 403 | }, 404 | "function-bind": { 405 | "version": "1.1.1", 406 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 407 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 408 | }, 409 | "get-intrinsic": { 410 | "version": "1.2.1", 411 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", 412 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", 413 | "requires": { 414 | "function-bind": "^1.1.1", 415 | "has": "^1.0.3", 416 | "has-proto": "^1.0.1", 417 | "has-symbols": "^1.0.3" 418 | } 419 | }, 420 | "gopd": { 421 | "version": "1.0.1", 422 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 423 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 424 | "requires": { 425 | "get-intrinsic": "^1.1.3" 426 | } 427 | }, 428 | "has": { 429 | "version": "1.0.3", 430 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 431 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 432 | "requires": { 433 | "function-bind": "^1.1.1" 434 | } 435 | }, 436 | "has-proto": { 437 | "version": "1.0.1", 438 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 439 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" 440 | }, 441 | "has-symbols": { 442 | "version": "1.0.3", 443 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 444 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 445 | }, 446 | "has-tostringtag": { 447 | "version": "1.0.0", 448 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 449 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 450 | "requires": { 451 | "has-symbols": "^1.0.2" 452 | } 453 | }, 454 | "ieee754": { 455 | "version": "1.1.13", 456 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 457 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 458 | }, 459 | "inherits": { 460 | "version": "2.0.4", 461 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 462 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 463 | }, 464 | "is-arguments": { 465 | "version": "1.1.1", 466 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 467 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 468 | "requires": { 469 | "call-bind": "^1.0.2", 470 | "has-tostringtag": "^1.0.0" 471 | } 472 | }, 473 | "is-callable": { 474 | "version": "1.2.7", 475 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 476 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" 477 | }, 478 | "is-generator-function": { 479 | "version": "1.0.10", 480 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", 481 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", 482 | "requires": { 483 | "has-tostringtag": "^1.0.0" 484 | } 485 | }, 486 | "is-typed-array": { 487 | "version": "1.1.12", 488 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", 489 | "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", 490 | "requires": { 491 | "which-typed-array": "^1.1.11" 492 | } 493 | }, 494 | "isarray": { 495 | "version": "1.0.0", 496 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 497 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" 498 | }, 499 | "jmespath": { 500 | "version": "0.16.0", 501 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", 502 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" 503 | }, 504 | "punycode": { 505 | "version": "1.3.2", 506 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 507 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 508 | }, 509 | "querystring": { 510 | "version": "0.2.0", 511 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 512 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" 513 | }, 514 | "sax": { 515 | "version": "1.2.1", 516 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 517 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" 518 | }, 519 | "url": { 520 | "version": "0.10.3", 521 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 522 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", 523 | "requires": { 524 | "punycode": "1.3.2", 525 | "querystring": "0.2.0" 526 | } 527 | }, 528 | "util": { 529 | "version": "0.12.5", 530 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", 531 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", 532 | "requires": { 533 | "inherits": "^2.0.3", 534 | "is-arguments": "^1.0.4", 535 | "is-generator-function": "^1.0.7", 536 | "is-typed-array": "^1.1.3", 537 | "which-typed-array": "^1.1.2" 538 | } 539 | }, 540 | "uuid": { 541 | "version": "8.0.0", 542 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", 543 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" 544 | }, 545 | "which-typed-array": { 546 | "version": "1.1.11", 547 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", 548 | "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", 549 | "requires": { 550 | "available-typed-arrays": "^1.0.5", 551 | "call-bind": "^1.0.2", 552 | "for-each": "^0.3.3", 553 | "gopd": "^1.0.1", 554 | "has-tostringtag": "^1.0.0" 555 | } 556 | }, 557 | "xml2js": { 558 | "version": "0.5.0", 559 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", 560 | "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", 561 | "requires": { 562 | "sax": ">=0.6.0", 563 | "xmlbuilder": "~11.0.0" 564 | } 565 | }, 566 | "xmlbuilder": { 567 | "version": "11.0.1", 568 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 569 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" 570 | } 571 | } 572 | } 573 | -------------------------------------------------------------------------------- /amplify/backend/function/amazonTranslateLambda/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amazonTranslateLambda", 3 | "version": "2.0.0", 4 | "description": "Lambda function generated by Amplify", 5 | "main": "index.js", 6 | "license": "Apache-2.0", 7 | "dependencies": { 8 | "aws-sdk": "^2.1113.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/amplify.state: -------------------------------------------------------------------------------- 1 | { 2 | "pluginId": "amplify-nodejs-function-runtime-provider", 3 | "functionRuntime": "nodejs", 4 | "useLegacyBuild": true, 5 | "defaultEditorFile": "src/index.js", 6 | "scripts": { 7 | "build": "npm install --no-bin-links --production" 8 | } 9 | } -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/function-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "lambdaLayers": [] 3 | } -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/postInstallScript-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"function-Lambda\",\"metadata\":{}}", 4 | "Parameters": { 5 | "CloudWatchRule": { 6 | "Type": "String", 7 | "Default": "NONE", 8 | "Description": " Schedule Expression" 9 | }, 10 | "deploymentBucketName": { 11 | "Type": "String" 12 | }, 13 | "env": { 14 | "Type": "String" 15 | }, 16 | "s3Key": { 17 | "Type": "String" 18 | }, 19 | "ConnectInstanceId": { 20 | "Type": "String", 21 | "Default": "ConnectInstanceId" 22 | } 23 | }, 24 | "Conditions": { 25 | "ShouldNotCreateEnvResources": { 26 | "Fn::Equals": [ 27 | { 28 | "Ref": "env" 29 | }, 30 | "NONE" 31 | ] 32 | } 33 | }, 34 | "Resources": { 35 | "LambdaFunction": { 36 | "Type": "AWS::Lambda::Function", 37 | "Metadata": { 38 | "aws:asset:path": "./src", 39 | "aws:asset:property": "Code" 40 | }, 41 | "Properties": { 42 | "Code": { 43 | "S3Bucket": { 44 | "Ref": "deploymentBucketName" 45 | }, 46 | "S3Key": { 47 | "Ref": "s3Key" 48 | } 49 | }, 50 | "Handler": "index.handler", 51 | "FunctionName": { 52 | "Fn::If": [ 53 | "ShouldNotCreateEnvResources", 54 | "postInstallScript", 55 | { 56 | "Fn::Join": [ 57 | "", 58 | [ 59 | "postInstallScript", 60 | "-", 61 | { 62 | "Ref": "env" 63 | } 64 | ] 65 | ] 66 | } 67 | ] 68 | }, 69 | "Environment": { 70 | "Variables": { 71 | "ENV": { 72 | "Ref": "env" 73 | }, 74 | "REGION": { 75 | "Ref": "AWS::Region" 76 | }, 77 | "ConnectInstanceId": { 78 | "Ref": "ConnectInstanceId" 79 | } 80 | } 81 | }, 82 | "Role": { 83 | "Fn::GetAtt": [ 84 | "LambdaExecutionRole", 85 | "Arn" 86 | ] 87 | }, 88 | "Runtime": "nodejs18.x", 89 | "Layers": [], 90 | "Timeout": "600" 91 | } 92 | }, 93 | "LambdaExecutionRole": { 94 | "Type": "AWS::IAM::Role", 95 | "Properties": { 96 | "RoleName": { 97 | "Fn::If": [ 98 | "ShouldNotCreateEnvResources", 99 | "connecttranslateblogLambdaRole70eeb513", 100 | { 101 | "Fn::Join": [ 102 | "", 103 | [ 104 | "connecttranslateblogLambdaRole70eeb513", 105 | "-", 106 | { 107 | "Ref": "env" 108 | } 109 | ] 110 | ] 111 | } 112 | ] 113 | }, 114 | "AssumeRolePolicyDocument": { 115 | "Version": "2012-10-17", 116 | "Statement": [ 117 | { 118 | "Effect": "Allow", 119 | "Principal": { 120 | "Service": [ 121 | "lambda.amazonaws.com" 122 | ] 123 | }, 124 | "Action": [ 125 | "sts:AssumeRole" 126 | ] 127 | } 128 | ] 129 | } 130 | } 131 | }, 132 | "lambdaexecutionpolicy": { 133 | "DependsOn": [ 134 | "LambdaExecutionRole" 135 | ], 136 | "Type": "AWS::IAM::Policy", 137 | "Properties": { 138 | "PolicyName": "lambda-execution-policy", 139 | "Roles": [ 140 | { 141 | "Ref": "LambdaExecutionRole" 142 | } 143 | ], 144 | "PolicyDocument": { 145 | "Version": "2012-10-17", 146 | "Statement": [ 147 | { 148 | "Effect": "Allow", 149 | "Action": [ 150 | "logs:CreateLogGroup", 151 | "logs:CreateLogStream", 152 | "logs:PutLogEvents" 153 | ], 154 | "Resource": { 155 | "Fn::Sub": [ 156 | "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", 157 | { 158 | "region": { 159 | "Ref": "AWS::Region" 160 | }, 161 | "account": { 162 | "Ref": "AWS::AccountId" 163 | }, 164 | "lambda": { 165 | "Ref": "LambdaFunction" 166 | } 167 | } 168 | ] 169 | } 170 | }, 171 | { 172 | "Sid": "CustomTerminology", 173 | "Effect": "Allow", 174 | "Action": [ 175 | "translate:DeleteTerminology", 176 | "translate:ImportTerminology" 177 | ], 178 | "Resource": "*" 179 | } 180 | ] 181 | } 182 | } 183 | } 184 | }, 185 | "Outputs": { 186 | "Name": { 187 | "Value": { 188 | "Ref": "LambdaFunction" 189 | } 190 | }, 191 | "Arn": { 192 | "Value": { 193 | "Fn::GetAtt": [ 194 | "LambdaFunction", 195 | "Arn" 196 | ] 197 | } 198 | }, 199 | "Region": { 200 | "Value": { 201 | "Ref": "AWS::Region" 202 | } 203 | }, 204 | "LambdaExecutionRole": { 205 | "Value": { 206 | "Ref": "LambdaExecutionRole" 207 | } 208 | }, 209 | "LambdaExecutionRoleArn": { 210 | "Value": { 211 | "Fn::GetAtt": [ 212 | "LambdaExecutionRole", 213 | "Arn" 214 | ] 215 | } 216 | } 217 | } 218 | } -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/src/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "key1": "value1", 3 | "key2": "value2", 4 | "key3": "value3" 5 | } 6 | -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/src/index.js: -------------------------------------------------------------------------------- 1 | var aws = require("aws-sdk"); 2 | var translate = new aws.Translate(); 3 | 4 | exports.handler = async function(event, context, callback) { 5 | console.log("CDEBUG ==> Request Received:\n" + JSON.stringify(event)); 6 | 7 | var responseStatus; 8 | var responseData = {}; 9 | if (event.RequestType === "Create") { 10 | 11 | var customTerminology = [ 12 | '"en","es","de"', 13 | '"Sunshine and Oranges","Sunshine y Oranges","Sunshine und Oranges"' 14 | ].join('\n'); 15 | 16 | var createTerminologyParams = { 17 | MergeStrategy: 'OVERWRITE', 18 | Name: 'connectChatTranslate', 19 | TerminologyData: { 20 | File: Buffer.from(customTerminology) || 'STRING_VALUE', 21 | Format: 'CSV' 22 | }, 23 | Description: 'Custom Terminology for Amazon Connect Chat sample web app', 24 | }; 25 | 26 | responseStatus = "SUCCESS"; 27 | var createTerminologyRequest = await translate.importTerminology(createTerminologyParams).promise(); 28 | responseData = {"REQUEST": "createTerminologyRequest"}; 29 | console.log("EVENT TYPE CREATE", createTerminologyRequest); 30 | return await sendResponse(event, context, responseStatus, responseData); 31 | } 32 | if (event.RequestType === "Update") { 33 | responseStatus = "SUCCESS"; 34 | responseData = {"REQUEST": "nothing"}; 35 | console.log("EVENT TYPE UPDATE"); 36 | return await sendResponse(event, context, responseStatus, responseData); 37 | } 38 | if (event.RequestType === "Delete") { 39 | 40 | var deleteTerminologyParams = { 41 | Name: 'connectChatTranslate' 42 | }; 43 | var deleteTerminologyRequest = await translate.deleteTerminology(deleteTerminologyParams).promise(); 44 | responseStatus = "SUCCESS"; 45 | responseData = {"REQUEST": "deleteTerminologyRequest"}; 46 | console.log("EVENT TYPE DELETE", deleteTerminologyRequest); 47 | return await sendResponse(event, context, responseStatus, responseData); 48 | } 49 | 50 | 51 | }; 52 | 53 | async function sendResponse(event, context, responseStatus, responseData) { 54 | let responsePromise = new Promise((resolve, reject) => { 55 | var responseBody = JSON.stringify({ 56 | Status: responseStatus, 57 | Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName, 58 | PhysicalResourceId: context.logStreamName, 59 | StackId: event.StackId, 60 | RequestId: event.RequestId, 61 | LogicalResourceId: event.LogicalResourceId, 62 | Data: responseData 63 | }); 64 | console.log("CDEBUG ==> Response Body:\n", responseBody); 65 | var https = require("https"); 66 | var url = require("url"); 67 | 68 | var parsedUrl = url.parse(event.ResponseURL); 69 | var options = { 70 | hostname: parsedUrl.hostname, 71 | port: 443, 72 | path: parsedUrl.path, 73 | method: "PUT", 74 | headers: { 75 | "content-type": "", 76 | "content-length": responseBody.length 77 | } 78 | }; 79 | console.log("CDEBUG ==> Sending Response...\n"); 80 | var request = https.request(options, function(response) { 81 | console.log("Status code: " + response.statusCode); 82 | console.log("Headers: " + JSON.stringify(response.headers)); 83 | resolve(JSON.parse(responseBody)); 84 | context.done(); 85 | }); 86 | request.on("error", function(error) { 87 | console.log("CDEBUG ==> Response Error:" + error); 88 | reject(error); 89 | context.done(); 90 | }); 91 | request.write(responseBody); 92 | request.end(); 93 | }); 94 | return await responsePromise; 95 | } 96 | -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postinstallscript", 3 | "version": "2.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "postinstallscript", 9 | "version": "2.0.0", 10 | "license": "Apache-2.0", 11 | "dependencies": { 12 | "aws-sdk": "^2.1587.0" 13 | } 14 | }, 15 | "node_modules/available-typed-arrays": { 16 | "version": "1.0.7", 17 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", 18 | "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", 19 | "dependencies": { 20 | "possible-typed-array-names": "^1.0.0" 21 | }, 22 | "engines": { 23 | "node": ">= 0.4" 24 | }, 25 | "funding": { 26 | "url": "https://github.com/sponsors/ljharb" 27 | } 28 | }, 29 | "node_modules/aws-sdk": { 30 | "version": "2.1587.0", 31 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1587.0.tgz", 32 | "integrity": "sha512-C9RUBgAaKWe7t/DqQlkIVAd98FHtYVzywUGBJh0Wd/XpelX4mjNhb9yjGGPNCchk0lEufcEXIEW/fLZRA44grA==", 33 | "hasInstallScript": true, 34 | "dependencies": { 35 | "buffer": "4.9.2", 36 | "events": "1.1.1", 37 | "ieee754": "1.1.13", 38 | "jmespath": "0.16.0", 39 | "querystring": "0.2.0", 40 | "sax": "1.2.1", 41 | "url": "0.10.3", 42 | "util": "^0.12.4", 43 | "uuid": "8.0.0", 44 | "xml2js": "0.6.2" 45 | }, 46 | "engines": { 47 | "node": ">= 10.0.0" 48 | } 49 | }, 50 | "node_modules/base64-js": { 51 | "version": "1.5.1", 52 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 53 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 54 | "funding": [ 55 | { 56 | "type": "github", 57 | "url": "https://github.com/sponsors/feross" 58 | }, 59 | { 60 | "type": "patreon", 61 | "url": "https://www.patreon.com/feross" 62 | }, 63 | { 64 | "type": "consulting", 65 | "url": "https://feross.org/support" 66 | } 67 | ] 68 | }, 69 | "node_modules/buffer": { 70 | "version": "4.9.2", 71 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 72 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 73 | "dependencies": { 74 | "base64-js": "^1.0.2", 75 | "ieee754": "^1.1.4", 76 | "isarray": "^1.0.0" 77 | } 78 | }, 79 | "node_modules/call-bind": { 80 | "version": "1.0.7", 81 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 82 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 83 | "dependencies": { 84 | "es-define-property": "^1.0.0", 85 | "es-errors": "^1.3.0", 86 | "function-bind": "^1.1.2", 87 | "get-intrinsic": "^1.2.4", 88 | "set-function-length": "^1.2.1" 89 | }, 90 | "engines": { 91 | "node": ">= 0.4" 92 | }, 93 | "funding": { 94 | "url": "https://github.com/sponsors/ljharb" 95 | } 96 | }, 97 | "node_modules/define-data-property": { 98 | "version": "1.1.4", 99 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 100 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 101 | "dependencies": { 102 | "es-define-property": "^1.0.0", 103 | "es-errors": "^1.3.0", 104 | "gopd": "^1.0.1" 105 | }, 106 | "engines": { 107 | "node": ">= 0.4" 108 | }, 109 | "funding": { 110 | "url": "https://github.com/sponsors/ljharb" 111 | } 112 | }, 113 | "node_modules/es-define-property": { 114 | "version": "1.0.0", 115 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 116 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 117 | "dependencies": { 118 | "get-intrinsic": "^1.2.4" 119 | }, 120 | "engines": { 121 | "node": ">= 0.4" 122 | } 123 | }, 124 | "node_modules/es-errors": { 125 | "version": "1.3.0", 126 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 127 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 128 | "engines": { 129 | "node": ">= 0.4" 130 | } 131 | }, 132 | "node_modules/events": { 133 | "version": "1.1.1", 134 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 135 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", 136 | "engines": { 137 | "node": ">=0.4.x" 138 | } 139 | }, 140 | "node_modules/for-each": { 141 | "version": "0.3.3", 142 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 143 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 144 | "dependencies": { 145 | "is-callable": "^1.1.3" 146 | } 147 | }, 148 | "node_modules/function-bind": { 149 | "version": "1.1.2", 150 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 151 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 152 | "funding": { 153 | "url": "https://github.com/sponsors/ljharb" 154 | } 155 | }, 156 | "node_modules/get-intrinsic": { 157 | "version": "1.2.4", 158 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 159 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 160 | "dependencies": { 161 | "es-errors": "^1.3.0", 162 | "function-bind": "^1.1.2", 163 | "has-proto": "^1.0.1", 164 | "has-symbols": "^1.0.3", 165 | "hasown": "^2.0.0" 166 | }, 167 | "engines": { 168 | "node": ">= 0.4" 169 | }, 170 | "funding": { 171 | "url": "https://github.com/sponsors/ljharb" 172 | } 173 | }, 174 | "node_modules/gopd": { 175 | "version": "1.0.1", 176 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 177 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 178 | "dependencies": { 179 | "get-intrinsic": "^1.1.3" 180 | }, 181 | "funding": { 182 | "url": "https://github.com/sponsors/ljharb" 183 | } 184 | }, 185 | "node_modules/has-property-descriptors": { 186 | "version": "1.0.2", 187 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 188 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 189 | "dependencies": { 190 | "es-define-property": "^1.0.0" 191 | }, 192 | "funding": { 193 | "url": "https://github.com/sponsors/ljharb" 194 | } 195 | }, 196 | "node_modules/has-proto": { 197 | "version": "1.0.3", 198 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 199 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 200 | "engines": { 201 | "node": ">= 0.4" 202 | }, 203 | "funding": { 204 | "url": "https://github.com/sponsors/ljharb" 205 | } 206 | }, 207 | "node_modules/has-symbols": { 208 | "version": "1.0.3", 209 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 210 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 211 | "engines": { 212 | "node": ">= 0.4" 213 | }, 214 | "funding": { 215 | "url": "https://github.com/sponsors/ljharb" 216 | } 217 | }, 218 | "node_modules/has-tostringtag": { 219 | "version": "1.0.2", 220 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 221 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 222 | "dependencies": { 223 | "has-symbols": "^1.0.3" 224 | }, 225 | "engines": { 226 | "node": ">= 0.4" 227 | }, 228 | "funding": { 229 | "url": "https://github.com/sponsors/ljharb" 230 | } 231 | }, 232 | "node_modules/hasown": { 233 | "version": "2.0.2", 234 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 235 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 236 | "dependencies": { 237 | "function-bind": "^1.1.2" 238 | }, 239 | "engines": { 240 | "node": ">= 0.4" 241 | } 242 | }, 243 | "node_modules/ieee754": { 244 | "version": "1.1.13", 245 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 246 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 247 | }, 248 | "node_modules/inherits": { 249 | "version": "2.0.4", 250 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 251 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 252 | }, 253 | "node_modules/is-arguments": { 254 | "version": "1.1.1", 255 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 256 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 257 | "dependencies": { 258 | "call-bind": "^1.0.2", 259 | "has-tostringtag": "^1.0.0" 260 | }, 261 | "engines": { 262 | "node": ">= 0.4" 263 | }, 264 | "funding": { 265 | "url": "https://github.com/sponsors/ljharb" 266 | } 267 | }, 268 | "node_modules/is-callable": { 269 | "version": "1.2.7", 270 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 271 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", 272 | "engines": { 273 | "node": ">= 0.4" 274 | }, 275 | "funding": { 276 | "url": "https://github.com/sponsors/ljharb" 277 | } 278 | }, 279 | "node_modules/is-generator-function": { 280 | "version": "1.0.10", 281 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", 282 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", 283 | "dependencies": { 284 | "has-tostringtag": "^1.0.0" 285 | }, 286 | "engines": { 287 | "node": ">= 0.4" 288 | }, 289 | "funding": { 290 | "url": "https://github.com/sponsors/ljharb" 291 | } 292 | }, 293 | "node_modules/is-typed-array": { 294 | "version": "1.1.13", 295 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", 296 | "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", 297 | "dependencies": { 298 | "which-typed-array": "^1.1.14" 299 | }, 300 | "engines": { 301 | "node": ">= 0.4" 302 | }, 303 | "funding": { 304 | "url": "https://github.com/sponsors/ljharb" 305 | } 306 | }, 307 | "node_modules/isarray": { 308 | "version": "1.0.0", 309 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 310 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" 311 | }, 312 | "node_modules/jmespath": { 313 | "version": "0.16.0", 314 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", 315 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", 316 | "engines": { 317 | "node": ">= 0.6.0" 318 | } 319 | }, 320 | "node_modules/possible-typed-array-names": { 321 | "version": "1.0.0", 322 | "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", 323 | "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", 324 | "engines": { 325 | "node": ">= 0.4" 326 | } 327 | }, 328 | "node_modules/punycode": { 329 | "version": "1.3.2", 330 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 331 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 332 | }, 333 | "node_modules/querystring": { 334 | "version": "0.2.0", 335 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 336 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", 337 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", 338 | "engines": { 339 | "node": ">=0.4.x" 340 | } 341 | }, 342 | "node_modules/sax": { 343 | "version": "1.2.1", 344 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 345 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" 346 | }, 347 | "node_modules/set-function-length": { 348 | "version": "1.2.2", 349 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 350 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 351 | "dependencies": { 352 | "define-data-property": "^1.1.4", 353 | "es-errors": "^1.3.0", 354 | "function-bind": "^1.1.2", 355 | "get-intrinsic": "^1.2.4", 356 | "gopd": "^1.0.1", 357 | "has-property-descriptors": "^1.0.2" 358 | }, 359 | "engines": { 360 | "node": ">= 0.4" 361 | } 362 | }, 363 | "node_modules/url": { 364 | "version": "0.10.3", 365 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 366 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", 367 | "dependencies": { 368 | "punycode": "1.3.2", 369 | "querystring": "0.2.0" 370 | } 371 | }, 372 | "node_modules/util": { 373 | "version": "0.12.5", 374 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", 375 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", 376 | "dependencies": { 377 | "inherits": "^2.0.3", 378 | "is-arguments": "^1.0.4", 379 | "is-generator-function": "^1.0.7", 380 | "is-typed-array": "^1.1.3", 381 | "which-typed-array": "^1.1.2" 382 | } 383 | }, 384 | "node_modules/uuid": { 385 | "version": "8.0.0", 386 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", 387 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", 388 | "bin": { 389 | "uuid": "dist/bin/uuid" 390 | } 391 | }, 392 | "node_modules/which-typed-array": { 393 | "version": "1.1.15", 394 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", 395 | "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", 396 | "dependencies": { 397 | "available-typed-arrays": "^1.0.7", 398 | "call-bind": "^1.0.7", 399 | "for-each": "^0.3.3", 400 | "gopd": "^1.0.1", 401 | "has-tostringtag": "^1.0.2" 402 | }, 403 | "engines": { 404 | "node": ">= 0.4" 405 | }, 406 | "funding": { 407 | "url": "https://github.com/sponsors/ljharb" 408 | } 409 | }, 410 | "node_modules/xml2js": { 411 | "version": "0.6.2", 412 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", 413 | "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", 414 | "dependencies": { 415 | "sax": ">=0.6.0", 416 | "xmlbuilder": "~11.0.0" 417 | }, 418 | "engines": { 419 | "node": ">=4.0.0" 420 | } 421 | }, 422 | "node_modules/xmlbuilder": { 423 | "version": "11.0.1", 424 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 425 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", 426 | "engines": { 427 | "node": ">=4.0" 428 | } 429 | } 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /amplify/backend/function/postInstallScript/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postinstallscript", 3 | "version": "2.0.0", 4 | "description": "Lambda function generated by Amplify", 5 | "main": "index.js", 6 | "license": "Apache-2.0", 7 | "dependencies": { 8 | "aws-sdk": "^2.1587.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /amplify/backend/hosting/amplifyhosting/amplifyhosting-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"hosting-amplifyhosting\",\"metadata\":{}}", 4 | "Parameters": { 5 | "env": { 6 | "Type": "String" 7 | }, 8 | "appId": { 9 | "Type": "String" 10 | }, 11 | "type": { 12 | "Type": "String" 13 | } 14 | }, 15 | "Conditions": { 16 | "isManual": { 17 | "Fn::Equals": [ 18 | { 19 | "Ref": "type" 20 | }, 21 | "manual" 22 | ] 23 | } 24 | }, 25 | "Resources": { 26 | "AmplifyBranch": { 27 | "Condition": "isManual", 28 | "Type": "AWS::Amplify::Branch", 29 | "Properties": { 30 | "BranchName": "nonprod", 31 | "AppId": { 32 | "Ref": "appId" 33 | } 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /amplify/backend/predictions/interpretTextcabd9d8d/interpretTextcabd9d8d-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"predictions-Comprehend\",\"metadata\":{}}", 4 | "Parameters": { 5 | "authRoleName": { 6 | "Type": "String" 7 | }, 8 | "unauthRoleName": { 9 | "Type": "String" 10 | }, 11 | "interpretPolicyName": { 12 | "Type": "String" 13 | }, 14 | "resourceName": { 15 | "Type": "String" 16 | }, 17 | "access": { 18 | "Type": "String" 19 | }, 20 | "type": { 21 | "Type": "String" 22 | }, 23 | "interpretType": { 24 | "Type": "String" 25 | }, 26 | "env": { 27 | "Type": "String" 28 | } 29 | }, 30 | "Conditions": { 31 | "AuthGuestRoleAccess": { 32 | "Fn::Equals": [ 33 | { 34 | "Ref": "access" 35 | }, 36 | "authAndGuest" 37 | ] 38 | } 39 | }, 40 | "Outputs": { 41 | "region": { 42 | "Value": { 43 | "Fn::FindInMap": [ 44 | "RegionMapping", 45 | { 46 | "Ref": "AWS::Region" 47 | }, 48 | { 49 | "Ref": "interpretType" 50 | } 51 | ] 52 | } 53 | }, 54 | "type": { 55 | "Value": { 56 | "Ref": "type" 57 | } 58 | } 59 | }, 60 | "Resources": { 61 | "InterpretPolicy": { 62 | "Type": "AWS::IAM::Policy", 63 | "Properties": { 64 | "PolicyName": { 65 | "Ref": "interpretPolicyName" 66 | }, 67 | "Roles": { 68 | "Fn::If": [ 69 | "AuthGuestRoleAccess", 70 | [ 71 | { 72 | "Ref": "authRoleName" 73 | }, 74 | { 75 | "Ref": "unauthRoleName" 76 | } 77 | ], 78 | [ 79 | { 80 | "Ref": "authRoleName" 81 | } 82 | ] 83 | ] 84 | }, 85 | "PolicyDocument": { 86 | "Version": "2012-10-17", 87 | "Statement": [ 88 | { 89 | "Effect": "Allow", 90 | "Action": [ 91 | "comprehend:DetectSentiment", 92 | "comprehend:DetectEntities", 93 | "comprehend:DetectDominantLanguage", 94 | "comprehend:DetectSyntax", 95 | "comprehend:DetectKeyPhrases" 96 | ], 97 | "Resource": "*" 98 | } 99 | ] 100 | } 101 | } 102 | } 103 | }, 104 | "Mappings": { 105 | "RegionMapping": { 106 | "us-east-1": { 107 | "interpretText": "us-east-1" 108 | }, 109 | "us-east-2": { 110 | "interpretText": "us-east-2" 111 | }, 112 | "us-west-2": { 113 | "interpretText": "us-west-2" 114 | }, 115 | "eu-west-1": { 116 | "interpretText": "eu-west-1" 117 | }, 118 | "eu-west-2": { 119 | "interpretText": "eu-west-2" 120 | }, 121 | "eu-central-1": { 122 | "interpretText": "eu-central-1" 123 | }, 124 | "ap-northeast-1": { 125 | "interpretText": "us-east-1" 126 | }, 127 | "ap-northeast-2": { 128 | "interpretText": "us-east-1" 129 | }, 130 | "ap-southeast-1": { 131 | "interpretText": "ap-southeast-1" 132 | }, 133 | "ap-southeast-2": { 134 | "interpretText": "ap-southeast-2" 135 | }, 136 | "ap-south-1": { 137 | "interpretText": "us-east-1" 138 | } 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /amplify/backend/predictions/interpretTextcabd9d8d/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceName": "interpretTextcabd9d8d", 3 | "interpretPolicyName": "interpretPolicycabd9d8d", 4 | "authRoleName": { 5 | "Ref": "AuthRoleName" 6 | }, 7 | "unauthRoleName": { 8 | "Ref": "UnauthRoleName" 9 | }, 10 | "interpretType": "interpretText", 11 | "type": "ALL", 12 | "access": "auth" 13 | } -------------------------------------------------------------------------------- /amplify/backend/predictions/translateText0519c50f/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceName": "translateText0519c50f", 3 | "convertPolicyName": "translateTextPolicy0519c50f", 4 | "authRoleName": { 5 | "Ref": "AuthRoleName" 6 | }, 7 | "unauthRoleName": { 8 | "Ref": "UnauthRoleName" 9 | }, 10 | "convertType": "translateText", 11 | "sourceLang": "en", 12 | "targetLang": "de", 13 | "access": "auth" 14 | } -------------------------------------------------------------------------------- /amplify/backend/predictions/translateText0519c50f/translateText0519c50f-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.4.0\",\"stackType\":\"predictions-Translate\",\"metadata\":{}}", 4 | "Parameters": { 5 | "authRoleName": { 6 | "Type": "String" 7 | }, 8 | "unauthRoleName": { 9 | "Type": "String" 10 | }, 11 | "convertPolicyName": { 12 | "Type": "String" 13 | }, 14 | "convertType": { 15 | "Type": "String" 16 | }, 17 | "access": { 18 | "Type": "String" 19 | }, 20 | "resourceName": { 21 | "Type": "String" 22 | }, 23 | "sourceLang": { 24 | "Type": "String" 25 | }, 26 | "targetLang": { 27 | "Type": "String" 28 | }, 29 | "env": { 30 | "Type": "String" 31 | } 32 | }, 33 | "Conditions": { 34 | "AuthGuestRoleAccess": { 35 | "Fn::Equals": [ 36 | { 37 | "Ref": "access" 38 | }, 39 | "authAndGuest" 40 | ] 41 | } 42 | }, 43 | "Outputs": { 44 | "region": { 45 | "Value": { 46 | "Fn::FindInMap": [ 47 | "RegionMapping", 48 | { 49 | "Ref": "AWS::Region" 50 | }, 51 | { 52 | "Ref": "convertType" 53 | } 54 | ] 55 | } 56 | }, 57 | "sourceLang": { 58 | "Value": { 59 | "Ref": "sourceLang" 60 | } 61 | }, 62 | "targetLang": { 63 | "Value": { 64 | "Ref": "targetLang" 65 | } 66 | } 67 | }, 68 | "Resources": { 69 | "TranslatePolicy": { 70 | "Type": "AWS::IAM::Policy", 71 | "Properties": { 72 | "PolicyName": { 73 | "Ref": "convertPolicyName" 74 | }, 75 | "Roles": { 76 | "Fn::If": [ 77 | "AuthGuestRoleAccess", 78 | [ 79 | { 80 | "Ref": "authRoleName" 81 | }, 82 | { 83 | "Ref": "unauthRoleName" 84 | } 85 | ], 86 | [ 87 | { 88 | "Ref": "authRoleName" 89 | } 90 | ] 91 | ] 92 | }, 93 | "PolicyDocument": { 94 | "Version": "2012-10-17", 95 | "Statement": [ 96 | { 97 | "Effect": "Allow", 98 | "Action": [ 99 | "translate:TranslateText" 100 | ], 101 | "Resource": "*" 102 | } 103 | ] 104 | } 105 | } 106 | } 107 | }, 108 | "Mappings": { 109 | "RegionMapping": { 110 | "us-east-1": { 111 | "translateText": "us-east-1" 112 | }, 113 | "us-east-2": { 114 | "translateText": "us-east-1" 115 | }, 116 | "us-west-2": { 117 | "translateText": "us-west-2" 118 | }, 119 | "ca-central-1": { 120 | "translateText": "ca-central-1" 121 | }, 122 | "eu-west-1": { 123 | "translateText": "eu-west-1" 124 | }, 125 | "eu-west-2": { 126 | "translateText": "eu-west-1" 127 | }, 128 | "eu-central-1": { 129 | "translateText": "eu-central-1" 130 | }, 131 | "ap-northeast-1": { 132 | "translateText": "ap-northeast-1" 133 | }, 134 | "ap-northeast-2": { 135 | "translateText": "ap-northeast-2" 136 | }, 137 | "ap-southeast-1": { 138 | "translateText": "ap-southeast-1" 139 | }, 140 | "ap-southeast-2": { 141 | "translateText": "ap-southeast-1" 142 | }, 143 | "ap-south-1": { 144 | "translateText": "ap-south-1" 145 | } 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /amplify/backend/tags.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Key": "user:Stack", 4 | "Value": "{project-env}" 5 | }, 6 | { 7 | "Key": "user:Application", 8 | "Value": "{project-name}" 9 | } 10 | ] -------------------------------------------------------------------------------- /amplify/backend/types/amplify-dependent-resources-ref.d.ts: -------------------------------------------------------------------------------- 1 | export type AmplifyDependentResourcesAttributes = { 2 | "api": { 3 | "amazonTranslateAPI": { 4 | "ApiId": "string", 5 | "ApiName": "string", 6 | "RootUrl": "string" 7 | } 8 | }, 9 | "auth": { 10 | "connecttranslateblog690eb6d1": { 11 | "AppClientID": "string", 12 | "AppClientIDWeb": "string", 13 | "CreatedSNSRole": "string", 14 | "IdentityPoolId": "string", 15 | "IdentityPoolName": "string", 16 | "UserPoolArn": "string", 17 | "UserPoolId": "string", 18 | "UserPoolName": "string" 19 | } 20 | }, 21 | "function": { 22 | "amazonTranslateLambda": { 23 | "Arn": "string", 24 | "LambdaExecutionRole": "string", 25 | "LambdaExecutionRoleArn": "string", 26 | "Name": "string", 27 | "Region": "string" 28 | }, 29 | "postInstallScript": { 30 | "Arn": "string", 31 | "LambdaExecutionRole": "string", 32 | "LambdaExecutionRoleArn": "string", 33 | "Name": "string", 34 | "Region": "string" 35 | } 36 | }, 37 | "predictions": { 38 | "interpretTextcabd9d8d": { 39 | "region": "string", 40 | "type": "string" 41 | }, 42 | "translateText0519c50f": { 43 | "region": "string", 44 | "sourceLang": "string", 45 | "targetLang": "string" 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /amplify/cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "features": { 3 | "graphqltransformer": { 4 | "addmissingownerfields": true, 5 | "validatetypenamereservedwords": true, 6 | "useexperimentalpipelinedtransformer": false, 7 | "enableiterativegsiupdates": false, 8 | "securityEnhancementNotification": false, 9 | "showFieldAuthNotification": false 10 | }, 11 | "project": { 12 | "overrides": true 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /artifacts/Arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/artifacts/Arch.png -------------------------------------------------------------------------------- /artifacts/Environment variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/artifacts/Environment variables.png -------------------------------------------------------------------------------- /artifacts/TranslateDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/artifacts/TranslateDemo.gif -------------------------------------------------------------------------------- /artifacts/Web app deployed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/artifacts/Web app deployed.png -------------------------------------------------------------------------------- /artifacts/Web app deploying.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/artifacts/Web app deploying.png -------------------------------------------------------------------------------- /artifacts/connectChatTranslate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/artifacts/connectChatTranslate.png -------------------------------------------------------------------------------- /artifacts/customTerminologySample.csv: -------------------------------------------------------------------------------- 1 | en,es 2 | Moonlight and Roses,Moonlight y Roses -------------------------------------------------------------------------------- /craco.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [{ plugin: require('@semantic-ui-react/craco-less') }], 3 | }; 4 | -------------------------------------------------------------------------------- /customHttp.yml: -------------------------------------------------------------------------------- 1 | customHeaders: 2 | - pattern: '**/*' 3 | headers: 4 | - key: 'Strict-Transport-Security' 5 | value: 'max-age=31536000; includeSubDomains' 6 | - key: 'X-Frame-Options' 7 | value: 'SAMEORIGIN' 8 | - key: 'X-XSS-Protection' 9 | value: '1; mode=block' 10 | - key: 'X-Content-Type-Options' 11 | value: 'nosniff' 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "translateblog", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@aws-amplify/auth": "^6.0.23", 7 | "@aws-amplify/core": "^6.5.3", 8 | "@aws-amplify/predictions": "^6.0.23", 9 | "@aws-amplify/storage": "6.0.23", 10 | "@aws-amplify/ui-react": "^6.1.6", 11 | "@babel/core": "7.24.3", 12 | "@babel/plugin-syntax-flow": "^7.24.1", 13 | "@babel/plugin-transform-react-jsx": "^7.23.4", 14 | "@craco/craco": "^7.1.0", 15 | "@semantic-ui-react/craco-less": "^3.0.0", 16 | "@svgr/webpack": "^8.1.0", 17 | "@testing-library/dom": "^9.3.4", 18 | "@testing-library/jest-dom": "^6.4.2", 19 | "@testing-library/react": "^14.2.2", 20 | "@testing-library/user-event": "^14.5.2", 21 | "@types/node": "*", 22 | "amazon-connect-chatjs": "^2.2.4", 23 | "amazon-connect-streams": "^2.14.0", 24 | "aws-amplify": "^6.6.2", 25 | "aws-cdk-lib": "^2.134.0", 26 | "constructs": "^10.3.0", 27 | "craco-less": "^3.0.1", 28 | "json5": "^2.2.3", 29 | "nth-check": "^2.1.1", 30 | "postcss": "^8.4.38", 31 | "postinstallscript": "file:amplify/backend/function/postInstallScript/src", 32 | "react": "^18.2.0", 33 | "react-dom": "^18.2.0", 34 | "react-hooks-global-state": "^2.1.0", 35 | "react-router-dom": "^6.22.3", 36 | "react-scripts": "^5.0.1", 37 | "semantic-ui-less": "^2.5.0", 38 | "semantic-ui-react": "^2.1.5", 39 | "typescript": "^5.4.3", 40 | "web-vitals": "^3.5.2", 41 | "webpack": "^5.91.0" 42 | }, 43 | "scripts": { 44 | "start": "craco start", 45 | "build": "craco build", 46 | "test": "craco test", 47 | "eject": "craco eject" 48 | }, 49 | "eslintConfig": { 50 | "extends": [ 51 | "react-app", 52 | "react-app/jest" 53 | ] 54 | }, 55 | "browserslist": { 56 | "production": [ 57 | ">0.2%", 58 | "not dead", 59 | "not op_mini all" 60 | ], 61 | "development": [ 62 | "last 3 chrome version", 63 | "last 3 firefox version" 64 | ] 65 | }, 66 | "devDependencies": { 67 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 68 | "@craco/craco": "^7.1.0", 69 | "@semantic-ui-react/craco-less": "^3.0.0", 70 | "@types/node": "*", 71 | "semantic-ui-less": "^2.5.0" 72 | }, 73 | "resolutions": { 74 | "@svgr/webpack": "^8.1.0", 75 | "react": "^18.2.0", 76 | "react-dom": "^18.2.0", 77 | "react-use": "^17.2.1", 78 | "nth-check": "^2.1.1", 79 | "postcss": "^8.4.38", 80 | "@craco/craco": "^7.1.0", 81 | "craco-less": "^3.0.1", 82 | "json5": "^2.2.3", 83 | "typescript": "^5.4.3", 84 | "@aws-amplify/core": "6.5.3", 85 | "@aws-amplify/storage": "6.6.16", 86 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11" 87 | }, 88 | "overrides": { 89 | "nth-check": "^2.1.1", 90 | "postcss": "^8.4.38", 91 | "@craco/craco": "^7.1.0", 92 | "craco-less": "^3.0.1", 93 | "json5": "^2.2.3", 94 | "@svgr/webpack": "^8.1.0", 95 | "react": "^18.2.0", 96 | "react-dom": "^18.2.0", 97 | "react-use": "^17.2.1", 98 | "@aws-amplify/storage": "6.0.23", 99 | "typescript": "^5.4.3" 100 | }, 101 | "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" 102 | } 103 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Amazon Connect with Translate Demo 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/.env: -------------------------------------------------------------------------------- 1 | REACT_APP_CCP_URL="https://vf-gold-london.awsapps.com/connect" -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | #ccp-container { 2 | height:500px; 3 | padding-top: 15px; 4 | padding-left: 15px; 5 | width: 330px; 6 | } 7 | 8 | .ui.toggle.checkbox input:checked ~ .box:before, 9 | .ui.toggle.checkbox input:checked ~ .coloring.red:before { 10 | background: #F25F5C !important; 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { Amplify } from '@aws-amplify/core'; 2 | import { withAuthenticator } from '@aws-amplify/ui-react'; 3 | import '@aws-amplify/ui-react/styles.css'; 4 | import awsconfig from './aws-exports'; 5 | import React, { useState, useEffect } from 'react'; 6 | import './App.css'; 7 | import 'semantic-ui-less/semantic.less'; 8 | import Ccp from './components/ccp'; 9 | //import { autoSignIn } from '@aws-amplify/auth'; 10 | 11 | // Component 12 | function App({ signOut, user }) { 13 | const [isConfigured, setIsConfigured] = useState(false); 14 | 15 | useEffect(() => { 16 | configureAuth(); 17 | //signedIn(); 18 | }, []); 19 | 20 | const configureAuth = () => { 21 | Amplify.configure(awsconfig); 22 | setIsConfigured(true); 23 | }; 24 | //const signedIn = async () => { 25 | //await autoSignIn(); 26 | //}; 27 | 28 | return ( 29 |
30 | {isConfigured && } 31 |
32 | ); 33 | } 34 | 35 | export default withAuthenticator(App); -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/components/ccp.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Grid } from 'semantic-ui-react'; 3 | import { Amplify } from 'aws-amplify'; 4 | import awsconfig from '../aws-exports'; 5 | import Chatroom from './chatroom'; 6 | import translateText from './translate' 7 | import detectText from './detectText' 8 | import { addChat, setLanguageTranslate, clearChat, useGlobalState, setCurrentContactId } from '../store/state'; 9 | 10 | Amplify.configure(awsconfig); 11 | 12 | const Ccp = () => { 13 | const [languageTranslate] = useGlobalState('languageTranslate'); 14 | var localLanguageTranslate = []; 15 | const [Chats] = useGlobalState('Chats'); 16 | const [lang, setLang] = useState(""); 17 | const [currentContactId] = useGlobalState('currentContactId'); 18 | const [languageOptions] = useGlobalState('languageOptions'); 19 | const [agentChatSessionState, setAgentChatSessionState] = useState([]); 20 | const [setRefreshChild] = useState([]); 21 | 22 | console.log(lang) 23 | console.log(currentContactId) 24 | //console.log(Chats) 25 | 26 | // ******* 27 | // Subscribe to the chat session 28 | // ******* 29 | function getEvents(contact, agentChatSession) { 30 | console.log(agentChatSession); 31 | contact.getAgentConnection().getMediaController().then(controller => { 32 | controller.onMessage(messageData => { 33 | if (messageData.chatDetails.participantId === messageData.data.ParticipantId) { 34 | console.log(`CDEBUG ===> Agent ${messageData.data.DisplayName} Says`, 35 | messageData.data.Content) 36 | } 37 | else { 38 | console.log(`CDEBUG ===> Customer ${messageData.data.DisplayName} Says`,messageData.data.Content); 39 | processChatText(messageData.data.Content, messageData.data.Type, messageData.data.ContactId ); 40 | } 41 | }) 42 | }) 43 | } 44 | // ******* 45 | // Processing the incoming chat from the Customer 46 | // ******* 47 | async function processChatText(content, type, contactId) { 48 | // Check if we know the language for this contactId, if not use dectectText(). This process means we only perform comprehend language detection at most once. 49 | console.log(type); 50 | let textLang = ''; 51 | for(var i = 0; i < languageTranslate.length; i++) { 52 | if (languageTranslate[i].contactId === contactId) { 53 | textLang = languageTranslate[i].lang 54 | break 55 | } 56 | } 57 | // If the contatId was not found in the store, or the store is empty, perform dectText API to comprehend 58 | if (localLanguageTranslate.length === 0 || textLang === ''){ 59 | let tempLang = await detectText(content); 60 | textLang = tempLang.textInterpretation.language 61 | } 62 | 63 | 64 | // Update (or Add if new contactId) the store with the the language code 65 | function upsert(array, item) { // (1) 66 | const i = array.findIndex(_item => _item.contactId === item.contactId); 67 | if (i > -1) array[i] = item; // (2) 68 | else array.push(item); 69 | } 70 | upsert(languageTranslate, {contactId: contactId, lang: textLang}) 71 | setLanguageTranslate(languageTranslate); 72 | 73 | // Translate the customer message into English. 74 | let translatedMessage = await translateText(content, textLang, 'en'); 75 | console.log(`CDEBUG ===> Original Message: ` + content + `\n Translated Message: ` + translatedMessage); 76 | // create the new message to add to Chats. 77 | let data2 = { 78 | contactId: contactId, 79 | username: 'customer', 80 | content:

{content}

, 81 | translatedMessage:

{translatedMessage}

82 | }; 83 | // Add the new message to the store 84 | addChat(prevMsg => [...prevMsg, data2]); 85 | } 86 | 87 | // ******* 88 | // Subscribing to CCP events. See : https://github.com/aws/amazon-connect-streams/blob/master/Documentation.md 89 | // ******* 90 | function subscribeConnectEvents() { 91 | window.connect.core.onViewContact(function(event) { 92 | var contactId = event.contactId; 93 | console.log("CDEBUG ===> onViewContact", contactId) 94 | setCurrentContactId(contactId); 95 | }); 96 | 97 | console.log("CDEBUG ===> subscribeConnectEvents"); 98 | 99 | // If this is a chat session 100 | if (window.connect.ChatSession) { 101 | console.log("CDEBUG ===> Subscribing to Connect Contact Events for chats"); 102 | window.connect.contact(contact => { 103 | 104 | // This is invoked when CCP is ringing 105 | contact.onConnecting(() => { 106 | console.log("CDEBUG ===> onConnecting() >> contactId: ", contact.contactId); 107 | let contactAttributes = contact.getAttributes(); 108 | console.log("CDEBUG ===> contactAttributes: ", JSON.stringify(contactAttributes)); 109 | let contactQueue = contact.getQueue(); 110 | console.log("CDEBUG ===> contactQueue: ", contactQueue); 111 | }); 112 | 113 | // This is invoked when the chat is accepted 114 | contact.onAccepted(async() => { 115 | console.log("CDEBUG ===> onAccepted: ", contact); 116 | const cnn = contact.getConnections().find(cnn => cnn.getType() === window.connect.ConnectionType.AGENT); 117 | const agentChatSession = await cnn.getMediaController(); 118 | setCurrentContactId(contact.contactId) 119 | console.log("CDEBUG ===> agentChatSession ", agentChatSession) 120 | // Save the session to props, this is required to send messages within the chatroom.js 121 | setAgentChatSessionState(agentChatSessionState => [...agentChatSessionState, {[contact.contactId] : agentChatSession}]) 122 | 123 | // Get the language from the attributes, if the value is valid then add to the store 124 | localLanguageTranslate = contact.getAttributes().x_lang.value 125 | if (Object.keys(languageOptions).find(key => languageOptions[key] === localLanguageTranslate) !== undefined){ 126 | console.log("CDEBUG ===> Setting lang code from attribites:", localLanguageTranslate) 127 | languageTranslate.push({contactId: contact.contactId, lang: localLanguageTranslate}) 128 | setLanguageTranslate(languageTranslate); 129 | setRefreshChild('updated') // Workaround to force a refresh of the chatroom UI to show the updated language based on contact attribute. 130 | 131 | } 132 | console.log("CDEBUG ===> onAccepted, languageTranslate ", languageTranslate) 133 | 134 | }); 135 | 136 | // This is invoked when the customer and agent are connected 137 | contact.onConnected(async() => { 138 | console.log("CDEBUG ===> onConnected() >> contactId: ", contact.contactId); 139 | const cnn = contact.getConnections().find(cnn => cnn.getType() === window.connect.ConnectionType.AGENT); 140 | const agentChatSession = await cnn.getMediaController(); 141 | getEvents(contact, agentChatSession); 142 | }); 143 | 144 | // This is invoked when new agent data is available 145 | contact.onRefresh(() => { 146 | console.log("CDEBUG ===> onRefresh() >> contactId: ", contact.contactId); 147 | }); 148 | 149 | // This is invoked when the agent moves to ACW 150 | contact.onEnded(() => { 151 | console.log("CDEBUG ===> onEnded() >> contactId: ", contact.contactId); 152 | setLang(''); 153 | }); 154 | 155 | // This is invoked when the agent moves out of ACW to a different state 156 | contact.onDestroy(() => { 157 | console.log("CDEBUG ===> onDestroy() >> contactId: ", contact.contactId); 158 | // TODO need to remove the previous chats from the store 159 | //clearChat() 160 | setCurrentContactId(''); 161 | clearChat(); 162 | }); 163 | }); 164 | 165 | /* 166 | **** Subscribe to the agent API **** 167 | See : https://github.com/aws/amazon-connect-streams/blob/master/Documentation.md 168 | */ 169 | 170 | console.log("CDEBUG ===> Subscribing to Connect Agent Events"); 171 | window.connect.agent((agent) => { 172 | agent.onStateChange((agentStateChange) => { 173 | // On agent state change, update the React state. 174 | let state = agentStateChange.newState; 175 | console.log("CDEBUG ===> New State: ", state); 176 | 177 | }); 178 | 179 | }); 180 | } 181 | else { 182 | console.log("CDEBUG ===> waiting 3s"); 183 | setTimeout(function() { subscribeConnectEvents(); }, 3000); 184 | } 185 | }; 186 | 187 | 188 | // ***** 189 | // Loading CCP 190 | // ***** 191 | useEffect(() => { 192 | const connectUrl = process.env.REACT_APP_CONNECT_INSTANCE_URL; 193 | window.connect.agentApp.initApp( 194 | "ccp", 195 | "ccp-container", 196 | connectUrl + "/connect/ccp-v2/", { 197 | ccpParams: { 198 | region: process.env.REACT_APP_CONNECT_REGION, 199 | pageOptions: { // optional 200 | enableAudioDeviceSettings: true, // optional, defaults to 'false' 201 | enablePhoneTypeSettings: true // optional, defaults to 'true' 202 | } 203 | } 204 | } 205 | ); 206 | subscribeConnectEvents(); 207 | }, []); 208 | 209 | 210 | return ( 211 |
212 | 213 | 214 | {/* CCP window will load here */} 215 |
216 | {/* Translate window will laod here. We pass the agent state to be able to use this to push messages to CCP */} 217 |
218 |
219 |
220 |
221 | ); 222 | }; 223 | 224 | export default Ccp; 225 | -------------------------------------------------------------------------------- /src/components/chat.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment, useEffect } from "react"; 2 | 3 | 4 | const Chat = () => { 5 | const isLoaded = window.connect && window.connect.ChatSession; 6 | const connect = window.connect; 7 | 8 | useEffect(() => { 9 | console.log("CHAT ===> ", connect.ChatSession); 10 | }, []); 11 | 12 | return ( 13 | 14 |

react-amazon-connect-chatjs

15 | {isLoaded ? "loaded!" : "failed"} 16 |
17 | ); 18 | }; 19 | 20 | export default Chat; 21 | -------------------------------------------------------------------------------- /src/components/chatroom.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | p { 6 | margin: 0; 7 | 8 | } 9 | 10 | #chatroom { 11 | height:485px; 12 | padding-top: 15px; 13 | padding-left: 15px; 14 | } 15 | 16 | .App { 17 | 18 | display: flex; 19 | align-items: center; 20 | justify-content: center; 21 | } 22 | 23 | .chatroom { 24 | width: 335px; 25 | height: 485px; 26 | background-color: #FFFFFF; 27 | border-radius: 5px; 28 | overflow: hidden; 29 | box-shadow: 0 0 8px 0 rgba(0,0,0, 0.3); 30 | } 31 | 32 | .chatroom h3 { 33 | background-color: #4A4A4A; 34 | color: #FFF; 35 | margin: 0; 36 | height: 40px; 37 | font-size: 20px; 38 | display: flex; 39 | align-items: center; 40 | justify-content: center; 41 | } 42 | 43 | .chatroom .chats { 44 | box-sizing: border-box; 45 | padding: 0 20px; 46 | margin: 10px 0 0; 47 | height: 395px; 48 | overflow-y: scroll; 49 | } 50 | 51 | .chatroom .chats .chat { 52 | background: #EDEDED; 53 | position: relative; 54 | padding: 5px 13px; 55 | font-size: 14px; 56 | border-radius: 10px; 57 | list-style: none; 58 | float: left; 59 | clear: both; 60 | margin: 10px 0; 61 | width: 250px; 62 | overflow-wrap: break-word; 63 | } 64 | 65 | 66 | 67 | .chatroom .chats .chat img { 68 | width: 20px; 69 | height: 20px; 70 | border-radius: 50%; 71 | position: absolute; 72 | top: -10px; 73 | left: 0px; 74 | } 75 | 76 | .chatroom .chats .chat.right { 77 | float: right; 78 | clear: both; 79 | background: #E8F6F8; 80 | } 81 | 82 | .chatroom .chats .chat a { 83 | text-decoration: none; 84 | color:#3498DB; 85 | } 86 | 87 | .translatedMessage { 88 | text-decoration: none; 89 | color: red; 90 | } 91 | 92 | .chatroom .input { 93 | height: 40px; 94 | width: 100%; 95 | background: #4A4A4A; 96 | display: flex; 97 | flex-direction: row; 98 | align-items: center; 99 | } 100 | 101 | .chatroom .input input[type="text"] { 102 | background: #F2F2F2; 103 | outline: 0; 104 | border: 2px solid #4A4A4A; 105 | padding: 0 5px; 106 | border-top-left-radius: 5px; 107 | border-bottom-left-radius: 5px; 108 | margin-left: 10px; 109 | height: 30px; 110 | width: 100%; 111 | box-sizing: border-box; 112 | font-size: 14px; 113 | } 114 | 115 | .chatroom .input input[type="submit"] { 116 | background: transparent; 117 | border: 0px solid #ffffff; 118 | height: 30px; 119 | width: 70px; 120 | color: #ffffff; 121 | font-size: 16px; 122 | box-sizing: border-box; 123 | border-top-right-radius: 5px; 124 | border-bottom-right-radius: 5px; 125 | cursor: pointer; 126 | transition: all 0.3s ease; 127 | } 128 | 129 | .chatroom .input input[type="submit"]:hover { 130 | background: #4A4A4A; 131 | color: #FFF; 132 | } -------------------------------------------------------------------------------- /src/components/chatroom.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef, useState } from 'react'; 2 | import './chatroom.css'; 3 | import Message from './message.js'; 4 | //import translateText from './translate' 5 | import translateTextAPI from './translateAPI' 6 | import { addChat, useGlobalState } from '../store/state'; 7 | 8 | const Chatroom = (props) => { 9 | 10 | const [Chats] = useGlobalState('Chats'); 11 | const currentContactId = useGlobalState('currentContactId'); 12 | const [newMessage, setNewMessage] = useState(""); 13 | const [languageTranslate] = useGlobalState('languageTranslate'); 14 | const [languageOptions] = useGlobalState('languageOptions'); 15 | const agentUsername = 'AGENT'; 16 | const messageEl = useRef(null); 17 | const input = useRef(null); 18 | 19 | function getKeyByValue(object) { 20 | let obj = languageTranslate.find(o => o.contactId === currentContactId[0]); 21 | if(obj === undefined) { 22 | return 23 | } else { 24 | return Object.keys(object).find(key => object[key] === obj.lang); 25 | } 26 | 27 | } 28 | 29 | const sendMessage = async(session, content) => { 30 | const awsSdkResponse = await session.sendMessage({ 31 | contentType: "text/plain", 32 | message: content 33 | }); 34 | const { AbsoluteTime, Id } = awsSdkResponse.data; 35 | console.log(AbsoluteTime, Id); 36 | } 37 | 38 | useEffect(() => { 39 | 40 | // this ensures that the chat window will auto scoll to ensure the more recent message is in view 41 | if (messageEl) { 42 | messageEl.current.addEventListener('DOMNodeInserted', event => { 43 | const { currentTarget: target } = event; 44 | target.scroll({ top: target.scrollHeight, behavior: 'smooth' }); 45 | }); 46 | } 47 | // this ensure that the input box has the focus on load and after each entry 48 | input.current.focus(); 49 | }, []); 50 | 51 | 52 | async function handleSubmit(event) { 53 | event.preventDefault(); 54 | // if there is no text in the the chat input box, do nothing. 55 | if (newMessage === "") { 56 | return; 57 | } 58 | let destLang = languageTranslate.find(o => o.contactId === currentContactId[0]); 59 | console.log("destLang: ", destLang); 60 | 61 | // translate the agent message ** Swap the below two round if you wnat to test custom termonologies ** 62 | // let translatedMessage = await translateText(newMessage, 'en', destLang.lang); 63 | 64 | /***********************************CUSTOM TERMINOLOGY************************************************* 65 | 66 | To support custom terminologies comment out the line above, and uncomment the below 2 lines 67 | 68 | ******************************************************************************************************/ 69 | console.log(newMessage); 70 | let translatedMessageAPI = await translateTextAPI(newMessage, 'en', destLang.lang); // Provide a custom terminology created outside of this deployment 71 | //let translatedMessageAPI = await translateTextAPI(newMessage, 'en', destLang.lang, ['connectChatTranslate']); // Provide a custom terminology created outside of this deployment 72 | let translatedMessage = translatedMessageAPI.TranslatedText 73 | 74 | console.log(` Original Message: ` + newMessage + `\n Translated Message: ` + translatedMessage); 75 | // create the new message to add to Chats. 76 | let data2 = { 77 | contactId: currentContactId[0], 78 | username: agentUsername, 79 | content:

{newMessage}

, 80 | translatedMessage:

{translatedMessage}

, // set to {translatedMessage.TranslatedText} if using custom terminologies 81 | }; 82 | // add the new message to the store 83 | addChat(prevMsg => [...prevMsg, data2]); 84 | // clear the chat input box 85 | setNewMessage(""); 86 | 87 | 88 | 89 | const session = retrieveValue(currentContactId[0]); 90 | 91 | function retrieveValue(key){ 92 | var value = ""; 93 | for(var obj in props.session) { 94 | for(var item in props.session[obj]) { 95 | if(item === key) { 96 | value = props.session[obj][item]; 97 | break; 98 | } 99 | } 100 | } 101 | return value; 102 | } 103 | sendMessage(session, translatedMessage); 104 | } 105 | 106 | 107 | 108 | return ( 109 |
110 |

Translate - ({languageTranslate.map(lang => {if(lang.contactId === currentContactId[0])return lang.lang})}) {getKeyByValue(languageOptions)}

111 |
    112 | { 113 | // iterate over the Chats, and only display the messages for the currently active chat session 114 | Chats.map(chat => { 115 | if(chat.contactId === currentContactId[0]) 116 | return 117 | } 118 | ) 119 | } 120 |
121 |
122 | setNewMessage(e.target.value)} 128 | /> 129 | 130 |
131 | 132 |
133 | ); 134 | }; 135 | 136 | 137 | export default Chatroom; 138 | -------------------------------------------------------------------------------- /src/components/detectText.js: -------------------------------------------------------------------------------- 1 | import { Predictions } from '@aws-amplify/predictions'; 2 | 3 | async function DetectChatText(content) { 4 | 5 | let detectLang = Predictions.interpret({ 6 | text: { 7 | source: { 8 | text: content, 9 | }, 10 | type: 'language' 11 | } 12 | }) 13 | return detectLang 14 | } 15 | 16 | export default DetectChatText 17 | -------------------------------------------------------------------------------- /src/components/message.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | // This function creates the HTML to add the chats to the store, controlling the layout 4 | const Message = ({ chat, user }) => ( 5 |
  • 6 | {chat.content} 7 |
  • {chat.translatedMessage}
  • 8 | 9 | ); 10 | 11 | export default Message; 12 | 13 | -------------------------------------------------------------------------------- /src/components/translate.js: -------------------------------------------------------------------------------- 1 | import { Predictions} from '@aws-amplify/predictions'; 2 | 3 | 4 | 5 | async function ProcessChatText(content, sourceLang, tagretLang) { 6 | 7 | let transcriptMessage = await Predictions.convert({ 8 | translateText: { 9 | source: { 10 | text: content, 11 | language: sourceLang, // defaults configured on aws-exports.js 12 | // supported languages https://docs.aws.amazon.com/translate/latest/dg/how-it-works.html#how-it-works-language-codes 13 | }, 14 | targetLanguage: tagretLang 15 | } 16 | }); 17 | return transcriptMessage.text 18 | } 19 | export default ProcessChatText 20 | -------------------------------------------------------------------------------- /src/components/translateAPI.js: -------------------------------------------------------------------------------- 1 | import { post } from '@aws-amplify/api'; 2 | //async function ProcessChatTextAPI(content, sourceLang, targetLang, terminologyNames) 3 | async function ProcessChatTextAPI(content, sourceLang, targetLang) { 4 | const apiName = 'amazonTranslateAPI'; 5 | const path = '/translate'; 6 | const myInit = { // OPTIONAL 7 | body: { 'content': content, 'sourceLang': sourceLang, 'targetLang': targetLang }, 8 | //body: { 'content': content, 'sourceLang': sourceLang, 'targetLang': targetLang, 'terminologyNames': terminologyNames }, 9 | headers: { 10 | }, // OPTIONAL 11 | }; 12 | console.log("ProcessChatTextAPI: ", content); 13 | console.log("ProcessChatTextAPI: ", sourceLang); 14 | console.log("ProcessChatTextAPI: ", targetLang); 15 | //console.log("ProcessChatTextAPI: ", terminologyNames); 16 | console.log("ProcessChatTextAPI: ", path); 17 | console.log("ProcessChatTextAPI: ", myInit); 18 | console.log("API Name: ", apiName); 19 | try { 20 | const result = await post({ 21 | apiName, 22 | path, 23 | options: myInit, 24 | }).response 25 | console.log("Translated Message Payload: ", result); 26 | const res = result.body 27 | console.log("Translated Message: ", res); 28 | const resp = await res.json(); 29 | console.log("Response: ", resp); 30 | return resp; 31 | } 32 | catch (error) { 33 | console.error("ProcessChatTextAPI: ", error); 34 | return error; 35 | } 36 | } 37 | export default ProcessChatTextAPI 38 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import "amazon-connect-streams"; // This will make the `connect` available in the current context. 7 | import "amazon-connect-chatjs"; 8 | 9 | 10 | // Import semantic 11 | import 'semantic-ui-less/semantic.less'; 12 | 13 | // Amplify imports for base install 14 | import { Amplify } from "aws-amplify"; 15 | import awsExports from "./aws-exports"; 16 | Amplify.configure(awsExports); 17 | // 18 | 19 | 20 | 21 | ReactDOM.render( 22 | 23 | 24 | 25 | , 26 | document.getElementById('root') 27 | ); 28 | 29 | // If you want to start measuring performance in your app, pass a function 30 | // to log results (for example: reportWebVitals(console.log)) 31 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 32 | reportWebVitals(); 33 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/breadcrumb.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/breadcrumb.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/form.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/form.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/grid.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/grid.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/menu.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/menu.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/message.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/message.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/table.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/collections/table.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/button.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/button.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/container.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/container.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/divider.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/divider.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/flag.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/flag.variables: -------------------------------------------------------------------------------- 1 | /*------------------- 2 | Flag Variables 3 | --------------------*/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/header.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/header.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/icon.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/icon.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/image.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/image.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/input.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/input.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/label.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/label.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/list.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/list.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/loader.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/loader.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/rail.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/rail.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/reveal.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/reveal.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/segment.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/segment.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/step.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/elements/step.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/globals/reset.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/globals/reset.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Global Variables 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/globals/site.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/globals/site.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Global Variables 3 | *******************************/ 4 | 5 | @primaryColor: #002f4e; 6 | @pageBackground: #282c34; 7 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/accordion.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/accordion.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/chatroom.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/chatroom.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/checkbox.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/checkbox.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/dimmer.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/dimmer.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/dropdown.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/dropdown.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/embed.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/embed.variables: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-connect-chat-translate/10c73cc7bbc3b73aba60f0fbec9f0b5a88d17676/src/semantic-ui/site/modules/embed.variables -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/modal.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/modal.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/nag.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/nag.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/popup.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/popup.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/progress.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/progress.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/rating.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/rating.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/search.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/search.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/shape.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/shape.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/sidebar.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/sidebar.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/sticky.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/sticky.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/tab.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/tab.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/transition.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/modules/transition.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/ad.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/ad.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/card.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/card.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/comment.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/comment.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/feed.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/feed.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/item.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/item.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/statistic.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/site/views/statistic.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /src/semantic-ui/theme.config: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ████████╗██╗ ██╗███████╗███╗ ███╗███████╗███████╗ 4 | ╚══██╔══╝██║ ██║██╔════╝████╗ ████║██╔════╝██╔════╝ 5 | ██║ ███████║█████╗ ██╔████╔██║█████╗ ███████╗ 6 | ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██╔══╝ ╚════██║ 7 | ██║ ██║ ██║███████╗██║ ╚═╝ ██║███████╗███████║ 8 | ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝ 9 | 10 | */ 11 | 12 | /******************************* 13 | Theme Selection 14 | *******************************/ 15 | 16 | /* To override a theme for an individual element 17 | specify theme name below 18 | */ 19 | 20 | /* Global */ 21 | @site : 'default'; 22 | @reset : 'default'; 23 | 24 | /* Elements */ 25 | @button : 'default'; 26 | @container : 'default'; 27 | @divider : 'default'; 28 | @flag : 'default'; 29 | @header : 'default'; 30 | @icon : 'default'; 31 | @image : 'default'; 32 | @input : 'default'; 33 | @label : 'default'; 34 | @list : 'default'; 35 | @loader : 'default'; 36 | @placeholder : 'default'; 37 | @rail : 'default'; 38 | @reveal : 'default'; 39 | @segment : 'default'; 40 | @step : 'default'; 41 | 42 | /* Collections */ 43 | @breadcrumb : 'default'; 44 | @form : 'default'; 45 | @grid : 'default'; 46 | @menu : 'default'; 47 | @message : 'default'; 48 | @table : 'default'; 49 | 50 | /* Modules */ 51 | @accordion : 'default'; 52 | @checkbox : 'default'; 53 | @dimmer : 'default'; 54 | @dropdown : 'default'; 55 | @embed : 'default'; 56 | @modal : 'default'; 57 | @nag : 'default'; 58 | @popup : 'default'; 59 | @progress : 'default'; 60 | @rating : 'default'; 61 | @search : 'default'; 62 | @shape : 'default'; 63 | @sidebar : 'default'; 64 | @sticky : 'default'; 65 | @tab : 'default'; 66 | @transition : 'default'; 67 | 68 | /* Views */ 69 | @ad : 'default'; 70 | @card : 'default'; 71 | @comment : 'default'; 72 | @feed : 'default'; 73 | @item : 'default'; 74 | @statistic : 'default'; 75 | 76 | /******************************* 77 | Folders 78 | *******************************/ 79 | 80 | /* Path to theme packages */ 81 | @themesFolder : 'themes'; 82 | 83 | /* Path to site override folder */ 84 | @siteFolder : 'site'; 85 | 86 | 87 | /******************************* 88 | Import Theme 89 | *******************************/ 90 | 91 | @themesFolder : 'themes'; 92 | @siteFolder : '../../src/semantic-ui/site'; 93 | 94 | @import (multiple) "~semantic-ui-less/theme.less"; 95 | @fontPath : '../../../themes/@{theme}/assets/fonts'; 96 | 97 | /* End Config */ 98 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/store/state.js: -------------------------------------------------------------------------------- 1 | import { createGlobalState } from "react-hooks-global-state"; 2 | 3 | 4 | const { setGlobalState, useGlobalState } = createGlobalState({ 5 | languageTranslate: [], 6 | Chats: [], 7 | currentContactId: 'none', 8 | languageOptions: { 9 | 'Afrikaans':'af', 10 | 'Albanian':'sq', 11 | 'Amharic':'am', 12 | 'Arabic':'ar', 13 | 'Armenian':'hy', 14 | 'Azerbaijani':'az', 15 | 'Bengali':'bn', 16 | 'Bosnian':'bs', 17 | 'Bulgarian':'bg', 18 | 'Catalan':'ca', 19 | 'Chinese (Simplified)':'zh', 20 | 'Chinese (Traditional)':'zh-TW', 21 | 'Croatian':'hr', 22 | 'Czech':'cs', 23 | 'Danish':'da', 24 | 'Dari':'fa-AF', 25 | 'Dutch':'nl', 26 | 'English':'en', 27 | 'Estonian':'et', 28 | 'Farsi (Persian)':'fa', 29 | 'Filipino Tagalog':'tl', 30 | 'Finnish':'fi', 31 | 'French':'fr', 32 | 'French (Canada)':'fr-CA', 33 | 'Georgian':'ka', 34 | 'German':'de', 35 | 'Greek':'el', 36 | 'Gujarati':'gu', 37 | 'Haitian Creole':'ht', 38 | 'Hausa':'ha', 39 | 'Hebrew':'he', 40 | 'Hindi':'hi', 41 | 'Hungarian':'hu', 42 | 'Icelandic':'is', 43 | 'Indonesian':'id', 44 | 'Italian':'it', 45 | 'Japanese':'ja', 46 | 'Kannada':'kn', 47 | 'Kazakh':'kk', 48 | 'Korean':'ko', 49 | 'Latvian':'lv', 50 | 'Lithuanian':'lt', 51 | 'Macedonian':'mk', 52 | 'Malay':'ms', 53 | 'Malayalam':'ml', 54 | 'Maltese':'mt', 55 | 'Mongolian':'mn', 56 | 'Norwegian':'no', 57 | 'Persian':'fa', 58 | 'Pashto':'ps', 59 | 'Polish':'pl', 60 | 'Portuguese':'pt', 61 | 'Romanian':'ro', 62 | 'Russian':'ru', 63 | 'Serbian':'sr', 64 | 'Sinhala':'si', 65 | 'Slovak':'sk', 66 | 'Slovenian':'sl', 67 | 'Somali':'so', 68 | 'Spanish':'es', 69 | 'Spanish (Mexico)':'es-MX', 70 | 'Swahili':'sw', 71 | 'Swedish':'sv', 72 | 'Tagalog':'tl', 73 | 'Tamil':'ta', 74 | 'Telugu':'te', 75 | 'Thai':'th', 76 | 'Turkish':'tr', 77 | 'Ukrainian':'uk', 78 | 'Urdu':'ur', 79 | 'Uzbek':'uz', 80 | 'Vietnamese':'vi', 81 | 'Welsh':'cy' 82 | }, 83 | }); 84 | 85 | export const addChat = (Chats, contactId) => { 86 | setGlobalState("Chats", Chats); 87 | }; 88 | 89 | export const clearChat = () => { 90 | setGlobalState("Chats", []); 91 | }; 92 | 93 | 94 | export const setLanguageTranslate = (state) => { 95 | setGlobalState("languageTranslate", state); 96 | }; 97 | 98 | export const setCurrentContactId = (contactId) => { 99 | setGlobalState("currentContactId", contactId); 100 | }; 101 | 102 | export { useGlobalState }; 103 | --------------------------------------------------------------------------------