# Deploy a Slack App

After you [set up your development environment](/docs/platform/salesforce-slack-sdk/guide/setup-your-env.md) and [configure your SFDX project](/docs/platform/salesforce-slack-sdk/guide/run-sfdx.md), you can create and deploy a Slack app by following these steps.

## Prerequisites

To deploy a Slack app, you must have a Slack account. If you don't have a Slack account, see [slack.com/get-started#/create](https://slack.com/get-started#/create).

## Create a Slack App

1. Navigate to <https://api.slack.com/apps> and click **Create New App**.

2. Select **From an app manifest**, and choose the workspace you want to develop your app in.

3. Use this app manifest to create your Say Hello app. Update `<your-name>` with a unique name to differentiate your app. Ignore the `<your-app-ID>` placeholder for now as you're updating this information later.

   ```yaml
   _metadata:
     major_version: 1
     minor_version: 1
   display_information:
     name: <your-name> Say Hello App
     description: Say Hello Example App
   features:
     app_home:
       home_tab_enabled: true
       messages_tab_enabled: false
       messages_tab_read_only_enabled: false
     bot_user:
       display_name: Say Hello
       always_online: false
     slash_commands:
       - command: /apex-hello
         url: https://slack-apps.salesforce.com:9443/a/<your-app-ID>
         description: Say Hello
         should_escape: false
   oauth_config:
     redirect_urls:
       - https://auth.slack-apps.salesforce.com/slack_oauth_callback/<your-app-ID>
     scopes:
       user:
         - reactions:read
         - chat:write
       bot:
         - channels:read
         - chat:write
         - commands
         - groups:read
         - reactions:read
         - users:read
   settings:
     event_subscriptions:
       request_url: https://slack-apps.salesforce.com:9443/a/<your-app-ID>
       bot_events:
         - app_home_opened
         - app_uninstalled
         - grid_migration_finished
         - grid_migration_started
         - team_access_granted
         - team_access_revoked
         - tokens_revoked
     interactivity:
       is_enabled: true
       request_url: https://slack-apps.salesforce.com:9443/a/<your-app-ID>
       message_menu_options_url: https://slack-apps.salesforce.com:9443/a/<your-app-ID>
     org_deploy_enabled: false
     socket_mode_enabled: false
     token_rotation_enabled: false
   ```

   :::note
   An app manifest enables you to create, configure, and copy your Slack apps easily. If you see an error while saving the manifest, check your indentation. For the manifest schema, see [Create and configure apps with manifests](https://api.slack.com/reference/manifests).
   :::

4. Click **Next**. Verify your app summary and click **Create**.

5. After you create the app, click **Install to Workspace**.

6. From the **Basic Information** page, copy the App ID value.

7. On the **Basic Information** page, scroll down to the **App-Level Tokens** section and generate a token. To enable routing on your app's interactions and event payloads over WebSockets, add the `connections:write` scope.

   :::tip
   Note of the App ID, App Token, and secrets on this page. We're using them shortly for the SlackApp metadata file.
   :::

8. Navigate to these pages and update the URLs. Replace `<your-app-ID>` in the app manifest file.

   - **Interactivity & Shortcuts** > Interactivity

     Update the Request URL, and save your changes.

   - **Interactivity & Shortcuts** > Select Menus

     Update the Options Load URL, and save your changes.

   - **Slash Commands** > Edit Command

     Update the Request URL, and save your changes. Repeat this step for each command you have.

   - **OAuth & Permissions**

     Update the Redirect URLs, click **Done**, and click **Save URLs**.

   - **Event Subscriptions**

     Update the Request URL. Save your changes.

   :::tip
   If any of the request URL is missing from the fields, copy and paste it from another Request URL field. The request URL follows the format `https://<Apex SDK for Slack-URL>/a/<your-app-ID>`.
   :::

9. View the app manifest file in Slack and confirm that the URLs are updated.

## Create and Deploy a View Definition

A [view definition](/docs/platform/salesforce-slack-sdk/guide/views.md) is translated to blocks at runtime.

1. Using VS Code for your scratch org, create a folder `viewdefinitions` in `force-app/main/default`.

2. Create a file called `hello.view`, inside the `viewdefinitions` folder. Include this YAML syntax.

   ```yaml
   description: "Say Hello Example"
   schema:
     properties:
       name:
         type: string
         required: true
   components:
     - definition: modal
       properties:
         title: "Hello {!view.properties.name}"
       components:
         - definition: section
           properties:
             text: "You did it!"
   ```

3. Add the `hello.view-meta.xml` metadata file in the same directory.

   ```xml
   <?xml version="1.0" encoding="UTF-8"?>
   <ViewDefinition xmlns="http://soap.sforce.com/2006/04/metadata">
       <apiVersion>54.0</apiVersion>
       <isProtected>false</isProtected>
       <masterLabel>Hello World Example</masterLabel>
       <targetType>slack</targetType>
   </ViewDefinition>
   ```

4. Deploy your view definition.

   ```bash
   sf project deploy start
   ```

   If you see an error when deploying, run `sf update stable` to update to the latest version. Run `sf autocomplete --refresh-cache` after you update Salesforce CLI to ensure that autocomplete works correctly on any new commands.

:::tip
If you've been using Salesforce CLI for a long time, and have previously set up Toolbelt with SFDX, uninstall the old unused plugins using `sf plugins uninstall salesforce-alm` and `sf plugins uninstall salesforcedx`.
:::

## Create and Deploy a SlackApp Definition

The [SlackApp metadata type](/docs/platform/salesforce-slack-sdk/guide/meta_slackapp.md) contains configuration information such as the app's commands and shortcut handlers, and the app's token and secrets.

To create the metadata definition:

1. Create a folder `slackapps` inside `force-app/main/default`.

2. Create a file called **HelloSlackApp.slackapp**, inside the `slackapps` folder. `SlackApp` files use YAML syntax. The Slash command defined as follows must match your Slack App configuration on `api.slack.com`.

   ```yaml
   description: Hello World Example App
   commands:
     /apex-hello:
       action:
         definition: apex__action__SayHello
       title: Say Hello
       description: A command to say Hello
   ```

3. In the `force-app/main/default/slackapps` directory, create a **HelloSlackApp.slackapp-meta.xml** file. Replace the `*` placeholders in the example with the values for your Slack app.

   ```xml
   <?xml version="1.0" encoding="UTF-8"?>
   <SlackApp xmlns="http://soap.sforce.com/2006/04/metadata">
       <appKey>*</appKey>
       <appToken>*</appToken>
       <botScopes>
           chat:write,chat:write.public,incoming-webhook,channels:history,groups:history,channels:read,reactions:read,commands
       </botScopes>
       <clientKey>*</clientKey>
       <clientSecret>*</clientSecret>
       <isProtected>false</isProtected>
       <masterLabel>Hello Slack App</masterLabel>
       <signingSecret>*</signingSecret>
       <userScopes>
           im:read,im:write,channels:read,channels:write,chat:write,groups:read,mpim:read,mpim:write,users:read,groups:write
       </userScopes>
   </SlackApp>
   ```

   :::tip
   The `appKey` and `clientKey` fields correspond to App ID and Client ID on `api.slack.com`. The `appToken` starts with `xapp-1-`. To locate the app token, see the **App-Level Tokens** section on the **Basic Information** page.
   :::

4. Deploy your Slack app definition.

   ```bash
   sf project deploy start
   ```

## Create and Deploy a Slack Action

Let's add some interactivity for the `/apex-hello` slash command you introduced in the app manifest, using a slash command dispatcher.

1. In the `classes` directory, open the **SayHello.cls** class.

2. Paste in the following code and save the file.

   ```java
   public class SayHello extends Slack.SlashCommandDispatcher {

      public override Slack.ActionHandler invoke(Slack.SlashCommandParameters parameters, Slack.RequestContext context) {
          return Slack.ActionHandler.modal(new Handler(parameters, context), 'Say Hello');
      }

      public class Handler implements Slack.ModalHandler {

          Slack.SlashCommandParameters parameters;
          Slack.RequestContext context;

          public Handler(Slack.SlashCommandParameters parameters, Slack.RequestContext context){
              this.parameters = parameters;
              this.context = context;
          }

          public Slack.ModalView call() {
              String name = parameters.getText();
              Slack.ViewReference viewReference = Slack.View.hello.get();
              viewReference.setParameter('name', name);
              Slack.ModalView modalView = new Slack.ModalView.builder()
                  .viewReference(viewReference)
                  .build();
              return modalView;
          }
      }
   }
   ```

3. Deploy your Slack action.

   ```bash
   sf project deploy start
   ```

## Run Your Slack App

Let's see your Slack app in action.

1. From the Slack Desktop client, go to a public channel and enter the following slash command: `/apex-hello`.

   :::tip
   If the slash command isn't available, make sure you've clicked the **Install to Workspace** button as described in [Create a Slack App](#create-a-slack-app).
   :::

2. When prompted to connect your app, click the **Connect** button in Slack.

To connect your Slack app and scratch org:

1. Accept the OAuth screen from Slack.

2. When you get to the Salesforce login page, select the **Would you rather connect to a sandbox?** link, if you’re not already on `test.salesforce.com`.

   :::tip
   If your scratch org uses a custom domain, for example, `connect-efficiency-1197-dev-ed.cs91.my.salesforce.com`, click **Use Custom Domain**, enter your custom domain `connect-efficiency-1197-dev-ed`, and click **Continue**.
   :::

3. Sign in with your scratch org username and password. When prompted to select which channel you want to allow your app to post to, select the channel and press **Allow**.

4. When you're connected successfully, a success message is displayed in the browser.

5. You can now close the window and return to Slack.

6. Execute the slash command again: `/apex-hello World` and observe that the modal appears.

   :::tip
   If you see an error that a channel is not found when running a slash command, it usually means the bot doesn't have access to post a message to the channel. Try adding the bot to the channel by typing `@<app name>` and then following the onscreen instructions.
   :::
