A Slack Slash Command is one way to write an integration with Slack to plug custom functionality into Slack for your team to use. Specifically, a Slash Command is an application that can be invoked by users in your Slack workspace. You can define the user input, what is returned to the user, and what is happening in the workflow behind the scenes.
To show how you can connect to the RMS Intelligent Risk Platform™ from a Slack Slash Command, let’s step through creating a Slash Command that a user can use to return the status of a given Risk Modeler workflow ID.
- Slack Slash Command is used to call an API endpoint.
- Serverless framework is used to create the AWS infrastructure.
- AWS API Gateway is used to create the API endpoint.
- AWS Lambda is triggered by the API call and is the function that calls Risk Modeler.
- The Lambda function in this tutorial is written in Python.
- AWS CloudWatch is used for function logging.
- AWS System Manager SSM Parameter Store is used for storing environment variables.
The Serverless Framework provides a way to quickly create and manage the AWS architecture behind the API that the Slack Slash Command calls.
Creating a New Serverless Application
The Serverless framework allows you to easily deploy an API endpoint by creating and managing the AWS infrastructure.
Start by creating a new Serverless application.
serverless create --template aws-python3 --path WorkflowSlackSlashCommand
This command creates a new project named workflow-status, and automatically generates serverless.yml to define the configuration for the service and handler.py which declares the Lambda function.
When you open serverless.yml, you can see additional configuration settings you are able to provide for your service. For this tutorial, update the file with the following code.
- Service: specifies the name of serverless application.
- Provider: defines the provider and runtime details.
- Functions: defines the lambda function, its handler, and trigger. The lambda function is named workflow_status. The events parameter will create and configure an API gateway that accepts post requests and triggers the lambda function.
- Environment: The api_key and env_url will be accessed from the AWS SSM parameter store.
Install Python Requirements
In Python, the Requests library will be used to make calls to Risk Modeler software. Add a requirements.txt file to your application, the Requests library in the requirements file, and install the requirement using the following command:
pip install -t src/vendor -r requirements.txt
This will generate the src folder with the required dependencies.
Add Environment Variables to the Parameter Store
The environment variables API_KEY and ENV_URL for your tenant will be referenced from the AWS SSM parameter store. To add your values for those parameters to the store, run:
aws ssm put-parameter --name "api_key" --type "String" --value "api-key value"
aws ssm put-parameter --name "env_url" --type "String" --value "env-url value"
Writing the Handler for the Lambda Function
You are now ready to write the actual Lambda function. The user Slack command will make a POST request to API Gateway and any user input passed in through the event is encoded in the text field of the event body.
When the user submits no input with the slash command, the handler returns the five most recent workflow names and IDs. When the user submits a valid workflow ID, the function returns the workflow status. Otherwise, an error message is returned.
Deploying the Serverless Application
Deploying the Lambda function handler and Serverless application configuration is done using the Serverless deploy command.
sls deploy -v
This command creates an AWS CloudFormation template and deploys the stack in AWS. The stack outputs will be returned on the command line, including an HttpApiUrl to point the Slack application to.
You can view the progress in the Cloudformation dashboard, and once complete, you can also view the API Gateway and Lambda dashboards in AWS. Logging for requests made to the Lambda function are captured in AWS CloudWatch.
Configuring the Slack Slash Command
Now that you have an API URL, you can create a Slack app here to call the API. Create an app from scratch, provide an App Name and Workspace, and click Create App. You may need to request admin approval to install your app to the workspace.
Navigate into the App you created and click on Slash Commands under Add Features and Functionality, then click on Create New Command.
The fields for the new command should be filled out as follows:
- Command: name of the slash command to be accessed from Slack. The command must start with a /, be all lowercase, and have no spaces.
- Request URL: API endpoint from AWS API Gateway, returned as HttpApiUrl above.
- Short Description: description to be shown to the user in the Slack App.
- Usage Hint: hint for users, including any parameters that can be passed into the command.
Test Out Your New Slack Slash Command
Finally, let’s test our new Slack Slash Command!
Once the application is installed on your Slack workspace, you will be able to preview the application functions and autocomplete entries when you type /workflow in Slack.
The command /workflow with no user input returns the five most recent workflow names and IDs.
The command with a valid workflow ID /workflow 4406222 returns the workflow status.
The command with an invalid workflow ID /workflow 123 returns an error message from Risk Modeler .
Manage Message Visibility
By default, the message will be visible only to the user who triggered the command. This is because the JSON returned from API Gateway to Slack has response_type = ephemeral in the response.
To make the command visible to all members of the channel where the command was triggered, response_type can be set to in_channel. For example, the sample response in the function handler that is passed out of API Gateway:
"text": 'workflow ID: ' + workflow_id + "\nstatus: " + status
"text": 'workflow ID: ' + workflow_id + "\nstatus: " + status
Redeploy using sls deploy and the command will be visible to all members of the channel where the command is triggered.