# Slash Command Dispatch
[](https://github.com/peter-evans/slash-command-dispatch/actions?query=workflow%3ACI)
[](https://github.com/marketplace/actions/slash-command-dispatch)
A GitHub action that facilitates ["ChatOps"](https://www.pagerduty.com/blog/what-is-chatops/) by creating repository dispatch events for slash commands.
### How does it work?
The action runs in `issue_comment` event workflows and checks the first line of comments for slash commands.
When a valid command is found it creates a repository dispatch event that includes a payload containing full details of the command and its context.
### Why repository dispatch?
"ChatOps" with slash commands can work in a basic way by parsing the commands during `issue_comment` events and immediately processing the command.
In repositories with a lot of activity, the workflow queue will get backed up very quickly trying to handle new `issue_comment` events *and* process the commands themselves.
Dispatching commands to be processed elsewhere keeps the workflow queue moving quickly. It essentially enables parallel processing of workflows.

## Demos
See it in action with the following live demos.
- [ChatOps Demo in Issues](https://github.com/peter-evans/slash-command-dispatch/issues/3)
- [ChatOps Demo in Pull Requests](https://github.com/peter-evans/slash-command-dispatch/pull/8)
- [Slash command code formatting - Python](https://github.com/peter-evans/slash-command-dispatch/pull/11)
## Documentation
- [Getting started](docs/getting-started.md)
- [Examples](docs/examples.md)
- [Standard configuration](#standard-configuration)
- [Advanced configuration](docs/advanced-configuration.md)
## Dispatching commands
### Standard configuration
The following workflow should be configured in the repository where commands will be dispatched from. This example will respond to comments containing the slash commands `/deploy`, `/integration-test` and `/build-docs`.
```yml
name: Slash Command Dispatch
on:
issue_comment:
types: [created]
jobs:
slashCommandDispatch:
runs-on: ubuntu-latest
steps:
- name: Slash Command Dispatch
uses: peter-evans/slash-command-dispatch@v1
with:
token: ${{ secrets.REPO_ACCESS_TOKEN }}
commands: deploy, integration-test, build-docs
```
Note that not specifying the `repository` input will mean that `repository_dispatch` events are created in the *current* repository by default. It's perfectly fine to use the current repository and not dispatch events to a seperate "processor" repository.
This action also features [advanced configuration](docs/advanced-configuration.md) that allows each command to be configured individually if necessary. Use the standard configuration shown above unless you require advanced features.
### Action inputs
| Input | Description | Default |
| --- | --- | --- |
| `token` | (**required**) A `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line). Note: `GITHUB_TOKEN` *does not* work here. See [token](#token) for further details. | |
| `reaction-token` | `GITHUB_TOKEN` or a `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line). See [reaction-token](#reaction-token) for further details. | `GITHUB_TOKEN` |
| `reactions` | Add reactions. :eyes: = seen, :rocket: = dispatched | `true` |
| `commands` | (**required**) A comma separated list of commands. | |
| `permission` | The repository permission level required by the user to dispatch commands. (`none`, `read`, `write`, `admin`) | `write` |
| `issue-type` | The issue type required for commands. (`issue`, `pull-request`, `both`) | `both` |
| `allow-edits` | Allow edited comments to trigger command dispatches. | `false` |
| `repository` | The full name of the repository to send the dispatch events. | Current repository |
| `event-type-suffix` | The repository dispatch event type suffix for the commands. | `-command` |
| `named-args` | Parse named arguments and add them to the command payload. | `false` |
| `config` | | JSON configuration for commands. See [Advanced configuration](docs/advanced-configuration.md) | |
| `config-from-file` | | JSON configuration from a file for commands. See [Advanced configuration](docs/advanced-configuration.md) | |
#### `token`
This action creates [`repository_dispatch`](https://developer.github.com/v3/repos/#create-a-repository-dispatch-event) events.
The default `GITHUB_TOKEN` does not have scopes to do this so a `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) is required.
If you will be dispatching commands to public repositories *only* then you can use the more limited `public_repo` scope.
#### `reaction-token`
If you don't specify a token for `reaction-token` it will use the default `GITHUB_TOKEN`.
Reactions to comments will then be made by the @github-actions bot user.
You can use a [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) if you would prefer reactions to be made by the user account associated with the PAT.
```yml
- name: Slash Command Dispatch
uses: peter-evans/slash-command-dispatch@v1
with:
token: ${{ secrets.REPO_ACCESS_TOKEN }}
reaction-token: ${{ secrets.REPO_ACCESS_TOKEN }}
commands: deploy, integration-test, build-docs
```
### How comments are parsed for slash commands
Slash commands must be placed in the first line of the comment to be interpreted as a command.
- The command must start with a `/`
- The slash command extends to the last non-whitespace character on the first line
- Anything after the first line is ignored and can be freely used for comments

## Handling dispatched commands
### Event types
Repository dispatch events have a `type` to distinguish between events. The `type` set by the action is a combination of the slash command and `event-type-suffix`. The `event-type-suffix` input defaults to `-command`.
For example, if your slash command is `integration-test`, the event type will be `integration-test-command`.
```yml
on:
repository_dispatch:
types: [integration-test-command]
```
### Accessing contexts
Commands are dispatched with a payload containing a number of contexts.
#### `slash_command` context
The slash command context can be accessed as follows.
`args` is a space separated string of all the supplied arguments.
Each argument is also supplied in a numbered property, i.e. `arg1`, `arg2`, `arg3`, etc.
```yml
- name: Output command and arguments
run: |
echo ${{ github.event.client_payload.slash_command.command }}
echo ${{ github.event.client_payload.slash_command.args }}
echo ${{ github.event.client_payload.slash_command.arg1 }}
echo ${{ github.event.client_payload.slash_command.arg2 }}
echo ${{ github.event.client_payload.slash_command.arg3 }}
# etc.
```
If the `named-args` input is set to `true`, any arguments that are prefixed in the format `name=argument` will be parsed and added to the payload.
For example, the slash command `/deploy branch=master env=prod some other args` will be set in the JSON payload as follows.
```json
"slash_command": {
"command": "deploy",
"args": "branch=master env=prod some other args",
"unnamed_args": "some other args",
"branch": "master",
"env": "prod",
"arg1": "some",
"arg2": "other",
"arg3": "args"
}
```
These named arguments can be accessed in a workflow as follows.
```yml
- name: Output command and named arguments
run: |
echo ${{ github.event.client_payload.slash_command.command }}
echo ${{ github.event.client_payload.slash_command.branch }}
echo ${{ github.event.client_payload.slash_command.env }}
echo ${{ github.event.client_payload.slash_command.unnamed_args }}
```
#### `github` and `pull_request` contexts
The payload contains the complete `github` context of the `issue_comment` event at path `github.event.client_payload.github`.
Additionally, if the comment was made in a pull request, the action calls the [GitHub API to fetch the pull request detail](https://developer.github.com/v3/pulls/#get-a-single-pull-request) and attach it to the payload at path `github.event.client_payload.pull_request`.
You can inspect the payload with the following step.
```yml
- name: Dump the client payload context
env:
PAYLOAD_CONTEXT: ${{ toJson(github.event.client_payload) }}
run: echo "$PAYLOAD_CONTEXT"
```
### Responding to the comment on command completion
Using [create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) action there are a number of ways you can respond to the comment once the command has completed.
The simplest response is to add a :tada: reaction to the comment.
```yml
- name: Add reaction
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.REPO_ACCESS_TOKEN }}
repository: ${{ github.event.client_payload.github.payload.repository.full_name }}
comment-id: ${{ github.event.client_payload.github.payload.comment.id }}
reaction-type: hooray
```
Another option is to reply with a new comment containing a link to the run output.
```yml
- name: Create URL to the run output
id: vars
run: echo ::set-output name=run-url::https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID
- name: Create comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.REPO_ACCESS_TOKEN }}
repository: ${{ github.event.client_payload.github.payload.repository.full_name }}
issue-number: ${{ github.event.client_payload.github.payload.issue.number }}
body: |
[Command run output][1]
[1]: ${{ steps.vars.outputs.run-url }}
```
## License
[MIT](LICENSE)