Slackのカスタムステップを利用してフォーム内容を任意の場所に送信する

こんにちは！anyのプロダクトチームに所属している小牟禮（こむれ）です。
この記事は、any Product Team Advent Calendar2024　19日目の記事になります。

https://qiita.com/advent-calendar/2024/anyinc

この記事ではSlackの **カスタムステップ（NEW）** の利用方法をご紹介します。
[カスタムステップ](https://api.slack.com/concepts/workflow-steps)を利用することで、Slackアプリ内のワークフローにカスタムステップを追加することができます。

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/a3f8c390-c8c0-5bcc-464b-795caf24d4cd.png" />

:::note warn
この記事では新しいステップ（**Workflow Steps 🆕**）の設定方法について記載しています。（レガシーはすでに追加できません🙅‍♂️）
:::

## チャンネルへの投稿内容を動的にしたい

フォームの入力内容をチャンネルへ投稿する場合は、あらかじめ備わっているステップを利用することが多いと思います。

この機能（チャンネルへの通知）はとても簡単に利用できる一方で、カスタマイズがほぼできないといった側面もあります。
たとえば、フォームの入力内容によって通知内容を変更したりなどは（おそらく）できません🙅‍♂️

と、いうことで、SlackAPIのカスタムステップを使い、フォーム内容をAWS Lambdaへリクエストするようにしました。

ちなみに、AWS Lambda関数では以下の処理を行なっています！
- ワークフローが実施されたチャンネルへ動的なメッセージを投稿
- 受け取った情報をノーションDBへ追加

:::note info
今回はAWS Lambdaへリクエストが送信されるまでに絞って記載します。
:::

## 1. Slack APIでアプリを作成する

1-1. [Slack API](https://api.slack.com/apps/)にアクセスし**Create New App**を押下します。
1-2. モーダルが表示されるので**From a manifest**を押下します。
1-3. アプリを追加するワークスペースを選択します。
1-4. マニフェストの設定画面にて**Next**を押下します。
1-5. 最後に**Create**を押下すればアプリの作成は完了です

![createapp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/da033a8e-ec39-7a8c-a0d9-9eaeb6fb1890.gif)

以下の画面が表示されればアプリの作成は成功です:clap:
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/86c66d7f-dd50-cc44-3204-3e7369139be7.png" />

## 2. Slack API・アプリの設定 〜 スコープ
2-1. 左サイドメニューの**OAuth & Permissions**を押下しページ遷移します。
2-2. **Scopes**セクションまでスクロールします。
2-3. Bot Token Scopes内の**Bot Token Scopes**から権限を適宜追加します。
　必要な権限は[こちら](https://api.slack.com/scopes)で確認してください。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/28e44271-a04d-bb61-a4ea-a5578f08efea.gif" />

## 3. Slack API・アプリの設定 〜 インストール
3-1. **OAuth & Permissions**ページの画面上部に戻ります。
3-2. OAuth Tokensセクションの**Reinstall to**を押下します。
3-3. 画面が切り替わるので**許可する**を押下します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/a65b84db-0d61-573f-eae7-cd50b2c7e3e3.gif" />

OAuth Tokensセクションに**Bot User OAuth Token**が追加されていれば成功です:clap::clap:
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/0c81334e-cd10-4b90-9438-30e6a38bf56b.png" />

## 4. Slack API・アプリの設定 〜 サブスクリプション
4-1. 左サイドメニューの**Event Subscriptions**を押下しページ遷移します。
4-2. **Enable Events**をONにします。
4-3. **Request URL**にSlack APIからのリクエストを受け取るエンドポイントを指定します。今回でいうとフォーム情報を受け取る先のURLです。
4-4. **Subscribe to bot events** で権限を適宜追加します。今回はワークフローのカスタムステップとして利用するので、`workflow_step_execute`は必須です。
4-5. 画面下部にある**Save Changes**を押下すれば完了です。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/e446e059-437e-fb1f-78a1-e12100045ab0.gif" />

##### ここまでくれば、Slack API側の設定完了まであと**3ステップ**です！

## 5. Slack API・アプリの設定 〜 ワークフローステップ初期設定
5-1. 左サイドメニューの**Workflow Steps**を押下しページ遷移します。
5-2. 画面上部で以下の更新を求められる場合があるので更新します。
  - org-readinessの有効化
    - `Org Level Apps`のリンク先にある**Enable org-readiness**を押下します

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/86a8c253-cb46-2ca9-b1f3-3df1c7e548cb.png" />

  - ランタイム設定の更新
    - `Upadte Settings`のリンクを押下します

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/15ccd5ec-554c-5afe-3369-919c13d379f4.png" />

最終的に**Add Step**ボタンが活性化すればここでの設定は完了です:clap::clap::clap:
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/77acf783-0e8b-011b-78e3-97b2ceca1b5c.png" />

## 6. Slack API・アプリの設定 〜 ワークフローステップ追加
6-1. **Add Step**を押下します。
6-2. モーダルが表示されるので基本情報（Basic Information）を適宜入力します。
6-3. 入力パラメータータブ（Input Parameters）に移動し、フォームの内容と関連付けるインプット要素を追加します。

例えばフォームに名前、詳細の2要素があり、これらを指定したサーバーへ送信する場合は、2つのインプット要素を追加します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/a60edef5-889f-8052-d396-2bdeeb00bf48.gif" />

:::note info
追加したインプット要素とフォーム項目の実際の関連付けはSlack アプリ内のワークフロー設定にて行います。
:::

## 7. Slack API・アプリの設定 〜 再インストール

7-1. 左サイドメニューの**Installed App Settings**を押下しページ遷移します。
7-2. **Reinstall to**を押下します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/8fb99506-c033-d129-27da-8b3490379291.png" />

これでSlack API側の設定は完了です。お疲れさまでした！🚀
以降ではSlack側でワークフローにカスタムステップを追加します。

## 8. Slack・ワークフロー 〜 カスタムステップへ変更

8-1. カスタムのステップを適用するワークフローを開きます。
8-2. フォーム内容を投稿しているステップを削除します。
8-3. ステップ一覧の最下部までスクロールし**カスタム**を選択します。
8-4. 追加したカスタムステップを選択します。
8-5. インプット項目にどの情報を紐つけるかのモーダルで、ポチポチと関連つけます。
8-6. すべての紐つけが終わったら**保存する**を押下します。
8-7. **変更内容を公開**を押下します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/a962817f-cd07-68ca-994a-b5d0c449a6cd.gif" />

以下の画面が表示されたら完了です:clap::clap::clap::clap:
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/cb458d5e-1244-85ab-51a0-d4b4a8e0deab.png" />

以降はフォーム内容がAWS Lambdaへ送信されます。
以上、「**Slackのカスタムステップを利用してフォーム内容を任意の場所に送信する**」でしたー！

## 番外編 ~ ハマりポイント

Slack API設定でのハマりポイントと解決策を紹介します。

<details>
    <summary>ワークフローステップの入力パラメーターは複数選択肢が考慮されていない:innocent:
    </summary>

フォームには複数選択できる質問タイプがあります。
選択された選択肢はすべてAWS Lambdaへ送信したいところではありますが、入力パラメーターを設定するUIには用意されていないようです🙅‍♂️
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944147/6444917c-d681-911b-1003-a62faac3ca10.png" />

**解決策**
Slack APIにある`App Manifest`を直接編集します。
以下の例でいうと`colors`要素が複数選択肢に対応した設定です。
```json
{
    "functions": {
        "myStep": {
            "title": "入力内容収集",
            "colors": {
                "type": "array",
                "description": "",
                "name": "colors",
                "items": {
                    "type": "string"
                }
            }
        }
    }
}
```
</details>

ハマりポイントは他にもありましたが、1番多そうな厄介ごとの共有でした！

***

any株式会社では[ナレッジ経営クラウドQast](https://qast.jp/)のエンジニアを絶賛募集中です。
是非[採用ページ](https://careers.anyinc.jp/)をご覧ください！
興味がある方は、[こちら](https://hrmos.co/pages/anyinc/jobs?category=1938133004283695106)よりご応募お待ちしております。
エンジニア組織/文化について詳しく知りたい方は[こちら](https://speakerdeck.com/any_tech/engineer-culture-deck-v3-dot-0)。