# Register and Dispatch an Action

Slack provides a [web API](https://api.slack.com/methods) that allows applications to invoke RPC-style methods to read and write data in Slack. The `Slack` namespace provides access to these web APIs by obtaining a Slack client and enabling you to post messages or work with reactions etc.

## Register an Action

To register an action with an app, use the [`SlackApp` metadata definition](/docs/platform/salesforce-slack-sdk/guide/meta_slackapp.md). The `.slackapp` file must have at least two properties.

- `description`—A brief description of the action.
- `action`—The location of the action.
- To register an action for commands and shortcuts, use the `commands`, `globalShortcuts`, and `messageShortcuts` properties.

```yaml
description: End to End Apex Example App
commands:
  /apex-create-record:
    action:
      definition: apex__action__CreateRecordCommandDispatcher
    title: Create Record Command
    description: Create a record using a slack command.
globalShortcuts:
  apex-create-record-global:
    action:
      definition: apex__action__CreateRecordShortcutDispatcher
    title: Create Record Global Shortcut
    description: Create a record using a slack global shortcut.
messageShortcuts:
  apex-create-record-message:
    action:
      definition: apex__action__CreateRecordShortcutDispatcher
    title: Create Record Message Shortcut
    description: Create a record using a slack message shortcut.
```

In the `ViewDefinition` metadata, use an action address to associate an event with an action. To build an action address, use the `apex__action__ClassName` or `apex__action__Namespace.ClassName` format. See [App Configuration Keys](/docs/platform/salesforce-slack-sdk/guide/app-definition.md#app-configuration-keys).

## Dispatch an Action

The action system comprises two phases, insulating the app from dealing with the timeouts Slack imposes for HTTP responses.

### Phase 1: Dispatching

In the dispatching phase, the action determines how it reacts to the request.

The action must decide how to handle the request. It must choose which of these types of responses it wants to use based on the inputs to the action.

- Ack: The action executes some arbitrary logic but doesn’t have to inform Slack of anything in particular about that logic.
- Open a modal: The action opens a modal view.
- Push a modal: The action pushes a modal view on to the existing modal view stack from which the request action originated.
- Update a modal: The action updates the current modal view from which the request action originated.
- Clear modal: The action closes the current modal view and clears the entire view stack.

### Phase 2: Handling

In the handling phase, the action determines the details of how to react to the request. The action can run any logic it wants, send requests over the network, query or update a database, or run process-intensive operations. This phase can take as much time as necessary because it isn’t susceptible to the initial HTTP request timeout or a `trigger_id` timeout based on the dispatching phase's logic.

:::note
Avoid expensive operations in the dispatching phase, such as database queries, calls to one of the provided Slack clients, or other network requests. Defer all such activity to the handling phase when possible.
:::

## Get Access to a Slack Context and Slack Client

An action can be bound directly in a Slack runtime context, such as:

1. An event handler in a declarative component.
2. A handler in Slack application metadata for commands, shortcuts, and events.

### Access Slack Context

An instance of `RequestContext` is passed to the `invoke()` method, which describes the context in which a particular Slack action is invoked.

The `invoke()` method is available via these dispatcher classes.

- [Slack.ActionDispatcher](/docs/platform/salesforce-slack-sdk/guide/apex_ref_dispatchers.md#actiondispatcher-class)
- [Slack.EventDispatcher](/docs/platform/salesforce-slack-sdk/guide/apex_ref_dispatchers.md#eventdispatcher-class)
- [Slack.ShortcutDispatcher](/docs/platform/salesforce-slack-sdk/guide/apex_ref_dispatchers.md#shortcutdispatcher-class)
- [Slack.SlashCommandDispatcher](/docs/platform/salesforce-slack-sdk/guide/apex_ref_dispatchers.md#slashcommanddispatcher-class)

The context exposes information about the source of the action in Slack, performs custom logic, and obtains the correct Slack client to respond to Slack based on the request. For example, you can respond to a slash command in the Slack app by extending `Slack.SlashCommandDispatcher`.

```java
public class ViewRecordCommandDispatcher extends Slack.SlashCommandDispatcher {
  public override Slack.ActionHandler invoke(Slack.SlashCommandParameters parameters, Slack.RequestContext context) {
      return Slack.ActionHandler.modal(new Handler(parameters, context));
  }
  // Set up Handler and update modal
  // or do something else
}
```

Each action type receives different information in its `RequestContext`. Here's a summary of the [`RequestContext` class](/docs/platform/salesforce-slack-sdk/guide/apex_ref_requestcontext.md).

```java
global class RequestContext {

    String appId;
    String enterpriseId;
    String teamId;
    String channelId;
    String triggerId;
    String userId;
    Map<String, Object> formData;
    ActionPayload actionPayload;
    MessageContext messageContext;
    ViewContext viewContext;
}
```

### Access a Slack Client

To respond to a request from Slack, obtain the appropriate client to interact with Slack's web API. Use the [`App` class](/docs/platform/salesforce-slack-sdk/guide/apex_ref_client_access.md) to obtain a Slack client.

- `getAppClient()`—Gets a client to invoke Slack web API methods as the application in this context.
- `getBotClientForTeam(String teamId)`—Gets a client to invoke Slack web API methods as the application's bot user in this context for the workspace.
- `getUserClientForTeam(String teamId, String slackUserId)`—Gets a client to invoke Slack web API methods as the user in this context.

### Example

This example calls the `getBotClientForTeam()` method and posts a message using `ChatPostMessageRequest`, which is an Apex wrapper for Slack's [`chat.postMessage` API method](https://api.slack.com/methods/chat.postMessage). It assumes that you created a `SlackApp` and `ViewDefinition` metadata definition and authorized the app.

```java
public class ClientTest {
    public static void run() {

        // Replace with your own values
        String teamId = 'Txxxx';
        String enterpriseId = 'xxxx';
        String channelId = 'Dxxxx';
        String userId = 'Uxxxx';
        String adminUserId = 'Uxxxx';
        String text = 'Hello from Apex!';

        Slack.App app = Slack.App.ExampleIsvApp.get();
        Slack.BotClient client = app.getBotClientForTeam(teamId);

        // Post a message
        Slack.ViewReference view = Slack.View.message_withblocks.get();
        view.setParameter('text', 'Hello from apex');
        Slack.ChatPostMessageRequest req = new Slack.ChatPostMessageRequest.builder()
            .channel(channelId)
            .viewReference(view)
            .build();

        Slack.ChatPostMessageResponse response = client.chatPostMessage(req);
        System.debug('response: ' + response.isOk());
        System.debug('error: ' + response.getError());
    }
}

```

## See Also

[Create an Apex Handler](/docs/platform/salesforce-slack-sdk/guide/actions_handlers_apex.md)
