diff --git a/.eslintignore b/.eslintignore index 86ab54b..73134d4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,5 @@ node_modules package.lock.json -bin -dist \ No newline at end of file +dist +cdk.out +build \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 998fd30..0af933c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,5 +10,16 @@ "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended" + ], + "env": { + "node": true + }, + "overrides": [ + { + "files": ["*.js"], + "rules": { + "@typescript-eslint/no-var-requires": "off" + } + } ] } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2862643..1ab2d3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -*.js !jest.config.js *.d.ts node_modules diff --git a/.prettierignore b/.prettierignore index 86ab54b..73134d4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ node_modules package.lock.json -bin -dist \ No newline at end of file +dist +cdk.out +build \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b59b8e..96ac28e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.1.0] - 2023-07-27 +## [0.1.1] - 2023-12-04 +### Added + - New 'Easy Button' option for deployment and update using pre-built CloudFormation templates (with no dependency on dev shell, cdk, etc.) - see [README - Deploy the stack](./README.md#1-deploy-the-stack). + - New `publish.sh` script used to create and publish standalone CloudFormation templates in an S3 bucket - see [README_DEVELOPERS - ](./README_DEVELOPERS.md#publish-the-solution). + +## [0.1.0] - 2023-11-27 ### Added Initial release - In DMs it responds to all messages @@ -19,5 +24,6 @@ Initial release - Process up to 5 attached files for document question answering, summaries, etc. - Reset and start new conversation in DM channel by using `/new_conversation` -[Unreleased]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/compare/v0.1.0...develop +[Unreleased]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/compare/v0.1.1...develop +[0.1.1]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/releases/tag/v0.1.1 [0.1.0]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/releases/tag/v0.1.0 diff --git a/README.md b/README.md index da37dc1..6b78aba 100644 --- a/README.md +++ b/README.md @@ -34,41 +34,46 @@ Follow the instructions below to deploy the project to your own AWS account and ## Deploy the solution -### 1. Dependencies +### Prerequisites -You need to have the following packages installed on your computer to build and deploy the project. - -1. bash shell (Linux, MacOS, Windows-WSL) -2. node and npm: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm -3. tsc (typescript): `npm install -g typescript` -4. esbuild: `npm i -g esbuild` -5. jq: https://jqlang.github.io/jq/download/ -6. aws (AWS CLI): https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html -7. cdk (AWS CDK): https://docs.aws.amazon.com/cdk/v2/guide/cli.html +You need to have an AWS account and an IAM Role/User with permissions to create and manage the necessary resources and components for this application. *(If you do not have an AWS account, please see [How do I create and activate a new Amazon Web Services account?](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/))* You also need to have an existing, working Amazon Q application. If you haven't set one up yet, see [Creating an Amazon Q application](https://docs.aws.amazon.com/amazonq/latest/business-use-dg/create-app.html) -### 2. Initialize and deploy the stack +### 1. Deploy the stack + +We've made this easy by providing pre-built AWS CloudFormation templates that deploy everything you need in your AWS account. + +If you are a developer, and you want to build, deploy and/or publish the solution from code, we've made that easy too! See [Developer README](./README_DEVELOPERS.md) -Copy the GitHub repo to your computer. Either: -- use the git command: git clone https://github.com/aws-samples/amazon-q-slack-gateway.git -- OR, download and expand the ZIP file from the GitHub page: https://github.com/aws-samples/amazon-q-slack-gateway/archive/refs/heads/main.zip +1. Log into the [AWS console](https://console.aws.amazon.com/) if you are not already. +2. Choose one of the **Launch Stack** buttons below for your desired AWS region to open the AWS CloudFormation console and create a new stack. +4. Enter the following parameters: + 1. `Stack Name`: Name your App, e.g. AMAZON-Q-SLACK-GATEWAY. + 2. `AmazonQAppId`: Your existing Amazon Q Application ID (copy from Amazon Q console). + 3. `AmazonQRegion`: Choose the region where you created your Amazon Q Application. + 4. `AmazonQUserId`: (Optional) Amazon Q User ID email address (leave empty to use Slack users email as user Id) + 5. `ContextDaysToLive`: Just leave this as the default (90 days) -Navigate into the project root directory and, in a bash shell, run: +Region | Easy Deploy Button | Template URL - use to upgrade existing stack to a new release +--- | --- | --- +N. Virginia (us-east-1) | [![Launch Stack](https://cdn.rawgit.com/buildkite/cloudformation-launch-stack-button-svg/master/launch-stack.svg)](https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?templateURL=https://s3.us-east-1.amazonaws.com/aws-ml-blog-us-east-1/artifacts/amazon-q-slack-gateway/AmazonQSlackGateway.json&stackName=AMAZON-Q-SLACK-GATEWAY) | https://s3.us-east-1.amazonaws.com/aws-ml-blog-us-east-1/artifacts/amazon-q-slack-gateway/AmazonQSlackGateway.json +Oregon (us-west-2) | [![Launch Stack](https://cdn.rawgit.com/buildkite/cloudformation-launch-stack-button-svg/master/launch-stack.svg)](https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?templateURL=https://s3.us-west-2.amazonaws.com/aws-ml-blog-us-west-2/artifacts/amazon-q-slack-gateway/AmazonQSlackGateway.json&stackName=AMAZON-Q-SLACK-GATEWAY) | https://s3.us-west-2.amazonaws.com/aws-ml-blog-us-west-2/artifacts/amazon-q-slack-gateway/AmazonQSlackGateway.json -1. `./init.sh` - checks your system dependendencies for required packages (see Dependencies above), sets up your environment file, and bootstraps your cdk environment. -2. `./deploy.sh` - runs the cdk build and deploys or updates a stack in your AWS account, creates a slack app manifest file, and outputs a link to the AWS Secrets Manager secret that you will need below. -### 3. Configure your Slack application +When your CloudFormation stack status is CREATE_COMPLETE, choose the **Outputs** tab, and keep it open - you'll need it below. -#### 3.2 Create your app + +### 2. Configure your Slack application + +#### 2.2 Create your app Now you can create your app in Slack! -1. Create a Slack app: https://api.slack.com/apps from the generated manifest `./slack-manifest-output.json` (copy / paste) +1. Create a Slack app: https://api.slack.com/apps from the generated manifest - copy / paste from the stack output: `SlackAppManifest`. 2. Go to `App Home`, scroll down to the section `Show Tabs` and enable `Message Tab` then check the box `Allow users to send Slash commands and messages from the messages tab` - This is a required step to enable your user to send messages to your app -#### 3.3 Add your app in your workspace +#### 2.3 Add your app in your workspace Let's now add your app into your workspace, this is required to generate the `Bot User OAuth Token` value that will be needed in the next step @@ -79,7 +84,7 @@ Let's now add your app into your workspace, this is required to generate the `Bo 4. In the right pane, click on "Open in App Directory" 5. Click "Open in Slack" -### 4. Configure your Secrets in AWS +### 3. Configure your Secrets in AWS Let's configure your Slack secrets in order to (1) verify the signature of each request, (2) post on behalf of your bot @@ -89,16 +94,11 @@ Let's configure your Slack secrets in order to (1) verify the signature of each > Please create an issue (or, better yet, a pull request!) in this repo if you want this feature added to a future version. 1. Login to your AWS console -2. In your AWS account go to Secret manager, using the URL that was output by the `deploy.sh` script above. +2. In your AWS account go to Secret manager, using the URL shown in the stack output: `SlackSecretConsoleUrl`. 3. Choose `Retrieve secret value` 4. Choose `Edit` -5. Replace secret value with the following JSON and replace with the value of `Signing Secret` and `Bot User OAuth Token`, you will find those values in the Slack application configuration under `Basic Information` and `OAuth & Permissions`: -``` -{ - "SlackSigningSecret": "VALUE_HERE", - "SlackBotUserOAuthToken": "VALUE_HERE" -} - ``` +5. Replace the value of `Signing Secret`\* and `Bot User OAuth Token`, you will find those values in the Slack application configuration under `Basic Information` and `OAuth & Permissions`. \**(Pro tip: Be careful you don't accidentally copy 'Client Secret' (wrong) instead of 'Signing Secret' (right)!)* + ### Say hello > Time to say Hi! diff --git a/README_DEVELOPERS.md b/README_DEVELOPERS.md new file mode 100644 index 0000000..1a130bd --- /dev/null +++ b/README_DEVELOPERS.md @@ -0,0 +1,123 @@ +# Developer README + +The main README is here: [Slack gateway for Amazon Q, your business expert (preview)](./README.md) + +This Developer README describes how to build the project from the source code - for developer types. You can: +- [Deploy the solution](#deploy-the-solution) +- [Publish the solution](#publish-the-solution) + +### 1. Dependencies + +To deploy or to publish, you need to have the following packages installed on your computer: + +1. bash shell (Linux, MacOS, Windows-WSL) +2. node and npm: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm +3. tsc (typescript): `npm install -g typescript` +4. esbuild: `npm i -g esbuild` +5. jq: https://jqlang.github.io/jq/download/ +6. aws (AWS CLI): https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html +7. cdk (AWS CDK): https://docs.aws.amazon.com/cdk/v2/guide/cli.html + +Copy the GitHub repo to your computer. Either: +- use the git command: git clone https://github.com/aws-samples/amazon-q-slack-gateway.git +- OR, download and expand the ZIP file from the GitHub page: https://github.com/aws-samples/amazon-q-slack-gateway/archive/refs/heads/main.zip + +## Deploy the solution + +Before starting, you need to have an existing, working Amazon Q application. If you haven't set one up yet, see [Creating an Amazon Q application](https://docs.aws.amazon.com/amazonq/latest/business-use-dg/create-app.html) + +### 1. Initialize and deploy the stack + +Navigate into the project root directory and, in a bash shell, run: + +1. `./init.sh` - checks your system dependendencies for required packages (see Dependencies above), sets up your environment file, and bootstraps your cdk environment. +2. `./deploy.sh` - runs the cdk build and deploys or updates a stack in your AWS account, creates a slack app manifest file, and outputs a link to the AWS Secrets Manager secret that you will need below. + +### 3. Configure your Slack application + +#### 3.2 Create your app + +Now you can create your app in Slack! + +1. Create a Slack app: https://api.slack.com/apps from the generated manifest `./slack-manifest-output.json` (copy / paste) +2. Go to `App Home`, scroll down to the section `Show Tabs` and enable `Message Tab` then check the box `Allow users to send Slash commands and messages from the messages tab` - This is a required step to enable your user to send messages to your app + +#### 3.3 Add your app in your workspace + +Let's now add your app into your workspace, this is required to generate the `Bot User OAuth Token` value that will be needed in the next step + +1. Go to OAuth & Permissions (in api.slack.com) and click `Install to Workspace`, this will generate the OAuth token +2. In Slack, go to your workspace +2. Click on your workspace name > Settings & administration > Manage apps +3. Click on your newly created app +4. In the right pane, click on "Open in App Directory" +5. Click "Open in Slack" + +### 4. Configure your Secrets in AWS + +Let's configure your Slack secrets in order to (1) verify the signature of each request, (2) post on behalf of your bot + +> **IMPORTANT** +> In this example we are not enabling Slack token rotation. Enable it for a production app by implementing +> rotation via AWS Secrets Manager. +> Please create an issue (or, better yet, a pull request!) in this repo if you want this feature added to a future version. + +1. Login to your AWS console +2. In your AWS account go to Secret manager, using the URL that was output by the `deploy.sh` script above. +3. Choose `Retrieve secret value` +4. Choose `Edit` +5. Replace the value of `Signing Secret` and `Bot User OAuth Token`, you will find those values in the Slack application configuration under `Basic Information` and `OAuth & Permissions`: + +### Say hello +> Time to say Hi! + +1. Go to Slack +2. Under Apps > Manage, add your new Amazon Q app +3. Optionally add your app to team channels +4. In the app DM channel, say *Hello*. In a team channel, ask it for help with an @mention. +5. Enjoy. + + +## Publish the solution + +In our main README, you will see that we provided Easy Deploy Buttons to launch a stack using pre-built templates that we published already to an S3 bucket. + +If you want to build and publish your own template, to your own S3 bucket, so that others can easily use a similar easy button approach to deploy a stack, using *your* templates, here's how. + +Navigate into the project root directory and, in a bash shell, run: + +1. `./publish.sh `. + This: + - checks your system dependendencies for required packages (see Dependencies above) + - bootstraps your cdk environment if needed + - creates a standalone CloudFormation template (that doesn't depend on CDK) + - publishes the template and required assets to an S3 bucket in your account called `cfn_bucket_basename-region` (it creates the bucket if it doesn't already exist) + - optionally add a final parameter `public` if you want to make the templates public. Note: your bucket and account must be configured not to Block Public Access using new ACLs. + +That's it! There's just one step. + +When completed, it displays the CloudFormation templates S3 URLs and 1-click URLs for launching the stack creation in CloudFormation console, e.g.: +``` +OUTPUTS +Template URL: https://s3.us-east-1.amazonaws.com/yourbucketbasename-us-east-1/qslack-test/AmazonQSlackGateway.json +CF Launch URL: https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?templateURL=https://s3.us-east-1.amazonaws.com/yourbucketbasename-us-east-1/qslack-test/AmazonQSlackGateway.json&stackName=AMAZON-Q-SLACK-GATEWAY +Done +`````` + +Follow the deployment directions in the main [README](./README.md), but use your own CF Launch URL instead of our pre-built templates (Launch Stack buttons). + + +## Contributing, and reporting issues + +We welcome your contributions to our project. Whether it's a bug report, new feature, correction, or additional +documentation, we greatly value feedback and contributions from our community. + +See [CONTRIBUTING](CONTRIBUTING.md) for more information. + +## Security + +See [Security issue notifications](CONTRIBUTING.md#security-issue-notifications) for more information. + +## License + +This library is licensed under the MIT-0 License. See the [LICENSE](./LICENSE) file. \ No newline at end of file diff --git a/bin/convert-cfn-template.js b/bin/convert-cfn-template.js new file mode 100644 index 0000000..78eaa86 --- /dev/null +++ b/bin/convert-cfn-template.js @@ -0,0 +1,298 @@ +const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); +const fs = require('fs'); +const path = require('path'); +const JSZip = require('jszip'); + +// Read command line arguments +const templateName = process.argv[2]; +const destinationBucket = process.argv[3]; +const destinationPrefix = process.argv[4]; +const awsRegion = process.argv[5]; +if (!templateName || !destinationBucket || !destinationPrefix || !awsRegion) { + console.error('Error: All arguments must be provided.'); + console.error( + 'Usage: