Yet another implementation for Slack Commands
Tags: python, devops, api
Published: 2022-09-19 13:27:48

We're using slack for communication within our team. Using slack slash commands, we also handle common day-to-day tasks like triggering deployments on different servers based on requirements. For a long time, that remained our primary use case, so we had a single AWS Lambda function taking care of this job, however, with the growing team and business, we felt the need to handle several other tasks this way. Thus we created a few more lambda functions that handled different tasks but the behavior among different lambda functions wasn't consistent, since every lambda was maintained separately.

## General Idea

We decided to create a single lambda function that will be solely used for handling all the slash command requirements. The commands will follow a similar structure as normal shell commands do. Some examples are as follows

| Command     | Description                                                  |
| ----------- | ------------------------------------------------------------ |
| help        | List down all the slash commands with usage                  |
| help deploy | List down help text for deploy commands, including all the options it takes and flags |
| deploy      | Deploy for a specific client                                 |

Some examples of slack slash commands are as follows (assuming our slash command is /example)

```
/example help
/example help deploy
/example help deploy --client test-client --branch master
```

We can limit users who can issue a command as well as channels where the command can be issued from by using a very simple configuration

```json
{
    "command": "deploy"
    "users": [
    	"example.user"
    ],
	"channels": [
        "channel_id"
    ]
}
```

## Implementation

We implemented this solution in python with the help of some useful packages from the open source community. Some of these packages are

- [Fast Api](https://fastapi.tiangolo.com/): For the implementation of the APIs
- [Mangum](https://mangum.io/): For the integration of the Aws Lambda and the Api Gateway with the FastApi 
- [Python Jenkins](https://python-jenkins.readthedocs.io/en/latest/): For interacting with the Jenkins server that handles deployments
- [Argparse](https://docs.python.org/3/library/argparse.html): For handling argument parsing 

The way our implementation worked was as follows

- The User sends a command via slack

- Lambda function verifies

  - If the command exists
  - If the user is allowed to run the command
  - If the command is allowed to be run from the specified channel
  - If the command has all the required parameters

  and responds appropriately

- Execute the command and send the response back to the slack channel

- Offload the long running commands to the Ecs container (e.g, database backup or restore)

The general architecture of this solution is as follows


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rczuzsg7f1cbaz0p22f.png)

This helps us implement new slack commands really quickly. All the error handling is similar across the different commands, so we don't need to handle the errors separately for every new command.