├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── customer-support-bot ├── .gitignore ├── README.md ├── airline-dataset │ └── dataset.csv ├── airline-qa-base │ └── PDF │ │ ├── Change_of_name_of_any_passenger_Lainventada_Airlines.pdf │ │ ├── Change_of_passage_from_round_from_flown_not_flown_lastainventada_airlines.pdf │ │ ├── How to know_if_can_change_the_passage_Lainventada_Airlines.pdf │ │ ├── Knows_the_the_right_to_retract_lainventada_airlines.pdf │ │ ├── Lainventada_airlines_ticket_cancellation_information.pdf │ │ ├── Request_the_refund_of_shipping_taxes_Lainventada_Airlines.pdf │ │ ├── buy_an_ticket_and_me_regretti_of_travel_Lainventada_Airlines.pdf │ │ ├── change passport_number_or_id_in_passage_lainventada_airlines.pdf │ │ ├── change_of_flights_or_dates_of_ticket_lainventada_airlines.pdf │ │ ├── change_of_passages_after_start_the_trip_the_travel_inventada_airlines.pdf │ │ ├── change_of_passages_before_an_affectation_LAINVENTADA_Airlines.pdf │ │ ├── change_of_passages_purchased_at_agencias_lainventada_airlines..pdf │ │ ├── deadline for_returns_of_passages_Lainventada_Airlines.pdf │ │ ├── deadlines for_make_an_change_of_passage_Lainventada_Airlines.pdf │ │ ├── discover_how_how_to receive_your_devolucin_lainventada_airlines.pdf │ │ ├── forward_or_postponingacin_flight_the same_from_Lainventada_airline.pdf │ │ ├── get_what_do_in_case_of_fraud_Lainventada_Airlines.pdf │ │ ├── how_to_request_the_devolucin_from_your_ticket_Lainventada_Airlines.pdf │ │ ├── refunds_of_money_for_passage_launventada_airlines.pdf │ │ ├── return_for_reduction_of_shipment_taxes_lastainventada_airlines.pdf │ │ ├── where to check_cost_of_change_of_passages_lainventada_Airlines.pdf │ │ ├── where_can_change_of_passages_Lainventada_Airlines.pdf │ │ └── where_to_request_the_return_of_the Lainventada_Airlines ticket.pdf ├── apis │ ├── __init__.py │ └── webhooks.py ├── app.py ├── cdk.json ├── customer_support_bot │ ├── __init__.py │ ├── application_insights_stack.py │ └── customer_support_bot_stack.py ├── databases │ ├── __init__.py │ └── databases.py ├── kendra_constructs │ ├── __init__.py │ ├── datasource.py │ ├── index.py │ └── roles.py ├── lambdas │ ├── __init__.py │ ├── code │ │ ├── audio_job_transcriptor │ │ │ └── lambda_function.py │ │ ├── data_source_creator │ │ │ ├── create.event.json │ │ │ ├── delete.event.json │ │ │ ├── lambda_function.py │ │ │ ├── play.ipynb │ │ │ └── update.event.json │ │ ├── dynamodb_put_item │ │ │ ├── dataset.csv │ │ │ └── lambda_function.py │ │ ├── langchain_agent_text │ │ │ └── lambda_function.py │ │ ├── process_stream │ │ │ └── lambda_function.py │ │ ├── query_dynamodb_passanger │ │ │ └── lambda_function.py │ │ ├── transcriber_done │ │ │ └── lambda_function.py │ │ ├── whatsapp_in │ │ │ └── lambda_function.py │ │ └── whatsapp_out │ │ │ └── lambda_function.py │ ├── datasource.py │ └── project_lambdas.py ├── layers │ ├── __init__.py │ ├── aiofile-amazon-transcribe.zip │ ├── boto3.1.28.62.zip │ ├── bs4_requests.zip │ ├── common │ │ └── python │ │ │ ├── agent_utils.py │ │ │ ├── db_utils.py │ │ │ ├── file_utils.py │ │ │ └── utils.py │ ├── langchain.zip │ └── project_layers.py ├── requirements-dev.txt ├── requirements.txt ├── s3_cloudfront │ ├── __init__.py │ └── s3_cloudfront_website.py ├── source.bat ├── tests │ ├── __init__.py │ └── unit │ │ ├── __init__.py │ │ └── test_customer_support_bot_stack.py └── text-to-whatsapp │ └── test.txt ├── elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra.code-workspace └── imagen ├── Kendra_datasources.jpg ├── QA.gif ├── code_whisper_gif.gif ├── diagram.png ├── passangerTable.jpg ├── passanger_information.gif ├── secret.png ├── stack.jpg ├── voice_note.gif └── webhook.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | .vscode 163 | .DS_Store 164 | event.json -------------------------------------------------------------------------------- /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 | # Elevating Customer Support With Rag Langchain Agent Bedrock Dynamodb And Kendra 2 | 3 | This assistant app understands multiple languages and aims to provide self-service support through natural conversation or voice messages for common travel issues, [present in this documentation](/customer-support-bot/airline-qa-base). You can check the status of your flights, as well as data related to your trip using your reservation number or passenger identification. 4 | 5 | And the best... ready to deploy using [AWS Cloud Development Kit](https://aws.amazon.com/cdk). 6 | 7 | --- 8 | ![Digrama parte 1](/imagen/diagram.png) 9 | 10 | ✅ **AWS Level**: Intermediate - 200 11 | 12 | **Prerequisites:** 13 | 14 | - [AWS Account](https://aws.amazon.com/resources/create-account/?sc_channel=el&sc_campaign=datamlwave&sc_content=cicdcfnaws&sc_geo=mult&sc_country=mult&sc_outcome=acq) 15 | - [Foundational knowledge of Python](https://catalog.us-east-1.prod.workshops.aws/workshops/3d705026-9edc-40e8-b353-bdabb116c89c/) 16 | 17 | 💰 **Cost To Complete**: 18 | - [Amazon Bedrock Pricing](https://aws.amazon.com/bedrock/pricing/) 19 | - [Amazon Lambda Pricing](https://aws.amazon.com/lambda/pricing/) 20 | - [Amazon DynamoDB Pricing](https://aws.amazon.com/dynamodb/pricing/) 21 | - [Amazon Kendra Pricing](https://aws.amazon.com/kendra/pricing/) 22 | - [Amazon ApiGateway](https://aws.amazon.com/api-gateway/pricing/) 23 | - [Amazon Transcribe Pricing](https://aws.amazon.com/transcribe/pricing/) 24 | - [Whatsapp pricing](https://developers.facebook.com/docs/whatsapp/pricing/) 25 | 26 | ## Step 0: Activate WhatsApp account Facebook Developers 27 | 28 | 1- [Get Started with the New WhatsApp Business Platform](https://www.youtube.com/watch?v=CEt_KMMv3V8&list=PLX_K_BlBdZKi4GOFmJ9_67og7pMzm2vXH&index=2&t=17s&pp=gAQBiAQB) 29 | 30 | 2- [How To Generate a Permanent Access Token — WhatsApp API](https://www.youtube.com/watch?v=LmoiCMJJ6S4&list=PLX_K_BlBdZKi4GOFmJ9_67og7pMzm2vXH&index=1&t=158s&pp=gAQBiAQB) 31 | 32 | 3- [Get started with the Messenger API for Instagram](https://www.youtube.com/watch?v=Pi2KxYeGMXo&list=PLX_K_BlBdZKi4GOFmJ9_67og7pMzm2vXH&index=5&t=376s&pp=gAQBiAQB) 33 | 34 | ## Step 1: Previous Configuration 35 | 36 | ✅ **Clone the repo** 37 | 38 | ``` 39 | git clone https://github.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra.git 40 | ``` 41 | 42 | ✅ **Go to**: 43 | 44 | ``` 45 | cd re-invent-agent 46 | ``` 47 | 48 | ✅ **Create The Virtual Environment**: by following the steps in the [README](/re-invent-agent/README.md) 49 | 50 | ``` 51 | python3 -m venv .venv 52 | ``` 53 | 54 | ``` 55 | source .venv/bin/activate 56 | ``` 57 | for windows: 58 | 59 | ``` 60 | .venv\Scripts\activate.bat 61 | ``` 62 | 63 | ✅ **Install The Requirements**: 64 | 65 | ``` 66 | pip install -r requirements.txt 67 | ``` 68 | 69 | ✅ **Set Values**: 70 | 71 | In [customer_support_bot_stack.py](/customer-support-bot/customer_support_bot/customer_support_bot_stack.py) edit this line with the whatsapp Facebook Developer app number: 72 | 73 | ` 74 | DISPLAY_PHONE_NUMBER = 'YOU-NUMBER' 75 | ` 76 | 77 | This agent maintains the history of the conversation, which is stored in the `session_tabble` Amazon DynamoDB table, also have control session management in the `session_active_tabble` Amazon DynamoDB table, and sets the time [here](/customer-support-bot/lambdas/code/langchain_agent_text/lambda_function.py) in this line: 78 | 79 | 80 | ` 81 | if diferencia > 300: #session time in seg 82 | ` 83 | 84 | > **Tip:** [Kenton Blacutt](https://github.com/KBB99), an AWS Associate Cloud App Developer, collaborated with Langchain, creating the [Amazon Dynamodb based memory class](https://github.com/langchain-ai/langchain/pull/1058) that allows us to store the history of a langchain agent in an [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html?sc_channel=el&sc_campaign=genaiwave&sc_content=working-with-your-live-data-using-langchain&sc_geo=mult&sc_country=mult&sc_outcome=acq). 85 | 86 | 87 | ## Step 2: Deploy The App With CDK. 88 | 89 | Follow steps [here](/customer-support-bot/README.md) 90 | 91 | ✅ **Synthesize The Cloudformation Template With The Following Command**: 92 | 93 | ``` 94 | cdk synth 95 | ``` 96 | 97 | ✅🚀 **The Deployment**: 98 | 99 | ``` 100 | cdk deploy 101 | ``` 102 | 103 | ✅ **Review what is deployed in the stack:** 104 | 105 | - Go to the [AWS Cloudformation console](console.aws.amazon.com/cloudformation), select the region where you deployed and click on `CustomerSupportBotStack`: 106 | 107 | Then go to the resources tab and explore what's deployed: 108 | 109 | ![Digrama parte 1](/imagen/stack.jpg) 110 | 111 | ✅ **Wait a few minutes:** 112 | 113 | This stack automatically creates an Amazon Kendra Index with the data source that contains the [Q&A database of the airline "La inventada"](/customer-support-bot/airline-qa-base), you must wait a few minutes for all the data to be synchronized. 114 | 115 | ![Digrama parte 1](/imagen/Kendra_datasources.jpg) 116 | 117 | ## Step 3: Activate WhatsApp Messaging In The App 118 | 119 | Go to AWS Secrets Manager and edit the WhatsApp settings and replace them with Facebook Developer settings. 120 | 121 | ![Digrama parte 1](/imagen/secret.png) 122 | 123 | ## Step 4: Configure Webhook In Facebook Developer Application 124 | 125 | 126 | ![Digrama parte 1](/imagen/webhook.png) 127 | 128 | ## Let´s try! 129 | 130 | ✅ **Q&A:** 131 | 132 | You can start asking for customer service information as if it were an airline customer service line. 133 | 134 | 135 | ![Digrama parte 1](/imagen/QA.gif) 136 | 137 | ✅ **Passenger information:** 138 | 139 | The CDK stack creates the dynamoDB table named `Passenger_ID` with the [sample passenger dataset](/customer-support-bot/airline-dataset) [from Kaggle](https://www.kaggle.com/datasets/iamsouravbanerjee/airline-dataset). Select one and request information regarding it. What if I now change the language and ask the AI in Spanish? 140 | 141 | ![Digrama parte 1](/imagen/passanger_information.gif) 142 | 143 | > The multilanguage function depends on the [LLM you use](https://aws.amazon.com/bedrock/). 144 | 145 | 146 | ✅ **Send it voice notes:** 147 | 148 | > [Amazon Transcribe](https://docs.aws.amazon.com/transcribe/latest/dg/lang-id.html) is able to automatically identify the languages spoken in your media without you having to specify a language code. 149 | 150 | ![Digrama parte 1](/imagen/voice_note.gif) 151 | 152 | 153 | ## 🚀 Keep testing the agent, play with the prompt in this Amazon Lambda function and adjust it to your need. 154 | 155 | 156 | ## Security 157 | 158 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 159 | 160 | ## License 161 | 162 | This library is licensed under the MIT-0 License. See the LICENSE file. 163 | -------------------------------------------------------------------------------- /customer-support-bot/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .venv 6 | *.egg-info 7 | 8 | # CDK asset staging directory 9 | .cdk.staging 10 | cdk.out 11 | -------------------------------------------------------------------------------- /customer-support-bot/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Welcome to your CDK Python project! 3 | 4 | This is a blank project for CDK development with Python. 5 | 6 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 7 | 8 | This project is set up like a standard Python project. The initialization 9 | process also creates a virtualenv within this project, stored under the `.venv` 10 | directory. To create the virtualenv it assumes that there is a `python3` 11 | (or `python` for Windows) executable in your path with access to the `venv` 12 | package. If for any reason the automatic creation of the virtualenv fails, 13 | you can create the virtualenv manually. 14 | 15 | To manually create a virtualenv on MacOS and Linux: 16 | 17 | ``` 18 | $ python3 -m venv .venv 19 | ``` 20 | 21 | After the init process completes and the virtualenv is created, you can use the following 22 | step to activate your virtualenv. 23 | 24 | ``` 25 | $ source .venv/bin/activate 26 | ``` 27 | 28 | If you are a Windows platform, you would activate the virtualenv like this: 29 | 30 | ``` 31 | % .venv\Scripts\activate.bat 32 | ``` 33 | 34 | Once the virtualenv is activated, you can install the required dependencies. 35 | 36 | ``` 37 | $ pip install -r requirements.txt 38 | ``` 39 | 40 | At this point you can now synthesize the CloudFormation template for this code. 41 | 42 | ``` 43 | $ cdk synth 44 | ``` 45 | 46 | To add additional dependencies, for example other CDK libraries, just add 47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt` 48 | command. 49 | 50 | ## Useful commands 51 | 52 | * `cdk ls` list all stacks in the app 53 | * `cdk synth` emits the synthesized CloudFormation template 54 | * `cdk deploy` deploy this stack to your default AWS account/region 55 | * `cdk diff` compare deployed stack with current state 56 | * `cdk docs` open CDK documentation 57 | 58 | Enjoy! 59 | -------------------------------------------------------------------------------- /customer-support-bot/airline-dataset/dataset.csv: -------------------------------------------------------------------------------- 1 | "Passenger_ID","Age","Airport_Continent","Airport_Country_Code","Airport_Name","Arrival_Airport","Continents","Country_Name","Departure_Date","First_Name","Flight_Status","Gender","Last_Name","Nationality","Pilot_Name" 2 | "90896710","45","EU","HR","Osijek Airport","OSI","Europe","Croatia","6/24/2022","Dorothea","On Time","Female","Rogister","Sweden","Trevor Braunston" 3 | "65668687","62","NAM","US","Coldfoot Airport","CXF","North America","United States","6/28/2022","Edithe","On Time","Female","Leggis","Japan","Fransisco Hazeldine" 4 | "10266115","48","NAM","US","Lebanon Municipal Airport","LEB","North America","United States","5/23/2022","Tansy","Delayed","Female","Symons","Indonesia","Olly Pawelek" 5 | "87351041","54","AS","SA","Turaif Domestic Airport","TUI","Asia","Saudi Arabia","02-08-2022","Rutger","Cancelled","Male","Georgeon","Myanmar","Steward Sainter" 6 | "76107902","46","NAM","US","Hattiesburg Laurel Regional Airport","PIB","North America","United States","7/27/2022","Marjory","Cancelled","Female","Franz","Nigeria","Padget Diben" 7 | "12297975","54","SAM","BR","Monte Carmelo Airport","0","South America","Brazil","9/14/2022","Krishnah","On Time","Male","Dabels","Russia","Freddie Wallach" 8 | "86308981","20","NAM","US","Nikolai Airport","NIB","North America","United States","08-11-2022","Anestassia","On Time","Female","Vauls","Albania","Lucio Notley" 9 | "11077747","55","SAM","BR","Coronel Horácio de Mattos Airport","LEC","South America","Brazil","06-10-2022","Lora","On Time","Female","Durbann","Brazil","Inglis Dolley" 10 | "10012037","45","AF","MG","Port Bergé Airport","WPB","Africa","Madagascar","8/24/2022","Bobbye","On Time","Female","Patmore","China","Stella Pittham" 11 | "10010778","85","NAM","DO","Casa De Campo International Airport","LRM","North America","Dominican Republic","04-04-2022","Violetta","Delayed","Female","Francois","Indonesia","Christel Blues" 12 | "11210410","3","NAM","US","Spirit of St Louis Airport","SUS","North America","United States","7/17/2022","Cordie","On Time","Female","Rosenberger","Brazil","Enrica Ferrarini" 13 | "10210212","56","NAM","CA","Victoria Harbour Seaplane Base","YWH","North America","Canada","01-12-2022","Gene","Delayed","Male","Cottham","Philippines","Sib Feragh" 14 | "10511788","37","SAM","CO","Orocue Airport","ORC","South America","Colombia","08-12-2022","Arel","Cancelled","Male","Tyson","Spain","Danie Maggiore" 15 | "11211310","36","SAM","BR","Maestro Wilson Fonseca Airport","STM","South America","Brazil","04-07-2022","Perceval","Cancelled","Male","Dallosso","Vietnam","Sharyl Eastmead" 16 | "11580310","19","OC","NC","Nesson Airport","HLU","Oceania","New Caledonia","3/25/2022","Murvyn","Cancelled","Male","Duff","Germany","Dorine Timmermann" 17 | "72741069","33","NAM","KY","Gerrard Smith International Airport","CYB","North America","Cayman Islands","06-11-2022","Gauthier","Cancelled","Male","Elsip","Uruguay","Leslie Delmage" 18 | "60786581","6","AS","VN","Cà Mau Airport","CAH","Asia","Viet Nam","1/13/2022","Leandra","Cancelled","Female","Demer","Colombia","Lizbeth Snaden" 19 | "11665108","45","NAM","CA","Fort Mcpherson Airport","ZFM","North America","Canada","12-04-2022","Maia","Delayed","Female","Kidwell","Philippines","Dorise Ronchka" 20 | "10769658","19","NAM","CA","St Augustin Airport","YIF","North America","Canada","11-05-2022","Dorisa","Cancelled","Female","Skill","Ukraine","Ilyse Bartleman" 21 | "11998719","70","SAM","CO","El Dorado International Airport","BOG","South America","Colombia","03-12-2022","Edlin","On Time","Male","Theobald","Poland","Lisha Retallick" 22 | "11072117","21","OC","PG","Pureni Airport","PUI","Oceania","Papua New Guinea","8/15/2022","Kelsy","Delayed","Female","Danhel","Indonesia","Sacha Munford" 23 | "69104710","23","EU","RU","Nalchik Airport","NAL","Europe","Russian Federation","11/26/2022","Rodolph","Delayed","Male","Grewcock","Kazakhstan","Constantine Leworthy" 24 | "87863978","87","NAM","US","Elkhart Municipal Airport","EKI","North America","United States","3/20/2022","Sayre","Cancelled","Male","Stroyan","Indonesia","Austine Crewe" 25 | "11710083","3","AS","ID","Yuruf Airport","RUF","Asia","Indonesia","05-02-2022","Fidelio","Delayed","Male","Guerry","China","Caye Donat" 26 | "10597717","79","OC","PG","Talasea Airport","TLW","Oceania","Papua New Guinea","07-07-2022","Cordy","On Time","Male","Plenderleith","Sweden","Fifine Dodshon" 27 | "47870741","57","NAM","US","Elkhart Municipal Airport","EKI","North America","United States","11/29/2022","Rufus","Cancelled","Male","Bernardini","Peru","Brittan Barends" 28 | "48586741","2","NAM","NI","Augusto C. Sandino (Managua) International Airport","MGA","North America","Nicaragua","02-02-2022","Ransell","Delayed","Male","Evins","Russia","Berna Tenwick" 29 | "11397887","89","AF","CM","Kribi Airport","KBI","Africa","Cameroon","1/13/2022","Biddy","On Time","Female","Rief","Vietnam","Darlleen Twohig" 30 | "12076115","37","AS","ID","Sultan Khairun Babullah Airport","TTE","Asia","Indonesia","05-11-2022","Carlota","Cancelled","Female","Llewhellin","China","Reube Branwhite" 31 | "10727145","89","AF","MR","Tamchakett Airport","THT","Africa","Mauritania","10/25/2022","Findley","Delayed","Male","Godleman","Indonesia","Mitchell Parsisson" 32 | "89761208","54","NAM","US","Central Maine Airport of Norridgewock","OWK","North America","United States","4/13/2022","Collin","Delayed","Male","Ciepluch","China","Torin Le Leu" 33 | "72836575","9","NAM","US","Phoenix-Mesa-Gateway Airport","AZA","North America","United States","06-10-2022","Skelly","On Time","Male","Gopsell","Czech Republic","Deborah Mathissen" 34 | "11972797","89","AF","ZA","Arathusa Safari Lodge Airport","ASS","Africa","South Africa","10-07-2022","Carolann","Cancelled","Female","Yves","Poland","Dulci Milne" 35 | "69310812","62","AS","RU","Mirny Airport","MJZ","Asia","Russian Federation","2/21/2022","Anders","On Time","Male","Treadger","Madagascar","Giacomo Tooth" 36 | "10570817","79","AS","IR","Bandar Lengeh Airport","BDH","Asia","""Iran, Islamic Republic of""","12-05-2022","Bernardo","Cancelled","Male","Bigland","Philippines","Corissa Lamps" 37 | "11610167","76","NAM","US","McGhee Tyson Airport","TYS","North America","United States","02-07-2022","Margaux","Delayed","Female","Lattin","Guatemala","Sydelle Danher" 38 | "80828421","27","EU","IS","Fáskrúðsfjörður Airport","FAS","Europe","Iceland","1/13/2022","Artemus","On Time","Male","Brewitt","China","Jayme Witard" 39 | "11075841","18","OC","PG","Hatzfeldhaven Airport","HAZ","Oceania","Papua New Guinea","5/25/2022","Basil","Cancelled","Male","Canon","Portugal","Siobhan Philippon" 40 | "11027997","87","OC","AU","Leinster Airport","LER","Oceania","Australia","8/21/2022","Flin","Delayed","Male","Bordone","Philippines","Hunt Sommerlie" 41 | "65682115","25","AS","ID","Muhammad Salahuddin Airport","BMU","Asia","Indonesia","8/28/2022","Marlin","Cancelled","Male","Yegorev","Egypt","Saidee Sellers" 42 | "77817010","54","NAM","CR","Islita Airport","PBP","North America","Costa Rica","7/15/2022","Dermot","Cancelled","Male","Stainburn","Armenia","Buddy Guslon" 43 | "85707977","76","EU","DE","""Magdeburg """"City"""" Airport""","ZMG","Europe","Germany","12-06-2022","Clemmie","Cancelled","Male","Harbertson","Ukraine","Tadio Hayne" 44 | "90102643","77","AF","BF","Ouahigouya Airport","OUG","Africa","Burkina Faso","4/29/2022","Eugenius","On Time","Male","Headon","Ukraine","Ibrahim Cotton" 45 | "11571798","66","OC","PG","Wanuma Airport","WNU","Oceania","Papua New Guinea","09-01-2022","Magda","Cancelled","Female","Nealand","United States","Brnaba Lilburne" 46 | "77501081","74","AF","DZ","In Guezzam Airport","INF","Africa","Algeria","1/20/2022","Lissa","Delayed","Female","Thynn","Luxembourg","Sean Searchwell" 47 | "56731101","76","AS","JP","Akita Airport","AXT","Asia","Japan","06-03-2022","Ag","Delayed","Female","Gumby","China","Annamarie Shrimpton" 48 | "10488104","78","NAM","US","Omar N Bradley Airport","MBY","North America","United States","5/19/2022","Cy","Cancelled","Male","Servante","China","Ludovika Purdon" 49 | "67677769","74","NAM","CA","Campbell River Airport","YBL","North America","Canada","7/22/2022","Rudolph","Delayed","Male","Housbie","Iran","Kirby Varvell" 50 | "10936912","44","NAM","US","Zahn's Airport","AYZ","North America","United States","11/23/2022","Ashlie","Delayed","Female","Rotham","Ireland","Vicky Silmon" 51 | "11970101","85","SAM","AR","Valcheta Airport","VCF","South America","Argentina","10/23/2022","Con","On Time","Male","Kaine","Yemen","Ginger Dominichelli" 52 | "88821088","23","EU","SE","Gällivare Airport","GEV","Europe","Sweden","5/21/2022","Elana","Delayed","Female","Heisham","Greece","Nathanial Gretton" 53 | "75841011","51","AS","LK","Batticaloa Airport","BTC","Asia","Sri Lanka","02-12-2022","Constancy","Cancelled","Female","Darke","China","Bron Alben" 54 | "79744010","80","NAM","CA","Brandon Municipal Airport","YBR","North America","Canada","4/14/2022","Allx","Cancelled","Female","Fretter","Brazil","Saxon Stoker" 55 | "89685887","30","NAM","US","Columbus Lowndes County Airport","UBS","North America","United States","1/13/2022","Seline","Cancelled","Female","Garvill","Philippines","Dael Schubuser" 56 | "11588768","12","NAM","CA","Schefferville Airport","YKL","North America","Canada","04-05-2022","Tobe","Cancelled","Female","Torrejon","Brazil","Gaelan Fforde" 57 | "90108115","90","NAM","GT","El Petén Airport","TKM","North America","Guatemala","05-05-2022","Sydney","On Time","Male","MacGhee","Guatemala","Ambur Boden" 58 | "11711175","6","AF","CG","Gamboma Airport","GMM","Africa","Congo","04-09-2022","Jessamyn","Delayed","Female","Buddles","Peru","Beau Stevens" 59 | "65118120","10","OC","PG","Omora Airport","OSE","Oceania","Papua New Guinea","08-01-2022","Sergio","On Time","Male","Edmonson","Sweden","Woodie Stearley" 60 | "27711966","87","NAM","US","White Mountain Airport","WMO","North America","United States","7/20/2022","Lilli","Delayed","Female","Sarath","Sweden","Ollie Ventom" 61 | "11111936","58","NAM","CA","Gorge Harbour Seaplane Base","YGE","North America","Canada","08-05-2022","Celina","Cancelled","Female","Boothebie","Latvia","Balduin Ingman" 62 | "11773666","24","SAM","BR","João Durval Carneiro Airport","FEC","South America","Brazil","1/25/2022","Bryna","On Time","Female","Monson","Poland","Elissa Ledwich" 63 | "10566861","29","OC","PG","Bewani Airport","BWP","Oceania","Papua New Guinea","11/29/2022","Benson","On Time","Male","Hook","Indonesia","Kristi Curteis" 64 | "99896811","80","NAM","CA","Tahsis Seaplane Base","ZTS","North America","Canada","11/16/2022","Noelyn","On Time","Female","Penquet","Brazil","Harlene Illingsworth" 65 | "72121122","73","NAM","BS","Colonel Hill Airport","CRI","North America","Bahamas","12-11-2022","Bibby","Delayed","Female","Evershed","Indonesia","Georgena Scanderet" 66 | "84116721","86","NAM","US","Valle Airport","VLE","North America","United States","5/19/2022","West","Cancelled","Male","Kernermann","Norway","Rosamund Gauchier" 67 | "75811097","53","NAM","US","Wiley Post Will Rogers Memorial Airport","BRW","North America","United States","12-05-2022","Halie","Delayed","Female","Jewar","France","Katerine Bartolomivis" 68 | "90121111","68","NAM","US","Okmulgee Regional Airport","OKM","North America","United States","7/15/2022","Terri","On Time","Female","Palle","Poland","Maisey Kubis" 69 | "11676510","42","AF","BW","Jwaneng Airport","JWA","Africa","Botswana","3/28/2022","Dunstan","On Time","Male","Fyrth","China","Sallie Jessop" 70 | "12110111","22","AF","GQ","Malabo Airport","SSG","Africa","Equatorial Guinea","9/23/2022","Lyndsie","Delayed","Female","Dyball","Czech Republic","Arlina Legging" 71 | "68211644","62","SAM","BR","Monte Dourado Airport","MEU","South America","Brazil","12/28/2022","Eran","On Time","Female","Summerill","Afghanistan","Fabien Lipprose" 72 | "89102113","82","AF","DZ","Tsletsi Airport","QDJ","Africa","Algeria","11-01-2022","Happy","Cancelled","Female","Jaskowicz","Mexico","Meridith Dibbe" 73 | "12210976","37","NAM","US","Dallas Love Field","DAL","North America","United States","5/31/2022","Loree","On Time","Female","Fishpond","Ukraine","Gaelan Kenyam" 74 | "10227116","8","AF","MR","Timbedra Airport","TMD","Africa","Mauritania","2/19/2022","Joellyn","On Time","Female","Stutter","Croatia","Janaya Retchford" 75 | "87380708","73","EU","GB","Duxford Aerodrome","QFO","Europe","United Kingdom","10/30/2022","Rand","Cancelled","Male","Bram","Ivory Coast","Stanislas Tiffin" 76 | "75410969","52","OC","AU","Helenvale Airport","HLV","Oceania","Australia","05-02-2022","Newton","Delayed","Male","Berni","Argentina","Rouvin Siflet" 77 | "83117110","79","AS","CN","Jiayuguan Airport","JGN","Asia","China","5/29/2022","Mead","On Time","Male","Syer","Venezuela","Monique Edworthye" 78 | "94666710","6","AS","CN","Guanghan Airport","GHN","Asia","China","2/24/2022","Lincoln","Cancelled","Male","Casburn","Vietnam","Coralie Chatterton" 79 | "08210810","54","NAM","CA","Geraldton Greenstone Regional Airport","YGQ","North America","Canada","7/28/2022","Isidor","Cancelled","Male","Rundall","Peru","Claresta Charter" 80 | "11871791","69","OC","NZ","Kaitaia Airport","KAT","Oceania","New Zealand","4/24/2022","Neal","Delayed","Male","Kulver","Thailand","Roldan Doyley" 81 | "10908998","54","OC","AU","Minlaton Airport","XML","Oceania","Australia","12/15/2022","Ransom","On Time","Male","Chippindale","Peru","Lenci Aitkin" 82 | "86120722","73","NAM","US","Denver International Airport","DEN","North America","United States","05-07-2022","Tan","On Time","Male","Connold","Sweden","Bevvy Cleall" 83 | "91071188","21","NAM","US","Gillespie Field","SEE","North America","United States","2/25/2022","Bay","On Time","Male","Pencost","China","Ebonee Tree" 84 | "28896711","74","AS","SY","Al Thaurah Airport","SOR","Asia","Syrian Arab Republic","11/15/2022","Rozelle","Delayed","Female","Neubigin","China","Missy Yepiskopov" 85 | "11280107","76","NAM","US","Lawson Army Air Field (Fort Benning)","LSF","North America","United States","7/21/2022","Francoise","Delayed","Female","Mustill","Netherlands","Carlye Egan" 86 | "10810407","14","NAM","US","Naval Outlying Field Imperial Beach (Ream Field)","NRS","North America","United States","9/26/2022","Fons","On Time","Male","Schrieves","Albania","Reinald Toffler" 87 | "76010275","9","OC","PG","Gora Airstrip","GOC","Oceania","Papua New Guinea","6/25/2022","Gardiner","On Time","Male","Ferbrache","Sweden","Pamela Franiak" 88 | "10105867","12","NAM","US","Hutchinson County Airport","BGD","North America","United States","07-03-2022","Arlee","On Time","Female","Levine","China","Kale Cabbell" 89 | "12288882","53","SAM","BR","Antônio Guerreiro Airport","GMS","South America","Brazil","9/16/2022","Jameson","On Time","Male","Sayce","Brazil","Maddy Siuda" 90 | "69100692","30","NAM","CA","Wabush Airport","YWK","North America","Canada","09-06-2022","Kaitlin","Cancelled","Female","Gaven","Sao Tome and Principe","Leshia Risby" 91 | "91058479","24","NAM","US","Crested Butte Airpark","CSE","North America","United States","2/19/2022","Paige","Delayed","Male","Hayhow","Sweden","Clyde Winn" 92 | "84120105","66","OC","AU","Yam Island Airport","XMY","Oceania","Australia","12/27/2022","Jewel","On Time","Female","Betteney","China","Bonnee Summerson" 93 | "11888118","7","EU","IT","Genoa Cristoforo Colombo Airport","GOA","Europe","Italy","12/18/2022","Ebony","On Time","Female","Knappitt","Russia","Laurence Queenborough" 94 | "38100120","45","NAM","CA","Gaspé (Michel-Pouliot) Airport","YGP","North America","Canada","5/15/2022","Dredi","Cancelled","Female","Curd","Russia","Fitzgerald Alberti" 95 | "21049767","28","SAM","VE","Zaraza Airport","ZRZ","South America","""Venezuela, Bolivarian Republic of""","9/23/2022","Janella","On Time","Female","Hardaker","Colombia","Shaylynn Alcott" 96 | "70971151","17","OC","AU","Kalbarri Airport","KAX","Oceania","Australia","5/29/2022","Lorilyn","On Time","Female","Annion","China","Annaliese Cramond" 97 | "10081186","65","OC","PG","Awaba Airport","AWB","Oceania","Papua New Guinea","10/28/2022","Arlena","Delayed","Female","Ridwood","Ireland","Alyosha Damp" 98 | "71851169","32","NAM","US","Farmington Regional Airport","FAM","North America","United States","03-07-2022","Amberly","Delayed","Female","Handling","China","Lothaire Eades" 99 | "11911111","39","OC","PG","Buka Airport","BUA","Oceania","Papua New Guinea","10/29/2022","Piggy","Delayed","Male","Hugle","Philippines","Far Cicci" 100 | "12175477","19","AS","NP","Bhojpur Airport","BHP","Asia","Nepal","12-10-2022","Cirilo","Delayed","Male","Camoletto","China","Louisa Worvell" 101 | "11010411","65","AS","IR","Lar Airport","LRR","Asia","""Iran, Islamic Republic of""","7/31/2022","Gabriella","Delayed","Female","Patry","China","Clyve Dickerson" 102 | "10587869","70","OC","AU","St George Airport","SGO","Oceania","Australia","07-12-2022","Hobie","Delayed","Male","Skace","China","Jenn Backshaw" 103 | "68981109","35","EU","DE","RAF Wildenrath","WID","Europe","Germany","2/17/2022","Gisella","Cancelled","Female","Watters","Philippines","Sherwin Izen" 104 | "10682102","4","OC","PG","Tapini Airport","TPI","Oceania","Papua New Guinea","7/30/2022","Care","Cancelled","Male","Kearton","Kenya","Britt Viney" 105 | "71065103","11","SAM","BR","Soledade Airport","0","South America","Brazil","10-03-2022","Modesty","Cancelled","Female","Zink","Ukraine","Charissa Figures" 106 | "98107210","49","NAM","US","Owatonna Degner Regional Airport","OWA","North America","United States","01-04-2022","Adlai","On Time","Male","Tilmouth","Serbia","Caresse Sumpner" 107 | "98102976","68","AF","MZ","Paradise Island Airport","NTC","Africa","Mozambique","10/29/2022","Randie","On Time","Male","Jankin","Mexico","Ibrahim Andraud" 108 | "78375104","1","SAM","EC","Nueva Loja Airport","LGQ","South America","Ecuador","12/17/2022","Gearalt","Delayed","Male","Bynold","China","Mic Rosenau" 109 | "70670731","23","NAM","US","Southwest Florida International Airport","RSW","North America","United States","3/24/2022","Franz","Cancelled","Male","Roset","Greece","Stanford Garnam" 110 | "73115651","50","SAM","BO","Roboré Airport","RBO","South America","""Bolivia, Plurinational State of""","5/13/2022","Andy","Cancelled","Male","Kettleson","China","Ivett Connikie" 111 | "89101695","66","AS","IN","Tezu Airport","TEI","Asia","India","5/23/2022","Shermy","Delayed","Male","Gatchell","Colombia","Albrecht Lorne" 112 | "82101114","65","OC","PG","Long Island Airport","LSJ","Oceania","Papua New Guinea","10/23/2022","Des","Cancelled","Male","Sutehall","Indonesia","Bartholomeus Gherardini" 113 | "68112971","29","SAM","CO","Hato Corozal Airport","HTZ","South America","Colombia","08-06-2022","Jayme","Delayed","Female","Dairton","Indonesia","Kaye Clews" 114 | "77829791","41","OC","PG","Doini Airport","DOI","Oceania","Papua New Guinea","07-06-2022","Genevra","On Time","Female","Shipperbottom","Ethiopia","Tandie Willbraham" 115 | "73840896","16","NAM","CA","Black Tickle Airport","YBI","North America","Canada","02-12-2022","Brunhilda","Delayed","Female","Davley","Indonesia","Constantino Flanigan" 116 | "99709910","75","AS","ID","Sangir Airport","SAE","Asia","Indonesia","10-01-2022","Corby","On Time","Male","Van Der Straaten","Kazakhstan","Maureen Slimming" 117 | "28041103","39","NAM","MX","Nuevo Casas Grandes Airport","NCG","North America","Mexico","5/27/2022","Porty","Cancelled","Male","Jori","Tunisia","Rasia Fidelus" 118 | "11383991","51","NAM","MX","General Lucio Blanco International Airport","REX","North America","Mexico","10/19/2022","Flora","On Time","Female","Delgardillo","Philippines","Keeley Kiltie" 119 | "84908011","64","OC","VU","Futuna Airport","FTA","Oceania","Vanuatu","09-04-2022","Felizio","Cancelled","Male","Kevern","Russia","Munroe Humble" 120 | "66104761","35","AF","ZM","Kasaba Bay Airport","ZKB","Africa","Zambia","4/14/2022","Clevie","Delayed","Male","Clubbe","China","Fenelia Print" 121 | "68112189","61","NAM","US","Cincinnati Northern Kentucky International Airport","CVG","North America","United States","6/16/2022","Zelig","On Time","Male","Brinded","Brazil","Cosmo Rossbrook" 122 | "10612154","14","OC","WS","Faleolo International Airport","APW","Oceania","Samoa","7/22/2022","Magdalen","Delayed","Female","Claiden","China","Micky Luno" 123 | "12199821","52","NAM","GT","Mundo Maya International Airport","FRS","North America","Guatemala","5/25/2022","Cairistiona","Cancelled","Female","Tummond","Tanzania","Burnaby De Mitris" 124 | "51027211","85","NAM","US","Springfield Branson National Airport","SGF","North America","United States","08-09-2022","Travers","Cancelled","Male","Selwyne","Colombia","Annetta Vasyunkin" 125 | "79735651","36","NAM","CA","Merritt Airport","YMB","North America","Canada","11-03-2022","Henryetta","Delayed","Female","Noice","Chile","Sybilla Hargey" 126 | "68907090","46","NAM","CA","Amos/Magny Airport","YEY","North America","Canada","4/18/2022","Fairleigh","On Time","Male","Hagger","China","Andre Sissel" 127 | "97111103","90","OC","AU","Mullewa Airport","MXU","Oceania","Australia","09-10-2022","Vernen","Delayed","Male","Ivakhnov","China","Lidia Kleinert" 128 | "12011098","35","NAM","US","University of Oklahoma Westheimer Airport","OUN","North America","United States","1/26/2022","Chris","On Time","Female","Body","Sweden","Loretta Bumphries" 129 | "73117799","62","AS","IR","Shahid Sadooghi Airport","AZD","Asia","""Iran, Islamic Republic of""","8/16/2022","Bethany","Cancelled","Female","Corona","Tanzania","Elmer Baldock" 130 | "81786511","35","EU","IT","Venice Marco Polo Airport","VCE","Europe","Italy","8/20/2022","Aleda","On Time","Female","Pigram","Palestinian Territory","Daryn Bardsley" 131 | "71107113","73","AF","ZA","Tanda Tula Airport","TDT","Africa","South Africa","6/17/2022","Winne","Cancelled","Female","Cowland","France","Ernaline Klain" 132 | "11810984","15","AS","MN","Khovd Airport","HVD","Asia","Mongolia","10/13/2022","Marylinda","Cancelled","Female","Gussie","Poland","Dyanna Edmondson" 133 | "83121101","55","SAM","BR","Canarana Airport","CQA","South America","Brazil","9/26/2022","Cymbre","Cancelled","Female","Steeden","Russia","Margit Filon" 134 | "12276776","79","NAM","US","Bemidji Regional Airport","BJI","North America","United States","6/19/2022","Virgil","Cancelled","Male","Markussen","Philippines","Bird Boarder" 135 | "11590811","7","AS","CN","Handan Airport","HDG","Asia","China","03-08-2022","Gwenore","Delayed","Female","Smaridge","Russia","Doria Coils" 136 | "09108711","58","OC","AU","Diamantina Lakes Airport","DYM","Oceania","Australia","11/23/2022","Tamas","Delayed","Male","Vigneron","Mali","Clemente Mateev" 137 | "80108119","47","AS","PK","Loralai Airport","LRG","Asia","Pakistan","3/19/2022","Kalie","Delayed","Female","Scoble","Sweden","Madelena Lennarde" 138 | "88071139","78","AS","RU","Aldan Airport","ADH","Asia","Russian Federation","08-07-2022","Mattias","Cancelled","Male","Darrell","Honduras","Masha Banville" 139 | "10270678","23","OC","AU","South Galway Airport","ZGL","Oceania","Australia","11-10-2022","Natalya","Cancelled","Female","Offner","Czech Republic","Christalle Lifton" 140 | "85791027","80","AS","JP","Tarama Airport","TRA","Asia","Japan","4/13/2022","Sherwood","On Time","Male","Woolaston","Portugal","Ardelia Milch" 141 | "21041121","36","NAM","DM","Canefield Airport","DCF","North America","Dominica","5/19/2022","Mischa","Delayed","Male","Caulwell","Mexico","Cari Moens" 142 | "27010010","51","AF","KE","Mulika Lodge Airport","JJM","Africa","Kenya","7/27/2022","Anabella","Cancelled","Female","Tutchings","China","Joceline Frangleton" 143 | "69103288","6","AF","CD","Kasenga Airport","KEC","Africa","""Congo, The Democratic Republic of the""","10/16/2022","Ephrayim","On Time","Male","Bedford","China","Park Thody" 144 | "10310510","54","NAM","US","Susanville Municipal Airport","SVE","North America","United States","3/21/2022","Haroun","On Time","Male","holmes","United States","Xerxes Arkcoll" 145 | "10577182","54","AF","SD","En Nahud Airport","NUD","Africa","Sudan","5/18/2022","Nicole","Cancelled","Female","Gages","South Africa","Chet Carryer" 146 | "10584691","7","NAM","US","Kalaupapa Airport","LUP","North America","United States","4/27/2022","Trudey","On Time","Female","Wagge","Poland","Manya Vaun" 147 | "72798575","54","AS","CN","Nanjing Lukou Airport","NKG","Asia","China","10-11-2022","Francine","Cancelled","Female","Adolfsen","Indonesia","Leanora Romney" 148 | "12161057","39","EU","HR","Rijeka Airport","RJK","Europe","Croatia","4/27/2022","Domenico","Cancelled","Male","Cadman","Ukraine","Tailor McGilroy" 149 | "88276116","45","EU","BG","Sofia Airport","SOF","Europe","Bulgaria","1/20/2022","Arlyn","On Time","Female","Boole","Philippines","Cindie Critten" 150 | "86871091","82","AF","DZ","Mecheria Airport","MZW","Africa","Algeria","05-12-2022","Pavlov","Cancelled","Male","Hadye","Brazil","Stefano Klampt" 151 | "10711311","62","OC","AU","Port Lincoln Airport","PLO","Oceania","Australia","03-06-2022","Chrotoem","On Time","Male","Abels","Russia","Che Brett" 152 | "11085991","21","NAM","US","Sawyer International Airport","MQT","North America","United States","5/17/2022","Lamond","Cancelled","Male","Ahmed","Croatia","Liv Heinig" 153 | "11386111","83","NAM","US","Moody Air Force Base","VAD","North America","United States","8/17/2022","Yasmin","Delayed","Female","Findlow","Macedonia","Parnell Gosby" 154 | "11566102","71","NAM","PA","Ruben Cantu Airport","SYP","North America","Panama","02-06-2022","Briant","Delayed","Male","De La Haye","Russia","Alina Flooks" 155 | "74105978","85","AS","MY","Sepulot Airport","SPE","Asia","Malaysia","11-01-2022","Virginie","Cancelled","Female","Vaneev","France","Wadsworth Gillyett" 156 | "11611175","90","NAM","US","Amchitka Army Airfield","AHT","North America","United States","06-07-2022","Pamella","Cancelled","Female","Eaden","Indonesia","Pearle Assiter" 157 | "87728910","56","EU","RU","Krasnoselkup Airport","KKQ","Europe","Russian Federation","8/19/2022","Bryn","On Time","Female","Pratley","Maldives","Loria Brogini" 158 | "31008678","16","OC","PG","Moro Airport","MXH","Oceania","Papua New Guinea","05-11-2022","Averell","Cancelled","Male","Shellsheere","Albania","Syman Milham" 159 | "78122100","37","NAM","US","Lemhi County Airport","SMN","North America","United States","1/23/2022","Paulie","Delayed","Male","Dunnet","Serbia","Ned Marnes" 160 | "11226687","54","NAM","US","Venice Municipal Airport","VNC","North America","United States","04-01-2022","Justinn","On Time","Female","Ishchenko","Pakistan","Sapphira MacKinnon" 161 | "10611610","88","NAM","US","Waycross Ware County Airport","AYS","North America","United States","9/17/2022","Leroi","Cancelled","Male","Raeburn","Brazil","Binny Launder" 162 | "76787910","75","NAM","CA","Shuswap Regional Airport","YSN","North America","Canada","10-05-2022","Heath","On Time","Male","Lackmann","China","Trude Querrard" 163 | "68683115","45","EU","SK","Lučenec Airport","LUE","Europe","Slovakia","7/27/2022","Kirbee","On Time","Female","Wrenn","Armenia","Mary Hurch" 164 | "72751070","37","OC","AU","Bairnsdale Airport","BSJ","Oceania","Australia","01-11-2022","Dasha","On Time","Female","Eppson","Indonesia","Merci Jeduch" 165 | "10585751","77","OC","AU","Cudal Airport","CUG","Oceania","Australia","3/24/2022","Catriona","Delayed","Female","Beaument","Russia","Margie Beal" 166 | "90665857","22","OC","AU","Etadunna Airport","ETD","Oceania","Australia","4/26/2022","Brien","On Time","Male","Gatherer","Poland","Liv Lydall" 167 | "70691201","76","EU","GB","Newcastle Airport","NCL","Europe","United Kingdom","3/17/2022","Reinaldo","On Time","Male","Caines","Indonesia","Kakalina Usmar" 168 | "36765726","26","EU","PT","João Paulo II Airport","PDL","Europe","Portugal","8/26/2022","Ajay","On Time","Female","Durward","Russia","Bertha Piborn" 169 | "99997911","70","EU","RU","Ust-Maya Airport","UMS","Europe","Russian Federation","11-10-2022","Peterus","Delayed","Male","Lettson","Botswana","Eugine Mainwaring" 170 | "11411611","75","NAM","US","Grumman Bethpage Airport","BPA","North America","United States","8/21/2022","Michele","On Time","Male","Olenchenko","Russia","Bessie Toller" 171 | "42612112","12","EU","RU","Talakan Airport","TLK","Europe","Russian Federation","06-12-2022","Ikey","On Time","Male","Dowty","China","Beverlee Da Costa" 172 | "11076810","62","AS","CN","Guilin Liangjiang International Airport","KWL","Asia","China","09-05-2022","Warner","Cancelled","Male","Driutti","China","Marita Holtom" 173 | "67610778","66","OC","AU","Cue Airport","CUY","Oceania","Australia","10/16/2022","Jedidiah","Cancelled","Male","Malins","Indonesia","Perren Salkild" 174 | "83101111","73","AS","MM","Pakhokku Airport","PKK","Asia","Myanmar","05-12-2022","Artair","Delayed","Male","Ondrich","Indonesia","Phoebe Quilkin" 175 | "12012284","32","OC","PG","Moki Airport","MJJ","Oceania","Papua New Guinea","12/21/2022","Dun","Cancelled","Male","Craythorn","China","Dunn MacSkeagan" 176 | "82881049","43","NAM","US","Lihue Airport","LIH","North America","United States","1/31/2022","Lennard","On Time","Male","Giorgi","Peru","Jordana Lantaff" 177 | "88104511","88","EU","DE","Rostock-Laage Airport","RLG","Europe","Germany","8/23/2022","Gabrila","On Time","Female","Speedin","Portugal","Hope O'Doherty" 178 | "82681101","37","OC","AU","Groote Eylandt Airport","GTE","Oceania","Australia","3/30/2022","Quentin","On Time","Male","Plaschke","Syria","Honey Gallaway" 179 | "89120122","54","NAM","US","Centralia Municipal Airport","ENL","North America","United States","3/24/2022","Neil","Cancelled","Male","McCory","Portugal","Odella Gregoretti" 180 | "12221221","38","OC","AU","Dalby Airport","DBY","Oceania","Australia","5/15/2022","Yuri","On Time","Male","Crossfield","Peru","Crista Timewell" 181 | "81136580","22","AF","ZA","Oudtshoorn Airport","OUH","Africa","South Africa","7/18/2022","Dyna","Cancelled","Female","De'Vere - Hunt","China","Neila Giercke" 182 | "87105861","12","AS","CN","Enshi Airport","ENH","Asia","China","3/29/2022","Alvin","Delayed","Male","Wenzel","Greece","Alfie MacMorland" 183 | "12250106","77","OC","AU","Badu Island Airport","BDD","Oceania","Australia","11/24/2022","Joeann","Delayed","Female","Gotcliff","Kyrgyzstan","Brandais Crielly" 184 | "65971024","13","SAM","PY","Fuerte Olimpo Airport","OLK","South America","Paraguay","7/21/2022","Sheridan","Delayed","Male","Casino","Ukraine","Carrissa McCooke" 185 | "83106116","41","AS","IN","Pune Airport","PNQ","Asia","India","2/19/2022","Myrtie","On Time","Female","MacScherie","Laos","Claude Ashington" 186 | "27166821","85","OC","PG","Kavieng Airport","KVG","Oceania","Papua New Guinea","6/22/2022","Willie","On Time","Male","Netherwood","Russia","Shirlee Weldrake" 187 | "86661174","25","NAM","HN","Copán Ruinas Airport","RUY","North America","Honduras","7/14/2022","Lisle","On Time","Male","Floyd","China","Kiley Skilton" 188 | "78118100","16","AS","MM","Putao Airport","PBU","Asia","Myanmar","12/18/2022","Peri","Cancelled","Female","Battram","Peru","Coralyn McMickan" 189 | "10288111","83","NAM","US","Kenmore Air Harbor Seaplane Base","LKE","North America","United States","12-08-2022","Tessy","On Time","Female","Athelstan","Sweden","Denny Mudd" 190 | "19989110","70","EU","BG","Gorna Oryahovitsa Airport","GOZ","Europe","Bulgaria","9/25/2022","Aeriela","On Time","Female","Clarke","Portugal","Devonne Jon" 191 | "67100851","67","EU","FR","Grenoble-Isère Airport","GNB","Europe","France","1/18/2022","Darby","On Time","Male","Felgate","Russia","Rhonda Amber" 192 | "10321061","14","AS","MM","Bagan Airport","NYU","Asia","Myanmar","10-03-2022","Julietta","Delayed","Female","Delahunt","Democratic Republic of the Congo","Aimil Shakshaft" 193 | "10810898","30","AS","ID","Fakfak Airport","FKQ","Asia","Indonesia","04-09-2022","Inge","Cancelled","Female","Hewins","Morocco","Danit Hazley" 194 | "66828338","71","NAM","CA","Ottawa / Gatineau Airport","YND","North America","Canada","9/16/2022","Dominica","Delayed","Female","Pyle","China","Kacie Commucci" 195 | "10107257","87","NAM","CA","Thompson Airport","YTH","North America","Canada","11-03-2022","Jerrine","Cancelled","Female","Peeters","Philippines","Chandra Dyhouse" 196 | "78911911","37","NAM","US","Wichita Eisenhower National Airport","ICT","North America","United States","11-08-2022","Kristan","Delayed","Female","Metzing","Peru","Ellene Gibby" 197 | "10671757","84","AS","IR","Ilam Airport","IIL","Asia","""Iran, Islamic Republic of""","10/21/2022","Rory","Cancelled","Female","Wank","Japan","Yoshiko Agastina" 198 | "11485808","33","AS","IN","Biju Patnaik Airport","BBI","Asia","India","7/22/2022","Denys","Delayed","Male","Endricci","Nigeria","Lolly Sine" 199 | "65707241","19","AS","VN","Dien Bien Phu Airport","DIN","Asia","Viet Nam","8/19/2022","Carley","Delayed","Female","Gowers","Poland","Gabriello Slinn" 200 | "10911411","86","OC","AU","Margaret River (Station) Airport","MGV","Oceania","Australia","12/15/2022","Murry","On Time","Male","Entreis","Russia","Delora Percival" 201 | "11110069","49","AF","BF","Arly Airport","ARL","Africa","Burkina Faso","10/29/2022","Star","Cancelled","Female","Casford","Greece","Bailey Priver" 202 | "99106988","40","AS","IL","Bar Yehuda Airfield","MTZ","Asia","Israel","11/14/2022","Heywood","On Time","Male","Bisp","Indonesia","Tomi Larkins" 203 | "10511812","72","OC","PG","Green River Airport","GVI","Oceania","Papua New Guinea","07-11-2022","Wilma","On Time","Female","Burdytt","Poland","Clarey Masding" 204 | "11187116","80","NAM","US","Panguitch Municipal Airport","PNU","North America","United States","10/19/2022","Mariann","Delayed","Female","Wilshin","China","Vanya Dami" 205 | "11278097","7","NAM","US","Southern Seaplane Airport","BCS","North America","United States","3/26/2022","Ferrel","Cancelled","Male","Elphey","Slovenia","Queenie Arends" 206 | "12211711","29","OC","AU","Nyngan Airport","NYN","Oceania","Australia","1/14/2022","Valle","On Time","Male","Christoforou","Benin","Constantia Rubery" 207 | "67100871","33","NAM","US","Memorial Field","HOT","North America","United States","11/28/2022","Mariele","Cancelled","Female","Lucius","Ukraine","Nickie Rudyard" 208 | "11511911","39","AS","TW","Matsu Nangan Airport","LZN","Asia","""Taiwan, Province of China""","10/27/2022","Kelci","On Time","Female","Colliver","China","Dulci Bastow" 209 | "09711784","62","NAM","US","Albert Lea Municipal Airport","AEL","North America","United States","07-05-2022","Leta","On Time","Female","Tartt","Afghanistan","Karlene Kempster" 210 | "10610788","62","NAM","CA","Kugluktuk Airport","YCO","North America","Canada","12/26/2022","Elwood","On Time","Male","Catt","Nicaragua","Marla Parsonage" 211 | "51099010","69","SAM","BR","Araraquara Airport","AQA","South America","Brazil","03-08-2022","Nathanil","On Time","Male","Monan","Brazil","Gabe Sartin" 212 | "11570198","12","NAM","CA","Tahsis Seaplane Base","ZTS","North America","Canada","1/31/2022","Erwin","Cancelled","Male","Baise","Haiti","Weber Swindon" 213 | "98861111","32","NAM","US","Abraham Lincoln Capital Airport","SPI","North America","United States","4/25/2022","George","Delayed","Female","Wildber","Brazil","Sayer Speakman" 214 | "90122113","85","AS","NP","Meghauli Airport","MEY","Asia","Nepal","2/26/2022","Rici","Delayed","Female","Rein","Russia","Eleni Avent" 215 | "65901110","2","NAM","US","Stewart International Airport","SWF","North America","United States","07-06-2022","Tann","Cancelled","Male","McCroary","Poland","Neysa Hendin" 216 | "72109661","69","EU","RU","Grabtsevo Airport","KLF","Europe","Russian Federation","10/26/2022","Adair","Delayed","Male","Spurman","China","Milka Towll" 217 | "76120121","72","AS","CN","Xinzhou Wutaishan Airport","WUT","Asia","China","4/27/2022","Darnall","Cancelled","Male","Comfort","Russia","Maryjane Wolseley" 218 | "10210191","8","NAM","US","Dalhart Municipal Airport","DHT","North America","United States","04-08-2022","Sybila","On Time","Female","Troker","Indonesia","Nelle Aldridge" 219 | "79728011","65","OC","PG","Mal Airport","MMV","Oceania","Papua New Guinea","10/26/2022","Kurt","Delayed","Male","Marling","Indonesia","Noelyn Abbey" 220 | "31061091","13","NAM","CA","Vermilion Airport","YVG","North America","Canada","04-06-2022","Burlie","On Time","Male","Schustl","Thailand","Alameda Carlyle" 221 | "90697736","73","EU","NO","Vadsø Airport","VDS","Europe","Norway","11/25/2022","Diannne","Cancelled","Female","Samter","Cameroon","Simmonds Gallihaulk" 222 | "12061141","13","NAM","US","Trona Airport","TRH","North America","United States","5/28/2022","Aprilette","Cancelled","Female","Veysey","Thailand","Neale MacMearty" 223 | "11611809","38","EU","RO","Sibiu International Airport","SBZ","Europe","Romania","12/24/2022","Jacenta","Cancelled","Female","Linner","Argentina","Joseito Zorzi" 224 | "61098710","18","NAM","US","Kenai Municipal Airport","ENA","North America","United States","07-03-2022","Cobbie","Delayed","Male","Imorts","Croatia","Eugenius Grishakov" 225 | "70978598","24","SAM","BR","Arapiraca Airport","APQ","South America","Brazil","4/26/2022","Aldon","Delayed","Male","Ridsdell","Ghana","Lynette Ortelt" 226 | "10879661","29","AS","IN","Gorakhpur Airport","GOP","Asia","India","1/30/2022","Ericha","Cancelled","Female","Dressel","Sweden","Rowena Krollman" 227 | "90691166","17","AS","CN","Quzhou Airport","JUZ","Asia","China","9/22/2022","Gnni","On Time","Female","Chaperling","Brazil","Justinn Hugh" 228 | "88718179","6","OC","PG","Wantoat Airport","WTT","Oceania","Papua New Guinea","11/30/2022","Dorthea","On Time","Female","Wealleans","China","Adi Sinclar" 229 | "85116118","52","OC","PF","Mururoa Atoll Airport","UOA","Oceania","French Polynesia","02-06-2022","Frank","On Time","Male","Greenhough","Philippines","Ronald Antonucci" 230 | "11584748","33","EU","UA","Mariupol International Airport","MPW","Europe","Ukraine","08-09-2022","Burty","On Time","Male","Blurton","China","Leonora Holah" 231 | "11366101","56","AS","ID","Rar Gwamar Airport","DOB","Asia","Indonesia","07-08-2022","Rosalyn","Delayed","Female","Vondrys","China","Fowler Desquesnes" 232 | "11811011","56","AS","SA","Jubail Airport","QJB","Asia","Saudi Arabia","2/13/2022","Herbert","Delayed","Male","Billingsly","Mongolia","Lincoln Blaske" -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/Change_of_name_of_any_passenger_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/Change_of_name_of_any_passenger_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/Change_of_passage_from_round_from_flown_not_flown_lastainventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/Change_of_passage_from_round_from_flown_not_flown_lastainventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/How to know_if_can_change_the_passage_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/How to know_if_can_change_the_passage_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/Knows_the_the_right_to_retract_lainventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/Knows_the_the_right_to_retract_lainventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/Lainventada_airlines_ticket_cancellation_information.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/Lainventada_airlines_ticket_cancellation_information.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/Request_the_refund_of_shipping_taxes_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/Request_the_refund_of_shipping_taxes_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/buy_an_ticket_and_me_regretti_of_travel_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/buy_an_ticket_and_me_regretti_of_travel_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/change passport_number_or_id_in_passage_lainventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/change passport_number_or_id_in_passage_lainventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/change_of_flights_or_dates_of_ticket_lainventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/change_of_flights_or_dates_of_ticket_lainventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/change_of_passages_after_start_the_trip_the_travel_inventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/change_of_passages_after_start_the_trip_the_travel_inventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/change_of_passages_before_an_affectation_LAINVENTADA_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/change_of_passages_before_an_affectation_LAINVENTADA_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/change_of_passages_purchased_at_agencias_lainventada_airlines..pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/change_of_passages_purchased_at_agencias_lainventada_airlines..pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/deadline for_returns_of_passages_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/deadline for_returns_of_passages_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/deadlines for_make_an_change_of_passage_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/deadlines for_make_an_change_of_passage_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/discover_how_how_to receive_your_devolucin_lainventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/discover_how_how_to receive_your_devolucin_lainventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/forward_or_postponingacin_flight_the same_from_Lainventada_airline.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/forward_or_postponingacin_flight_the same_from_Lainventada_airline.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/get_what_do_in_case_of_fraud_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/get_what_do_in_case_of_fraud_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/how_to_request_the_devolucin_from_your_ticket_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/how_to_request_the_devolucin_from_your_ticket_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/refunds_of_money_for_passage_launventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/refunds_of_money_for_passage_launventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/return_for_reduction_of_shipment_taxes_lastainventada_airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/return_for_reduction_of_shipment_taxes_lastainventada_airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/where to check_cost_of_change_of_passages_lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/where to check_cost_of_change_of_passages_lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/where_can_change_of_passages_Lainventada_Airlines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/where_can_change_of_passages_Lainventada_Airlines.pdf -------------------------------------------------------------------------------- /customer-support-bot/airline-qa-base/PDF/where_to_request_the_return_of_the Lainventada_Airlines ticket.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/airline-qa-base/PDF/where_to_request_the_return_of_the Lainventada_Airlines ticket.pdf -------------------------------------------------------------------------------- /customer-support-bot/apis/__init__.py: -------------------------------------------------------------------------------- 1 | from apis.webhooks import WebhookApi -------------------------------------------------------------------------------- /customer-support-bot/apis/webhooks.py: -------------------------------------------------------------------------------- 1 | 2 | from aws_cdk import ( 3 | aws_apigateway as apg, 4 | Stack 5 | ) 6 | 7 | from constructs import Construct 8 | 9 | 10 | 11 | class WebhookApi(Construct): 12 | 13 | def __init__(self, scope: Construct, construct_id: str,lambdas, **kwargs) -> None: 14 | super().__init__(scope, construct_id, **kwargs) 15 | 16 | api = apg.RestApi(self, "myapi") 17 | api.root.add_cors_preflight(allow_origins=["*"], allow_methods=["GET", "POST"], allow_headers=["*"]) 18 | 19 | cloudapi = api.root.add_resource("cloudapi",default_integration=apg.LambdaIntegration(lambdas.whatsapp_in, allow_test_invoke=False)) 20 | 21 | cloudapi.add_method("GET") 22 | 23 | cloudapi.add_method("POST") 24 | -------------------------------------------------------------------------------- /customer-support-bot/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | 4 | import aws_cdk as cdk 5 | 6 | from customer_support_bot.customer_support_bot_stack import CustomerSupportBotStack 7 | from customer_support_bot.application_insights_stack import ApplicationInsightsStack 8 | 9 | TAGS = { 10 | 'APP': 'CustomerChatReinvent2023', 11 | } 12 | 13 | app = cdk.App() 14 | 15 | stk = CustomerSupportBotStack(app, "CustomerSupportBotStack", 16 | # If you don't specify 'env', this stack will be environment-agnostic. 17 | # Account/Region-dependent features and context lookups will not work, 18 | # but a single synthesized template can be deployed anywhere. 19 | 20 | # Uncomment the next line to specialize this stack for the AWS Account 21 | # and Region that are implied by the current CLI configuration. 22 | 23 | #env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')), 24 | 25 | # Uncomment the next line if you know exactly what Account and Region you 26 | # want to deploy the stack to. */ 27 | 28 | #env=cdk.Environment(account='123456789012', region='us-east-1'), 29 | 30 | # For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html 31 | ) 32 | 33 | if TAGS.keys(): 34 | for k in TAGS.keys(): 35 | cdk.Tags.of(stk).add(k, TAGS[k]) 36 | 37 | 38 | ApplicationInsightsStack(app, "AolicationInsightGroup") 39 | 40 | app.synth() 41 | -------------------------------------------------------------------------------- /customer-support-bot/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "requirements*.txt", 11 | "source.bat", 12 | "**/__init__.py", 13 | "python/__pycache__", 14 | "tests" 15 | ] 16 | }, 17 | "context": { 18 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true, 19 | "@aws-cdk/core:checkSecretUsage": true, 20 | "@aws-cdk/core:target-partitions": [ 21 | "aws", 22 | "aws-cn" 23 | ], 24 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 25 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 26 | "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, 27 | "@aws-cdk/aws-iam:minimizePolicies": true, 28 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true, 29 | "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, 30 | "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, 31 | "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, 32 | "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, 33 | "@aws-cdk/core:enablePartitionLiterals": true, 34 | "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, 35 | "@aws-cdk/aws-iam:standardizedServicePrincipals": true, 36 | "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, 37 | "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, 38 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, 39 | "@aws-cdk/aws-route53-patters:useCertificate": true, 40 | "@aws-cdk/customresources:installLatestAwsSdkDefault": false, 41 | "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, 42 | "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, 43 | "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, 44 | "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, 45 | "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, 46 | "@aws-cdk/aws-redshift:columnId": true, 47 | "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, 48 | "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, 49 | "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, 50 | "@aws-cdk/aws-kms:aliasNameRef": true, 51 | "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, 52 | "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, 53 | "@aws-cdk/aws-efs:denyAnonymousAccess": true, 54 | "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, 55 | "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, 56 | "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /customer-support-bot/customer_support_bot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/customer_support_bot/__init__.py -------------------------------------------------------------------------------- /customer-support-bot/customer_support_bot/application_insights_stack.py: -------------------------------------------------------------------------------- 1 | 2 | from aws_cdk import ( 3 | Stack, 4 | aws_resourcegroups as rg, 5 | aws_applicationinsights as ai, 6 | ) 7 | # For consistency with other languages, `cdk` is the preferred import name for 8 | # the CDK's core module. The following line also imports it as `core` for use 9 | # with examples from the CDK Developer's Guide, which are in the process of 10 | # being updated to use `cdk`. You may delete this import if you don't need it. 11 | 12 | 13 | 14 | from constructs import Construct 15 | class ApplicationInsightsStack(Stack): 16 | 17 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 18 | super().__init__(scope, construct_id, **kwargs) 19 | 20 | 21 | group = rg.CfnGroup(self, 'rgroup', name='reinvent-rg', 22 | resource_query= rg.CfnGroup.ResourceQueryProperty( 23 | query=rg.CfnGroup.QueryProperty( 24 | resource_type_filters = [ 25 | "AWS::Lambda::Function", 26 | "AWS::DynamoDB::Table", 27 | "AWS::SQS::Queue", 28 | "AWS::S3::Bucket", 29 | "AWS::Events::Rule", 30 | "AWS::ApiGateway::RestApi", 31 | "AWS::SNS::Topic", 32 | "AWS::StepFunctions::Activity", 33 | "AWS::StepFunctions::StateMachine", 34 | ], 35 | tag_filters = [ 36 | rg.CfnGroup.TagFilterProperty(key='APP', values=['CustomerChatReinvent2023']) 37 | ] 38 | ), 39 | type='TAG_FILTERS_1_0' 40 | )) 41 | 42 | app_insights = ai.CfnApplication( 43 | self, 'application_insight', 44 | resource_group_name = 'reinvent-rg', 45 | ) 46 | 47 | app_insights.add_depends_on(group) 48 | 49 | -------------------------------------------------------------------------------- /customer-support-bot/customer_support_bot/customer_support_bot_stack.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import ( 2 | # Duration, 3 | Stack, SecretValue, 4 | aws_secretsmanager as secretsmanager, 5 | aws_iam as iam, 6 | # aws_sqs as sqs, 7 | aws_dynamodb as ddb, 8 | RemovalPolicy, 9 | aws_s3_notifications, 10 | aws_s3 as s3, 11 | aws_lambda_event_sources, 12 | aws_lambda, 13 | 14 | ) 15 | from constructs import Construct 16 | from lambdas import (Lambdas, DynamodbWithSampleDataStack) 17 | from apis import WebhookApi 18 | from databases import Tables 19 | from s3_cloudfront import S3Deploy 20 | from kendra_constructs import ( 21 | KendraIndex, CRKendraS3Datasource 22 | ) 23 | 24 | #Amazon DynamoDB Table commun data 25 | REMOVAL_POLICY = RemovalPolicy.DESTROY 26 | TABLE_CONFIG = dict (removal_policy=REMOVAL_POLICY, billing_mode= ddb.BillingMode.PAY_PER_REQUEST) 27 | AudioKeyName = "audio-from-whatsapp" 28 | TextBucketName = "text-to-whatsapp" 29 | model_id = "anthropic.claude-instant-v1" 30 | DISPLAY_PHONE_NUMBER = 'YOU-NUMBER' 31 | 32 | 33 | class CustomerSupportBotStack(Stack): 34 | 35 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 36 | super().__init__(scope, construct_id, **kwargs) 37 | 38 | # The code that defines your stack goes here 39 | stk = Stack.of(self) 40 | account_id = stk.account 41 | region_name = self.region 42 | 43 | #Whatsapp Secrets Values 44 | secrets = secretsmanager.Secret(self, "Secrets", secret_object_value = { 45 | 'WHATS_TOKEN': SecretValue.unsafe_plain_text('FROM_WHATSAPP'), 46 | 'WHATS_VERIFICATION_TOKEN': SecretValue.unsafe_plain_text('CREATE_ONE'), 47 | 'WHATS_PHONE_ID':SecretValue.unsafe_plain_text('FROM_WHATSAPP'), 48 | 'WHATS_TOKEN': SecretValue.unsafe_plain_text('FROM_WHATSAPP') 49 | }) 50 | 51 | # Create Amazon DynamoDB Tables 52 | 53 | Tbl = Tables(self, 'Tbl') 54 | 55 | table_whatsapp_metadata = Tbl.whatsapp_MetaData 56 | table_session_tabble = Tbl.session_tabble 57 | table_passangerTable = Tbl.passangerTable 58 | table_session_active = Tbl.session_active_tabble 59 | 60 | table_whatsapp_metadata.add_global_secondary_index(index_name = 'jobnameindex', 61 | partition_key = ddb.Attribute(name="jobName",type=ddb.AttributeType.STRING), 62 | projection_type=ddb.ProjectionType.KEYS_ONLY) 63 | 64 | # Amazon Kendra 65 | index = KendraIndex(self, "I") 66 | 67 | 68 | #Create Amazon S3 Bucket 69 | 70 | s3_deploy = S3Deploy(self, "airline-demo-", TextBucketName,TextBucketName) 71 | s3_deploy_qa = S3Deploy(self, "airline-qa-base-", TextBucketName,TextBucketName) 72 | 73 | s3_deploy_qa.deploy("airline-qa-base", "airline-qa-base", "airline-qa-base") 74 | 75 | #Create Amazon Lambda Functions 76 | 77 | Fn = Lambdas(self,'Fn') 78 | 79 | #Create Amazon API Gateweay 80 | 81 | Api = WebhookApi(self, "API", lambdas=Fn) 82 | 83 | #Data to Amazon Kendra Index 84 | 85 | s3_files_es_ds = CRKendraS3Datasource( 86 | self, "airline-qa-base", 87 | service_token=Fn.data_source_creator.function_arn, 88 | index_id= index.index_id, 89 | role_arn=index.role.arn, 90 | name = "airline-qa-base-v1", 91 | description = "airline-qa-base", 92 | bucket_name=s3_deploy_qa.bucket.bucket_name, 93 | language_code = 'en', 94 | inclusion_prefixes=["airline-qa-base/"], 95 | inclusion_patterns = [] 96 | ) 97 | 98 | # Amazon Lambda Function dynamodb_put_item to passanger table 99 | 100 | Tbl.passangerTable.grant_full_access(Fn.dynamodb_put_item) 101 | 102 | # Load data into table 103 | DynamodbWithSampleDataStack( 104 | self, "pasanger-qa-base", 105 | lambda_function=Fn.dynamodb_put_item, 106 | table= Tbl.passangerTable, 107 | file_name = "dataset.csv" 108 | ) 109 | 110 | # Amazon Lambda Function whatsapp_in - Config 111 | 112 | Fn.whatsapp_in.add_environment(key='CONFIG_PARAMETER', value=secrets.secret_arn) 113 | Fn.whatsapp_in.add_environment(key='whatsapp_MetaData', value=table_whatsapp_metadata.table_name) 114 | Fn.whatsapp_in.add_environment(key='REFRESH_SECRETS', value='false') 115 | Fn.whatsapp_in.add_environment(key='DISPLAY_PHONE_NUMBER', value= DISPLAY_PHONE_NUMBER) 116 | secrets.grant_read(Fn.whatsapp_in) 117 | Fn.whatsapp_in.add_environment(key='ENV_KEY_NAME', value="messages_id") 118 | table_whatsapp_metadata.grant_full_access(Fn.whatsapp_in) 119 | 120 | 121 | # Amazon Lambda Function process_stream - Config 122 | 123 | Fn.process_stream.add_environment( key='ENV_LAMBDA_AGENT_TEXT', value=Fn.langchain_agent_text.function_name ) 124 | Fn.process_stream.add_environment( key='JOB_TRANSCRIPTOR_LAMBDA', value=Fn.audio_job_transcriptor.function_name ) 125 | Fn.process_stream.add_environment(key='whatsapp_MetaData', value=Tbl.whatsapp_MetaData.table_name) 126 | 127 | Fn.process_stream.add_event_source( 128 | aws_lambda_event_sources.DynamoEventSource(table=Tbl.whatsapp_MetaData, 129 | starting_position=aws_lambda.StartingPosition.TRIM_HORIZON)) 130 | Tbl.whatsapp_MetaData.grant_full_access(Fn.process_stream) 131 | 132 | Fn.langchain_agent_text.grant_invoke(Fn.process_stream) 133 | 134 | # Amazon Lambda Function whatsapp_out - Config 135 | 136 | Fn.whatsapp_out.grant_invoke(Fn.langchain_agent_text) 137 | 138 | # Amazon Lambda Function audio_job_transcriptor - Config 139 | 140 | Fn.audio_job_transcriptor.add_to_role_policy(iam.PolicyStatement( actions=["transcribe:*"], resources=['*'])) 141 | Fn.audio_job_transcriptor.add_environment(key='BucketName', value=s3_deploy.bucket.bucket_name) 142 | Fn.audio_job_transcriptor.add_environment(key='whatsapp_MetaData', value=Tbl.whatsapp_MetaData.table_name) 143 | Fn.audio_job_transcriptor.add_environment(key='AudioKeyName', value=AudioKeyName) 144 | Fn.audio_job_transcriptor.add_environment(key='TextBucketName', value=TextBucketName) 145 | 146 | Fn.audio_job_transcriptor.grant_invoke(Fn.process_stream) 147 | 148 | Fn.audio_job_transcriptor.add_to_role_policy(iam.PolicyStatement( actions=["dynamodb:*"], resources=[f"{Tbl.whatsapp_MetaData.table_arn}",f"{Tbl.whatsapp_MetaData.table_arn}/*"])) 149 | Fn.audio_job_transcriptor.add_environment(key='ENV_INDEX_NAME', value="jobnameindex") 150 | Fn.audio_job_transcriptor.add_environment(key='ENV_KEY_NAME', value="messages_id") 151 | 152 | s3_deploy.bucket.grant_read_write(Fn.audio_job_transcriptor) 153 | Tbl.whatsapp_MetaData.grant_full_access(Fn.audio_job_transcriptor) 154 | 155 | # Amazon Lambda Function audio_job_transcriptor done - Config 156 | 157 | 158 | s3_deploy.bucket.grant_read(Fn.transcriber_done) 159 | 160 | s3_deploy.bucket.add_event_notification(s3.EventType.OBJECT_CREATED, 161 | aws_s3_notifications.LambdaDestination(Fn.transcriber_done), 162 | s3.NotificationKeyFilter(prefix=TextBucketName+"/")) 163 | 164 | Fn.transcriber_done.add_to_role_policy(iam.PolicyStatement( actions=["dynamodb:*"], resources=[f"{Tbl.whatsapp_MetaData.table_arn}",f"{Tbl.whatsapp_MetaData.table_arn}/*"])) 165 | Fn.transcriber_done.add_environment(key='ENV_INDEX_NAME', value="jobnameindex") 166 | Fn.transcriber_done.add_environment(key='ENV_KEY_NAME', value="messages_id") 167 | Fn.transcriber_done.add_environment( key='ENV_LAMBDA_AGENT_TEXT', value=Fn.langchain_agent_text.function_name ) 168 | 169 | Fn.langchain_agent_text.grant_invoke(Fn.transcriber_done) 170 | 171 | Tbl.whatsapp_MetaData.grant_full_access(Fn.transcriber_done) 172 | Fn.transcriber_done.add_environment(key='whatsapp_MetaData', value=Tbl.whatsapp_MetaData.table_name) 173 | 174 | 175 | 176 | 177 | """ 178 | s3_deploy.bucket.grant_read_write(Fn.dynamodb_put_item) 179 | 180 | s3_deploy.bucket.add_event_notification(s3.EventType.OBJECT_CREATED, 181 | aws_s3_notifications.LambdaDestination(Fn.dynamodb_put_item), 182 | s3.NotificationKeyFilter(prefix="airline-dataset/")) 183 | """ 184 | 185 | # Amazon Lambda Function query_dynamodb passanger table 186 | 187 | Fn.query_dynamodb_passanger.add_environment(key='TABLE_PASSANGER', value=table_passangerTable.table_name) 188 | Fn.query_dynamodb_passanger.add_environment(key='ENV_KEY_NAME', value="Passenger_ID") 189 | Tbl.passangerTable.grant_full_access(Fn.query_dynamodb_passanger) 190 | 191 | # Amazon Lambda Function agent Langchain with Amazon Becrock 192 | 193 | Fn.langchain_agent_text.add_environment(key='whatsapp_MetaData', value=table_whatsapp_metadata.table_name) 194 | Fn.langchain_agent_text.add_environment(key='ENV_INDEX_NAME', value="jobnameindex") 195 | Fn.langchain_agent_text.add_environment(key='ENV_KEY_NAME', value="messages_id") 196 | Fn.langchain_agent_text.add_environment(key='TABLE_SESSION_ACTIVE', value=table_session_active.table_name) 197 | Fn.langchain_agent_text.add_environment(key='KENDRA_INDEX', value= index.index_id) 198 | 199 | 200 | table_session_tabble.grant_full_access(Fn.langchain_agent_text) 201 | table_whatsapp_metadata.grant_full_access(Fn.langchain_agent_text) 202 | table_session_active.grant_full_access(Fn.langchain_agent_text) 203 | 204 | Fn.langchain_agent_text.add_to_role_policy(iam.PolicyStatement( actions=["dynamodb:*"], resources=[f"{table_whatsapp_metadata.table_arn}",f"{table_whatsapp_metadata.table_arn}/*"])) 205 | 206 | s3_deploy.bucket.grant_read_write(Fn.langchain_agent_text) 207 | 208 | Fn.langchain_agent_text.add_environment( key='ENV_LAMBDA_QUERY_NAME', value=Fn.query_dynamodb_passanger.function_name) 209 | Fn.langchain_agent_text.add_environment( key='TABLE_SESSION', value=table_session_tabble.table_name) 210 | Fn.langchain_agent_text.add_environment(key='ENV_MODEL_ID', value=model_id) 211 | Fn.langchain_agent_text.add_environment( key='WHATSAPP_OUT', value=Fn.whatsapp_out.function_name ) 212 | 213 | Fn.langchain_agent_text.add_to_role_policy(iam.PolicyStatement( actions=["bedrock:*"], resources=['*'])) 214 | 215 | Fn.query_dynamodb_passanger.grant_invoke(Fn.langchain_agent_text) 216 | Tbl.passangerTable.grant_full_access(Fn.langchain_agent_text) 217 | 218 | Fn.langchain_agent_text.grant_invoke(Fn.whatsapp_in) 219 | 220 | Fn.langchain_agent_text.add_to_role_policy(iam.PolicyStatement( actions=["kendra:Retrieve"], resources=[f"arn:aws:kendra:{region_name}:{account_id}:index/{index.index_id}"])) 221 | Fn.langchain_agent_text.add_to_role_policy(iam.PolicyStatement( actions=["kendra:Query"], resources=[f"arn:aws:kendra:{region_name}:{account_id}:index/{index.index_id}"])) 222 | 223 | #s3_deploy.deploy("airline-dataset", "airline-dataset", "airline-dataset") 224 | 225 | 226 | #Application insights 227 | 228 | -------------------------------------------------------------------------------- /customer-support-bot/databases/__init__.py: -------------------------------------------------------------------------------- 1 | from databases.databases import Tables -------------------------------------------------------------------------------- /customer-support-bot/databases/databases.py: -------------------------------------------------------------------------------- 1 | from aws_cdk import ( 2 | RemovalPolicy, 3 | aws_dynamodb as ddb 4 | ) 5 | from constructs import Construct 6 | 7 | 8 | REMOVAL_POLICY = RemovalPolicy.DESTROY 9 | 10 | TABLE_CONFIG = dict (removal_policy=REMOVAL_POLICY, billing_mode= ddb.BillingMode.PAY_PER_REQUEST) 11 | 12 | 13 | class Tables(Construct): 14 | 15 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 16 | super().__init__(scope, construct_id, **kwargs) 17 | 18 | self.whatsapp_MetaData = ddb.Table( 19 | self, "whatsapp-MetaData", 20 | partition_key=ddb.Attribute(name="messages_id", type=ddb.AttributeType.STRING), 21 | stream=ddb.StreamViewType.NEW_AND_OLD_IMAGES 22 | ) 23 | 24 | self.session_tabble = ddb.Table( 25 | self, "SessionTable", 26 | partition_key=ddb.Attribute(name="SessionId", type=ddb.AttributeType.STRING), 27 | **TABLE_CONFIG) 28 | 29 | self.passangerTable = ddb.Table( 30 | self, "passangerTable", 31 | partition_key=ddb.Attribute(name="Passenger_ID", type=ddb.AttributeType.STRING), 32 | **TABLE_CONFIG) 33 | 34 | self.session_active_tabble = ddb.Table( 35 | self, "Session_active_value_Table", 36 | partition_key=ddb.Attribute(name="phone_number", type=ddb.AttributeType.STRING), 37 | **TABLE_CONFIG) -------------------------------------------------------------------------------- /customer-support-bot/kendra_constructs/__init__.py: -------------------------------------------------------------------------------- 1 | from kendra_constructs.roles import KendraServiceRole 2 | from kendra_constructs.index import KendraIndex 3 | from kendra_constructs.datasource import KendraCrawlerDatasource, CRKendraCrawlerV2Datasource, CRKendraS3Datasource 4 | 5 | -------------------------------------------------------------------------------- /customer-support-bot/kendra_constructs/datasource.py: -------------------------------------------------------------------------------- 1 | import json 2 | from constructs import Construct 3 | 4 | from aws_cdk import ( 5 | aws_iam as iam, 6 | Stack, 7 | aws_kendra as kendra, 8 | custom_resources as cr, 9 | CustomResource, 10 | ) 11 | from datetime import datetime 12 | 13 | 14 | default_schedule = "cron(0 0 1 * ? *)" 15 | default_schedule = "" 16 | 17 | 18 | class CRKendraCrawlerV2Datasource(Construct): 19 | def __init__( 20 | self, 21 | scope: Construct, 22 | id: str, 23 | service_token, 24 | index_id, 25 | role_arn, 26 | name, 27 | seed_urls, 28 | s3_seed_url, 29 | url_inclusion_patterns, 30 | url_exclusion_patterns, 31 | description="default description", 32 | schedule=default_schedule, 33 | language_code="en", 34 | **kwargs 35 | ) -> None: 36 | super().__init__(scope, id, **kwargs) 37 | 38 | if seed_urls: 39 | seed_url_connections = [{"seedUrl": s} for s in seed_urls] 40 | connection_configuration = dict( 41 | repositoryEndpointMetadata=dict( 42 | s3SeedUrl=None, 43 | siteMapUrls=None, 44 | seedUrlConnections=seed_url_connections, 45 | s3SiteMapUrl=None, 46 | authentication="NoAuthentication", 47 | ) 48 | ) 49 | 50 | if s3_seed_url: 51 | connection_configuration = dict( 52 | repositoryEndpointMetadata=dict( 53 | s3SeedUrl=s3_seed_url, 54 | siteMapUrls=None, 55 | seedUrlConnections=None, 56 | s3SiteMapUrl=None, 57 | authentication="NoAuthentication", 58 | ) 59 | ) 60 | 61 | repository_configurations = dict( 62 | attachment=dict( 63 | fieldMappings=[ 64 | dict( 65 | dataSourceFieldName="category", 66 | indexFieldName="_category", 67 | indexFieldType="STRING", 68 | ), 69 | dict( 70 | dataSourceFieldName="sourceUrl", 71 | indexFieldName="_source_uri", 72 | indexFieldType="STRING", 73 | ), 74 | ] 75 | ), 76 | webPage=dict( 77 | fieldMappings=[ 78 | dict( 79 | dataSourceFieldName="category", 80 | indexFieldName="_category", 81 | indexFieldType="STRING", 82 | ), 83 | dict( 84 | dataSourceFieldName="sourceUrl", 85 | indexFieldName="_source_uri", 86 | indexFieldType="STRING", 87 | ), 88 | ] 89 | ), 90 | ) 91 | 92 | additiona_properties = dict( 93 | inclusionFileIndexPatterns=[], 94 | rateLimit="300", 95 | maxFileSize="50", 96 | crawlDepth="1", 97 | crawlAllDomain=False, 98 | crawlSubDomain=False, 99 | inclusionURLIndexPatterns=url_inclusion_patterns, 100 | exclusionFileIndexPatterns=[], 101 | proxy={}, 102 | exclusionURLCrawlPatterns=url_exclusion_patterns, 103 | exclusionURLIndexPatterns=url_exclusion_patterns, 104 | crawlAttachments=False, 105 | honorRobots=True, 106 | inclusionURLCrawlPatterns=url_inclusion_patterns, 107 | crawlDomainsOnly=True, 108 | maxLinksPerUrl="100", 109 | ) 110 | 111 | template = dict( 112 | connectionConfiguration=connection_configuration, 113 | enableIdentityCrawler=False, 114 | syncMode="FORCED_FULL_CRAWL", 115 | additionalProperties=additiona_properties, 116 | type="WEBCRAWLERV2", 117 | version="1.0.0", 118 | repositoryConfigurations=repository_configurations, 119 | ) 120 | 121 | cr_docs_ds = CustomResource( 122 | self, 123 | "CR2", 124 | resource_type="Custom::CRDataSource", 125 | service_token=service_token, 126 | properties=dict( 127 | index_id=index_id, 128 | role_arn=role_arn, 129 | name=name, 130 | description=description, 131 | type="TEMPLATE", 132 | template=json.dumps(template), 133 | schedule=schedule, 134 | language_code=language_code, 135 | ), 136 | ) 137 | 138 | 139 | class KendraCrawlerDatasource(Construct): 140 | def __init__( 141 | self, 142 | scope: Construct, 143 | id: str, 144 | index_id, 145 | role_arn, 146 | name, 147 | seed_urls, 148 | url_inclusion_patterns, 149 | url_exclusion_patterns, 150 | **kwargs 151 | ) -> None: 152 | super().__init__(scope, id, **kwargs) 153 | 154 | self.data_source = kendra.CfnDataSource( 155 | self, 156 | "WC", 157 | index_id=index_id, 158 | name=name, 159 | type="WEBCRAWLER", 160 | data_source_configuration=kendra.CfnDataSource.DataSourceConfigurationProperty( 161 | web_crawler_configuration=kendra.CfnDataSource.WebCrawlerConfigurationProperty( 162 | urls=kendra.CfnDataSource.WebCrawlerUrlsProperty( 163 | seed_url_configuration=kendra.CfnDataSource.WebCrawlerSeedUrlConfigurationProperty( 164 | seed_urls=seed_urls, 165 | ) 166 | ), 167 | crawl_depth=10, 168 | url_exclusion_patterns=url_exclusion_patterns, 169 | url_inclusion_patterns=url_inclusion_patterns, 170 | ), 171 | ), 172 | role_arn=role_arn, 173 | schedule=default_schedule, 174 | ) 175 | 176 | 177 | import json 178 | from constructs import Construct 179 | 180 | from aws_cdk import ( 181 | aws_iam as iam, 182 | Stack, 183 | aws_kendra as kendra, 184 | custom_resources as cr, 185 | CustomResource, 186 | ) 187 | from datetime import datetime 188 | 189 | 190 | default_schedule = "cron(0 0 1 * ? *)" 191 | default_schedule = "" 192 | 193 | 194 | class CRKendraCrawlerV2Datasource(Construct): 195 | def __init__( 196 | self, 197 | scope: Construct, 198 | id: str, 199 | service_token, 200 | index_id, 201 | role_arn, 202 | name, 203 | seed_urls, 204 | s3_seed_url, 205 | url_inclusion_patterns, 206 | url_exclusion_patterns, 207 | description="default description", 208 | schedule=default_schedule, 209 | language_code="en", 210 | **kwargs 211 | ) -> None: 212 | super().__init__(scope, id, **kwargs) 213 | 214 | if seed_urls: 215 | seed_url_connections = [{"seedUrl": s} for s in seed_urls] 216 | connection_configuration = dict( 217 | repositoryEndpointMetadata=dict( 218 | s3SeedUrl=None, 219 | siteMapUrls=None, 220 | seedUrlConnections=seed_url_connections, 221 | s3SiteMapUrl=None, 222 | authentication="NoAuthentication", 223 | ) 224 | ) 225 | 226 | if s3_seed_url: 227 | connection_configuration = dict( 228 | repositoryEndpointMetadata=dict( 229 | s3SeedUrl=s3_seed_url, 230 | siteMapUrls=None, 231 | seedUrlConnections=None, 232 | s3SiteMapUrl=None, 233 | authentication="NoAuthentication", 234 | ) 235 | ) 236 | 237 | repository_configurations = dict( 238 | attachment=dict( 239 | fieldMappings=[ 240 | dict( 241 | dataSourceFieldName="category", 242 | indexFieldName="_category", 243 | indexFieldType="STRING", 244 | ), 245 | dict( 246 | dataSourceFieldName="sourceUrl", 247 | indexFieldName="_source_uri", 248 | indexFieldType="STRING", 249 | ), 250 | ] 251 | ), 252 | webPage=dict( 253 | fieldMappings=[ 254 | dict( 255 | dataSourceFieldName="category", 256 | indexFieldName="_category", 257 | indexFieldType="STRING", 258 | ), 259 | dict( 260 | dataSourceFieldName="sourceUrl", 261 | indexFieldName="_source_uri", 262 | indexFieldType="STRING", 263 | ), 264 | ] 265 | ), 266 | ) 267 | 268 | additiona_properties = dict( 269 | inclusionFileIndexPatterns=[], 270 | rateLimit="300", 271 | maxFileSize="50", 272 | crawlDepth="1", 273 | crawlAllDomain=False, 274 | crawlSubDomain=False, 275 | inclusionURLIndexPatterns=url_inclusion_patterns, 276 | exclusionFileIndexPatterns=[], 277 | proxy={}, 278 | exclusionURLCrawlPatterns=url_exclusion_patterns, 279 | exclusionURLIndexPatterns=url_exclusion_patterns, 280 | crawlAttachments=False, 281 | honorRobots=True, 282 | inclusionURLCrawlPatterns=url_inclusion_patterns, 283 | crawlDomainsOnly=True, 284 | maxLinksPerUrl="100", 285 | ) 286 | 287 | template = dict( 288 | connectionConfiguration=connection_configuration, 289 | enableIdentityCrawler=False, 290 | syncMode="FORCED_FULL_CRAWL", 291 | additionalProperties=additiona_properties, 292 | type="WEBCRAWLERV2", 293 | version="1.0.0", 294 | repositoryConfigurations=repository_configurations, 295 | ) 296 | 297 | cr_docs_ds = CustomResource( 298 | self, 299 | "CR2", 300 | resource_type="Custom::CRDataSource", 301 | service_token=service_token, 302 | properties=dict( 303 | index_id=index_id, 304 | role_arn=role_arn, 305 | name=name, 306 | description=description, 307 | type="TEMPLATE", 308 | template=json.dumps(template), 309 | schedule=schedule, 310 | language_code=language_code, 311 | ), 312 | ) 313 | 314 | 315 | class CRKendraS3Datasource(Construct): 316 | def __init__( 317 | self, 318 | scope: Construct, 319 | id: str, 320 | service_token, 321 | index_id, 322 | role_arn, 323 | name, 324 | bucket_name, 325 | inclusion_patterns, 326 | inclusion_prefixes, 327 | metadata_files_prefix = None, 328 | exclusion_patterns = [], 329 | exclusion_prefixes = [], 330 | description="default description", 331 | schedule=default_schedule, 332 | language_code="en", 333 | **kwargs 334 | ) -> None: 335 | super().__init__(scope, id, **kwargs) 336 | 337 | 338 | connection_configuration = dict( 339 | repositoryEndpointMetadata=dict( 340 | BucketName=bucket_name 341 | ) 342 | ) 343 | 344 | repository_configurations = dict( 345 | document=dict( 346 | fieldMappings=[ 347 | dict( 348 | dataSourceFieldName="s3_document_id", 349 | indexFieldName="s3_document_id", 350 | indexFieldType="STRING", 351 | ) 352 | ] 353 | ) 354 | ) 355 | additiona_properties = dict( 356 | inclusionPrefixes=inclusion_prefixes, 357 | exclusionPatterns=exclusion_patterns, 358 | inclusionPatterns=inclusion_patterns, 359 | maxFileSizeInMegaBytes ="100", 360 | #exclusionPrefixes=exclusion_prefixes, 361 | ) 362 | 363 | if metadata_files_prefix: 364 | additiona_properties = dict(**additiona_properties, metadataFilesPrefix = metadata_files_prefix) 365 | 366 | template = dict( 367 | connectionConfiguration=connection_configuration, 368 | syncMode="FORCED_FULL_CRAWL", 369 | additionalProperties=additiona_properties, 370 | type="S3", 371 | version="1.0.0", 372 | repositoryConfigurations=repository_configurations, 373 | ) 374 | 375 | 376 | ds = CustomResource( 377 | self, 378 | "S3DS", 379 | resource_type="Custom::S3DataSource", 380 | service_token=service_token, 381 | properties=dict( 382 | index_id=index_id, 383 | role_arn=role_arn, 384 | name=name, 385 | description=description, 386 | type="TEMPLATE", 387 | template=json.dumps(template), 388 | schedule=schedule, 389 | language_code=language_code, 390 | ), 391 | ) 392 | -------------------------------------------------------------------------------- /customer-support-bot/kendra_constructs/index.py: -------------------------------------------------------------------------------- 1 | from constructs import Construct 2 | 3 | from aws_cdk import ( 4 | aws_iam as iam, Stack, 5 | aws_kendra as kendra 6 | ) 7 | 8 | from kendra_constructs.roles import KendraServiceRole 9 | 10 | 11 | class KendraIndex(Construct): 12 | def __init__(self, scope: Construct, id: str, edition="DEVELOPER_EDITION", **kwargs) -> None: 13 | super().__init__(scope, id, **kwargs) 14 | 15 | 16 | stk = Stack.of(self) 17 | self.role = KendraServiceRole(self, "KSR") 18 | 19 | 20 | document_metadata_configurations=[kendra.CfnIndex.DocumentMetadataConfigurationProperty( 21 | name="s3_document_id", 22 | type="STRING_VALUE", 23 | 24 | search=kendra.CfnIndex.SearchProperty( 25 | displayable=True, 26 | facetable=False, 27 | searchable=True, 28 | sortable=False 29 | ) 30 | )] 31 | 32 | self.index = kendra.CfnIndex(self, "I", 33 | edition=edition, 34 | name=stk.stack_name, 35 | role_arn=self.role.arn, 36 | document_metadata_configurations=document_metadata_configurations 37 | 38 | ) 39 | self.index_id = self.index.attr_id 40 | 41 | -------------------------------------------------------------------------------- /customer-support-bot/kendra_constructs/roles.py: -------------------------------------------------------------------------------- 1 | from constructs import Construct 2 | from aws_cdk import ( aws_iam as iam, Stack, CfnOutput) 3 | 4 | 5 | 6 | class KendraServiceRole(Construct): 7 | def __init__(self, scope: Construct, id: str, **kwargs) -> None: 8 | super().__init__(scope, id, **kwargs) 9 | 10 | stk = Stack.of(self) 11 | account_id = stk.account 12 | role_name = stk.stack_name 13 | 14 | self.role = iam.Role(self, "R",assumed_by=iam.ServicePrincipal("kendra.amazonaws.com")) 15 | 16 | self.arn = self.role.role_arn 17 | 18 | self.role.attach_inline_policy( 19 | policy = iam.Policy(self, "cw",statements=[ 20 | iam.PolicyStatement(actions=["cloudwatch:PutMetricData"], resources=['*']), 21 | iam.PolicyStatement(actions=["logs:*"], resources=['*']), 22 | iam.PolicyStatement(actions=["kendra:BatchPutDocument","kendra:BatchDeleteDocument"], resources=['*']), 23 | iam.PolicyStatement(actions=["lambda:*"], resources=['*']), 24 | iam.PolicyStatement(actions=["s3:GetObject"], resources=['*']), 25 | iam.PolicyStatement(actions=["s3:*"], resources=['*']) 26 | 27 | ]) 28 | ) 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/__init__.py: -------------------------------------------------------------------------------- 1 | from lambdas.project_lambdas import Lambdas 2 | from lambdas.datasource import DynamodbWithSampleDataStack -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/audio_job_transcriptor/lambda_function.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | 4 | import time 5 | import sys 6 | import datetime 7 | import uuid 8 | from botocore.exceptions import ClientError 9 | 10 | 11 | from file_utils import( get_media_url , get_whats_media,put_file) 12 | 13 | base_path="/tmp/" 14 | 15 | SOURCE_LANG_CODE = os.environ.get('SOURCE_LANG_CODE') 16 | 17 | BucketName = os.environ.get('BucketName') 18 | AudioKeyName = os.environ.get('AudioKeyName') 19 | TextBucketName = os.environ.get('TextBucketName') 20 | 21 | table_name_active_connections = os.environ.get('whatsapp_MetaData') 22 | key_name_active_connections = os.environ.get('ENV_KEY_NAME') 23 | 24 | dynamodb_resource=boto3.resource('dynamodb') 25 | table = dynamodb_resource.Table(table_name_active_connections) 26 | 27 | transcribe_client = boto3.client('transcribe') 28 | client_s3 = boto3.client('s3') 29 | 30 | #https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/transcribe/client/start_transcription_job.html 31 | 32 | def update_item(value,jobName,now): 33 | try: 34 | response = table.update_item( 35 | Key={ 36 | "messages_id" : value 37 | }, 38 | UpdateExpression="set jobName=:item1, now=:item2", 39 | ExpressionAttributeValues={ 40 | ':item1': jobName, 41 | ':item2': now, 42 | }, 43 | ReturnValues="UPDATED_NEW") 44 | print (response) 45 | except Exception as e: 46 | print (e) 47 | else: 48 | return response 49 | 50 | 51 | def start_job_transciptor (jobName,s3Path_in,OutputKey,codec): 52 | print(s3Path_in) 53 | response = transcribe_client.start_transcription_job( 54 | TranscriptionJobName=jobName, 55 | #LanguageCode='es-US', 56 | IdentifyLanguage=True, 57 | MediaFormat=codec, 58 | Media={ 59 | 'MediaFileUri': s3Path_in 60 | }, 61 | OutputBucketName = BucketName, 62 | OutputKey=OutputKey 63 | ) 64 | TranscriptionJobName = response['TranscriptionJob']['TranscriptionJobName'] 65 | job = transcribe_client.get_transcription_job(TranscriptionJobName=TranscriptionJobName) 66 | job_status = job['TranscriptionJob']['TranscriptionJobStatus'] 67 | 68 | print("Processing....") 69 | print("Print job_status ....",job_status) 70 | print("TranscriptionJobName : {}".format(TranscriptionJobName)) 71 | 72 | 73 | def lambda_handler(event, context): 74 | 75 | print(event) 76 | 77 | start = int( time.time() ) 78 | whats_message = event['whats_message'] 79 | 80 | whats_token = event['whats_token'] 81 | messages_id = event['messages_id'] 82 | phone = event['phone'] 83 | phone_id = event['phone_id'] 84 | 85 | messageType = whats_message['type'] 86 | 87 | fileType = whats_message[messageType]['mime_type'] 88 | fileExtension = fileType.split('/')[-1] 89 | fileId = whats_message[messageType]['id'] 90 | fileName = f'{fileId}.{fileExtension}' 91 | fileUrl = get_media_url(fileId, whats_token) 92 | 93 | mime_type = fileType.split(";")[0] 94 | codec = mime_type.split("/")[-1] 95 | print(codec) 96 | 97 | if not fileUrl: return 98 | 99 | fileContents = get_whats_media(fileUrl,whats_token) 100 | fileSize = sys.getsizeof(fileContents) - 33 ## Removing BYTES overhead 101 | 102 | 103 | print(f"messageType:{messageType}") 104 | print(f"fileType:{fileType}") 105 | print(f"fileName:{fileName}") 106 | print(f"fileId:{fileId}") 107 | print(f"fileUrl:{fileUrl}") 108 | print("Size downloaded:" + str(fileSize)) 109 | 110 | print ("Ready To TRANSCRIPTION!") 111 | 112 | now = int( time.time() ) 113 | 114 | LOCAL_FILE = f"audio_{fileId}.{codec}" 115 | 116 | with open(f"{base_path}{LOCAL_FILE}", "wb") as binary_file: 117 | binary_file.write(fileContents) 118 | 119 | put_file(base_path,LOCAL_FILE, BucketName, AudioKeyName+"/") 120 | 121 | s3Path_in = "s3://" + BucketName + "/" + AudioKeyName +"/"+LOCAL_FILE 122 | 123 | jobName = fileId 124 | 125 | bucket_key_out = TextBucketName +"/" + f"texto_{fileId}" 126 | 127 | start_job_transciptor (jobName,s3Path_in,bucket_key_out,codec) 128 | 129 | value = whats_message['id'] 130 | print(value) 131 | print(jobName) 132 | print(now) 133 | update_item(value,jobName,now) 134 | 135 | 136 | return True -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/data_source_creator/create.event.json: -------------------------------------------------------------------------------- 1 | { 2 | "RequestType": "Create", 3 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 4 | "ResponseURL": "https://cloudformation-custom-resource-response-uswest2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A320205374826%3Astack/kendra-index/9ba2dfa0-50fb-11ee-b463-0a3aed41439b%7CCR29646A773%7C44154c3f-3bac-47f9-a8c5-f79c7ef186d0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230916T032815Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA54RCMT6SBI2P4EYF%2F20230916%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=1672265163d2580eee170620f277572c19baba259d833a1de846ccc25e3becaa", 5 | "StackId": "arn:aws:cloudformation:us-west-2:320205374826:stack/kendra-index/9ba2dfa0-50fb-11ee-b463-0a3aed41439b", 6 | "RequestId": "44154c3f-3bac-47f9-a8c5-f79c7ef186d0", 7 | "LogicalResourceId": "CR29646A773", 8 | "ResourceType": "Custom::CRDataSource", 9 | "ResourceProperties": { 10 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 11 | "schedule": "", 12 | "language_code": "en", 13 | "role_arn": "arn:aws:iam::320205374826:role/kendra-index-IKSRC7156E80-UBOWSCNEAXV9", 14 | "configuration": { 15 | "TemplateConfiguration": { 16 | "Template": "{\"connectionConfiguration\": {\"repositoryEndpointMetadata\": {\"s3SeedUrl\": \"s3://kendra-index-urlsbucket330222cc-uh1kqmon5xj7/s3_urls/connect_blogs_1.txt\", \"siteMapUrls\": null, \"seedUrlConnections\": null, \"s3SiteMapUrl\": null, \"authentication\": \"NoAuthentication\"}}, \"enableIdentityCrawler\": false, \"syncMode\": \"FORCED_FULL_CRAWL\", \"additionalProperties\": {\"inclusionFileIndexPatterns\": [], \"rateLimit\": \"300\", \"maxFileSize\": \"50\", \"crawlDepth\": \"1\", \"crawlAllDomain\": false, \"crawlSubDomain\": false, \"inclusionURLIndexPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"exclusionFileIndexPatterns\": [], \"proxy\": {}, \"exclusionURLCrawlPatterns\": [\"*./tag/.*\"], \"exclusionURLIndexPatterns\": [\"*./tag/.*\"], \"crawlAttachments\": false, \"honorRobots\": true, \"inclusionURLCrawlPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"crawlDomainsOnly\": true, \"maxLinksPerUrl\": \"100\"}, \"type\": \"WEBCRAWLERV2\", \"version\": \"1.0.0\", \"repositoryConfigurations\": {\"attachment\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}, \"webPage\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}}}" 17 | } 18 | }, 19 | "name": "connect-blogs-100-v5", 20 | "description": "Creado con custom resources", 21 | "index_id": "9cfc368a-f4d6-4469-96bf-a6476b94ac31", 22 | "type": "TEMPLATE" 23 | } 24 | } -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/data_source_creator/delete.event.json: -------------------------------------------------------------------------------- 1 | { 2 | "RequestType": "Delete", 3 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 4 | "ResponseURL": "https://cloudformation-custom-resource-response-uswest2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A320205374826%3Astack/kendra-index/9ba2dfa0-50fb-11ee-b463-0a3aed41439b%7CCR29646A773%7C1ada474a-f088-4820-a538-e87d689bc24e?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230916T050041Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA54RCMT6SBI2P4EYF%2F20230916%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=bf064488cc8043f42d0ae6a63066cd3c7feaad10bfb44f5b5b9c8b7f4f8a2394", 5 | "StackId": "arn:aws:cloudformation:us-west-2:320205374826:stack/kendra-index/9ba2dfa0-50fb-11ee-b463-0a3aed41439b", 6 | "RequestId": "1ada474a-f088-4820-a538-e87d689bc24e", 7 | "LogicalResourceId": "CR29646A773", 8 | "PhysicalResourceId": "NOT_YET", 9 | "ResourceType": "Custom::CRDataSource", 10 | "ResourceProperties": { 11 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 12 | "template": "{\"connectionConfiguration\": {\"repositoryEndpointMetadata\": {\"s3SeedUrl\": \"s3://kendra-index-urlsbucket330222cc-uh1kqmon5xj7/s3_urls/connect_blogs_1.txt\", \"siteMapUrls\": null, \"seedUrlConnections\": null, \"s3SiteMapUrl\": null, \"authentication\": \"NoAuthentication\"}}, \"enableIdentityCrawler\": false, \"syncMode\": \"FORCED_FULL_CRAWL\", \"additionalProperties\": {\"inclusionFileIndexPatterns\": [], \"rateLimit\": \"300\", \"maxFileSize\": \"50\", \"crawlDepth\": \"1\", \"crawlAllDomain\": false, \"crawlSubDomain\": false, \"inclusionURLIndexPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"exclusionFileIndexPatterns\": [], \"proxy\": {}, \"exclusionURLCrawlPatterns\": [\"*./tag/.*\"], \"exclusionURLIndexPatterns\": [\"*./tag/.*\"], \"crawlAttachments\": false, \"honorRobots\": true, \"inclusionURLCrawlPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"crawlDomainsOnly\": true, \"maxLinksPerUrl\": \"100\"}, \"type\": \"WEBCRAWLERV2\", \"version\": \"1.0.0\", \"repositoryConfigurations\": {\"attachment\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}, \"webPage\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}}}", 13 | "schedule": "", 14 | "language_code": "en", 15 | "role_arn": "arn:aws:iam::320205374826:role/kendra-index-IKSRC7156E80-UBOWSCNEAXV9", 16 | "name": "connect-blogs-100-v5", 17 | "description": "Creado con custom resources", 18 | "index_id": "9cfc368a-f4d6-4469-96bf-a6476b94ac31", 19 | "type": "TEMPLATE" 20 | } 21 | } -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/data_source_creator/lambda_function.py: -------------------------------------------------------------------------------- 1 | '''Custom generic CloudFormation resource example''' 2 | 3 | import json 4 | import requests 5 | import boto3 6 | import botocore.exceptions 7 | 8 | kendra_client = boto3.client("kendra") 9 | 10 | 11 | def lambda_handler(event, context): 12 | '''Handle Lambda event from AWS''' 13 | # Setup alarm for remaining runtime minus a second 14 | # signal.alarm((context.get_remaining_time_in_millis() / 1000) - 1) 15 | try: 16 | 17 | print('REQUEST RECEIVED:', event) 18 | print('REQUEST RECEIVED:', context) 19 | if event['RequestType'] == 'Create': 20 | print('CREATE!') 21 | event['PhysicalResourceId'] = 'NOT_YET' 22 | create_webcrawler2(event, context) 23 | # send_response(event, context, "SUCCESS",{"Message": "Resource creation successful!"}) 24 | elif event['RequestType'] == 'Update': 25 | print('UPDATE!') 26 | update_webcrawler2(event, context) 27 | 28 | elif event['RequestType'] == 'Delete': 29 | print('DELETE!') 30 | delete_webcrawler2(event, context) 31 | 32 | else: 33 | print('FAILED!') 34 | send_response(event, context, "FAILED", 35 | {"Message": "Unexpected event received from CloudFormation"}) 36 | except Exception as error: 37 | print('FAILED!', error) 38 | send_response(event, context, "FAILED", { 39 | "Message": "Exception during processing"}) 40 | 41 | 42 | def create_webcrawler2 (event, context): 43 | 44 | if "ResourceProperties" in event: 45 | print ("create_datasource") 46 | props = event['ResourceProperties'] 47 | 48 | print("props:",props) 49 | 50 | kwargs = dict ( 51 | Name=props['name'], 52 | IndexId=props['index_id'], 53 | Type=props['type'], 54 | Configuration={"TemplateConfiguration": {"Template":json.loads(props['template'])}}, 55 | Description=props['description'], 56 | Schedule=props['schedule'], 57 | RoleArn=props['role_arn'], 58 | LanguageCode=props['language_code'] 59 | ) 60 | 61 | print ("kwargs:",kwargs) 62 | res = kendra_client.create_data_source(**kwargs) 63 | index_id = props['index_id'] 64 | ds_id = res['Id'] 65 | starting = kendra_client.start_data_source_sync_job( 66 | Id=ds_id, 67 | IndexId=index_id 68 | ) 69 | print ("start sync job:", starting) 70 | 71 | event['PhysicalResourceId'] = f"{index_id}|{ds_id}" 72 | send_response(event, context, "SUCCESS",{"Message": "Resource creation successful!"}) 73 | else: 74 | print("no resource properties!") 75 | 76 | 77 | def delete_webcrawler2 (event, context): 78 | if 'PhysicalResourceId' in event: 79 | if event['PhysicalResourceId'] !="NOT_YET": 80 | index_id, id = event['PhysicalResourceId'].split("|") 81 | response = kendra_client.delete_data_source(Id=id,IndexId=index_id) 82 | send_response(event, context, "SUCCESS", {"Message": "Resource deletion successful!"}) 83 | 84 | 85 | def update_webcrawler2(event, context): 86 | if "ResourceProperties" in event: 87 | print ("create_datasource") 88 | props = event['ResourceProperties'] 89 | index_id, id = event['PhysicalResourceId'].split("|") 90 | 91 | print("props:",props) 92 | 93 | kwargs = dict ( 94 | Id = id, 95 | Name=props['name'], 96 | IndexId=index_id, 97 | Configuration={"TemplateConfiguration": {"Template":json.loads(props['template'])}}, 98 | Description=props['description'], 99 | Schedule=props['schedule'], 100 | RoleArn=props['role_arn'], 101 | LanguageCode=props['language_code'] 102 | ) 103 | 104 | print ("kwargs:",kwargs) 105 | res = kendra_client.update_data_source(**kwargs) 106 | print ("response: ",res) 107 | starting = kendra_client.start_data_source_sync_job( 108 | Id=id, 109 | IndexId=index_id 110 | ) 111 | print ("start sync job:", starting) 112 | #index_id = props['index_id'] 113 | #event['PhysicalResourceId'] = f"{index_id}|{ds_id}" 114 | ##ds_id = res['Id'] 115 | # send_response(event, context, "SUCCESS",{"Message": "Resource creation successful!"}) 116 | else: 117 | print("no resource properties!") 118 | send_response(event, context, "SUCCESS", {"Message": "Resource update successful!"}) 119 | 120 | def send_response(event, context, response_status, response_data): 121 | '''Send a resource manipulation status response to CloudFormation''' 122 | response_body = json.dumps({ 123 | "Status": response_status, 124 | "Reason": "See the details in CloudWatch Log Stream: " + context.log_stream_name, 125 | "PhysicalResourceId": event['PhysicalResourceId'] if 'PhysicalResourceId' in event else "NOPHYID", 126 | "StackId": event['StackId'], 127 | "RequestId": event['RequestId'], 128 | "LogicalResourceId": event['LogicalResourceId'], 129 | "Data": response_data 130 | }) 131 | headers = { 132 | 'Content-Type': 'application/json', 133 | 'Content-Length': str(len(response_body)) 134 | } 135 | 136 | 137 | print('ResponseURL: ', event['ResponseURL']) 138 | print('ResponseBody:', response_body) 139 | 140 | response = requests.put(event['ResponseURL'], 141 | data=response_body, headers=headers) 142 | 143 | print("Status code:", response.status_code) 144 | print("Status message:", response.text) 145 | 146 | return response 147 | 148 | 149 | def timeout_handler(_signal, _frame): 150 | '''Handle SIGALRM''' 151 | raise Exception('Time exceeded') 152 | 153 | # signal.signal(signal.SIGALRM, timeout_handler) 154 | 155 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/data_source_creator/play.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import json \n", 10 | "import requests" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 16, 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "def send_response(event, context, response_status, response_data):\n", 20 | " '''Send a resource manipulation status response to CloudFormation'''\n", 21 | " response_body = json.dumps({\n", 22 | " \"Status\": response_status,\n", 23 | " \"Reason\": \"See the details in CloudWatch Log Stream: \" + context,\n", 24 | " \"PhysicalResourceId\": context,\n", 25 | " \"StackId\": event['StackId'],\n", 26 | " \"RequestId\": event['RequestId'],\n", 27 | " \"LogicalResourceId\": event['LogicalResourceId'],\n", 28 | " \"Data\": response_data\n", 29 | " })\n", 30 | " headers = {\n", 31 | " 'Content-Type': 'application/json', \n", 32 | " 'Content-Length': str(len(response_body))\n", 33 | " } \n", 34 | "\n", 35 | "\n", 36 | " response = requests.put(event['ResponseURL'], \n", 37 | " data=response_body, headers=headers)\n", 38 | " return response" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 12, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "with open (\"./create.event.json\") as f:\n", 48 | " event = json.load(f)\n", 49 | "\n", 50 | "context = \"hello world\"" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 17, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "res = send_response(event, context, \"SUCCESS\",\n", 67 | " {\"Message\": \"Resource creation successful!\"})" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 18, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "" 79 | ] 80 | }, 81 | "execution_count": 18, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "res" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 21, 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "b''" 99 | ] 100 | }, 101 | "execution_count": 21, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "res.content" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": ".venv", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.11.2" 135 | }, 136 | "orig_nbformat": 4 137 | }, 138 | "nbformat": 4, 139 | "nbformat_minor": 2 140 | } 141 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/data_source_creator/update.event.json: -------------------------------------------------------------------------------- 1 | { 2 | "RequestType": "Update", 3 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 4 | "ResponseURL": "https://cloudformation-custom-resource-response-uswest2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A320205374826%3Astack/kendra-index/9ba2dfa0-50fb-11ee-b463-0a3aed41439b%7CBlogs200CR2A50B61D9%7C5116d65b-2b7a-4033-b151-a0a5ddb0d26a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230916T155650Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA54RCMT6SBI2P4EYF%2F20230916%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=954703b3dfd959e42b5285bb29e280a801f5108978964572b70c35d761d14141", 5 | "StackId": "arn:aws:cloudformation:us-west-2:320205374826:stack/kendra-index/9ba2dfa0-50fb-11ee-b463-0a3aed41439b", 6 | "RequestId": "5116d65b-2b7a-4033-b151-a0a5ddb0d26a", 7 | "LogicalResourceId": "Blogs200CR2A50B61D9", 8 | "PhysicalResourceId": "9cfc368a-f4d6-4469-96bf-a6476b94ac31|434e5b1a-4224-4fa2-b51f-9100037121c1", 9 | "ResourceType": "Custom::CRDataSource", 10 | "ResourceProperties": { 11 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 12 | "template": "{\"connectionConfiguration\": {\"repositoryEndpointMetadata\": {\"s3SeedUrl\": \"s3://kendra-index-urlsbucket330222cc-uh1kqmon5xj7/s3_urls/connect_blogs_2.txt\", \"siteMapUrls\": null, \"seedUrlConnections\": null, \"s3SiteMapUrl\": null, \"authentication\": \"NoAuthentication\"}}, \"enableIdentityCrawler\": false, \"syncMode\": \"FORCED_FULL_CRAWL\", \"additionalProperties\": {\"inclusionFileIndexPatterns\": [], \"rateLimit\": \"300\", \"maxFileSize\": \"50\", \"crawlDepth\": \"1\", \"crawlAllDomain\": false, \"crawlSubDomain\": false, \"inclusionURLIndexPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"exclusionFileIndexPatterns\": [], \"proxy\": {}, \"exclusionURLCrawlPatterns\": [\"*./tag/.*\"], \"exclusionURLIndexPatterns\": [\"*./tag/.*\"], \"crawlAttachments\": false, \"honorRobots\": true, \"inclusionURLCrawlPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"crawlDomainsOnly\": true, \"maxLinksPerUrl\": \"100\"}, \"type\": \"WEBCRAWLERV2\", \"version\": \"1.0.0\", \"repositoryConfigurations\": {\"attachment\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}, \"webPage\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}}}", 13 | "schedule": "", 14 | "language_code": "en", 15 | "role_arn": "arn:aws:iam::320205374826:role/kendra-index-IKSRC7156E80-UBOWSCNEAXV9", 16 | "name": "connect-blogs-200", 17 | "description": "Blogs de 101 a 200", 18 | "index_id": "9cfc368a-f4d6-4469-96bf-a6476b94ac31", 19 | "type": "TEMPLATE" 20 | }, 21 | "OldResourceProperties": { 22 | "ServiceToken": "arn:aws:lambda:us-west-2:320205374826:function:kendra-index-FnCRdatasource483468B7-a0gSZM9dG64O", 23 | "template": "{\"connectionConfiguration\": {\"repositoryEndpointMetadata\": {\"s3SeedUrl\": \"s3://kendra-index-urlsbucket330222cc-uh1kqmon5xj7/s3_urls/connect_blogs_2.txt\", \"siteMapUrls\": null, \"seedUrlConnections\": null, \"s3SiteMapUrl\": null, \"authentication\": \"NoAuthentication\"}}, \"enableIdentityCrawler\": false, \"syncMode\": \"FORCED_FULL_CRAWL\", \"additionalProperties\": {\"inclusionFileIndexPatterns\": [], \"rateLimit\": \"300\", \"maxFileSize\": \"50\", \"crawlDepth\": \"1\", \"crawlAllDomain\": false, \"crawlSubDomain\": false, \"inclusionURLIndexPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"exclusionFileIndexPatterns\": [], \"proxy\": {}, \"exclusionURLCrawlPatterns\": [\"*./tag/.*\"], \"exclusionURLIndexPatterns\": [\"*./tag/.*\"], \"crawlAttachments\": false, \"honorRobots\": true, \"inclusionURLCrawlPatterns\": [\"*.aws.amazon.com/blogs/contact-center/.*\"], \"crawlDomainsOnly\": true, \"maxLinksPerUrl\": \"100\"}, \"type\": \"WEBCRAWLERV2\", \"version\": \"1.0.0\", \"repositoryConfigurations\": {\"attachment\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}, \"webPage\": {\"fieldMappings\": [{\"dataSourceFieldName\": \"category\", \"indexFieldName\": \"_category\", \"indexFieldType\": \"STRING\"}, {\"dataSourceFieldName\": \"sourceUrl\", \"indexFieldName\": \"_source_uri\", \"indexFieldType\": \"STRING\"}]}}}", 24 | "schedule": "", 25 | "language_code": "en", 26 | "role_arn": "arn:aws:iam::320205374826:role/kendra-index-IKSRC7156E80-UBOWSCNEAXV9", 27 | "name": "connect-blogs-200", 28 | "description": "Blogs de 100 a 200", 29 | "index_id": "9cfc368a-f4d6-4469-96bf-a6476b94ac31", 30 | "type": "TEMPLATE" 31 | } 32 | } -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/dynamodb_put_item/dataset.csv: -------------------------------------------------------------------------------- 1 | "Passenger_ID","Age","Airport_Continent","Airport_Country_Code","Airport_Name","Arrival_Airport","Continents","Country_Name","Departure_Date","First_Name","Flight_Status","Gender","Last_Name","Nationality","Pilot_Name" 2 | "90896710","45","EU","HR","Osijek Airport","OSI","Europe","Croatia","6/24/2022","Dorothea","On Time","Female","Rogister","Sweden","Trevor Braunston" 3 | "65668687","62","NAM","US","Coldfoot Airport","CXF","North America","United States","6/28/2022","Edithe","On Time","Female","Leggis","Japan","Fransisco Hazeldine" 4 | "10266115","48","NAM","US","Lebanon Municipal Airport","LEB","North America","United States","5/23/2022","Tansy","Delayed","Female","Symons","Indonesia","Olly Pawelek" 5 | "87351041","54","AS","SA","Turaif Domestic Airport","TUI","Asia","Saudi Arabia","02-08-2022","Rutger","Cancelled","Male","Georgeon","Myanmar","Steward Sainter" 6 | "76107902","46","NAM","US","Hattiesburg Laurel Regional Airport","PIB","North America","United States","7/27/2022","Marjory","Cancelled","Female","Franz","Nigeria","Padget Diben" 7 | "12297975","54","SAM","BR","Monte Carmelo Airport","0","South America","Brazil","9/14/2022","Krishnah","On Time","Male","Dabels","Russia","Freddie Wallach" 8 | "86308981","20","NAM","US","Nikolai Airport","NIB","North America","United States","08-11-2022","Anestassia","On Time","Female","Vauls","Albania","Lucio Notley" 9 | "11077747","55","SAM","BR","Coronel Horácio de Mattos Airport","LEC","South America","Brazil","06-10-2022","Lora","On Time","Female","Durbann","Brazil","Inglis Dolley" 10 | "10012037","45","AF","MG","Port Bergé Airport","WPB","Africa","Madagascar","8/24/2022","Bobbye","On Time","Female","Patmore","China","Stella Pittham" 11 | "10010778","85","NAM","DO","Casa De Campo International Airport","LRM","North America","Dominican Republic","04-04-2022","Violetta","Delayed","Female","Francois","Indonesia","Christel Blues" 12 | "11210410","3","NAM","US","Spirit of St Louis Airport","SUS","North America","United States","7/17/2022","Cordie","On Time","Female","Rosenberger","Brazil","Enrica Ferrarini" 13 | "10210212","56","NAM","CA","Victoria Harbour Seaplane Base","YWH","North America","Canada","01-12-2022","Gene","Delayed","Male","Cottham","Philippines","Sib Feragh" 14 | "10511788","37","SAM","CO","Orocue Airport","ORC","South America","Colombia","08-12-2022","Arel","Cancelled","Male","Tyson","Spain","Danie Maggiore" 15 | "11211310","36","SAM","BR","Maestro Wilson Fonseca Airport","STM","South America","Brazil","04-07-2022","Perceval","Cancelled","Male","Dallosso","Vietnam","Sharyl Eastmead" 16 | "11580310","19","OC","NC","Nesson Airport","HLU","Oceania","New Caledonia","3/25/2022","Murvyn","Cancelled","Male","Duff","Germany","Dorine Timmermann" 17 | "72741069","33","NAM","KY","Gerrard Smith International Airport","CYB","North America","Cayman Islands","06-11-2022","Gauthier","Cancelled","Male","Elsip","Uruguay","Leslie Delmage" 18 | "60786581","6","AS","VN","Cà Mau Airport","CAH","Asia","Viet Nam","1/13/2022","Leandra","Cancelled","Female","Demer","Colombia","Lizbeth Snaden" 19 | "11665108","45","NAM","CA","Fort Mcpherson Airport","ZFM","North America","Canada","12-04-2022","Maia","Delayed","Female","Kidwell","Philippines","Dorise Ronchka" 20 | "10769658","19","NAM","CA","St Augustin Airport","YIF","North America","Canada","11-05-2022","Dorisa","Cancelled","Female","Skill","Ukraine","Ilyse Bartleman" 21 | "11998719","70","SAM","CO","El Dorado International Airport","BOG","South America","Colombia","03-12-2022","Edlin","On Time","Male","Theobald","Poland","Lisha Retallick" 22 | "11072117","21","OC","PG","Pureni Airport","PUI","Oceania","Papua New Guinea","8/15/2022","Kelsy","Delayed","Female","Danhel","Indonesia","Sacha Munford" 23 | "69104710","23","EU","RU","Nalchik Airport","NAL","Europe","Russian Federation","11/26/2022","Rodolph","Delayed","Male","Grewcock","Kazakhstan","Constantine Leworthy" 24 | "87863978","87","NAM","US","Elkhart Municipal Airport","EKI","North America","United States","3/20/2022","Sayre","Cancelled","Male","Stroyan","Indonesia","Austine Crewe" 25 | "11710083","3","AS","ID","Yuruf Airport","RUF","Asia","Indonesia","05-02-2022","Fidelio","Delayed","Male","Guerry","China","Caye Donat" 26 | "10597717","79","OC","PG","Talasea Airport","TLW","Oceania","Papua New Guinea","07-07-2022","Cordy","On Time","Male","Plenderleith","Sweden","Fifine Dodshon" 27 | "47870741","57","NAM","US","Elkhart Municipal Airport","EKI","North America","United States","11/29/2022","Rufus","Cancelled","Male","Bernardini","Peru","Brittan Barends" 28 | "48586741","2","NAM","NI","Augusto C. Sandino (Managua) International Airport","MGA","North America","Nicaragua","02-02-2022","Ransell","Delayed","Male","Evins","Russia","Berna Tenwick" 29 | "11397887","89","AF","CM","Kribi Airport","KBI","Africa","Cameroon","1/13/2022","Biddy","On Time","Female","Rief","Vietnam","Darlleen Twohig" 30 | "12076115","37","AS","ID","Sultan Khairun Babullah Airport","TTE","Asia","Indonesia","05-11-2022","Carlota","Cancelled","Female","Llewhellin","China","Reube Branwhite" 31 | "10727145","89","AF","MR","Tamchakett Airport","THT","Africa","Mauritania","10/25/2022","Findley","Delayed","Male","Godleman","Indonesia","Mitchell Parsisson" 32 | "89761208","54","NAM","US","Central Maine Airport of Norridgewock","OWK","North America","United States","4/13/2022","Collin","Delayed","Male","Ciepluch","China","Torin Le Leu" 33 | "72836575","9","NAM","US","Phoenix-Mesa-Gateway Airport","AZA","North America","United States","06-10-2022","Skelly","On Time","Male","Gopsell","Czech Republic","Deborah Mathissen" 34 | "11972797","89","AF","ZA","Arathusa Safari Lodge Airport","ASS","Africa","South Africa","10-07-2022","Carolann","Cancelled","Female","Yves","Poland","Dulci Milne" 35 | "69310812","62","AS","RU","Mirny Airport","MJZ","Asia","Russian Federation","2/21/2022","Anders","On Time","Male","Treadger","Madagascar","Giacomo Tooth" 36 | "10570817","79","AS","IR","Bandar Lengeh Airport","BDH","Asia","""Iran, Islamic Republic of""","12-05-2022","Bernardo","Cancelled","Male","Bigland","Philippines","Corissa Lamps" 37 | "11610167","76","NAM","US","McGhee Tyson Airport","TYS","North America","United States","02-07-2022","Margaux","Delayed","Female","Lattin","Guatemala","Sydelle Danher" 38 | "80828421","27","EU","IS","Fáskrúðsfjörður Airport","FAS","Europe","Iceland","1/13/2022","Artemus","On Time","Male","Brewitt","China","Jayme Witard" 39 | "11075841","18","OC","PG","Hatzfeldhaven Airport","HAZ","Oceania","Papua New Guinea","5/25/2022","Basil","Cancelled","Male","Canon","Portugal","Siobhan Philippon" 40 | "11027997","87","OC","AU","Leinster Airport","LER","Oceania","Australia","8/21/2022","Flin","Delayed","Male","Bordone","Philippines","Hunt Sommerlie" 41 | "65682115","25","AS","ID","Muhammad Salahuddin Airport","BMU","Asia","Indonesia","8/28/2022","Marlin","Cancelled","Male","Yegorev","Egypt","Saidee Sellers" 42 | "77817010","54","NAM","CR","Islita Airport","PBP","North America","Costa Rica","7/15/2022","Dermot","Cancelled","Male","Stainburn","Armenia","Buddy Guslon" 43 | "85707977","76","EU","DE","""Magdeburg """"City"""" Airport""","ZMG","Europe","Germany","12-06-2022","Clemmie","Cancelled","Male","Harbertson","Ukraine","Tadio Hayne" 44 | "90102643","77","AF","BF","Ouahigouya Airport","OUG","Africa","Burkina Faso","4/29/2022","Eugenius","On Time","Male","Headon","Ukraine","Ibrahim Cotton" 45 | "11571798","66","OC","PG","Wanuma Airport","WNU","Oceania","Papua New Guinea","09-01-2022","Magda","Cancelled","Female","Nealand","United States","Brnaba Lilburne" 46 | "77501081","74","AF","DZ","In Guezzam Airport","INF","Africa","Algeria","1/20/2022","Lissa","Delayed","Female","Thynn","Luxembourg","Sean Searchwell" 47 | "56731101","76","AS","JP","Akita Airport","AXT","Asia","Japan","06-03-2022","Ag","Delayed","Female","Gumby","China","Annamarie Shrimpton" 48 | "10488104","78","NAM","US","Omar N Bradley Airport","MBY","North America","United States","5/19/2022","Cy","Cancelled","Male","Servante","China","Ludovika Purdon" 49 | "67677769","74","NAM","CA","Campbell River Airport","YBL","North America","Canada","7/22/2022","Rudolph","Delayed","Male","Housbie","Iran","Kirby Varvell" 50 | "10936912","44","NAM","US","Zahn's Airport","AYZ","North America","United States","11/23/2022","Ashlie","Delayed","Female","Rotham","Ireland","Vicky Silmon" 51 | "11970101","85","SAM","AR","Valcheta Airport","VCF","South America","Argentina","10/23/2022","Con","On Time","Male","Kaine","Yemen","Ginger Dominichelli" 52 | "88821088","23","EU","SE","Gällivare Airport","GEV","Europe","Sweden","5/21/2022","Elana","Delayed","Female","Heisham","Greece","Nathanial Gretton" 53 | "75841011","51","AS","LK","Batticaloa Airport","BTC","Asia","Sri Lanka","02-12-2022","Constancy","Cancelled","Female","Darke","China","Bron Alben" 54 | "79744010","80","NAM","CA","Brandon Municipal Airport","YBR","North America","Canada","4/14/2022","Allx","Cancelled","Female","Fretter","Brazil","Saxon Stoker" 55 | "89685887","30","NAM","US","Columbus Lowndes County Airport","UBS","North America","United States","1/13/2022","Seline","Cancelled","Female","Garvill","Philippines","Dael Schubuser" 56 | "11588768","12","NAM","CA","Schefferville Airport","YKL","North America","Canada","04-05-2022","Tobe","Cancelled","Female","Torrejon","Brazil","Gaelan Fforde" 57 | "90108115","90","NAM","GT","El Petén Airport","TKM","North America","Guatemala","05-05-2022","Sydney","On Time","Male","MacGhee","Guatemala","Ambur Boden" 58 | "11711175","6","AF","CG","Gamboma Airport","GMM","Africa","Congo","04-09-2022","Jessamyn","Delayed","Female","Buddles","Peru","Beau Stevens" 59 | "65118120","10","OC","PG","Omora Airport","OSE","Oceania","Papua New Guinea","08-01-2022","Sergio","On Time","Male","Edmonson","Sweden","Woodie Stearley" 60 | "27711966","87","NAM","US","White Mountain Airport","WMO","North America","United States","7/20/2022","Lilli","Delayed","Female","Sarath","Sweden","Ollie Ventom" 61 | "11111936","58","NAM","CA","Gorge Harbour Seaplane Base","YGE","North America","Canada","08-05-2022","Celina","Cancelled","Female","Boothebie","Latvia","Balduin Ingman" 62 | "11773666","24","SAM","BR","João Durval Carneiro Airport","FEC","South America","Brazil","1/25/2022","Bryna","On Time","Female","Monson","Poland","Elissa Ledwich" 63 | "10566861","29","OC","PG","Bewani Airport","BWP","Oceania","Papua New Guinea","11/29/2022","Benson","On Time","Male","Hook","Indonesia","Kristi Curteis" 64 | "99896811","80","NAM","CA","Tahsis Seaplane Base","ZTS","North America","Canada","11/16/2022","Noelyn","On Time","Female","Penquet","Brazil","Harlene Illingsworth" 65 | "72121122","73","NAM","BS","Colonel Hill Airport","CRI","North America","Bahamas","12-11-2022","Bibby","Delayed","Female","Evershed","Indonesia","Georgena Scanderet" 66 | "84116721","86","NAM","US","Valle Airport","VLE","North America","United States","5/19/2022","West","Cancelled","Male","Kernermann","Norway","Rosamund Gauchier" 67 | "75811097","53","NAM","US","Wiley Post Will Rogers Memorial Airport","BRW","North America","United States","12-05-2022","Halie","Delayed","Female","Jewar","France","Katerine Bartolomivis" 68 | "90121111","68","NAM","US","Okmulgee Regional Airport","OKM","North America","United States","7/15/2022","Terri","On Time","Female","Palle","Poland","Maisey Kubis" 69 | "11676510","42","AF","BW","Jwaneng Airport","JWA","Africa","Botswana","3/28/2022","Dunstan","On Time","Male","Fyrth","China","Sallie Jessop" 70 | "12110111","22","AF","GQ","Malabo Airport","SSG","Africa","Equatorial Guinea","9/23/2022","Lyndsie","Delayed","Female","Dyball","Czech Republic","Arlina Legging" 71 | "68211644","62","SAM","BR","Monte Dourado Airport","MEU","South America","Brazil","12/28/2022","Eran","On Time","Female","Summerill","Afghanistan","Fabien Lipprose" 72 | "89102113","82","AF","DZ","Tsletsi Airport","QDJ","Africa","Algeria","11-01-2022","Happy","Cancelled","Female","Jaskowicz","Mexico","Meridith Dibbe" 73 | "12210976","37","NAM","US","Dallas Love Field","DAL","North America","United States","5/31/2022","Loree","On Time","Female","Fishpond","Ukraine","Gaelan Kenyam" 74 | "10227116","8","AF","MR","Timbedra Airport","TMD","Africa","Mauritania","2/19/2022","Joellyn","On Time","Female","Stutter","Croatia","Janaya Retchford" 75 | "87380708","73","EU","GB","Duxford Aerodrome","QFO","Europe","United Kingdom","10/30/2022","Rand","Cancelled","Male","Bram","Ivory Coast","Stanislas Tiffin" 76 | "75410969","52","OC","AU","Helenvale Airport","HLV","Oceania","Australia","05-02-2022","Newton","Delayed","Male","Berni","Argentina","Rouvin Siflet" 77 | "83117110","79","AS","CN","Jiayuguan Airport","JGN","Asia","China","5/29/2022","Mead","On Time","Male","Syer","Venezuela","Monique Edworthye" 78 | "94666710","6","AS","CN","Guanghan Airport","GHN","Asia","China","2/24/2022","Lincoln","Cancelled","Male","Casburn","Vietnam","Coralie Chatterton" 79 | "08210810","54","NAM","CA","Geraldton Greenstone Regional Airport","YGQ","North America","Canada","7/28/2022","Isidor","Cancelled","Male","Rundall","Peru","Claresta Charter" 80 | "11871791","69","OC","NZ","Kaitaia Airport","KAT","Oceania","New Zealand","4/24/2022","Neal","Delayed","Male","Kulver","Thailand","Roldan Doyley" 81 | "10908998","54","OC","AU","Minlaton Airport","XML","Oceania","Australia","12/15/2022","Ransom","On Time","Male","Chippindale","Peru","Lenci Aitkin" 82 | "86120722","73","NAM","US","Denver International Airport","DEN","North America","United States","05-07-2022","Tan","On Time","Male","Connold","Sweden","Bevvy Cleall" 83 | "91071188","21","NAM","US","Gillespie Field","SEE","North America","United States","2/25/2022","Bay","On Time","Male","Pencost","China","Ebonee Tree" 84 | "28896711","74","AS","SY","Al Thaurah Airport","SOR","Asia","Syrian Arab Republic","11/15/2022","Rozelle","Delayed","Female","Neubigin","China","Missy Yepiskopov" 85 | "11280107","76","NAM","US","Lawson Army Air Field (Fort Benning)","LSF","North America","United States","7/21/2022","Francoise","Delayed","Female","Mustill","Netherlands","Carlye Egan" 86 | "10810407","14","NAM","US","Naval Outlying Field Imperial Beach (Ream Field)","NRS","North America","United States","9/26/2022","Fons","On Time","Male","Schrieves","Albania","Reinald Toffler" 87 | "76010275","9","OC","PG","Gora Airstrip","GOC","Oceania","Papua New Guinea","6/25/2022","Gardiner","On Time","Male","Ferbrache","Sweden","Pamela Franiak" 88 | "10105867","12","NAM","US","Hutchinson County Airport","BGD","North America","United States","07-03-2022","Arlee","On Time","Female","Levine","China","Kale Cabbell" 89 | "12288882","53","SAM","BR","Antônio Guerreiro Airport","GMS","South America","Brazil","9/16/2022","Jameson","On Time","Male","Sayce","Brazil","Maddy Siuda" 90 | "69100692","30","NAM","CA","Wabush Airport","YWK","North America","Canada","09-06-2022","Kaitlin","Cancelled","Female","Gaven","Sao Tome and Principe","Leshia Risby" 91 | "91058479","24","NAM","US","Crested Butte Airpark","CSE","North America","United States","2/19/2022","Paige","Delayed","Male","Hayhow","Sweden","Clyde Winn" 92 | "84120105","66","OC","AU","Yam Island Airport","XMY","Oceania","Australia","12/27/2022","Jewel","On Time","Female","Betteney","China","Bonnee Summerson" 93 | "11888118","7","EU","IT","Genoa Cristoforo Colombo Airport","GOA","Europe","Italy","12/18/2022","Ebony","On Time","Female","Knappitt","Russia","Laurence Queenborough" 94 | "38100120","45","NAM","CA","Gaspé (Michel-Pouliot) Airport","YGP","North America","Canada","5/15/2022","Dredi","Cancelled","Female","Curd","Russia","Fitzgerald Alberti" 95 | "21049767","28","SAM","VE","Zaraza Airport","ZRZ","South America","""Venezuela, Bolivarian Republic of""","9/23/2022","Janella","On Time","Female","Hardaker","Colombia","Shaylynn Alcott" 96 | "70971151","17","OC","AU","Kalbarri Airport","KAX","Oceania","Australia","5/29/2022","Lorilyn","On Time","Female","Annion","China","Annaliese Cramond" 97 | "10081186","65","OC","PG","Awaba Airport","AWB","Oceania","Papua New Guinea","10/28/2022","Arlena","Delayed","Female","Ridwood","Ireland","Alyosha Damp" 98 | "71851169","32","NAM","US","Farmington Regional Airport","FAM","North America","United States","03-07-2022","Amberly","Delayed","Female","Handling","China","Lothaire Eades" 99 | "11911111","39","OC","PG","Buka Airport","BUA","Oceania","Papua New Guinea","10/29/2022","Piggy","Delayed","Male","Hugle","Philippines","Far Cicci" 100 | "12175477","19","AS","NP","Bhojpur Airport","BHP","Asia","Nepal","12-10-2022","Cirilo","Delayed","Male","Camoletto","China","Louisa Worvell" 101 | "11010411","65","AS","IR","Lar Airport","LRR","Asia","""Iran, Islamic Republic of""","7/31/2022","Gabriella","Delayed","Female","Patry","China","Clyve Dickerson" 102 | "10587869","70","OC","AU","St George Airport","SGO","Oceania","Australia","07-12-2022","Hobie","Delayed","Male","Skace","China","Jenn Backshaw" 103 | "68981109","35","EU","DE","RAF Wildenrath","WID","Europe","Germany","2/17/2022","Gisella","Cancelled","Female","Watters","Philippines","Sherwin Izen" 104 | "10682102","4","OC","PG","Tapini Airport","TPI","Oceania","Papua New Guinea","7/30/2022","Care","Cancelled","Male","Kearton","Kenya","Britt Viney" 105 | "71065103","11","SAM","BR","Soledade Airport","0","South America","Brazil","10-03-2022","Modesty","Cancelled","Female","Zink","Ukraine","Charissa Figures" 106 | "98107210","49","NAM","US","Owatonna Degner Regional Airport","OWA","North America","United States","01-04-2022","Adlai","On Time","Male","Tilmouth","Serbia","Caresse Sumpner" 107 | "98102976","68","AF","MZ","Paradise Island Airport","NTC","Africa","Mozambique","10/29/2022","Randie","On Time","Male","Jankin","Mexico","Ibrahim Andraud" 108 | "78375104","1","SAM","EC","Nueva Loja Airport","LGQ","South America","Ecuador","12/17/2022","Gearalt","Delayed","Male","Bynold","China","Mic Rosenau" 109 | "70670731","23","NAM","US","Southwest Florida International Airport","RSW","North America","United States","3/24/2022","Franz","Cancelled","Male","Roset","Greece","Stanford Garnam" 110 | "73115651","50","SAM","BO","Roboré Airport","RBO","South America","""Bolivia, Plurinational State of""","5/13/2022","Andy","Cancelled","Male","Kettleson","China","Ivett Connikie" 111 | "89101695","66","AS","IN","Tezu Airport","TEI","Asia","India","5/23/2022","Shermy","Delayed","Male","Gatchell","Colombia","Albrecht Lorne" 112 | "82101114","65","OC","PG","Long Island Airport","LSJ","Oceania","Papua New Guinea","10/23/2022","Des","Cancelled","Male","Sutehall","Indonesia","Bartholomeus Gherardini" 113 | "68112971","29","SAM","CO","Hato Corozal Airport","HTZ","South America","Colombia","08-06-2022","Jayme","Delayed","Female","Dairton","Indonesia","Kaye Clews" 114 | "77829791","41","OC","PG","Doini Airport","DOI","Oceania","Papua New Guinea","07-06-2022","Genevra","On Time","Female","Shipperbottom","Ethiopia","Tandie Willbraham" 115 | "73840896","16","NAM","CA","Black Tickle Airport","YBI","North America","Canada","02-12-2022","Brunhilda","Delayed","Female","Davley","Indonesia","Constantino Flanigan" 116 | "99709910","75","AS","ID","Sangir Airport","SAE","Asia","Indonesia","10-01-2022","Corby","On Time","Male","Van Der Straaten","Kazakhstan","Maureen Slimming" 117 | "28041103","39","NAM","MX","Nuevo Casas Grandes Airport","NCG","North America","Mexico","5/27/2022","Porty","Cancelled","Male","Jori","Tunisia","Rasia Fidelus" 118 | "11383991","51","NAM","MX","General Lucio Blanco International Airport","REX","North America","Mexico","10/19/2022","Flora","On Time","Female","Delgardillo","Philippines","Keeley Kiltie" 119 | "84908011","64","OC","VU","Futuna Airport","FTA","Oceania","Vanuatu","09-04-2022","Felizio","Cancelled","Male","Kevern","Russia","Munroe Humble" 120 | "66104761","35","AF","ZM","Kasaba Bay Airport","ZKB","Africa","Zambia","4/14/2022","Clevie","Delayed","Male","Clubbe","China","Fenelia Print" 121 | "68112189","61","NAM","US","Cincinnati Northern Kentucky International Airport","CVG","North America","United States","6/16/2022","Zelig","On Time","Male","Brinded","Brazil","Cosmo Rossbrook" 122 | "10612154","14","OC","WS","Faleolo International Airport","APW","Oceania","Samoa","7/22/2022","Magdalen","Delayed","Female","Claiden","China","Micky Luno" 123 | "12199821","52","NAM","GT","Mundo Maya International Airport","FRS","North America","Guatemala","5/25/2022","Cairistiona","Cancelled","Female","Tummond","Tanzania","Burnaby De Mitris" 124 | "51027211","85","NAM","US","Springfield Branson National Airport","SGF","North America","United States","08-09-2022","Travers","Cancelled","Male","Selwyne","Colombia","Annetta Vasyunkin" 125 | "79735651","36","NAM","CA","Merritt Airport","YMB","North America","Canada","11-03-2022","Henryetta","Delayed","Female","Noice","Chile","Sybilla Hargey" 126 | "68907090","46","NAM","CA","Amos/Magny Airport","YEY","North America","Canada","4/18/2022","Fairleigh","On Time","Male","Hagger","China","Andre Sissel" 127 | "97111103","90","OC","AU","Mullewa Airport","MXU","Oceania","Australia","09-10-2022","Vernen","Delayed","Male","Ivakhnov","China","Lidia Kleinert" 128 | "12011098","35","NAM","US","University of Oklahoma Westheimer Airport","OUN","North America","United States","1/26/2022","Chris","On Time","Female","Body","Sweden","Loretta Bumphries" 129 | "73117799","62","AS","IR","Shahid Sadooghi Airport","AZD","Asia","""Iran, Islamic Republic of""","8/16/2022","Bethany","Cancelled","Female","Corona","Tanzania","Elmer Baldock" 130 | "81786511","35","EU","IT","Venice Marco Polo Airport","VCE","Europe","Italy","8/20/2022","Aleda","On Time","Female","Pigram","Palestinian Territory","Daryn Bardsley" 131 | "71107113","73","AF","ZA","Tanda Tula Airport","TDT","Africa","South Africa","6/17/2022","Winne","Cancelled","Female","Cowland","France","Ernaline Klain" 132 | "11810984","15","AS","MN","Khovd Airport","HVD","Asia","Mongolia","10/13/2022","Marylinda","Cancelled","Female","Gussie","Poland","Dyanna Edmondson" 133 | "83121101","55","SAM","BR","Canarana Airport","CQA","South America","Brazil","9/26/2022","Cymbre","Cancelled","Female","Steeden","Russia","Margit Filon" 134 | "12276776","79","NAM","US","Bemidji Regional Airport","BJI","North America","United States","6/19/2022","Virgil","Cancelled","Male","Markussen","Philippines","Bird Boarder" 135 | "11590811","7","AS","CN","Handan Airport","HDG","Asia","China","03-08-2022","Gwenore","Delayed","Female","Smaridge","Russia","Doria Coils" 136 | "09108711","58","OC","AU","Diamantina Lakes Airport","DYM","Oceania","Australia","11/23/2022","Tamas","Delayed","Male","Vigneron","Mali","Clemente Mateev" 137 | "80108119","47","AS","PK","Loralai Airport","LRG","Asia","Pakistan","3/19/2022","Kalie","Delayed","Female","Scoble","Sweden","Madelena Lennarde" 138 | "88071139","78","AS","RU","Aldan Airport","ADH","Asia","Russian Federation","08-07-2022","Mattias","Cancelled","Male","Darrell","Honduras","Masha Banville" 139 | "10270678","23","OC","AU","South Galway Airport","ZGL","Oceania","Australia","11-10-2022","Natalya","Cancelled","Female","Offner","Czech Republic","Christalle Lifton" 140 | "85791027","80","AS","JP","Tarama Airport","TRA","Asia","Japan","4/13/2022","Sherwood","On Time","Male","Woolaston","Portugal","Ardelia Milch" 141 | "21041121","36","NAM","DM","Canefield Airport","DCF","North America","Dominica","5/19/2022","Mischa","Delayed","Male","Caulwell","Mexico","Cari Moens" 142 | "27010010","51","AF","KE","Mulika Lodge Airport","JJM","Africa","Kenya","7/27/2022","Anabella","Cancelled","Female","Tutchings","China","Joceline Frangleton" 143 | "69103288","6","AF","CD","Kasenga Airport","KEC","Africa","""Congo, The Democratic Republic of the""","10/16/2022","Ephrayim","On Time","Male","Bedford","China","Park Thody" 144 | "10310510","54","NAM","US","Susanville Municipal Airport","SVE","North America","United States","3/21/2022","Haroun","On Time","Male","holmes","United States","Xerxes Arkcoll" 145 | "10577182","54","AF","SD","En Nahud Airport","NUD","Africa","Sudan","5/18/2022","Nicole","Cancelled","Female","Gages","South Africa","Chet Carryer" 146 | "10584691","7","NAM","US","Kalaupapa Airport","LUP","North America","United States","4/27/2022","Trudey","On Time","Female","Wagge","Poland","Manya Vaun" 147 | "72798575","54","AS","CN","Nanjing Lukou Airport","NKG","Asia","China","10-11-2022","Francine","Cancelled","Female","Adolfsen","Indonesia","Leanora Romney" 148 | "12161057","39","EU","HR","Rijeka Airport","RJK","Europe","Croatia","4/27/2022","Domenico","Cancelled","Male","Cadman","Ukraine","Tailor McGilroy" 149 | "88276116","45","EU","BG","Sofia Airport","SOF","Europe","Bulgaria","1/20/2022","Arlyn","On Time","Female","Boole","Philippines","Cindie Critten" 150 | "86871091","82","AF","DZ","Mecheria Airport","MZW","Africa","Algeria","05-12-2022","Pavlov","Cancelled","Male","Hadye","Brazil","Stefano Klampt" 151 | "10711311","62","OC","AU","Port Lincoln Airport","PLO","Oceania","Australia","03-06-2022","Chrotoem","On Time","Male","Abels","Russia","Che Brett" 152 | "11085991","21","NAM","US","Sawyer International Airport","MQT","North America","United States","5/17/2022","Lamond","Cancelled","Male","Ahmed","Croatia","Liv Heinig" 153 | "11386111","83","NAM","US","Moody Air Force Base","VAD","North America","United States","8/17/2022","Yasmin","Delayed","Female","Findlow","Macedonia","Parnell Gosby" 154 | "11566102","71","NAM","PA","Ruben Cantu Airport","SYP","North America","Panama","02-06-2022","Briant","Delayed","Male","De La Haye","Russia","Alina Flooks" 155 | "74105978","85","AS","MY","Sepulot Airport","SPE","Asia","Malaysia","11-01-2022","Virginie","Cancelled","Female","Vaneev","France","Wadsworth Gillyett" 156 | "11611175","90","NAM","US","Amchitka Army Airfield","AHT","North America","United States","06-07-2022","Pamella","Cancelled","Female","Eaden","Indonesia","Pearle Assiter" 157 | "87728910","56","EU","RU","Krasnoselkup Airport","KKQ","Europe","Russian Federation","8/19/2022","Bryn","On Time","Female","Pratley","Maldives","Loria Brogini" 158 | "31008678","16","OC","PG","Moro Airport","MXH","Oceania","Papua New Guinea","05-11-2022","Averell","Cancelled","Male","Shellsheere","Albania","Syman Milham" 159 | "78122100","37","NAM","US","Lemhi County Airport","SMN","North America","United States","1/23/2022","Paulie","Delayed","Male","Dunnet","Serbia","Ned Marnes" 160 | "11226687","54","NAM","US","Venice Municipal Airport","VNC","North America","United States","04-01-2022","Justinn","On Time","Female","Ishchenko","Pakistan","Sapphira MacKinnon" 161 | "10611610","88","NAM","US","Waycross Ware County Airport","AYS","North America","United States","9/17/2022","Leroi","Cancelled","Male","Raeburn","Brazil","Binny Launder" 162 | "76787910","75","NAM","CA","Shuswap Regional Airport","YSN","North America","Canada","10-05-2022","Heath","On Time","Male","Lackmann","China","Trude Querrard" 163 | "68683115","45","EU","SK","Lučenec Airport","LUE","Europe","Slovakia","7/27/2022","Kirbee","On Time","Female","Wrenn","Armenia","Mary Hurch" 164 | "72751070","37","OC","AU","Bairnsdale Airport","BSJ","Oceania","Australia","01-11-2022","Dasha","On Time","Female","Eppson","Indonesia","Merci Jeduch" 165 | "10585751","77","OC","AU","Cudal Airport","CUG","Oceania","Australia","3/24/2022","Catriona","Delayed","Female","Beaument","Russia","Margie Beal" 166 | "90665857","22","OC","AU","Etadunna Airport","ETD","Oceania","Australia","4/26/2022","Brien","On Time","Male","Gatherer","Poland","Liv Lydall" 167 | "70691201","76","EU","GB","Newcastle Airport","NCL","Europe","United Kingdom","3/17/2022","Reinaldo","On Time","Male","Caines","Indonesia","Kakalina Usmar" 168 | "36765726","26","EU","PT","João Paulo II Airport","PDL","Europe","Portugal","8/26/2022","Ajay","On Time","Female","Durward","Russia","Bertha Piborn" 169 | "99997911","70","EU","RU","Ust-Maya Airport","UMS","Europe","Russian Federation","11-10-2022","Peterus","Delayed","Male","Lettson","Botswana","Eugine Mainwaring" 170 | "11411611","75","NAM","US","Grumman Bethpage Airport","BPA","North America","United States","8/21/2022","Michele","On Time","Male","Olenchenko","Russia","Bessie Toller" 171 | "42612112","12","EU","RU","Talakan Airport","TLK","Europe","Russian Federation","06-12-2022","Ikey","On Time","Male","Dowty","China","Beverlee Da Costa" 172 | "11076810","62","AS","CN","Guilin Liangjiang International Airport","KWL","Asia","China","09-05-2022","Warner","Cancelled","Male","Driutti","China","Marita Holtom" 173 | "67610778","66","OC","AU","Cue Airport","CUY","Oceania","Australia","10/16/2022","Jedidiah","Cancelled","Male","Malins","Indonesia","Perren Salkild" 174 | "83101111","73","AS","MM","Pakhokku Airport","PKK","Asia","Myanmar","05-12-2022","Artair","Delayed","Male","Ondrich","Indonesia","Phoebe Quilkin" 175 | "12012284","32","OC","PG","Moki Airport","MJJ","Oceania","Papua New Guinea","12/21/2022","Dun","Cancelled","Male","Craythorn","China","Dunn MacSkeagan" 176 | "82881049","43","NAM","US","Lihue Airport","LIH","North America","United States","1/31/2022","Lennard","On Time","Male","Giorgi","Peru","Jordana Lantaff" 177 | "88104511","88","EU","DE","Rostock-Laage Airport","RLG","Europe","Germany","8/23/2022","Gabrila","On Time","Female","Speedin","Portugal","Hope O'Doherty" 178 | "82681101","37","OC","AU","Groote Eylandt Airport","GTE","Oceania","Australia","3/30/2022","Quentin","On Time","Male","Plaschke","Syria","Honey Gallaway" 179 | "89120122","54","NAM","US","Centralia Municipal Airport","ENL","North America","United States","3/24/2022","Neil","Cancelled","Male","McCory","Portugal","Odella Gregoretti" 180 | "12221221","38","OC","AU","Dalby Airport","DBY","Oceania","Australia","5/15/2022","Yuri","On Time","Male","Crossfield","Peru","Crista Timewell" 181 | "81136580","22","AF","ZA","Oudtshoorn Airport","OUH","Africa","South Africa","7/18/2022","Dyna","Cancelled","Female","De'Vere - Hunt","China","Neila Giercke" 182 | "87105861","12","AS","CN","Enshi Airport","ENH","Asia","China","3/29/2022","Alvin","Delayed","Male","Wenzel","Greece","Alfie MacMorland" 183 | "12250106","77","OC","AU","Badu Island Airport","BDD","Oceania","Australia","11/24/2022","Joeann","Delayed","Female","Gotcliff","Kyrgyzstan","Brandais Crielly" 184 | "65971024","13","SAM","PY","Fuerte Olimpo Airport","OLK","South America","Paraguay","7/21/2022","Sheridan","Delayed","Male","Casino","Ukraine","Carrissa McCooke" 185 | "83106116","41","AS","IN","Pune Airport","PNQ","Asia","India","2/19/2022","Myrtie","On Time","Female","MacScherie","Laos","Claude Ashington" 186 | "27166821","85","OC","PG","Kavieng Airport","KVG","Oceania","Papua New Guinea","6/22/2022","Willie","On Time","Male","Netherwood","Russia","Shirlee Weldrake" 187 | "86661174","25","NAM","HN","Copán Ruinas Airport","RUY","North America","Honduras","7/14/2022","Lisle","On Time","Male","Floyd","China","Kiley Skilton" 188 | "78118100","16","AS","MM","Putao Airport","PBU","Asia","Myanmar","12/18/2022","Peri","Cancelled","Female","Battram","Peru","Coralyn McMickan" 189 | "10288111","83","NAM","US","Kenmore Air Harbor Seaplane Base","LKE","North America","United States","12-08-2022","Tessy","On Time","Female","Athelstan","Sweden","Denny Mudd" 190 | "19989110","70","EU","BG","Gorna Oryahovitsa Airport","GOZ","Europe","Bulgaria","9/25/2022","Aeriela","On Time","Female","Clarke","Portugal","Devonne Jon" 191 | "67100851","67","EU","FR","Grenoble-Isère Airport","GNB","Europe","France","1/18/2022","Darby","On Time","Male","Felgate","Russia","Rhonda Amber" 192 | "10321061","14","AS","MM","Bagan Airport","NYU","Asia","Myanmar","10-03-2022","Julietta","Delayed","Female","Delahunt","Democratic Republic of the Congo","Aimil Shakshaft" 193 | "10810898","30","AS","ID","Fakfak Airport","FKQ","Asia","Indonesia","04-09-2022","Inge","Cancelled","Female","Hewins","Morocco","Danit Hazley" 194 | "66828338","71","NAM","CA","Ottawa / Gatineau Airport","YND","North America","Canada","9/16/2022","Dominica","Delayed","Female","Pyle","China","Kacie Commucci" 195 | "10107257","87","NAM","CA","Thompson Airport","YTH","North America","Canada","11-03-2022","Jerrine","Cancelled","Female","Peeters","Philippines","Chandra Dyhouse" 196 | "78911911","37","NAM","US","Wichita Eisenhower National Airport","ICT","North America","United States","11-08-2022","Kristan","Delayed","Female","Metzing","Peru","Ellene Gibby" 197 | "10671757","84","AS","IR","Ilam Airport","IIL","Asia","""Iran, Islamic Republic of""","10/21/2022","Rory","Cancelled","Female","Wank","Japan","Yoshiko Agastina" 198 | "11485808","33","AS","IN","Biju Patnaik Airport","BBI","Asia","India","7/22/2022","Denys","Delayed","Male","Endricci","Nigeria","Lolly Sine" 199 | "65707241","19","AS","VN","Dien Bien Phu Airport","DIN","Asia","Viet Nam","8/19/2022","Carley","Delayed","Female","Gowers","Poland","Gabriello Slinn" 200 | "10911411","86","OC","AU","Margaret River (Station) Airport","MGV","Oceania","Australia","12/15/2022","Murry","On Time","Male","Entreis","Russia","Delora Percival" 201 | "11110069","49","AF","BF","Arly Airport","ARL","Africa","Burkina Faso","10/29/2022","Star","Cancelled","Female","Casford","Greece","Bailey Priver" 202 | "99106988","40","AS","IL","Bar Yehuda Airfield","MTZ","Asia","Israel","11/14/2022","Heywood","On Time","Male","Bisp","Indonesia","Tomi Larkins" 203 | "10511812","72","OC","PG","Green River Airport","GVI","Oceania","Papua New Guinea","07-11-2022","Wilma","On Time","Female","Burdytt","Poland","Clarey Masding" 204 | "11187116","80","NAM","US","Panguitch Municipal Airport","PNU","North America","United States","10/19/2022","Mariann","Delayed","Female","Wilshin","China","Vanya Dami" 205 | "11278097","7","NAM","US","Southern Seaplane Airport","BCS","North America","United States","3/26/2022","Ferrel","Cancelled","Male","Elphey","Slovenia","Queenie Arends" 206 | "12211711","29","OC","AU","Nyngan Airport","NYN","Oceania","Australia","1/14/2022","Valle","On Time","Male","Christoforou","Benin","Constantia Rubery" 207 | "67100871","33","NAM","US","Memorial Field","HOT","North America","United States","11/28/2022","Mariele","Cancelled","Female","Lucius","Ukraine","Nickie Rudyard" 208 | "11511911","39","AS","TW","Matsu Nangan Airport","LZN","Asia","""Taiwan, Province of China""","10/27/2022","Kelci","On Time","Female","Colliver","China","Dulci Bastow" 209 | "09711784","62","NAM","US","Albert Lea Municipal Airport","AEL","North America","United States","07-05-2022","Leta","On Time","Female","Tartt","Afghanistan","Karlene Kempster" 210 | "10610788","62","NAM","CA","Kugluktuk Airport","YCO","North America","Canada","12/26/2022","Elwood","On Time","Male","Catt","Nicaragua","Marla Parsonage" 211 | "51099010","69","SAM","BR","Araraquara Airport","AQA","South America","Brazil","03-08-2022","Nathanil","On Time","Male","Monan","Brazil","Gabe Sartin" 212 | "11570198","12","NAM","CA","Tahsis Seaplane Base","ZTS","North America","Canada","1/31/2022","Erwin","Cancelled","Male","Baise","Haiti","Weber Swindon" 213 | "98861111","32","NAM","US","Abraham Lincoln Capital Airport","SPI","North America","United States","4/25/2022","George","Delayed","Female","Wildber","Brazil","Sayer Speakman" 214 | "90122113","85","AS","NP","Meghauli Airport","MEY","Asia","Nepal","2/26/2022","Rici","Delayed","Female","Rein","Russia","Eleni Avent" 215 | "65901110","2","NAM","US","Stewart International Airport","SWF","North America","United States","07-06-2022","Tann","Cancelled","Male","McCroary","Poland","Neysa Hendin" 216 | "72109661","69","EU","RU","Grabtsevo Airport","KLF","Europe","Russian Federation","10/26/2022","Adair","Delayed","Male","Spurman","China","Milka Towll" 217 | "76120121","72","AS","CN","Xinzhou Wutaishan Airport","WUT","Asia","China","4/27/2022","Darnall","Cancelled","Male","Comfort","Russia","Maryjane Wolseley" 218 | "10210191","8","NAM","US","Dalhart Municipal Airport","DHT","North America","United States","04-08-2022","Sybila","On Time","Female","Troker","Indonesia","Nelle Aldridge" 219 | "79728011","65","OC","PG","Mal Airport","MMV","Oceania","Papua New Guinea","10/26/2022","Kurt","Delayed","Male","Marling","Indonesia","Noelyn Abbey" 220 | "31061091","13","NAM","CA","Vermilion Airport","YVG","North America","Canada","04-06-2022","Burlie","On Time","Male","Schustl","Thailand","Alameda Carlyle" 221 | "90697736","73","EU","NO","Vadsø Airport","VDS","Europe","Norway","11/25/2022","Diannne","Cancelled","Female","Samter","Cameroon","Simmonds Gallihaulk" 222 | "12061141","13","NAM","US","Trona Airport","TRH","North America","United States","5/28/2022","Aprilette","Cancelled","Female","Veysey","Thailand","Neale MacMearty" 223 | "11611809","38","EU","RO","Sibiu International Airport","SBZ","Europe","Romania","12/24/2022","Jacenta","Cancelled","Female","Linner","Argentina","Joseito Zorzi" 224 | "61098710","18","NAM","US","Kenai Municipal Airport","ENA","North America","United States","07-03-2022","Cobbie","Delayed","Male","Imorts","Croatia","Eugenius Grishakov" 225 | "70978598","24","SAM","BR","Arapiraca Airport","APQ","South America","Brazil","4/26/2022","Aldon","Delayed","Male","Ridsdell","Ghana","Lynette Ortelt" 226 | "10879661","29","AS","IN","Gorakhpur Airport","GOP","Asia","India","1/30/2022","Ericha","Cancelled","Female","Dressel","Sweden","Rowena Krollman" 227 | "90691166","17","AS","CN","Quzhou Airport","JUZ","Asia","China","9/22/2022","Gnni","On Time","Female","Chaperling","Brazil","Justinn Hugh" 228 | "88718179","6","OC","PG","Wantoat Airport","WTT","Oceania","Papua New Guinea","11/30/2022","Dorthea","On Time","Female","Wealleans","China","Adi Sinclar" 229 | "85116118","52","OC","PF","Mururoa Atoll Airport","UOA","Oceania","French Polynesia","02-06-2022","Frank","On Time","Male","Greenhough","Philippines","Ronald Antonucci" 230 | "11584748","33","EU","UA","Mariupol International Airport","MPW","Europe","Ukraine","08-09-2022","Burty","On Time","Male","Blurton","China","Leonora Holah" 231 | "11366101","56","AS","ID","Rar Gwamar Airport","DOB","Asia","Indonesia","07-08-2022","Rosalyn","Delayed","Female","Vondrys","China","Fowler Desquesnes" 232 | "11811011","56","AS","SA","Jubail Airport","QJB","Asia","Saudi Arabia","2/13/2022","Herbert","Delayed","Male","Billingsly","Mongolia","Lincoln Blaske" -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/dynamodb_put_item/lambda_function.py: -------------------------------------------------------------------------------- 1 | '''Custom generic CloudFormation resource example''' 2 | 3 | import json 4 | import requests 5 | import boto3 6 | import botocore.exceptions 7 | import csv 8 | import json 9 | 10 | 11 | dynamodb = boto3.resource('dynamodb') 12 | 13 | 14 | 15 | def lambda_handler(event, context): 16 | '''Handle Lambda event from AWS''' 17 | # Setup alarm for remaining runtime minus a second 18 | # signal.alarm((context.get_remaining_time_in_millis() / 1000) - 1) 19 | try: 20 | 21 | print('REQUEST RECEIVED:', event) 22 | print('CONTEXT RECEIVED:', context) 23 | 24 | if event['RequestType'] == 'Create': 25 | print('CREATE!') 26 | event['PhysicalResourceId'] = 'NOT_YET' 27 | load_data(event, context) 28 | 29 | elif event['RequestType'] == 'Update': 30 | print('UPDATE!') 31 | send_response(event, context, "SUCCESS",{"Message": "Resource update successful!"}) 32 | 33 | elif event['RequestType'] == 'Delete': 34 | print('DELETE!') 35 | send_response(event, context, "SUCCESS",{"Message": "Resource delete successful!"}) 36 | else: 37 | print('FAILED!') 38 | send_response(event, context, "FAILED", 39 | {"Message": "Unexpected event received from CloudFormation"}) 40 | except Exception as error: 41 | print('FAILED!', error) 42 | send_response(event, context, "FAILED", { 43 | "Message": "Exception during processing"}) 44 | 45 | 46 | def load_data (event, context): 47 | 48 | if "ResourceProperties" in event: 49 | print ("create_datasource") 50 | props = event['ResourceProperties'] 51 | 52 | print("props:",props) 53 | table_name = props['table_name'] 54 | sample_data_file = props['sample_data_file'] 55 | table = dynamodb.Table(table_name) 56 | 57 | rows = [] 58 | 59 | 60 | with open(sample_data_file) as csv_file: 61 | csv_reader = csv.DictReader(csv_file) 62 | for row in csv_reader: 63 | rows.append(dict(row)) 64 | 65 | 66 | with table.batch_writer() as batch: 67 | for item in rows: 68 | batch.put_item(Item=item) 69 | 70 | 71 | event['PhysicalResourceId'] = f"{table_name}|{len(rows)}" 72 | send_response(event, context, "SUCCESS",{"Message": "Resource creation successful!"}) 73 | 74 | else: 75 | print("no resource properties!") 76 | 77 | 78 | def send_response(event, context, response_status, response_data): 79 | '''Send a resource manipulation status response to CloudFormation''' 80 | response_body = json.dumps({ 81 | "Status": response_status, 82 | "Reason": "See the details in CloudWatch Log Stream: " + context.log_stream_name, 83 | "PhysicalResourceId": event['PhysicalResourceId'] if 'PhysicalResourceId' in event else "NOPHYID", 84 | "StackId": event['StackId'], 85 | "RequestId": event['RequestId'], 86 | "LogicalResourceId": event['LogicalResourceId'], 87 | "Data": response_data 88 | }) 89 | headers = { 90 | 'Content-Type': 'application/json', 91 | 'Content-Length': str(len(response_body)) 92 | } 93 | 94 | 95 | print('ResponseURL: ', event['ResponseURL']) 96 | print('ResponseBody:', response_body) 97 | 98 | response = requests.put(event['ResponseURL'], 99 | data=response_body, headers=headers) 100 | 101 | print("Status code:", response.status_code) 102 | print("Status message:", response.text) 103 | 104 | return response 105 | 106 | 107 | def timeout_handler(_signal, _frame): 108 | '''Handle SIGALRM''' 109 | raise Exception('Time exceeded') 110 | 111 | # signal.signal(signal.SIGALRM, timeout_handler) 112 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/langchain_agent_text/lambda_function.py: -------------------------------------------------------------------------------- 1 | ################ 2 | ## The Agent ### 3 | ################ 4 | 5 | import json 6 | import boto3 7 | import os 8 | import time 9 | 10 | from db_utils import query,save_item_ddb,update_item_session,update_items_out 11 | from agent_utils import langchain_agent 12 | 13 | from langchain.agents import load_tools,Tool 14 | from langchain.prompts import PromptTemplate 15 | from langchain.llms.bedrock import Bedrock 16 | from utils import (whats_reply) 17 | from langchain.retrievers import AmazonKendraRetriever 18 | from langchain.memory import ConversationBufferMemory 19 | from langchain.chains import ConversationalRetrievalChain 20 | from langchain.memory.chat_message_histories import DynamoDBChatMessageHistory 21 | 22 | client_s3 = boto3.client('s3') 23 | dynamodb_resource=boto3.resource('dynamodb') 24 | bedrock_client = boto3.client("bedrock-runtime") 25 | kendra_client=boto3.client(service_name='kendra') 26 | 27 | table_name_active_connections = os.environ.get('whatsapp_MetaData') 28 | table_session_active = dynamodb_resource.Table(os.environ['TABLE_SESSION_ACTIVE']) 29 | kendra_index_id = os.environ.get('KENDRA_INDEX') 30 | 31 | key_name_active_connections = os.environ.get('ENV_KEY_NAME') 32 | Index_Name = os.environ.get('ENV_INDEX_NAME') 33 | 34 | base_path="/tmp/" 35 | 36 | table_name_session = os.environ.get('TABLE_SESSION') 37 | lambda_query_function_name = os.environ.get('ENV_LAMBDA_QUERY_NAME') 38 | model_id = os.environ.get('ENV_MODEL_ID') 39 | whatsapp_out_lambda = os.environ.get('WHATSAPP_OUT') 40 | 41 | table = dynamodb_resource.Table(table_name_active_connections) 42 | 43 | model_parameter = {"temperature": 0.0, "top_p": .9, "max_tokens_to_sample": 350} 44 | llm = Bedrock(model_id=model_id, model_kwargs=model_parameter,client=bedrock_client) 45 | 46 | def memory_dynamodb(id,table_name_session,llm): 47 | message_history = DynamoDBChatMessageHistory(table_name=table_name_session, session_id=id) 48 | memory = ConversationBufferMemory( 49 | memory_key="chat_history", llm=llm,max_token_limit=800,chat_memory=message_history, return_messages=True,ai_prefix="A",human_prefix="H" 50 | ) 51 | return memory 52 | 53 | 54 | def promp_definition(): 55 | 56 | prompt_template = """ 57 | You are an assistant in the airline La Inventada who answers to users factual information about the status of the passengers through their ID or rservation number, deliver information to help the passenger and also do casual conversation. 58 | 59 | Use the following format: 60 | History: the context of a previous conversation with the user. Useful if you need to recall past conversation, make a summary, or rephrase the answers. if History is empty it continues. 61 | Question: the input question you must answer 62 | Thought: you should always think about what to do, also try to follow steps mentioned above.Idenfity if user wants to do casual chat, search passanger information or search knowledge base. Also try to follow steps mentioned above. You must undestand the identification ID as number, no words. 63 | Action: the action to take, should be one of ["search-passanger-information","search_knowledge_base"] or use your sympathy. 64 | Action Input: the input to the action 65 | Observation: the result of the action 66 | Thought: I now know the final answer 67 | Final Answer: the final answer to the original input question, always reply in the original user language and human legible. 68 | 69 | History: 70 | {chat_history} 71 | 72 | Question: {input} 73 | 74 | Assistant: 75 | {agent_scratchpad}""" 76 | 77 | updated_prompt = PromptTemplate( 78 | input_variables=['chat_history','input', 'agent_scratchpad'], template=prompt_template) 79 | 80 | return updated_prompt 81 | 82 | 83 | def kendra_tool(llm,kendra_index_id): 84 | retriever = AmazonKendraRetriever(index_id=kendra_index_id) 85 | memory_kendra = ConversationBufferMemory(memory_key="chat_history", return_messages=True,ai_prefix="A",human_prefix="H") 86 | 87 | Kendra_prompt_template = """Human: 88 | The following is a friendly conversation between a human and an AI. 89 | The AI is an assistant in the airline La Inventada and deliver information to help the passengers and provides specific details with but limits it to 240 tokens. 90 | If the AI does not know the answer to a question, it truthfully says it does not know. 91 | 92 | Assistant: OK, got it, I'll be a talkative truthful assistant. 93 | 94 | Human: Here are a few documents in tags: 95 | 96 | {context} 97 | 98 | Based on the above documents, provide a detailed answer for, {question} 99 | Answer "don't know" if not present in the document. 100 | 101 | Assistant: 102 | """ 103 | PROMPT = PromptTemplate( 104 | template=Kendra_prompt_template, input_variables=["context","question"] 105 | ) 106 | 107 | condense_qa_template_kendra = """{chat_history} 108 | Human: 109 | Given the following conversation and a follow up question, rephrase the follow up question 110 | to be a standalone question. 111 | 112 | Standalone Question: 113 | 114 | Assistant:""" 115 | 116 | standalone_question_prompt_kendra = PromptTemplate.from_template(condense_qa_template_kendra) 117 | 118 | qa_kendra = ConversationalRetrievalChain.from_llm( 119 | llm=llm, 120 | retriever=retriever, 121 | condense_question_prompt=standalone_question_prompt_kendra, 122 | return_source_documents=False, 123 | combine_docs_chain_kwargs={"prompt":PROMPT}, 124 | memory = memory_kendra, 125 | #verbose=True 126 | ) 127 | return qa_kendra 128 | 129 | 130 | def lambda_handler(event, context): 131 | print (event) 132 | 133 | whats_message = event['whats_message'] 134 | print(whats_message) 135 | whats_token = event['whats_token'] 136 | messages_id = event['messages_id'] 137 | phone = event['phone'] 138 | phone_id = event['phone_id'] 139 | phone_number = phone.replace("+","") 140 | 141 | #The session ID is created to store the history of the chat. 142 | 143 | try: 144 | session_data = query("phone_number",table_session_active,phone_number) 145 | now = int(time.time()) 146 | diferencia = now - session_data["session_time"] 147 | if diferencia > 300: #session time in seg 148 | update_item_session(table_session_active,phone_number,now) 149 | id = str(phone_number) + "_" + str(now) 150 | else: 151 | id = str(phone_number) + "_" + str(session_data["session_time"]) 152 | 153 | except: 154 | now = int(time.time()) 155 | new_row = {"phone_number": phone_number, "session_time":now} 156 | save_item_ddb(table_session_active,new_row) 157 | 158 | id = str(phone_number) + "_" + str(now) 159 | 160 | try: 161 | print('REQUEST RECEIVED:', event) 162 | print('REQUEST CONTEXT:', context) 163 | print("PROMPT: ",whats_message) 164 | 165 | #s = re.sub(r'[^a-zA-Z0-9]', '', query) 166 | 167 | tools = load_tools( 168 | ["awslambda"], 169 | awslambda_tool_name="search-passanger-information", 170 | awslambda_tool_description="useful for searching passenger data by their ID, only send the number", 171 | function_name=lambda_query_function_name, 172 | ) 173 | 174 | qa_kendra = kendra_tool(llm,kendra_index_id) 175 | 176 | tools.append( 177 | Tool.from_function( 178 | func=qa_kendra.run, 179 | name="search_knowledge_base", 180 | description="Searches and returns documents regarding to help the passenger", 181 | ) 182 | ) 183 | 184 | memory = memory_dynamodb(id,table_name_session,llm) 185 | 186 | agent = langchain_agent(memory,tools,llm) 187 | 188 | agent.agent.llm_chain.prompt=promp_definition() 189 | response = agent(whats_message) 190 | print(response) 191 | 192 | whats_reply(whatsapp_out_lambda,phone, whats_token, phone_id, f"{response['output']}", messages_id) 193 | 194 | 195 | end = int(time.time()) 196 | 197 | update_items_out(table,messages_id,response['output'],end) 198 | 199 | return({"body":response['output']}) 200 | 201 | 202 | except Exception as error: 203 | print('FAILED!', error) 204 | return({"body": "Cuek! I dont know"}) 205 | 206 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/process_stream/lambda_function.py: -------------------------------------------------------------------------------- 1 | #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 | ##++++++ Amazon Lambda Function for processing WhatsApp incoming messages +++++ 3 | ## Updated to Whatsapp API v14 4 | #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 | 6 | import boto3 7 | from boto3.dynamodb.types import TypeDeserializer 8 | import decimal 9 | import json 10 | import os 11 | 12 | import requests 13 | from botocore.exceptions import ClientError 14 | 15 | lambda_client = boto3.client('lambda') 16 | 17 | from file_utils import( get_media_url ) 18 | 19 | from utils import (build_response) 20 | 21 | SUPPORTED_FILE_TYPES = ['text/csv','image/png','image/jpeg','application/pdf'] 22 | 23 | 24 | def ddb_deserialize(r, type_deserializer = TypeDeserializer()): 25 | return type_deserializer.deserialize({"M": r}) 26 | 27 | class DecimalEncoder(json.JSONEncoder): 28 | def default(self, o): 29 | if isinstance(o, decimal.Decimal): 30 | if o % 1 > 0: 31 | return float(o) 32 | else: 33 | return int(o) 34 | return super(DecimalEncoder, self).default(o) 35 | 36 | def lambda_handler(event, context): 37 | print (event) 38 | 39 | for rec in event['Records']: 40 | 41 | try: 42 | entry = json.loads(json.dumps(ddb_deserialize(rec['dynamodb']['NewImage']), cls=DecimalEncoder)) 43 | messages_id = entry["messages_id"] 44 | event_name = rec['eventName'] 45 | print(event_name) 46 | 47 | if event_name == "INSERT": 48 | print("messages_id: ", messages_id) 49 | print("entry: ",entry) 50 | WHATS_TOKEN = entry["whats_token"] 51 | 52 | for change in entry['changes']: 53 | print("Iterating change") 54 | print(change) 55 | ## Skipping as no contact info was relevant. 56 | if('contacts' not in change['value']): 57 | continue 58 | 59 | whats_message = change['value']['messages'][0] 60 | 61 | phone_id = change['value']['metadata']['phone_number_id'] 62 | name = change['value']['contacts'][0]['profile']['name'] 63 | phone = '+' + str(whats_message['from']) 64 | channel = 'whatsapp' 65 | 66 | ##Define message type 67 | messageType =whats_message['type'] 68 | if(messageType == 'text'): 69 | message = whats_message['text']['body'] 70 | process_text(message, WHATS_TOKEN,phone,phone_id,messages_id) 71 | 72 | 73 | # Agregar para respuestas a boton! 74 | elif(messageType == 'button'): 75 | message =whats_message['button']['text'] 76 | 77 | elif(messageType == 'audio'): 78 | #processed_audio = process_audio(whats_message, WHATS_TOKEN,phone,systemNumber) 79 | processed_job_audio = star_job_audio(whats_message, WHATS_TOKEN,phone,phone_id,messages_id) 80 | 81 | message = "Procesando.." 82 | else: 83 | message = 'Attachment' 84 | fileType = whats_message[messageType]['mime_type'] 85 | fileName = whats_message[messageType].get('filename',phone + '.'+fileType.split("/")[1]) 86 | fileId = whats_message[messageType]['id'] 87 | fileUrl = get_media_url(fileId,WHATS_TOKEN) 88 | 89 | print(fileType) 90 | print(message, messageType, name, phone_id) 91 | print(build_response (200,json.dumps('All good!'))) 92 | else: 93 | print("no New INSERT") 94 | except: 95 | print("no New Image") 96 | 97 | return True 98 | 99 | 100 | 101 | def process_text(whats_message, whats_token,phone,phone_id,messages_id): 102 | 103 | print("text", whats_message, whats_token) 104 | LAMBDA_AGENT_TEXT = os.environ['ENV_LAMBDA_AGENT_TEXT'] 105 | 106 | try: 107 | 108 | response_3 = lambda_client.invoke( 109 | FunctionName = LAMBDA_AGENT_TEXT, 110 | InvocationType = 'Event' ,#'RequestResponse', 111 | Payload = json.dumps({ 112 | 'whats_message': whats_message, 113 | 'whats_token': whats_token, 114 | 'phone': phone, 115 | 'phone_id': phone_id, 116 | 'messages_id': messages_id 117 | 118 | }) 119 | ) 120 | 121 | print(f'\nRespuesta:{response_3}') 122 | 123 | return response_3 124 | 125 | except ClientError as e: 126 | err = e.response 127 | error = err 128 | print(err.get("Error", {}).get("Code")) 129 | return f"Un error invocando {LAMBDA_AGENT_TEXT}" 130 | 131 | 132 | def star_job_audio(whats_message, whats_token,phone,phone_id,messages_id): 133 | 134 | print("audio", whats_message, whats_token) 135 | JOB_TRANSCRIPTOR_LAMBDA = os.environ['JOB_TRANSCRIPTOR_LAMBDA'] 136 | 137 | try: 138 | 139 | response_2 = lambda_client.invoke( 140 | FunctionName = JOB_TRANSCRIPTOR_LAMBDA, 141 | InvocationType = 'Event' ,#'RequestResponse', 142 | Payload = json.dumps({ 143 | 'whats_message': whats_message, 144 | 'whats_token': whats_token, 145 | 'phone': phone, 146 | 'phone_id': phone_id, 147 | 'messages_id': messages_id 148 | 149 | }) 150 | ) 151 | 152 | print(f'\nRespuesta:{response_2}') 153 | 154 | return response_2 155 | 156 | except ClientError as e: 157 | err = e.response 158 | error = err 159 | print(err.get("Error", {}).get("Code")) 160 | return f"Un error invocando {JOB_TRANSCRIPTOR_LAMBDA}" -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/query_dynamodb_passanger/lambda_function.py: -------------------------------------------------------------------------------- 1 | ################################################# 2 | ## This function is to query a dynamoDB table ### 3 | ################################################# 4 | 5 | import json 6 | from boto3.dynamodb.conditions import Key 7 | import boto3 8 | import botocore.exceptions 9 | import os 10 | import re 11 | 12 | dynamodb_resource=boto3.resource('dynamodb') 13 | 14 | table_name = os.environ.get('TABLE_PASSANGER') 15 | key_name = os.environ.get('ENV_KEY_NAME') 16 | 17 | table = dynamodb_resource.Table(table_name) 18 | 19 | def db_query(key,table,keyvalue): 20 | response = table.query( 21 | KeyConditionExpression=Key(key).eq(keyvalue) 22 | ) 23 | print(response) 24 | return response['Items'][0] 25 | 26 | 27 | def lambda_handler(event, context): 28 | print(event) 29 | '''Handle Lambda event from AWS''' 30 | # Setup alarm for remaining runtime minus a second 31 | # signal.alarm((context.get_remaining_time_in_millis() / 1000) - 1) 32 | try: 33 | print('REQUEST RECEIVED:', event) 34 | print('REQUEST CONTEXT:', context) 35 | 36 | query = event['body'] 37 | print(query) 38 | s = re.sub(r'[^a-zA-Z0-9]', '', query) 39 | tabla_response = db_query(key_name,table,str(s)) 40 | print(tabla_response) 41 | 42 | return({"body":tabla_response}) 43 | 44 | 45 | except Exception as error: 46 | print('FAILED!', error) 47 | return({"body":"Cuek! no in Data Base"}) 48 | 49 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/transcriber_done/lambda_function.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import json 3 | import os 4 | import requests 5 | from boto3.dynamodb.conditions import Key 6 | from botocore.exceptions import ClientError 7 | 8 | lambda_client = boto3.client('lambda') 9 | 10 | from db_utils import query_gd, query 11 | 12 | from file_utils import download_file 13 | 14 | table_name_active_connections = os.environ.get('whatsapp_MetaData') 15 | 16 | key_name_active_connections = os.environ.get('ENV_KEY_NAME') 17 | Index_Name = os.environ.get('ENV_INDEX_NAME') 18 | whatsapp_out_lambda = os.environ.get('WHATSAPP_OUT') 19 | 20 | client_s3 = boto3.client('s3') 21 | dynamodb_resource=boto3.resource('dynamodb') 22 | table = dynamodb_resource.Table(table_name_active_connections) 23 | 24 | base_path="/tmp/" 25 | 26 | def process_text(whats_message, whats_token,phone,phone_id,messages_id): 27 | 28 | print("text", whats_message, whats_token) 29 | LAMBDA_AGENT_TEXT = os.environ['ENV_LAMBDA_AGENT_TEXT'] 30 | 31 | try: 32 | 33 | response_3 = lambda_client.invoke( 34 | FunctionName = LAMBDA_AGENT_TEXT, 35 | InvocationType = 'Event' ,#'RequestResponse', 36 | Payload = json.dumps({ 37 | 'whats_message': whats_message, 38 | 'whats_token': whats_token, 39 | 'phone': phone, 40 | 'phone_id': phone_id, 41 | 'messages_id': messages_id 42 | 43 | }) 44 | ) 45 | 46 | print(f'\nRespuesta:{response_3}') 47 | 48 | return response_3 49 | 50 | except ClientError as e: 51 | err = e.response 52 | error = err 53 | print(err.get("Error", {}).get("Code")) 54 | return f"Un error invocando {LAMBDA_AGENT_TEXT}" 55 | 56 | 57 | def lambda_handler(event, context): 58 | 59 | print (event) 60 | 61 | for record in event['Records']: 62 | print("Event: ",event['Records']) 63 | record = event['Records'][0] 64 | 65 | s3bucket = record['s3']['bucket']['name'] 66 | s3object = record['s3']['object']['key'] 67 | filename = s3object.split("/")[-1] 68 | keyvalue = s3object.split("/")[-2] 69 | 70 | key = s3object.split("/")[1]+"/" 71 | print("s3object: ",s3object) 72 | print("filename: ",filename) 73 | print("key: ",key) 74 | 75 | if os.path.splitext(filename)[1] != ".temp": 76 | 77 | download_file(base_path,s3bucket, s3object, filename) 78 | value = filename.split("_")[-1].replace(".txt","") 79 | print(value) 80 | 81 | with open(base_path+filename) as f: 82 | message = f.readlines() 83 | 84 | messages_id = query_gd("jobName",table,value,Index_Name)[key_name_active_connections] 85 | whatsapp_data = query(key_name_active_connections,table,messages_id) 86 | message_json = json.loads(message[0]) 87 | text = message_json["results"]['transcripts'][0]['transcript'] 88 | phone = '+' + str(whatsapp_data['changes'][0]["value"]["messages"][0]["from"]) 89 | whats_token = whatsapp_data['whats_token'] 90 | phone_id = whatsapp_data['changes'][0]["value"]["metadata"]["phone_number_id"] 91 | 92 | print(text) 93 | 94 | process_text(text, whats_token,phone,phone_id,messages_id) 95 | 96 | try: 97 | print('REQUEST RECEIVED:', event) 98 | print('REQUEST CONTEXT:', context) 99 | print("PROMPT: ",text) 100 | 101 | process_text(text, whats_token,phone,phone_id,messages_id) 102 | 103 | return True 104 | 105 | except Exception as error: 106 | print('FAILED!', error) 107 | return True 108 | 109 | else: 110 | print("No text file") 111 | return True -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/whatsapp_in/lambda_function.py: -------------------------------------------------------------------------------- 1 | 2 | #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 | ##++++++ Amazon Lambda Function for processing WhatsApp incoming messages +++++ 4 | ## Updated to Whatsapp API v14 5 | #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 | 7 | import json 8 | import os 9 | import boto3 10 | import time 11 | 12 | lambda_client = boto3.client('lambda') 13 | 14 | from utils import ( get_config,build_response,validate_healthcheck) 15 | 16 | whatsapp_MetaData = os.environ.get('whatsapp_MetaData') 17 | key_name_active_connections = os.environ.get('ENV_KEY_NAME') 18 | 19 | dynamodb_resource=boto3.resource('dynamodb') 20 | table = dynamodb_resource.Table(whatsapp_MetaData) 21 | 22 | valid_display_phone_number = os.environ.get('DISPLAY_PHONE_NUMBER') 23 | 24 | CONFIG_PARAMETER= os.environ['CONFIG_PARAMETER'] 25 | 26 | def batch_put_items(client, table_name, item_arrays): 27 | table = client.Table(table_name) 28 | with table.batch_writer() as batch: 29 | for itm in item_arrays: 30 | res = batch.put_item(Item=itm) 31 | print(res) 32 | 33 | 34 | def lambda_handler(event, context): 35 | print (event) 36 | connect_config=json.loads(get_config(CONFIG_PARAMETER)) 37 | 38 | if event['httpMethod'] == 'GET': 39 | return build_response(200, 40 | validate_healthcheck(event, connect_config['WHATS_VERIFICATION_TOKEN'])) 41 | 42 | if event.get("body") == None: build_response(200,"bye bye") 43 | 44 | body = json.loads(event['body']) 45 | WHATS_TOKEN = 'Bearer ' + connect_config['WHATS_TOKEN'] 46 | 47 | ##WhatsApp specific iterations. 48 | for entry in body['entry']: 49 | print("Iterating entry") 50 | print(entry) 51 | display_phone_number=entry["changes"][0]["value"]["metadata"]["display_phone_number"] 52 | timestamp = int(entry["changes"][0]["value"]["messages"][0]["timestamp"]) 53 | now = int(time.time()) 54 | diferencia = now - timestamp 55 | if diferencia > 300: #session time in seg 56 | print("old message") 57 | break 58 | 59 | if display_phone_number == valid_display_phone_number: 60 | try: 61 | entry[key_name_active_connections]=entry["changes"][0]["value"]["messages"][0]["id"] 62 | entry["whats_token"] = WHATS_TOKEN 63 | print("key_name_active_connections",entry[key_name_active_connections]) 64 | batch_put_items(dynamodb_resource, whatsapp_MetaData, [entry]) 65 | except: 66 | print("No messages") 67 | else: 68 | print("No valid diplay phone number: ", display_phone_number) 69 | 70 | 71 | return build_response(200,"OK") 72 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/code/whatsapp_out/lambda_function.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import json 3 | import requests 4 | from utils import ( normalize_phone,) 5 | 6 | base_path="/tmp/" 7 | 8 | def whats_out(phone, whats_token, phone_id, message, in_reply_to): 9 | 10 | # https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#reply-to-message 11 | URL = 'https://graph.facebook.com/v15.0/'+phone_id+'/messages' 12 | headers = {'Authorization': whats_token, 'Content-Type': 'application/json'} 13 | data = { 14 | "messaging_product": "whatsapp", 15 | "to": normalize_phone(phone), 16 | "context": json.dumps({ "message_id": in_reply_to}), 17 | "type": "text", 18 | "text": json.dumps({ "preview_url": False, "body": message}) 19 | } 20 | 21 | print("Sending") 22 | print(data) 23 | response = requests.post(URL, headers=headers, data=data) 24 | responsejson = response.json() 25 | print("Responses: "+ str(responsejson) 26 | ) 27 | 28 | def lambda_handler(event, context): 29 | 30 | print (event) 31 | 32 | phone = event['phone'] 33 | whats_token = event['whats_token'] 34 | phone_id = event['phone_id'] 35 | message = event['message'] 36 | in_reply_to = event['in_reply_to'] 37 | 38 | try: 39 | whats_out(phone, whats_token, phone_id, message, in_reply_to) 40 | return True 41 | 42 | except Exception as error: 43 | print('FAILED!', error) 44 | return True -------------------------------------------------------------------------------- /customer-support-bot/lambdas/datasource.py: -------------------------------------------------------------------------------- 1 | 2 | from aws_cdk import ( 3 | # Duration, 4 | Stack, 5 | # aws_sqs as sqs, 6 | CustomResource, 7 | CfnOutput 8 | ) 9 | from constructs import Construct 10 | from databases import Tables 11 | from lambdas import Lambdas 12 | 13 | 14 | class DynamodbWithSampleDataStack(Construct): 15 | def __init__( 16 | self, scope: Construct, 17 | construct_id: str, 18 | table, 19 | lambda_function, 20 | file_name, 21 | **kwargs) -> None: 22 | 23 | super().__init__(scope, construct_id, **kwargs) 24 | 25 | 26 | table.grant_full_access(lambda_function) 27 | CfnOutput(self, "table", value=table.table_name) 28 | 29 | ds = CustomResource( 30 | self, 31 | "S3DS", 32 | resource_type="Custom::S3DataSource", 33 | service_token=lambda_function.function_arn, 34 | properties=dict( 35 | table_name=table.table_name, sample_data_file=file_name 36 | ), 37 | ) 38 | -------------------------------------------------------------------------------- /customer-support-bot/lambdas/project_lambdas.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from aws_cdk import ( 4 | Duration, 5 | aws_lambda, 6 | aws_ssm as ssm, 7 | Stack, 8 | aws_iam as iam 9 | 10 | ) 11 | 12 | from constructs import Construct 13 | 14 | 15 | LAMBDA_TIMEOUT= 900 16 | 17 | BASE_LAMBDA_CONFIG = dict ( 18 | timeout=Duration.seconds(LAMBDA_TIMEOUT), 19 | memory_size=520, 20 | tracing= aws_lambda.Tracing.ACTIVE) 21 | 22 | COMMON_LAMBDA_CONF = dict (runtime=aws_lambda.Runtime.PYTHON_3_11, **BASE_LAMBDA_CONFIG) 23 | 24 | from layers import Layers 25 | 26 | 27 | class Lambdas(Construct): 28 | 29 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 30 | super().__init__(scope, construct_id, **kwargs) 31 | 32 | Lay = Layers(self, 'Lay') 33 | 34 | self.whatsapp_in = aws_lambda.Function( 35 | self, "WAIn", handler="lambda_function.lambda_handler", 36 | description ="process WhatsApp incoming messages" , 37 | code=aws_lambda.Code.from_asset("./lambdas/code/whatsapp_in"), 38 | layers= [Lay.bs4_requests, Lay.common],**COMMON_LAMBDA_CONF) 39 | 40 | self.whatsapp_out = aws_lambda.Function( 41 | self, "whatsapp_out", handler="lambda_function.lambda_handler", 42 | description ="Send WhatsApp message" , 43 | code=aws_lambda.Code.from_asset("./lambdas/code/whatsapp_out"), 44 | layers= [Lay.bs4_requests, Lay.common],**COMMON_LAMBDA_CONF) 45 | 46 | self.audio_job_transcriptor = aws_lambda.Function( 47 | self, "job_Transcribe", 48 | description ="Start Transcribe Job audio to text WhatsApp incoming messages" , 49 | handler="lambda_function.lambda_handler", 50 | code=aws_lambda.Code.from_asset("./lambdas/code/audio_job_transcriptor"), 51 | layers= [Lay.bs4_requests, Lay.common],**COMMON_LAMBDA_CONF) 52 | 53 | self.dynamodb_put_item = aws_lambda.Function( 54 | self, "DynamoDB_put_item", 55 | description ="Put items to csv to DynamoDB" , 56 | handler="lambda_function.lambda_handler", 57 | layers=[Lay.bs4_requests,Lay.common], 58 | code=aws_lambda.Code.from_asset("./lambdas/code/dynamodb_put_item"), 59 | **COMMON_LAMBDA_CONF) 60 | 61 | self.query_dynamodb_passanger = aws_lambda.Function( 62 | self, "query_dynamodb_passanger", 63 | description ="Query DynamoDB passanger table" , 64 | handler="lambda_function.lambda_handler", 65 | code=aws_lambda.Code.from_asset("./lambdas/code/query_dynamodb_passanger"), 66 | **COMMON_LAMBDA_CONF) 67 | 68 | self.langchain_agent_text = aws_lambda.Function( 69 | self, "langChain_agent_text", 70 | description ="Airline Agent with LangChain and Amacon Bedrock" , 71 | handler="lambda_function.lambda_handler", 72 | code=aws_lambda.Code.from_asset("./lambdas/code/langchain_agent_text"), 73 | layers= [Lay.bedrock,Lay.bs4_requests,Lay.common,Lay.langchain], 74 | architecture=aws_lambda.Architecture.ARM_64, 75 | **COMMON_LAMBDA_CONF) 76 | 77 | self.transcriber_done = aws_lambda.Function( 78 | self, "transcriber_done", 79 | description ="Read the text from transcriber job" , 80 | handler="lambda_function.lambda_handler", 81 | code=aws_lambda.Code.from_asset("./lambdas/code/transcriber_done"), 82 | layers= [Lay.bs4_requests, Lay.common],**COMMON_LAMBDA_CONF) 83 | 84 | self.data_source_creator = aws_lambda.Function( 85 | self, 86 | "CR_datasource", 87 | handler="lambda_function.lambda_handler", 88 | layers=[Lay.bs4_requests], 89 | code=aws_lambda.Code.from_asset("./lambdas/code/data_source_creator"), 90 | **COMMON_LAMBDA_CONF 91 | ) 92 | 93 | self.process_stream = aws_lambda.Function( 94 | self, "process_stream", 95 | description ="Read the text from transcriber job" , 96 | handler="lambda_function.lambda_handler", 97 | code=aws_lambda.Code.from_asset("./lambdas/code/process_stream"), 98 | layers= [Lay.bs4_requests, Lay.common],**COMMON_LAMBDA_CONF) 99 | 100 | self.data_source_creator.add_to_role_policy( 101 | iam.PolicyStatement(actions=["kendra:*"], resources=["*"]) 102 | ) 103 | 104 | self.data_source_creator.add_to_role_policy( 105 | iam.PolicyStatement(actions=["iam:PassRole"], resources=["*"]) 106 | ) 107 | -------------------------------------------------------------------------------- /customer-support-bot/layers/__init__.py: -------------------------------------------------------------------------------- 1 | from layers.project_layers import Layers -------------------------------------------------------------------------------- /customer-support-bot/layers/aiofile-amazon-transcribe.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/layers/aiofile-amazon-transcribe.zip -------------------------------------------------------------------------------- /customer-support-bot/layers/boto3.1.28.62.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/layers/boto3.1.28.62.zip -------------------------------------------------------------------------------- /customer-support-bot/layers/bs4_requests.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/layers/bs4_requests.zip -------------------------------------------------------------------------------- /customer-support-bot/layers/common/python/agent_utils.py: -------------------------------------------------------------------------------- 1 | 2 | from langchain import LLMMathChain 3 | from langchain.llms.bedrock import Bedrock 4 | from langchain.memory import ConversationBufferMemory 5 | from langchain.agents import load_tools, initialize_agent, AgentType,Tool 6 | 7 | 8 | def match_function(model_id,bedrock_client): 9 | math_chain_llm = Bedrock(model_id=model_id,model_kwargs={"temperature":0,"stop_sequences" : ["```output"]},client=bedrock_client) 10 | llm_math_chain = LLMMathChain(llm=math_chain_llm, verbose=True) 11 | 12 | llm_math_chain.llm_chain.prompt.template = """Human: Given a question with a math problem, provide only a single line mathematical expression that solves the problem in the following format. Don't solve the expression only create a parsable expression. 13 | ```text 14 | ${{single line mathematical expression that solves the problem}} 15 | ``` 16 | 17 | Assistant: 18 | Here is an example response with a single line mathematical expression for solving a math problem: 19 | ```text 20 | 37593**(1/5) 21 | ``` 22 | 23 | Human: {question} 24 | Assistant:""" 25 | return Tool.from_function( 26 | func=llm_math_chain.run, 27 | name="Calculator", 28 | description="Useful for when you need to answer questions about math.", 29 | ) 30 | 31 | def memory_dynamodb(id,table_name_session,llm): 32 | message_history = DynamoDBChatMessageHistory(table_name=table_name_session, session_id=id) 33 | memory = ConversationBufferMemory( 34 | memory_key="chat_history", llm=llm,max_token_limit=800,chat_memory=message_history, return_messages=True,ai_prefix="A",human_prefix="H" 35 | ) 36 | return memory 37 | 38 | def langchain_agent(memory,tools,llm): 39 | zero_shot_agent=initialize_agent( 40 | llm=llm, 41 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 42 | tools=tools, 43 | #verbose=True, 44 | max_iteration=1, 45 | #return_intermediate_steps=True, 46 | handle_parsing_errors=True, 47 | memory=memory 48 | ) 49 | return zero_shot_agent -------------------------------------------------------------------------------- /customer-support-bot/layers/common/python/db_utils.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import requests 3 | from boto3.dynamodb.conditions import Key 4 | 5 | 6 | def query_gd(key,table,keyvalue,Index_Name): 7 | resp = table.query( 8 | # Add the name of the index you want to use in your query. 9 | IndexName="jobnameindex", 10 | KeyConditionExpression=Key(key).eq(keyvalue), 11 | ) 12 | print(resp) 13 | return resp['Items'][0] 14 | 15 | def query(key,table,keyvalue): 16 | response = table.query( 17 | KeyConditionExpression=Key(key).eq(keyvalue) 18 | ) 19 | print(response) 20 | return response['Items'][0] 21 | 22 | def update_item(value,end,duration,table): 23 | try: 24 | response = table.update_item( 25 | Key={ 26 | "messages_id" : value 27 | }, 28 | UpdateExpression="set end=:newState, duration=:newState1", 29 | ExpressionAttributeValues={ 30 | ':newState': end, 31 | ':newState1': duration, 32 | }, 33 | ReturnValues="UPDATED_NEW") 34 | print (response) 35 | except Exception as e: 36 | print (e) 37 | else: 38 | return response 39 | 40 | def save_item_ddb(table,item): 41 | response = table.put_item(Item=item) 42 | return response 43 | 44 | def update_items_out(table,value,response_out,end_response): 45 | try: 46 | response = table.update_item( 47 | Key={ 48 | "messages_id" : value 49 | }, 50 | UpdateExpression="set response_out=:item1, end_response=:item2", 51 | ExpressionAttributeValues={ 52 | ':item1': response_out, 53 | ':item2': end_response, 54 | }, 55 | ReturnValues="UPDATED_NEW") 56 | print (response) 57 | except Exception as e: 58 | print (e) 59 | else: 60 | return response 61 | 62 | def update_item_session(table_name_session,value,session_time): 63 | try: 64 | response = table_name_session.update_item( 65 | Key={ 66 | "phone_number" : value 67 | }, 68 | UpdateExpression="set session_time=:item1", 69 | ExpressionAttributeValues={ 70 | ':item1': session_time 71 | }, 72 | ReturnValues="UPDATED_NEW") 73 | print (response) 74 | except Exception as e: 75 | print (e) 76 | else: 77 | return response 78 | 79 | -------------------------------------------------------------------------------- /customer-support-bot/layers/common/python/file_utils.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import requests 3 | 4 | s3_resource = boto3.resource('s3') 5 | 6 | client_s3 = boto3.client('s3') 7 | 8 | def download_file(base_path,bucket, key, filename): 9 | print("Download file from s3://{}{}".format(bucket,key)) 10 | with open(base_path+filename, "wb") as data: 11 | client_s3.download_fileobj(bucket, key, data) 12 | print("Download file from s3://{}{}".format(bucket,key)) 13 | return True 14 | 15 | def upload_data_to_s3(bytes_data,bucket_name, s3_key): 16 | obj = s3_resource.Object(bucket_name, s3_key) 17 | obj.put(ACL='private', Body=bytes_data) 18 | s3_url = f"https://{bucket_name}.s3.amazonaws.com/{s3_key}" 19 | return s3_url 20 | 21 | def download_file_from_url(url): 22 | response = requests.get(url) 23 | if response.status_code == 200: 24 | return response.content 25 | else: 26 | return None 27 | 28 | def get_media_url(mediaId,whatsToken): 29 | 30 | URL = 'https://graph.facebook.com/v17.0/'+mediaId 31 | headers = {'Authorization': whatsToken} 32 | print("Requesting") 33 | response = requests.get(URL, headers=headers) 34 | responsejson = response.json() 35 | if('url' in responsejson): 36 | print("Responses: "+ str(responsejson)) 37 | return responsejson['url'] 38 | else: 39 | print("No URL returned") 40 | return None 41 | 42 | def get_whats_media(url,whatsToken): 43 | headers = {'Authorization': whatsToken} 44 | response = requests.get(url,headers=headers) 45 | if response.status_code == 200: 46 | return response.content 47 | else: 48 | return None 49 | 50 | def put_file(base_path,filename, bucket, key): 51 | with open(base_path+filename, "rb") as data: 52 | client_s3.upload_fileobj(data,bucket, key+filename) 53 | print("Put file in s3://{}{}{}".format(bucket,key,filename)) 54 | 55 | 56 | -------------------------------------------------------------------------------- /customer-support-bot/layers/common/python/utils.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | from botocore.exceptions import ClientError 3 | import json 4 | secrets_client = boto3.client(service_name='secretsmanager') 5 | lambda_client = boto3.client('lambda') 6 | 7 | 8 | def get_config(secret_name): 9 | # Create a Secrets Manager client 10 | try: 11 | get_secret_value_response = secrets_client.get_secret_value( 12 | SecretId=secret_name 13 | ) 14 | except ClientError as e: 15 | if e.response['Error']['Code'] == 'DecryptionFailureException': 16 | # Secrets Manager can't decrypt the protected secret text using the provided KMS key. 17 | # Deal with the exception here, and/or rethrow at your discretion. 18 | raise e 19 | elif e.response['Error']['Code'] == 'InternalServiceErrorException': 20 | # An error occurred on the server side. 21 | # Deal with the exception here, and/or rethrow at your discretion. 22 | raise e 23 | elif e.response['Error']['Code'] == 'InvalidParameterException': 24 | # You provided an invalid value for a parameter. 25 | # Deal with the exception here, and/or rethrow at your discretion. 26 | raise e 27 | elif e.response['Error']['Code'] == 'InvalidRequestException': 28 | # You provided a parameter value that is not valid for the current state of the resource. 29 | # Deal with the exception here, and/or rethrow at your discretion. 30 | raise e 31 | elif e.response['Error']['Code'] == 'ResourceNotFoundException': 32 | # We can't find the resource that you asked for. 33 | # Deal with the exception here, and/or rethrow at your discretion. 34 | raise e 35 | else: 36 | # Decrypts secret using the associated KMS CMK. 37 | # Depending on whether the secret is a string or binary, one of these fields will be populated. 38 | if 'SecretString' in get_secret_value_response: 39 | secret = get_secret_value_response['SecretString'] 40 | else: 41 | secret = None 42 | return secret 43 | 44 | def normalize_phone(phone): 45 | ### Country specific changes required on phone numbers 46 | 47 | ### Mexico specific, remove 1 after 52 48 | if(phone[0:2]=='52' and phone[2] == '1'): 49 | normalized = phone[0:2] + phone[3:] 50 | else: 51 | normalized = phone 52 | return normalized 53 | ### End Mexico specific 54 | 55 | def get_file_category(mimeType): 56 | ## Possible {AUDIO, CONTACTS, DOCUMENT, IMAGE, TEXT, TEMPLATE, VIDEO, STICKER, LOCATION, INTERACTIVE, REACTION} 57 | if('application' in mimeType): return 'document' 58 | elif('image' in mimeType): return 'image' 59 | elif('audio' in mimeType): return 'audio' 60 | elif('video' in mimeType): return 'video' 61 | 62 | 63 | def build_response(status_code, json_content): 64 | return { 65 | 'statusCode': status_code, 66 | "headers": { 67 | "Content-Type": "text/html;charset=UTF-8", 68 | "charset": "UTF-8", 69 | "Access-Control-Allow-Origin": "*" 70 | }, 71 | 'body': json_content 72 | } 73 | 74 | def validate_healthcheck(event, WHATS_VERIFICATION_TOKEN ): 75 | if('queryStringParameters' in event and 'hub.challenge' in event['queryStringParameters']): 76 | print(event['queryStringParameters']) 77 | print("Token challenge") 78 | if(event['queryStringParameters']['hub.verify_token'] == WHATS_VERIFICATION_TOKEN): 79 | print("Token verified") 80 | print(event['queryStringParameters']['hub.challenge']) 81 | response = event['queryStringParameters']['hub.challenge'] 82 | else: 83 | response = '' 84 | else: 85 | print("Not challenge related") 86 | response = ' No key, no fun!' 87 | return response 88 | 89 | def whats_reply(whatsapp_out_lambda,phone, whats_token, phone_id, message, in_reply_to): 90 | 91 | print("WHATSAPP_OUT", in_reply_to, whats_token) 92 | 93 | try: 94 | 95 | response_2 = lambda_client.invoke( 96 | FunctionName = whatsapp_out_lambda, 97 | InvocationType = 'Event' ,#'RequestResponse', 98 | Payload = json.dumps({ 99 | 'phone': phone, 100 | 'whats_token': whats_token, 101 | 'phone_id': phone_id, 102 | 'message': message, 103 | 'in_reply_to': in_reply_to 104 | 105 | }) 106 | ) 107 | 108 | print(f'\nRespuesta:{response_2}') 109 | 110 | return response_2 111 | except ClientError as e: 112 | err = e.response 113 | error = err 114 | print(err.get("Error", {}).get("Code")) 115 | return f"Un error invocando {whatsapp_out_lambda}" -------------------------------------------------------------------------------- /customer-support-bot/layers/langchain.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/layers/langchain.zip -------------------------------------------------------------------------------- /customer-support-bot/layers/project_layers.py: -------------------------------------------------------------------------------- 1 | import json 2 | from constructs import Construct 3 | 4 | from aws_cdk import ( 5 | aws_lambda 6 | 7 | ) 8 | 9 | 10 | class Layers(Construct): 11 | 12 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 13 | super().__init__(scope, construct_id, **kwargs) 14 | 15 | #layer con beautiful soup y requests 16 | bs4_requests = aws_lambda.LayerVersion( 17 | self, "Bs4Requests", code=aws_lambda.Code.from_asset("./layers/bs4_requests.zip"), 18 | compatible_runtimes = [ 19 | aws_lambda.Runtime.PYTHON_3_8, 20 | aws_lambda.Runtime.PYTHON_3_9, 21 | aws_lambda.Runtime.PYTHON_3_10, 22 | aws_lambda.Runtime.PYTHON_3_11], 23 | description = 'BeautifulSoup y Requests') 24 | 25 | self.bs4_requests = bs4_requests 26 | 27 | aiofile_transcribe = aws_lambda.LayerVersion( 28 | self, "aiofile-transcribe", code=aws_lambda.Code.from_asset("./layers/aiofile-amazon-transcribe.zip"), 29 | compatible_runtimes = [ 30 | aws_lambda.Runtime.PYTHON_3_8, 31 | aws_lambda.Runtime.PYTHON_3_9, 32 | aws_lambda.Runtime.PYTHON_3_10, 33 | aws_lambda.Runtime.PYTHON_3_11], 34 | description = 'aiofile y amazon-transcribe', layer_version_name = "aiofile-transcribe-streamig" 35 | ) 36 | 37 | self.aiofile_transcribe = aiofile_transcribe 38 | 39 | common = aws_lambda.LayerVersion( 40 | self, "common-layer", code=aws_lambda.Code.from_asset("./layers/common/"), 41 | compatible_runtimes = [ 42 | aws_lambda.Runtime.PYTHON_3_8, 43 | aws_lambda.Runtime.PYTHON_3_9, 44 | aws_lambda.Runtime.PYTHON_3_10, 45 | aws_lambda.Runtime.PYTHON_3_11], 46 | description = 'librerias adicionales', layer_version_name = "librerias-adicionales" 47 | ) 48 | 49 | self.common = common 50 | 51 | 52 | bedrock = aws_lambda.LayerVersion( 53 | self, "Boto3+Bedrock", code=aws_lambda.Code.from_asset("./layers/boto3.1.28.62.zip"), 54 | compatible_runtimes = [ 55 | aws_lambda.Runtime.PYTHON_3_8, 56 | aws_lambda.Runtime.PYTHON_3_9, 57 | aws_lambda.Runtime.PYTHON_3_10, 58 | aws_lambda.Runtime.PYTHON_3_11], 59 | description = 'Boto3 with Bedrock API') 60 | 61 | 62 | self.bedrock = bedrock 63 | 64 | langchain = aws_lambda.LayerVersion( 65 | self, "Langchain", code=aws_lambda.Code.from_asset("./layers/langchain.zip"), 66 | compatible_runtimes = [ 67 | aws_lambda.Runtime.PYTHON_3_8, 68 | aws_lambda.Runtime.PYTHON_3_9, 69 | aws_lambda.Runtime.PYTHON_3_10, 70 | aws_lambda.Runtime.PYTHON_3_11], 71 | description = 'langchain') 72 | 73 | 74 | self.langchain = langchain 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /customer-support-bot/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest==6.2.5 2 | -------------------------------------------------------------------------------- /customer-support-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | aws-cdk-lib==2.94.0 2 | constructs>=10.0.0,<11.0.0 3 | -------------------------------------------------------------------------------- /customer-support-bot/s3_cloudfront/__init__.py: -------------------------------------------------------------------------------- 1 | from s3_cloudfront.s3_cloudfront_website import S3Deploy 2 | -------------------------------------------------------------------------------- /customer-support-bot/s3_cloudfront/s3_cloudfront_website.py: -------------------------------------------------------------------------------- 1 | from constructs import Construct 2 | from aws_cdk import ( 3 | aws_s3_deployment as s3deploy, 4 | aws_s3 as s3, RemovalPolicy) 5 | 6 | 7 | class S3Deploy(Construct): 8 | def __init__(self, scope: Construct, id: str, files_location, dest_prefix,**kwargs) -> None: 9 | super().__init__(scope, id, **kwargs) 10 | 11 | self.bucket = s3.Bucket(self, "Bucket",access_control=s3.BucketAccessControl.PRIVATE, removal_policy=RemovalPolicy.DESTROY) 12 | 13 | 14 | self.s3deploy = s3deploy.BucketDeployment(self, "Deployment", 15 | sources=[s3deploy.Source.asset(files_location)], 16 | destination_bucket = self.bucket, 17 | retain_on_delete=False, 18 | destination_key_prefix=dest_prefix 19 | ) 20 | 21 | 22 | def deploy(self, id, files_loc, prefix): 23 | deployment = s3deploy.BucketDeployment(self, id, 24 | sources=[s3deploy.Source.asset(files_loc)], 25 | destination_bucket = self.bucket, 26 | retain_on_delete=False, 27 | destination_key_prefix=prefix 28 | ) 29 | return deployment 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /customer-support-bot/source.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The sole purpose of this script is to make the command 4 | rem 5 | rem source .venv/bin/activate 6 | rem 7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. 8 | rem On Windows, this command just runs this batch file (the argument is ignored). 9 | rem 10 | rem Now we don't need to document a Windows command for activating a virtualenv. 11 | 12 | echo Executing .venv\Scripts\activate.bat for you 13 | .venv\Scripts\activate.bat 14 | -------------------------------------------------------------------------------- /customer-support-bot/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/tests/__init__.py -------------------------------------------------------------------------------- /customer-support-bot/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/tests/unit/__init__.py -------------------------------------------------------------------------------- /customer-support-bot/tests/unit/test_customer_support_bot_stack.py: -------------------------------------------------------------------------------- 1 | import aws_cdk as core 2 | import aws_cdk.assertions as assertions 3 | 4 | from customer_support_bot.customer_support_bot_stack import CustomerSupportBotStack 5 | 6 | # example tests. To run these tests, uncomment this file along with the example 7 | # resource in customer_support_bot/customer_support_bot_stack.py 8 | def test_sqs_queue_created(): 9 | app = core.App() 10 | stack = CustomerSupportBotStack(app, "customer-support-bot") 11 | template = assertions.Template.from_stack(stack) 12 | 13 | # template.has_resource_properties("AWS::SQS::Queue", { 14 | # "VisibilityTimeout": 300 15 | # }) 16 | -------------------------------------------------------------------------------- /customer-support-bot/text-to-whatsapp/test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/customer-support-bot/text-to-whatsapp/test.txt -------------------------------------------------------------------------------- /elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": { 8 | "workbench.colorCustomizations": { 9 | "activityBar.background": "#5B0736", 10 | "titleBar.activeBackground": "#80094C", 11 | "titleBar.activeForeground": "#FFFBFD" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /imagen/Kendra_datasources.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/Kendra_datasources.jpg -------------------------------------------------------------------------------- /imagen/QA.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/QA.gif -------------------------------------------------------------------------------- /imagen/code_whisper_gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/code_whisper_gif.gif -------------------------------------------------------------------------------- /imagen/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/diagram.png -------------------------------------------------------------------------------- /imagen/passangerTable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/passangerTable.jpg -------------------------------------------------------------------------------- /imagen/passanger_information.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/passanger_information.gif -------------------------------------------------------------------------------- /imagen/secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/secret.png -------------------------------------------------------------------------------- /imagen/stack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/stack.jpg -------------------------------------------------------------------------------- /imagen/voice_note.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/voice_note.gif -------------------------------------------------------------------------------- /imagen/webhook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/build-on-aws/elevating-customer-support-with-rag-langchain-agent-bedrock-dynamodb-and-kendra/fd860bd81ea1082982197c2ed14ed60a9f0b5bdc/imagen/webhook.png --------------------------------------------------------------------------------