├── .gitallowed ├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ExecutionRole.json ├── LICENSE ├── README.md ├── misc ├── Lex_chat-267x300.jpg ├── PinpointLex.drawio ├── ReInvent2019.md └── architecture.png ├── src ├── .eslintrc.json ├── Sample-AccountBot.json ├── app.js ├── package-lock.json ├── package.json └── tests │ └── unit │ ├── PinpointEventsSample.json │ └── eventData.json └── template.yaml /.gitallowed: -------------------------------------------------------------------------------- 1 | literal "awsAccountId": "12345678901" -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | src/node_modules/ 3 | packaged.yaml 4 | 5 | -------------------------------------------------------------------------------- /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](https://github.com/aws-samples/amazon-pinpoint-lex-bot/issues), or [recently closed](https://github.com/aws-samples/amazon-pinpoint-lex-bot/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), 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 *master* 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'](https://github.com/aws-samples/amazon-pinpoint-lex-bot/labels/help%20wanted) 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](https://github.com/aws-samples/amazon-pinpoint-lex-bot/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /ExecutionRole.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "Logs", 6 | "Effect": "Allow", 7 | "Action": [ 8 | "logs:CreateLogStream", 9 | "logs:CreateLogGroup", 10 | "logs:PutLogEvents" 11 | ], 12 | "Resource": [ 13 | "arn:aws:logs:*:*:*" 14 | ] 15 | }, 16 | { 17 | "Sid": "Pinpoint", 18 | "Effect": "Allow", 19 | "Action": [ 20 | "mobiletargeting:SendMessages" 21 | ], 22 | "Resource": [ 23 | "arn:aws:mobiletargeting:YOURREGION:YOURACCOUNTID:apps/YOURPROJECTORAPPID/*" 24 | ] 25 | }, 26 | { 27 | "Sid": "Lex", 28 | "Effect": "Allow", 29 | "Action": [ 30 | "lex:PostContent", 31 | "lex:PostText" 32 | ], 33 | "Resource": [ 34 | "arn:aws:lex:YOURREGION:YOURACCOUNTID:bot:YOURBOTNAME:*" 35 | ] 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Amazon Pinpoint-Lex Bot 2 | Use Amazon Web Services (AWS) Pinpoint, Lambda, and Lex to let your customers interact with (Lex) chat-bots via 2-way SMS. 3 | 4 | ![Sample SMS conversation screenshot](misc/Lex_chat-267x300.jpg?raw=true) 5 | 6 | With this approach you will be able to create an SMS-based chatbot using Amazon Lex and Amazon Pinpoint. Such a chatbot can help your customers schedule appointments, lookup latest account information, or most common solutions to their troubles. Note that we will be using a generic Lex bot, which means you can reuse the same bot for your other services as well, be it Web or, for example, Amazon Connect/IVR. 7 | 8 | Major benefits: 9 | 1. Customer can use standard SMS 10 | 2. No need for any other means of communication or installation of proprietary apps 11 | 3. No need for a dedicated/separate chatbot 12 | 4. Standard Lex settings and capabilities are supported 13 | 5. Standard Lex security can be easily enabled for further security 14 | 6. Customer phone number context is standard, remains linked to the phone number, allowing for pause-resume/reuse off another application (eg. website, app, etc.) 15 | 7. Lex conversations can be easily stored and reused to enrich customer view 16 | 17 | ## License Summary 18 | This sample code and flow is made available under Open Source - MIT No Attribution License (MIT-0). See the [LICENSE](/LICENSE) file. 19 | 20 | ### Architecture 21 | Upon an SMS request from the user, AWS Pinpoint publishes to AWS SNS queue. A custom AWS Lambda function detects a new event and redirects information, specifically the originating phone number and message, to Lex. Lex uses the phone number to keep context of the conversation, sends response back, and Lambda sends that response over to the customer. Once first loop completes, the customer can continue this back-and-forth, just like they would with the chat-bot in Alexa or on a website. 22 | 23 | ![Architecture Diagram](misc/architecture.png?raw=true) 24 | 25 | ### Prerequisites 26 | This flow requires that you have an AWS Account with AWS Pinpoint project and access to Lex. 27 | No extra configuration is required - you can start right out of the gate. 28 | 29 | ### Repository content 30 | Main files: 31 | ```bash 32 | . 33 | ├── README.MD <-- This instructions file 34 | ├── template.yaml <-- SAM template. Make sure to edit manually first! 35 | ├── ExecutionRole.json <-- Sample IAM policy (also part of the SAM template). Make sure to edit manually first! 36 | ├── src <-- Actual source code 37 | │ └── app.js <-- Lambda function code 38 | │ └── Sample-AccountBot.json <-- Sample Lex bot you can reuse for testing your flow for the fist time. 39 | │ └── package.json <-- NodeJS dependencies and scripts 40 | │ └── tests <-- Unit tests 41 | │ └── unit 42 | │ └── eventData.json <-- Sample payload that mimics the SMS received from customer (from Pinpoint via SNS). Make sure to edit manually first! 43 | ``` 44 | 45 | ### Setup 46 | > Below is a high-level how-to, but you should feel free to follow the more expanded version of the walk-through with screenshots @ https://aws.amazon.com/blogs/messaging-and-targeting/create-an-sms-chatbox-with-amazon-pinpoint-and-lex/ 47 | #### Step 1: Pinpoint 48 | 1. Create the new Pinpoint project and request a new long-code (the phone number through which all of the interactions will take place). See [steps 1.1 and 1.2 of this tutorial](https://docs.aws.amazon.com/pinpoint/latest/developerguide/tutorials-two-way-sms-part-1.html). Alternatively, you can simply reuse an existing project and phone number (aka long- or short-code). 49 | 2. Enable two-way SMS by clicking on the long-code of choice under the "SMS and voice" Settings and enabling the 2-way with the SNS topic defined. See [step 1.3 of the same tutorial](https://docs.aws.amazon.com/pinpoint/latest/developerguide/tutorials-two-way-sms-part-1.html). Take note of this SNS topic (new or existing). 50 | If this number will be used for outgoing notifications, make sure you handle unsubscribe (aka STOP) requests before going to production. 51 | 3. Optionally add a temporary email subscription to the SNS topic to passively and proactively monitor it during debugging. 52 | 4. Send SMS through and confirm SNS event occurs. 53 | #### Step 2: Lex 54 | 1. Create the new Lex bot or identify the one you want to reuse. 55 | There are no special considerations in our implementation, even one intent should be sufficient. Feel free to use one of the Demo Lex bots as a starting point, if you don't have one already. 56 | As with any bot, try to keep messages on the shorter side and avoid special characters. 57 | #### Step 3: Permissions/IAM 58 | 1. Add new Lambda execution role with limited permissions to Pinpoint (to respond to the customer), Lex (to actually communicate with the bot), and CloudWatch Logs (for basic logging and debugging). 59 | Feel free to either reuse ExecutionRole.json provided, copy YAML portion from template.yaml if you prefer, or use Managed policies to build out the role. 60 | Remember that AWS Policies are always designed to only allow what is absolutely necessary. As you expand your application, you may need to add new (or remove) resources and functions you intend to call. You may also want to add X-Ray permissions down the line for full tracing support. 61 | #### Step 4: Lambda 62 | 1. Add the new Lambda function (either upload the included Lambda directly or copy-paste). 63 | 2. Set Environment variables - these are dynamic configuration parameters that you will be able to switch/change in production. 64 | * PinpointApplicationId The ID of the Pinpoint project that you created earlier. 65 | * BotName The name of the Lex bot that you created earlier. 66 | * BotNumber The Pinpoint number Lex Bot should use (if you have more than one). Alternatively, consider checking which number customer sent the request to first. 67 | * BotAlias Latest (or whichever alias you gave the bot) 68 | * Region The AWS Region that you created the Amazon Pinpoint project and Lex bot in. 69 | 3. Associate Lambda with SNS. 70 | 4. Save. 71 | 5. Configure a new Lambda Test event - use included eventData.json for the sample payload, but remember to change the phone number. 72 | #### Step 5: Run and Confirm 73 | 1. Run test and confirm your event produces the SMS back to the number you specified or check console for errors. 74 | 2. Send a manual SMS to your Pinpoint number and confirm your event goes through SNS and you receive the bot response via SMS. 75 | 3. Feel free to engage the bot and try out various scenarios. -------------------------------------------------------------------------------- /misc/Lex_chat-267x300.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-pinpoint-lex-bot/de480a300ef8736e0db12d0386cadd7bad841e2f/misc/Lex_chat-267x300.jpg -------------------------------------------------------------------------------- /misc/PinpointLex.drawio: -------------------------------------------------------------------------------- 1 | 7VrZduI4EP0aHuF4AUMeA9lmmu7hhD6TzKOwha2ObHlkmSVfP5ItL7INJB1DmBzCQ6Bc2qpu1S0VdMyJv7mnIPS+EwfijqE5m4550zEMXbP6/J+QbFPJlTlKBS5FjlQqBHP0CrORUhojB0aKIiMEMxSqQpsEAbSZIgOUkrWqtiRYXTUErlxRKwRzG2BYU3tCDvNS6WhQ0n6AyPWylXVNPvFBpiwFkQccsi6JzNuOOaGEsPSdv5lALIyX2SUdd7fjab4xCgP2lgHd16kVUeA9D2Z/br+NnsKHv9yubqTTrACO5Ynlbtk2MwF0uEXkR0KZR1wSAHxbSMeUxIEDxToa/1ToTAkJuVDnwl+Qsa10L4gZ4SKP+Vg+rZ9FHk+sXRLIk91D4kNGt1yBQgwYWqneAtLpbq6XD50RxJcwNAlQM3OXhKfR7/cG6iQRiakN5biyfQ9MZWaOzyZigLqQ1Sbib0onKkSJ+97hSsOqufLnmnTXQJhp/n3eEfuxMLfveEH5O5clhk8lDlplooAwtEQ2tyoJ9o7huywNa5hpzTUmJGBww3aNqUAtUVWQQWGEXsEiURDgCoX5EoMOxp3BDZcAjNyAC2yOHUi5YAUp4/vH1/KBjxwngSkGC4jHwH5xE8BOCCY0WddcJn9cZcm3m2HdqKNyfwzxdeGm05CV5P6VwFdQLEd1tR6H0UiBkZzpd3G+bRxAlssIHgWFo/POJ2kw79n/8HPyjm7W8s6R08VVzVEosImPAjdLF18hNjM4thKamjlUyeJjoXn8YBweDsa8KhEOdEDk5WFXcnTEKHmBmU8CEgiPLRHGJTcNNPHKPDkjEUoIpMH304rCgjBG/AZwMBHtYxIzjAK+elbgaU3A4ucIxZH8jSsK0R43KrJhL44gjXoc134cSE6L9uWHGlB2AsKwTDWCZUCviypxKGtfr1QgDq9240Nx/3t9rfcbnF2j5Ls4mekAK9eGJZXAT4pcF9K3FwSnz/sHUkRzUclvFEmqTUWh8w0+eC+r54dVNPMAslyNdfvHIYF+pWIcVirGt5aefePARO1xSaN59Br0rn3wmoBmhoIwX7aMhsawFv4r5RT+uhPbGPOYdhAsnskUpOYlhSvU5JRPpGS4XQkpJ6VqQsozVS39lDC49hCD8xAkZcaaJ6MMlyloda2C0yTBcnXBvOaN2ZDLwDrq90JKnNhmf9hii+OQpm8qOpmxW8pw1RplUEtxI62e4nRd2x0Jb81xjTgzd+Ns/qNesVwg1j7EomPxZ35dPoQu7VjoOo+rS8RzNbsWnSvhfAyiCNmZ+A7hd91wdnOZynnd2fBv8x99wyxyv3p+xPDX03Wmd+yb0GBU4a5q9thBgm1xV/0epNQ/Je9b/8aiV5dEVjdK/HfNFXQ93BQPqzWRUP79WYo6DfgiyINFFCaPtVLNlS7R5rJd/uQRRiEvluGBhdSab0zEqj+gSxiSDaTzvkWqebM5sPYmiw9fLLWeZlnyonYWN8l9SaPMvE+iozgF/sIBF+Y9AfPi1NStkG+/evP4dPLV67XdZ7Dv4WzwVprNaEzh2U/sOA4qHcfh0dqNzeao8yxPEi45937j+5khR3IbPcdzbjnuhf2lF/ClegFVwugOep/dDDDqSPt/M0bDxWxviB2bMaxKV1G3TnszM+ptxUd+om2n6Uvp4rryRWgkh3cLNwxdH37wa+R2v6tqajdceshfkTfqPWTrdLTRiDNjN84uPeRLD/mD6Grok2TomvIzXdB1gj6JwE4b6LKqnekjoot/LH4JmlJq8Xta8/Y/ -------------------------------------------------------------------------------- /misc/ReInvent2019.md: -------------------------------------------------------------------------------- 1 | ## Amazon Pinpoint-Lex Bot: ReInvent 2019 2 | Materials for the 2019 re:Invent Pinpoint Builder Session - Build and Deploy Your Own 2 Way Text Chatbot for re:Invent 2019. 3 | Use https://github.com/Mottie/GitHub-userscripts/wiki/GitHub-copy-code-snippet to quickly copy the code. 4 | 5 | ## License Summary 6 | This sample code and flow is made available under Open Source - MIT No Attribution License (MIT-0). See the [LICENSE](../LICENSE) file. 7 | 8 | ### Setup 9 | > Quick setup below, but you should follow the [expanded version](https://aws.amazon.com/blogs/messaging-and-targeting/create-an-sms-chatbox-with-amazon-pinpoint-and-lex/). 10 | #### Step 3: Permissions/IAM 11 | ```JSON 12 | { 13 | "Version": "2012-10-17", 14 | "Statement": [ 15 | { 16 | "Sid": "Logs", 17 | "Effect": "Allow", 18 | "Action": [ 19 | "logs:CreateLogStream", 20 | "logs:CreateLogGroup", 21 | "logs:PutLogEvents" 22 | ], 23 | "Resource": [ 24 | "arn:aws:logs:*:*:*" 25 | ] 26 | }, 27 | { 28 | "Sid": "Pinpoint", 29 | "Effect": "Allow", 30 | "Action": [ 31 | "mobiletargeting:SendMessages" 32 | ], 33 | "Resource": [ 34 | "arn:aws:mobiletargeting:YOURREGION:YOURACCOUNTID:apps/YOURPROJECTORAPPID/*" 35 | ] 36 | }, 37 | { 38 | "Sid": "Lex", 39 | "Effect": "Allow", 40 | "Action": [ 41 | "lex:PostContent", 42 | "lex:PostText" 43 | ], 44 | "Resource": [ 45 | "arn:aws:lex:YOURREGION:YOURACCOUNTID:bot:YOURBOTNAME:*" 46 | ] 47 | } 48 | ] 49 | } 50 | ``` 51 | #### Step 4: Lambda 52 | ```javascript 53 | const AWS = require('aws-sdk'); 54 | AWS.config.update({ 55 | region: process.env.Region 56 | }); 57 | const pinpoint = new AWS.Pinpoint(); 58 | const lex = new AWS.LexRuntime(); 59 | 60 | var AppId = process.env.PinpointApplicationId; 61 | var BotName = process.env.BotName; 62 | var BotAlias = process.env.BotAlias; 63 | 64 | exports.handler = (event, context) => { 65 | /* 66 | * Event info is sent via the SNS subscription: https://console.aws.amazon.com/sns/home 67 | * 68 | * - PinpointApplicationId is your Pinpoint Project ID. 69 | * - BotName is your Lex Bot name. 70 | * - BotAlias is your Lex Bot alias (aka Lex function/flow). 71 | */ 72 | console.log('Received event: ' + event.Records[0].Sns.Message); 73 | var message = JSON.parse(event.Records[0].Sns.Message); 74 | var customerPhoneNumber = message.originationNumber; 75 | var chatbotPhoneNumber = message.destinationNumber; 76 | var response = message.messageBody.toLowerCase(); 77 | var userId = customerPhoneNumber.replace("+1", ""); 78 | 79 | var params = { 80 | botName: BotName, 81 | botAlias: BotAlias, 82 | inputText: response, 83 | userId: userId 84 | }; 85 | response = lex.postText(params, function (err, data) { 86 | if (err) { 87 | console.log(err, err.stack); 88 | //return null; 89 | } 90 | else if (data != null && data.message != null) { 91 | console.log("Lex response: " + data.message); 92 | sendResponse(customerPhoneNumber, chatbotPhoneNumber, response.response.data.message); 93 | } 94 | else { 95 | console.log("Lex did not send a message back!"); 96 | } 97 | }); 98 | } 99 | 100 | function sendResponse(custPhone, botPhone, response) { 101 | var paramsSMS = { 102 | ApplicationId: AppId, 103 | MessageRequest: { 104 | Addresses: { 105 | [custPhone]: { 106 | ChannelType: 'SMS' 107 | } 108 | }, 109 | MessageConfiguration: { 110 | SMSMessage: { 111 | Body: response, 112 | MessageType: "TRANSACTIONAL", 113 | OriginationNumber: botPhone 114 | } 115 | } 116 | } 117 | }; 118 | pinpoint.sendMessages(paramsSMS, function (err, data) { 119 | if (err) { 120 | console.log("An error occurred.\n"); 121 | console.log(err, err.stack); 122 | } 123 | else if (data['MessageResponse']['Result'][custPhone]['DeliveryStatus'] != "SUCCESSFUL") { 124 | console.log("Failed to send SMS response:"); 125 | console.log(data['MessageResponse']['Result']); 126 | } 127 | else { 128 | console.log("Successfully sent response via SMS from " + botPhone + " to " + custPhone); 129 | } 130 | }); 131 | } 132 | ``` 133 | Remember to set: 134 | 135 | | Key | Value | 136 | | ------------- | ------------- | 137 | | PinpointApplicationId | The name of the Pinpoint project that you created earlier. | 138 | | BotName | The name of the Lex bot that you created earlier. | 139 | | BotAlias | Latest | 140 | | Region | The AWS Region that you created the Amazon Pinpoint project and Lex bot in. | 141 | -------------------------------------------------------------------------------- /misc/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-pinpoint-lex-bot/de480a300ef8736e0db12d0386cadd7bad841e2f/misc/architecture.png -------------------------------------------------------------------------------- /src/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "globals": { 8 | "Atomics": "readonly", 9 | "SharedArrayBuffer": "readonly" 10 | }, 11 | "parserOptions": { 12 | "ecmaVersion": 2018, 13 | "sourceType": "module" 14 | }, 15 | "rules": { 16 | } 17 | } -------------------------------------------------------------------------------- /src/Sample-AccountBot.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "schemaVersion": "1.0", 4 | "importType": "LEX", 5 | "importFormat": "JSON" 6 | }, 7 | "resource": { 8 | "name": "AccountBot", 9 | "version": "4", 10 | "intents": [ 11 | { 12 | "rejectionStatement": { 13 | "messages": [ 14 | { 15 | "contentType": "PlainText", 16 | "content": "Okay, cancelling the entry. Please retry from scratch." 17 | } 18 | ] 19 | }, 20 | "name": "AccountLookup", 21 | "version": "3", 22 | "fulfillmentActivity": { 23 | "type": "ReturnIntent" 24 | }, 25 | "sampleUtterances": [ 26 | "Check my account balance", 27 | "One" 28 | ], 29 | "slots": [ 30 | { 31 | "sampleUtterances": [], 32 | "slotType": "AMAZON.NUMBER", 33 | "slotConstraint": "Required", 34 | "valueElicitationPrompt": { 35 | "messages": [ 36 | { 37 | "contentType": "PlainText", 38 | "content": "Please enter your account number." 39 | } 40 | ], 41 | "responseCard": "{\"version\":1,\"contentType\":\"application/vnd.amazonaws.card.generic\"}", 42 | "maxAttempts": 3 43 | }, 44 | "priority": 1, 45 | "name": "AccountNumber" 46 | } 47 | ], 48 | "followUpPrompt": { 49 | "prompt": { 50 | "messages": [ 51 | { 52 | "groupNumber": 1, 53 | "contentType": "PlainText", 54 | "content": "Thank you, I understood {AccountNumber} successfully and will process accordingly. If this is not what you wanted to do, please respond with a NO and the processing will be cancelled." 55 | } 56 | ], 57 | "maxAttempts": 3 58 | }, 59 | "rejectionStatement": { 60 | "messages": [ 61 | { 62 | "groupNumber": 1, 63 | "contentType": "PlainText", 64 | "content": "Sorry it was not what you wanted to see. Please retry from scratch." 65 | } 66 | ] 67 | } 68 | }, 69 | "confirmationPrompt": { 70 | "messages": [ 71 | { 72 | "contentType": "PlainText", 73 | "content": "Are you sure the number is {AccountNumber}?" 74 | } 75 | ], 76 | "maxAttempts": 3 77 | } 78 | } 79 | ], 80 | "voiceId": "Joanna", 81 | "childDirected": false, 82 | "locale": "en-US", 83 | "idleSessionTTLInSeconds": 60, 84 | "clarificationPrompt": { 85 | "messages": [ 86 | { 87 | "contentType": "PlainText", 88 | "content": "Possible requests are a simple '1' or 'Check my account balance', but we will try our best to guess as well." 89 | } 90 | ], 91 | "maxAttempts": 5 92 | }, 93 | "abortStatement": { 94 | "messages": [ 95 | { 96 | "contentType": "PlainText", 97 | "content": "Sorry, I could not understand. Please try again later or reach out directly to our customer support @ 1-800-YOUKNOW." 98 | } 99 | ] 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | * software and associated documentation files (the "Software"), to deal in the Software 6 | * without restriction, including without limitation the rights to use, copy, modify, 7 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 11 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 12 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 13 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 14 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 15 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | */ 17 | const AWS = require('aws-sdk'); 18 | AWS.config.update({ 19 | region: process.env.region 20 | }); 21 | const pinpoint = new AWS.Pinpoint(); 22 | const lex = new AWS.LexRuntime(); 23 | 24 | var AppId = process.env.PinpointApplicationId; 25 | var BotName = process.env.BotName; 26 | var BotAlias = process.env.BotAlias; 27 | var BotNumber = process.env.BotNumber; 28 | 29 | // eslint-disable-next-line no-unused-vars 30 | exports.handler = (event, context) => { 31 | /* 32 | * Event info is sent via the SNS subscription: https://console.aws.amazon.com/sns/home 33 | * 34 | * - PinpointApplicationId is your Pinpoint Project ID. 35 | * - BotName is your Lex Bot name. 36 | * - BotAlias is your Lex Bot alias (aka Lex function/flow). 37 | * - BotNumber is your Pinpoint number Lex Bot should use (if you have more than one). 38 | * Alternatively, consider checking which number customer sent the request on. 39 | */ 40 | console.log('Received event: ' + event.Records[0].Sns.Message); 41 | var message = JSON.parse(event.Records[0].Sns.Message); 42 | var originationNumber = message.originationNumber; 43 | var response = message.messageBody.toLowerCase(); 44 | var userId = originationNumber.replace("+1", ""); 45 | 46 | var params = { 47 | botName: BotName, 48 | botAlias: BotAlias, 49 | inputText: response, 50 | userId: userId 51 | }; 52 | response = lex.postText(params, function (err, data) { 53 | if (err) { 54 | console.log(err, err.stack); 55 | //return null; 56 | } 57 | else if (data != null && data.message != null) { 58 | console.log("Lex response: " + data.message); 59 | sendResponse(originationNumber, BotNumber, response.response.data.message); 60 | } 61 | else { 62 | console.log("Lex did not send a message back!"); 63 | } 64 | }); 65 | } 66 | 67 | function sendResponse(phone, botPhone, response) { 68 | var paramsSMS = { 69 | ApplicationId: AppId, 70 | MessageRequest: { 71 | Addresses: { 72 | [phone]: { 73 | ChannelType: 'SMS' 74 | } 75 | }, 76 | MessageConfiguration: { 77 | SMSMessage: { 78 | Body: response, 79 | MessageType: "TRANSACTIONAL", 80 | OriginationNumber: botPhone 81 | } 82 | } 83 | } 84 | }; 85 | pinpoint.sendMessages(paramsSMS, function (err, data) { 86 | if (err) { 87 | console.log("An error occurred.\n"); 88 | console.log(err, err.stack); 89 | } 90 | else if (data['MessageResponse']['Result'][phone]['DeliveryStatus'] != "SUCCESSFUL") { 91 | console.log("Failed to send SMS response:"); 92 | console.log(data['MessageResponse']['Result']); 93 | } 94 | else { 95 | console.log("Successfully sent response via SMS from " + botPhone + " to " + phone); 96 | } 97 | }); 98 | } -------------------------------------------------------------------------------- /src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amazon-pinpoint-lex-bot", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.8.3", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", 10 | "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.8.3" 14 | } 15 | }, 16 | "@babel/highlight": { 17 | "version": "7.8.3", 18 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", 19 | "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", 20 | "dev": true, 21 | "requires": { 22 | "chalk": "^2.0.0", 23 | "esutils": "^2.0.2", 24 | "js-tokens": "^4.0.0" 25 | } 26 | }, 27 | "@types/color-name": { 28 | "version": "1.1.1", 29 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 30 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", 31 | "dev": true 32 | }, 33 | "acorn": { 34 | "version": "7.1.1", 35 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", 36 | "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", 37 | "dev": true 38 | }, 39 | "acorn-jsx": { 40 | "version": "5.2.0", 41 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", 42 | "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", 43 | "dev": true 44 | }, 45 | "ajv": { 46 | "version": "6.12.6", 47 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 48 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 49 | "dev": true, 50 | "requires": { 51 | "fast-deep-equal": "^3.1.1", 52 | "fast-json-stable-stringify": "^2.0.0", 53 | "json-schema-traverse": "^0.4.1", 54 | "uri-js": "^4.2.2" 55 | } 56 | }, 57 | "ansi-escapes": { 58 | "version": "4.3.1", 59 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", 60 | "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", 61 | "dev": true, 62 | "requires": { 63 | "type-fest": "^0.11.0" 64 | }, 65 | "dependencies": { 66 | "type-fest": { 67 | "version": "0.11.0", 68 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", 69 | "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", 70 | "dev": true 71 | } 72 | } 73 | }, 74 | "ansi-regex": { 75 | "version": "5.0.1", 76 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 77 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 78 | "dev": true 79 | }, 80 | "ansi-styles": { 81 | "version": "3.2.1", 82 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 83 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 84 | "dev": true, 85 | "requires": { 86 | "color-convert": "^1.9.0" 87 | } 88 | }, 89 | "argparse": { 90 | "version": "1.0.10", 91 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 92 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 93 | "dev": true, 94 | "requires": { 95 | "sprintf-js": "~1.0.2" 96 | } 97 | }, 98 | "astral-regex": { 99 | "version": "1.0.0", 100 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 101 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 102 | "dev": true 103 | }, 104 | "available-typed-arrays": { 105 | "version": "1.0.5", 106 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", 107 | "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" 108 | }, 109 | "aws-sdk": { 110 | "version": "2.1354.0", 111 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", 112 | "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", 113 | "requires": { 114 | "buffer": "4.9.2", 115 | "events": "1.1.1", 116 | "ieee754": "1.1.13", 117 | "jmespath": "0.16.0", 118 | "querystring": "0.2.0", 119 | "sax": "1.2.1", 120 | "url": "0.10.3", 121 | "util": "^0.12.4", 122 | "uuid": "8.0.0", 123 | "xml2js": "0.5.0" 124 | } 125 | }, 126 | "balanced-match": { 127 | "version": "1.0.0", 128 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 129 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 130 | "dev": true 131 | }, 132 | "base64-js": { 133 | "version": "1.5.1", 134 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 135 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 136 | }, 137 | "brace-expansion": { 138 | "version": "1.1.11", 139 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 140 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 141 | "dev": true, 142 | "requires": { 143 | "balanced-match": "^1.0.0", 144 | "concat-map": "0.0.1" 145 | } 146 | }, 147 | "buffer": { 148 | "version": "4.9.2", 149 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 150 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 151 | "requires": { 152 | "base64-js": "^1.0.2", 153 | "ieee754": "^1.1.4", 154 | "isarray": "^1.0.0" 155 | } 156 | }, 157 | "call-bind": { 158 | "version": "1.0.2", 159 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 160 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 161 | "requires": { 162 | "function-bind": "^1.1.1", 163 | "get-intrinsic": "^1.0.2" 164 | } 165 | }, 166 | "callsites": { 167 | "version": "3.1.0", 168 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 169 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 170 | "dev": true 171 | }, 172 | "chalk": { 173 | "version": "2.4.2", 174 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 175 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 176 | "dev": true, 177 | "requires": { 178 | "ansi-styles": "^3.2.1", 179 | "escape-string-regexp": "^1.0.5", 180 | "supports-color": "^5.3.0" 181 | } 182 | }, 183 | "chardet": { 184 | "version": "0.7.0", 185 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 186 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 187 | "dev": true 188 | }, 189 | "cli-cursor": { 190 | "version": "3.1.0", 191 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 192 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", 193 | "dev": true, 194 | "requires": { 195 | "restore-cursor": "^3.1.0" 196 | } 197 | }, 198 | "cli-width": { 199 | "version": "2.2.0", 200 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 201 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 202 | "dev": true 203 | }, 204 | "color-convert": { 205 | "version": "1.9.3", 206 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 207 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 208 | "dev": true, 209 | "requires": { 210 | "color-name": "1.1.3" 211 | } 212 | }, 213 | "color-name": { 214 | "version": "1.1.3", 215 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 216 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 217 | "dev": true 218 | }, 219 | "concat-map": { 220 | "version": "0.0.1", 221 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 222 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 223 | "dev": true 224 | }, 225 | "cross-spawn": { 226 | "version": "6.0.5", 227 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 228 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 229 | "dev": true, 230 | "requires": { 231 | "nice-try": "^1.0.4", 232 | "path-key": "^2.0.1", 233 | "semver": "^5.5.0", 234 | "shebang-command": "^1.2.0", 235 | "which": "^1.2.9" 236 | }, 237 | "dependencies": { 238 | "semver": { 239 | "version": "5.7.1", 240 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 241 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 242 | "dev": true 243 | } 244 | } 245 | }, 246 | "debug": { 247 | "version": "4.1.1", 248 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 249 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 250 | "dev": true, 251 | "requires": { 252 | "ms": "^2.1.1" 253 | } 254 | }, 255 | "deep-is": { 256 | "version": "0.1.3", 257 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 258 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 259 | "dev": true 260 | }, 261 | "doctrine": { 262 | "version": "3.0.0", 263 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 264 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 265 | "dev": true, 266 | "requires": { 267 | "esutils": "^2.0.2" 268 | } 269 | }, 270 | "emoji-regex": { 271 | "version": "8.0.0", 272 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 273 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 274 | "dev": true 275 | }, 276 | "escape-string-regexp": { 277 | "version": "1.0.5", 278 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 279 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 280 | "dev": true 281 | }, 282 | "eslint": { 283 | "version": "6.8.0", 284 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", 285 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", 286 | "dev": true, 287 | "requires": { 288 | "@babel/code-frame": "^7.0.0", 289 | "ajv": "^6.10.0", 290 | "chalk": "^2.1.0", 291 | "cross-spawn": "^6.0.5", 292 | "debug": "^4.0.1", 293 | "doctrine": "^3.0.0", 294 | "eslint-scope": "^5.0.0", 295 | "eslint-utils": "^1.4.3", 296 | "eslint-visitor-keys": "^1.1.0", 297 | "espree": "^6.1.2", 298 | "esquery": "^1.0.1", 299 | "esutils": "^2.0.2", 300 | "file-entry-cache": "^5.0.1", 301 | "functional-red-black-tree": "^1.0.1", 302 | "glob-parent": "^5.0.0", 303 | "globals": "^12.1.0", 304 | "ignore": "^4.0.6", 305 | "import-fresh": "^3.0.0", 306 | "imurmurhash": "^0.1.4", 307 | "inquirer": "^7.0.0", 308 | "is-glob": "^4.0.0", 309 | "js-yaml": "^3.13.1", 310 | "json-stable-stringify-without-jsonify": "^1.0.1", 311 | "levn": "^0.3.0", 312 | "lodash": "^4.17.14", 313 | "minimatch": "^3.0.4", 314 | "mkdirp": "^0.5.1", 315 | "natural-compare": "^1.4.0", 316 | "optionator": "^0.8.3", 317 | "progress": "^2.0.0", 318 | "regexpp": "^2.0.1", 319 | "semver": "^6.1.2", 320 | "strip-ansi": "^5.2.0", 321 | "strip-json-comments": "^3.0.1", 322 | "table": "^5.2.3", 323 | "text-table": "^0.2.0", 324 | "v8-compile-cache": "^2.0.3" 325 | } 326 | }, 327 | "eslint-scope": { 328 | "version": "5.0.0", 329 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", 330 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", 331 | "dev": true, 332 | "requires": { 333 | "esrecurse": "^4.1.0", 334 | "estraverse": "^4.1.1" 335 | } 336 | }, 337 | "eslint-utils": { 338 | "version": "1.4.3", 339 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 340 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 341 | "dev": true, 342 | "requires": { 343 | "eslint-visitor-keys": "^1.1.0" 344 | } 345 | }, 346 | "eslint-visitor-keys": { 347 | "version": "1.1.0", 348 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 349 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", 350 | "dev": true 351 | }, 352 | "espree": { 353 | "version": "6.2.1", 354 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", 355 | "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", 356 | "dev": true, 357 | "requires": { 358 | "acorn": "^7.1.1", 359 | "acorn-jsx": "^5.2.0", 360 | "eslint-visitor-keys": "^1.1.0" 361 | } 362 | }, 363 | "esprima": { 364 | "version": "4.0.1", 365 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 366 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 367 | "dev": true 368 | }, 369 | "esquery": { 370 | "version": "1.1.0", 371 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", 372 | "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", 373 | "dev": true, 374 | "requires": { 375 | "estraverse": "^4.0.0" 376 | } 377 | }, 378 | "esrecurse": { 379 | "version": "4.2.1", 380 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 381 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 382 | "dev": true, 383 | "requires": { 384 | "estraverse": "^4.1.0" 385 | } 386 | }, 387 | "estraverse": { 388 | "version": "4.3.0", 389 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 390 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 391 | "dev": true 392 | }, 393 | "esutils": { 394 | "version": "2.0.3", 395 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 396 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 397 | "dev": true 398 | }, 399 | "events": { 400 | "version": "1.1.1", 401 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 402 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" 403 | }, 404 | "external-editor": { 405 | "version": "3.1.0", 406 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 407 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 408 | "dev": true, 409 | "requires": { 410 | "chardet": "^0.7.0", 411 | "iconv-lite": "^0.4.24", 412 | "tmp": "^0.0.33" 413 | } 414 | }, 415 | "fast-deep-equal": { 416 | "version": "3.1.1", 417 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 418 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", 419 | "dev": true 420 | }, 421 | "fast-json-stable-stringify": { 422 | "version": "2.1.0", 423 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 424 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 425 | "dev": true 426 | }, 427 | "fast-levenshtein": { 428 | "version": "2.0.6", 429 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 430 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 431 | "dev": true 432 | }, 433 | "figures": { 434 | "version": "3.2.0", 435 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", 436 | "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", 437 | "dev": true, 438 | "requires": { 439 | "escape-string-regexp": "^1.0.5" 440 | } 441 | }, 442 | "file-entry-cache": { 443 | "version": "5.0.1", 444 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 445 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 446 | "dev": true, 447 | "requires": { 448 | "flat-cache": "^2.0.1" 449 | } 450 | }, 451 | "flat-cache": { 452 | "version": "2.0.1", 453 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 454 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 455 | "dev": true, 456 | "requires": { 457 | "flatted": "^2.0.0", 458 | "rimraf": "2.6.3", 459 | "write": "1.0.3" 460 | } 461 | }, 462 | "flatted": { 463 | "version": "2.0.1", 464 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 465 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 466 | "dev": true 467 | }, 468 | "for-each": { 469 | "version": "0.3.3", 470 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 471 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 472 | "requires": { 473 | "is-callable": "^1.1.3" 474 | } 475 | }, 476 | "fs.realpath": { 477 | "version": "1.0.0", 478 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 479 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 480 | "dev": true 481 | }, 482 | "function-bind": { 483 | "version": "1.1.1", 484 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 485 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 486 | }, 487 | "functional-red-black-tree": { 488 | "version": "1.0.1", 489 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 490 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 491 | "dev": true 492 | }, 493 | "get-intrinsic": { 494 | "version": "1.2.0", 495 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", 496 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", 497 | "requires": { 498 | "function-bind": "^1.1.1", 499 | "has": "^1.0.3", 500 | "has-symbols": "^1.0.3" 501 | } 502 | }, 503 | "glob": { 504 | "version": "7.1.6", 505 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 506 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 507 | "dev": true, 508 | "requires": { 509 | "fs.realpath": "^1.0.0", 510 | "inflight": "^1.0.4", 511 | "inherits": "2", 512 | "minimatch": "^3.0.4", 513 | "once": "^1.3.0", 514 | "path-is-absolute": "^1.0.0" 515 | } 516 | }, 517 | "glob-parent": { 518 | "version": "5.1.2", 519 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 520 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 521 | "dev": true, 522 | "requires": { 523 | "is-glob": "^4.0.1" 524 | } 525 | }, 526 | "globals": { 527 | "version": "12.4.0", 528 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", 529 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", 530 | "dev": true, 531 | "requires": { 532 | "type-fest": "^0.8.1" 533 | } 534 | }, 535 | "gopd": { 536 | "version": "1.0.1", 537 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 538 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 539 | "requires": { 540 | "get-intrinsic": "^1.1.3" 541 | } 542 | }, 543 | "has": { 544 | "version": "1.0.3", 545 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 546 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 547 | "requires": { 548 | "function-bind": "^1.1.1" 549 | } 550 | }, 551 | "has-flag": { 552 | "version": "3.0.0", 553 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 554 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 555 | "dev": true 556 | }, 557 | "has-symbols": { 558 | "version": "1.0.3", 559 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 560 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 561 | }, 562 | "has-tostringtag": { 563 | "version": "1.0.0", 564 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 565 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 566 | "requires": { 567 | "has-symbols": "^1.0.2" 568 | } 569 | }, 570 | "iconv-lite": { 571 | "version": "0.4.24", 572 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 573 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 574 | "dev": true, 575 | "requires": { 576 | "safer-buffer": ">= 2.1.2 < 3" 577 | } 578 | }, 579 | "ieee754": { 580 | "version": "1.1.13", 581 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 582 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 583 | }, 584 | "ignore": { 585 | "version": "4.0.6", 586 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 587 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 588 | "dev": true 589 | }, 590 | "import-fresh": { 591 | "version": "3.2.1", 592 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 593 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 594 | "dev": true, 595 | "requires": { 596 | "parent-module": "^1.0.0", 597 | "resolve-from": "^4.0.0" 598 | } 599 | }, 600 | "imurmurhash": { 601 | "version": "0.1.4", 602 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 603 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 604 | "dev": true 605 | }, 606 | "inflight": { 607 | "version": "1.0.6", 608 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 609 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 610 | "dev": true, 611 | "requires": { 612 | "once": "^1.3.0", 613 | "wrappy": "1" 614 | } 615 | }, 616 | "inherits": { 617 | "version": "2.0.4", 618 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 619 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 620 | }, 621 | "inquirer": { 622 | "version": "7.1.0", 623 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", 624 | "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", 625 | "dev": true, 626 | "requires": { 627 | "ansi-escapes": "^4.2.1", 628 | "chalk": "^3.0.0", 629 | "cli-cursor": "^3.1.0", 630 | "cli-width": "^2.0.0", 631 | "external-editor": "^3.0.3", 632 | "figures": "^3.0.0", 633 | "lodash": "^4.17.15", 634 | "mute-stream": "0.0.8", 635 | "run-async": "^2.4.0", 636 | "rxjs": "^6.5.3", 637 | "string-width": "^4.1.0", 638 | "strip-ansi": "^6.0.0", 639 | "through": "^2.3.6" 640 | }, 641 | "dependencies": { 642 | "ansi-styles": { 643 | "version": "4.2.1", 644 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 645 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 646 | "dev": true, 647 | "requires": { 648 | "@types/color-name": "^1.1.1", 649 | "color-convert": "^2.0.1" 650 | } 651 | }, 652 | "chalk": { 653 | "version": "3.0.0", 654 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", 655 | "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", 656 | "dev": true, 657 | "requires": { 658 | "ansi-styles": "^4.1.0", 659 | "supports-color": "^7.1.0" 660 | } 661 | }, 662 | "color-convert": { 663 | "version": "2.0.1", 664 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 665 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 666 | "dev": true, 667 | "requires": { 668 | "color-name": "~1.1.4" 669 | } 670 | }, 671 | "color-name": { 672 | "version": "1.1.4", 673 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 674 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 675 | "dev": true 676 | }, 677 | "has-flag": { 678 | "version": "4.0.0", 679 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 680 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 681 | "dev": true 682 | }, 683 | "strip-ansi": { 684 | "version": "6.0.0", 685 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 686 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 687 | "dev": true, 688 | "requires": { 689 | "ansi-regex": "^5.0.0" 690 | } 691 | }, 692 | "supports-color": { 693 | "version": "7.1.0", 694 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 695 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 696 | "dev": true, 697 | "requires": { 698 | "has-flag": "^4.0.0" 699 | } 700 | } 701 | } 702 | }, 703 | "is-arguments": { 704 | "version": "1.1.1", 705 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 706 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 707 | "requires": { 708 | "call-bind": "^1.0.2", 709 | "has-tostringtag": "^1.0.0" 710 | } 711 | }, 712 | "is-callable": { 713 | "version": "1.2.7", 714 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 715 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" 716 | }, 717 | "is-extglob": { 718 | "version": "2.1.1", 719 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 720 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 721 | "dev": true 722 | }, 723 | "is-fullwidth-code-point": { 724 | "version": "3.0.0", 725 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 726 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 727 | "dev": true 728 | }, 729 | "is-generator-function": { 730 | "version": "1.0.10", 731 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", 732 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", 733 | "requires": { 734 | "has-tostringtag": "^1.0.0" 735 | } 736 | }, 737 | "is-glob": { 738 | "version": "4.0.1", 739 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 740 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 741 | "dev": true, 742 | "requires": { 743 | "is-extglob": "^2.1.1" 744 | } 745 | }, 746 | "is-promise": { 747 | "version": "2.1.0", 748 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 749 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 750 | "dev": true 751 | }, 752 | "is-typed-array": { 753 | "version": "1.1.10", 754 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", 755 | "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", 756 | "requires": { 757 | "available-typed-arrays": "^1.0.5", 758 | "call-bind": "^1.0.2", 759 | "for-each": "^0.3.3", 760 | "gopd": "^1.0.1", 761 | "has-tostringtag": "^1.0.0" 762 | } 763 | }, 764 | "isarray": { 765 | "version": "1.0.0", 766 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 767 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" 768 | }, 769 | "isexe": { 770 | "version": "2.0.0", 771 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 772 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 773 | "dev": true 774 | }, 775 | "jmespath": { 776 | "version": "0.16.0", 777 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", 778 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" 779 | }, 780 | "js-tokens": { 781 | "version": "4.0.0", 782 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 783 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 784 | "dev": true 785 | }, 786 | "js-yaml": { 787 | "version": "3.13.1", 788 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 789 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 790 | "dev": true, 791 | "requires": { 792 | "argparse": "^1.0.7", 793 | "esprima": "^4.0.0" 794 | } 795 | }, 796 | "json-schema-traverse": { 797 | "version": "0.4.1", 798 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 799 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 800 | "dev": true 801 | }, 802 | "json-stable-stringify-without-jsonify": { 803 | "version": "1.0.1", 804 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 805 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 806 | "dev": true 807 | }, 808 | "levn": { 809 | "version": "0.3.0", 810 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 811 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 812 | "dev": true, 813 | "requires": { 814 | "prelude-ls": "~1.1.2", 815 | "type-check": "~0.3.2" 816 | } 817 | }, 818 | "lodash": { 819 | "version": "4.17.21", 820 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 821 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 822 | "dev": true 823 | }, 824 | "mimic-fn": { 825 | "version": "2.1.0", 826 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 827 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 828 | "dev": true 829 | }, 830 | "minimatch": { 831 | "version": "3.1.2", 832 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 833 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 834 | "dev": true, 835 | "requires": { 836 | "brace-expansion": "^1.1.7" 837 | } 838 | }, 839 | "minimist": { 840 | "version": "1.2.6", 841 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 842 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 843 | "dev": true 844 | }, 845 | "mkdirp": { 846 | "version": "0.5.3", 847 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", 848 | "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", 849 | "dev": true, 850 | "requires": { 851 | "minimist": "^1.2.5" 852 | } 853 | }, 854 | "ms": { 855 | "version": "2.1.2", 856 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 857 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 858 | "dev": true 859 | }, 860 | "mute-stream": { 861 | "version": "0.0.8", 862 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", 863 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", 864 | "dev": true 865 | }, 866 | "natural-compare": { 867 | "version": "1.4.0", 868 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 869 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 870 | "dev": true 871 | }, 872 | "nice-try": { 873 | "version": "1.0.5", 874 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 875 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 876 | "dev": true 877 | }, 878 | "once": { 879 | "version": "1.4.0", 880 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 881 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 882 | "dev": true, 883 | "requires": { 884 | "wrappy": "1" 885 | } 886 | }, 887 | "onetime": { 888 | "version": "5.1.0", 889 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", 890 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", 891 | "dev": true, 892 | "requires": { 893 | "mimic-fn": "^2.1.0" 894 | } 895 | }, 896 | "optionator": { 897 | "version": "0.8.3", 898 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 899 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 900 | "dev": true, 901 | "requires": { 902 | "deep-is": "~0.1.3", 903 | "fast-levenshtein": "~2.0.6", 904 | "levn": "~0.3.0", 905 | "prelude-ls": "~1.1.2", 906 | "type-check": "~0.3.2", 907 | "word-wrap": "~1.2.3" 908 | } 909 | }, 910 | "os-tmpdir": { 911 | "version": "1.0.2", 912 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 913 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 914 | "dev": true 915 | }, 916 | "parent-module": { 917 | "version": "1.0.1", 918 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 919 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 920 | "dev": true, 921 | "requires": { 922 | "callsites": "^3.0.0" 923 | } 924 | }, 925 | "path-is-absolute": { 926 | "version": "1.0.1", 927 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 928 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 929 | "dev": true 930 | }, 931 | "path-key": { 932 | "version": "2.0.1", 933 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 934 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 935 | "dev": true 936 | }, 937 | "prelude-ls": { 938 | "version": "1.1.2", 939 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 940 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 941 | "dev": true 942 | }, 943 | "progress": { 944 | "version": "2.0.3", 945 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 946 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 947 | "dev": true 948 | }, 949 | "punycode": { 950 | "version": "1.3.2", 951 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 952 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 953 | }, 954 | "querystring": { 955 | "version": "0.2.0", 956 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 957 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" 958 | }, 959 | "regexpp": { 960 | "version": "2.0.1", 961 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 962 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 963 | "dev": true 964 | }, 965 | "resolve-from": { 966 | "version": "4.0.0", 967 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 968 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 969 | "dev": true 970 | }, 971 | "restore-cursor": { 972 | "version": "3.1.0", 973 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", 974 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", 975 | "dev": true, 976 | "requires": { 977 | "onetime": "^5.1.0", 978 | "signal-exit": "^3.0.2" 979 | } 980 | }, 981 | "rimraf": { 982 | "version": "2.6.3", 983 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 984 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 985 | "dev": true, 986 | "requires": { 987 | "glob": "^7.1.3" 988 | } 989 | }, 990 | "run-async": { 991 | "version": "2.4.0", 992 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", 993 | "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", 994 | "dev": true, 995 | "requires": { 996 | "is-promise": "^2.1.0" 997 | } 998 | }, 999 | "rxjs": { 1000 | "version": "6.5.4", 1001 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 1002 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 1003 | "dev": true, 1004 | "requires": { 1005 | "tslib": "^1.9.0" 1006 | } 1007 | }, 1008 | "safer-buffer": { 1009 | "version": "2.1.2", 1010 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1011 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1012 | "dev": true 1013 | }, 1014 | "sax": { 1015 | "version": "1.2.1", 1016 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 1017 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" 1018 | }, 1019 | "semver": { 1020 | "version": "6.3.0", 1021 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1022 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1023 | "dev": true 1024 | }, 1025 | "shebang-command": { 1026 | "version": "1.2.0", 1027 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1028 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1029 | "dev": true, 1030 | "requires": { 1031 | "shebang-regex": "^1.0.0" 1032 | } 1033 | }, 1034 | "shebang-regex": { 1035 | "version": "1.0.0", 1036 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1037 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1038 | "dev": true 1039 | }, 1040 | "signal-exit": { 1041 | "version": "3.0.2", 1042 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1043 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1044 | "dev": true 1045 | }, 1046 | "slice-ansi": { 1047 | "version": "2.1.0", 1048 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1049 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1050 | "dev": true, 1051 | "requires": { 1052 | "ansi-styles": "^3.2.0", 1053 | "astral-regex": "^1.0.0", 1054 | "is-fullwidth-code-point": "^2.0.0" 1055 | }, 1056 | "dependencies": { 1057 | "is-fullwidth-code-point": { 1058 | "version": "2.0.0", 1059 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1060 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1061 | "dev": true 1062 | } 1063 | } 1064 | }, 1065 | "sprintf-js": { 1066 | "version": "1.0.3", 1067 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1068 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1069 | "dev": true 1070 | }, 1071 | "string-width": { 1072 | "version": "4.2.0", 1073 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 1074 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 1075 | "dev": true, 1076 | "requires": { 1077 | "emoji-regex": "^8.0.0", 1078 | "is-fullwidth-code-point": "^3.0.0", 1079 | "strip-ansi": "^6.0.0" 1080 | }, 1081 | "dependencies": { 1082 | "strip-ansi": { 1083 | "version": "6.0.0", 1084 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1085 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1086 | "dev": true, 1087 | "requires": { 1088 | "ansi-regex": "^5.0.0" 1089 | } 1090 | } 1091 | } 1092 | }, 1093 | "strip-ansi": { 1094 | "version": "5.2.0", 1095 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1096 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1097 | "dev": true, 1098 | "requires": { 1099 | "ansi-regex": "^4.1.0" 1100 | }, 1101 | "dependencies": { 1102 | "ansi-regex": { 1103 | "version": "4.1.1", 1104 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", 1105 | "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", 1106 | "dev": true 1107 | } 1108 | } 1109 | }, 1110 | "strip-json-comments": { 1111 | "version": "3.0.1", 1112 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 1113 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 1114 | "dev": true 1115 | }, 1116 | "supports-color": { 1117 | "version": "5.5.0", 1118 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1119 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1120 | "dev": true, 1121 | "requires": { 1122 | "has-flag": "^3.0.0" 1123 | } 1124 | }, 1125 | "table": { 1126 | "version": "5.4.6", 1127 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1128 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1129 | "dev": true, 1130 | "requires": { 1131 | "ajv": "^6.10.2", 1132 | "lodash": "^4.17.14", 1133 | "slice-ansi": "^2.1.0", 1134 | "string-width": "^3.0.0" 1135 | }, 1136 | "dependencies": { 1137 | "emoji-regex": { 1138 | "version": "7.0.3", 1139 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 1140 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 1141 | "dev": true 1142 | }, 1143 | "is-fullwidth-code-point": { 1144 | "version": "2.0.0", 1145 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1146 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1147 | "dev": true 1148 | }, 1149 | "string-width": { 1150 | "version": "3.1.0", 1151 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1152 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1153 | "dev": true, 1154 | "requires": { 1155 | "emoji-regex": "^7.0.1", 1156 | "is-fullwidth-code-point": "^2.0.0", 1157 | "strip-ansi": "^5.1.0" 1158 | } 1159 | } 1160 | } 1161 | }, 1162 | "text-table": { 1163 | "version": "0.2.0", 1164 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1165 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1166 | "dev": true 1167 | }, 1168 | "through": { 1169 | "version": "2.3.8", 1170 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1171 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 1172 | "dev": true 1173 | }, 1174 | "tmp": { 1175 | "version": "0.0.33", 1176 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1177 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1178 | "dev": true, 1179 | "requires": { 1180 | "os-tmpdir": "~1.0.2" 1181 | } 1182 | }, 1183 | "tslib": { 1184 | "version": "1.11.1", 1185 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", 1186 | "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", 1187 | "dev": true 1188 | }, 1189 | "type-check": { 1190 | "version": "0.3.2", 1191 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1192 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1193 | "dev": true, 1194 | "requires": { 1195 | "prelude-ls": "~1.1.2" 1196 | } 1197 | }, 1198 | "type-fest": { 1199 | "version": "0.8.1", 1200 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1201 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 1202 | "dev": true 1203 | }, 1204 | "uri-js": { 1205 | "version": "4.2.2", 1206 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1207 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1208 | "dev": true, 1209 | "requires": { 1210 | "punycode": "^2.1.0" 1211 | }, 1212 | "dependencies": { 1213 | "punycode": { 1214 | "version": "2.1.1", 1215 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1216 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1217 | "dev": true 1218 | } 1219 | } 1220 | }, 1221 | "url": { 1222 | "version": "0.10.3", 1223 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 1224 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", 1225 | "requires": { 1226 | "punycode": "1.3.2", 1227 | "querystring": "0.2.0" 1228 | } 1229 | }, 1230 | "util": { 1231 | "version": "0.12.5", 1232 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", 1233 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", 1234 | "requires": { 1235 | "inherits": "^2.0.3", 1236 | "is-arguments": "^1.0.4", 1237 | "is-generator-function": "^1.0.7", 1238 | "is-typed-array": "^1.1.3", 1239 | "which-typed-array": "^1.1.2" 1240 | } 1241 | }, 1242 | "uuid": { 1243 | "version": "8.0.0", 1244 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", 1245 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" 1246 | }, 1247 | "v8-compile-cache": { 1248 | "version": "2.1.0", 1249 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", 1250 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", 1251 | "dev": true 1252 | }, 1253 | "which": { 1254 | "version": "1.3.1", 1255 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1256 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1257 | "dev": true, 1258 | "requires": { 1259 | "isexe": "^2.0.0" 1260 | } 1261 | }, 1262 | "which-typed-array": { 1263 | "version": "1.1.9", 1264 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", 1265 | "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", 1266 | "requires": { 1267 | "available-typed-arrays": "^1.0.5", 1268 | "call-bind": "^1.0.2", 1269 | "for-each": "^0.3.3", 1270 | "gopd": "^1.0.1", 1271 | "has-tostringtag": "^1.0.0", 1272 | "is-typed-array": "^1.1.10" 1273 | } 1274 | }, 1275 | "word-wrap": { 1276 | "version": "1.2.3", 1277 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1278 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1279 | "dev": true 1280 | }, 1281 | "wrappy": { 1282 | "version": "1.0.2", 1283 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1284 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1285 | "dev": true 1286 | }, 1287 | "write": { 1288 | "version": "1.0.3", 1289 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 1290 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 1291 | "dev": true, 1292 | "requires": { 1293 | "mkdirp": "^0.5.1" 1294 | } 1295 | }, 1296 | "xml2js": { 1297 | "version": "0.5.0", 1298 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", 1299 | "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", 1300 | "requires": { 1301 | "sax": ">=0.6.0", 1302 | "xmlbuilder": "~11.0.0" 1303 | } 1304 | }, 1305 | "xmlbuilder": { 1306 | "version": "11.0.1", 1307 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 1308 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" 1309 | } 1310 | } 1311 | } 1312 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amazon-pinpoint-lex-bot", 3 | "version": "1.0.0", 4 | "description": "Use AWS Pinpoint and AWS Lex to let your customers have two-way chats with bots via SMS.", 5 | "main": "src/app.js", 6 | "repository": "https://github.com/aws-samples/amazon-pinpoint-lex-bot", 7 | "author": "Ilya Pupko", 8 | "license": "MIT-0", 9 | "dependencies": { 10 | "aws-sdk": "^2.1354.0" 11 | }, 12 | "devDependencies": { 13 | "eslint": "^6.1.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/tests/unit/PinpointEventsSample.json: -------------------------------------------------------------------------------- 1 | { 2 | "event_type": "_SMS.SUCCESS", 3 | "event_timestamp": 1566423396986, 4 | "arrival_timestamp": 1566423396990, 5 | "event_version": "3.1", 6 | "application": { 7 | "app_id": "0b3ab2f3a84c4a3b345a851d96236621", 8 | "sdk": {} 9 | }, 10 | "client": { 11 | "client_id": "abc2ab3url4t1adzrpjgnhw+a1g" 12 | }, 13 | "device": { 14 | "platform": {} 15 | }, 16 | "session": {}, 17 | "attributes": { 18 | "sender_request_id": "723af033-bf36-4f4f-9a1c-f2c73b456abc", 19 | "destination_phone_number": "+19999999999", 20 | "record_status": "DELIVERED", 21 | "iso_country_code": "US", 22 | "number_of_message_parts": "1", 23 | "message_id": "tmc1g1hjjfg3k4dhia7v5tr76e7cc3v4ricg7f00", 24 | "message_type": "Transactional", 25 | "origination_phone_number": "+18888888888" 26 | }, 27 | "metrics": { 28 | "price_in_millicents_usd": 645 29 | }, 30 | "awsAccountId": "12345678901" 31 | } -------------------------------------------------------------------------------- /src/tests/unit/eventData.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "Sns": { 5 | "Message": "{\"originationNumber\":\"+10000000000\",\"messageBody\":\"1\"}", 6 | "Timestamp": "2019-02-20T17:47:44.147Z" 7 | } 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: 'AWS::Serverless-2016-10-31' 3 | Description: Pinpoint-Lex-Bot AWS Lambda function. 4 | Resources: 5 | PinpointLexFunction: 6 | Type: 'AWS::Serverless::Function' 7 | Properties: 8 | Handler: app.handler 9 | Runtime: nodejs12.x 10 | CodeUri: src/ 11 | Description: Pinpoint-Lex-Bot AWS Lambda function. 12 | MemorySize: 128 13 | Timeout: 10 14 | Role: !GetAtt PinpointLexFunctionIamRole.Arn 15 | Events: 16 | SNS1: 17 | Type: SNS 18 | Properties: 19 | Topic: 20 | Ref: SNSTopic1 21 | Environment: 22 | Variables: 23 | PinpointApplicationId: YOURPINPOINTPROJECTID 24 | BotName: YOURBOTNAME 25 | BotAlias: YOURBOTALIAS 26 | SNSTopic1: 27 | Type: 'AWS::SNS::Topic' 28 | 29 | PinpointLexFunctionIamRole: 30 | Type: AWS::IAM::Role 31 | Properties: 32 | RoleName: PinpointLexFunctionRole 33 | AssumeRolePolicyDocument: 34 | Version: '2012-10-17' 35 | Statement: 36 | - Effect: Allow 37 | Principal: 38 | Service: lambda.amazonaws.com 39 | Action: 40 | - sts:AssumeRole 41 | Path: '/' 42 | Policies: 43 | - PolicyName: Logs 44 | PolicyDocument: 45 | Statement: 46 | - Effect: Allow 47 | Action: 48 | - logs:CreateLogGroup 49 | - logs:CreateLogStream 50 | - logs:PutLogEvents 51 | Resource: arn:aws:logs:*:*:* 52 | - PolicyName: Pinpoint 53 | PolicyDocument: 54 | Statement: 55 | - Effect: Allow 56 | Action: 57 | - mobiletargeting:SendMessages 58 | Resource: arn:aws:mobiletargeting:YOURREGION:YOURACCOUNTID:apps/YOURPROJECTORAPPID/endpoints/* 59 | - PolicyName: Lex 60 | PolicyDocument: 61 | Statement: 62 | - Effect: Allow 63 | Action: 64 | - lex:PostContent 65 | - lex:PostText 66 | Resource: arn:aws:lex:YOURREGION:YOURACCOUNTID:bot/YOURBOTNAME 67 | #Outputs: 68 | 69 | PinpointLexFunction: 70 | Description: "Lambda function to trigger calls" 71 | Value: !GetAtt PinpointLexFunction.Arn 72 | 73 | PinpointLexFunctionIamRole: 74 | Description: "IAM Role created for this function" 75 | Value: !GetAtt PinpointLexFunctionIamRole.Arn 76 | --------------------------------------------------------------------------------