BoltでSlackアプリを作る際につまづきやすいこと


最近BoltでSlackアプリを作成しています。
何気にいろんなつまづきポイントがあったので、まとめて行こうと思います。


## Slackアプリ作成時につまづきやすいポイント

### 送信データを処理してくれない!
モーダルを開くところまでは実装できても、送信ができない...というケースがありました。

```
url: (56) Recv failure: Connection reset by peer
```

何かの操作に対してアプリがアクションを起こすには、 `Interactivity & Shortcuts` をオンにして
Request先のURLを登録する必要があります。

![スクリーンショット 2021-06-24 18.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/4bff9b4c-e126-1c8f-7815-222058181dc6.png)


### 特定の動作で弾かれる!
権限のスコープがうまく設定できていない可能性があります。
`OAuth& Permissions`のScopesをチェックしましょう。
![スクリーンショット 2021-06-24 18.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/7e45720f-3790-887b-0d9e-4d7dc7c28995.png)

ちなみに動作ベースで自動でスコープを追加する方法もあります。
`Event Subscriptions` の**Subscribe to bot events**から登録しましょう。
![スクリーンショット 2021-06-24 18.44.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/0a977817-7aa9-dab8-8250-6dfa9f9604a3.png)


## Boltの記述で躓きやすいポイント
### ackが返らずタイムエラーになる
BoltはAPIが走って3秒以内にackを実行しないとタイムエラーとなります。
基本的には処理の先頭に記述するようにします。

```js
exports.default = (app) => {
  app.command('/register', async ({ ack, body, client }) => {
    await ack()

    try {
      const result = await client.views.open({
...
```

### inputを必須に出来ない
slack apiドキュメントを読んでいて気づきました。
blockのtypeをsectionにしてしまうと、必須項目実装ができません。
必須にしたい場合はtypeをinputにする必要があるようです。

```js
    try {
      const result = await client.views.open({
        ...// 略
          blocks: [
            {
              type: 'input',
              block_id: 'person',
              element: {
                type: 'users_select',
                placeholder: {
                  type: 'plain_text',
                  text: '田中　太郎',
                  emoji: true,
                },
                action_id: 'person',
              },
              label: {
                type: 'plain_text',
                text: '氏名',
                emoji: true,
              },
              optional: false // ここで必須・任意が切り替えられる
            },
            {
```

https://api.slack.com/reference/block-kit/blocks#input
![スクリーンショット 2021-06-24 18.56.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/ae7d9c0a-c93d-20f1-7c91-48ff99f466d0.png)

typeがinputだと上記のようにoptionalがありますが、


https://api.slack.com/reference/block-kit/blocks
![スクリーンショット 2021-06-24 18.55.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/7bd52ca0-2faf-238e-fe48-6706b4e1693b.png)

typeがsectionだと上記のようにaccessoryでinput系を選べるにも関わらず、optinalも存在しません。


### blockを組み立てるのが難しい
[Block Kit Builder](https://app.slack.com/block-kit-builder/T011BP8DJ5D#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E7%99%BB%E9%8C%B2%22%7D%7D,%7B%22type%22:%22input%22,%22element%22:%7B%22type%22:%22plain_text_input%22,%22action_id%22:%22plain_text_input-action%22%7D,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Label%22,%22emoji%22:true%7D%7D,%7B%22type%22:%22input%22,%22element%22:%7B%22type%22:%22static_select%22,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Select%20an%20item%22,%22emoji%22:true%7D,%22options%22:%5B%7B%22text%22:%7B%22type%22:%22plain_text%22,%22text%22:%22*this%20is%20plain_text%20text*%22,%22emoji%22:true%7D,%22value%22:%22value-0%22%7D,%7B%22text%22:%7B%22type%22:%22plain_text%22,%22text%22:%22*this%20is%20plain_text%20text*%22,%22emoji%22:true%7D,%22value%22:%22value-1%22%7D,%7B%22text%22:%7B%22type%22:%22plain_text%22,%22text%22:%22*this%20is%20plain_text%20text*%22,%22emoji%22:true%7D,%22value%22:%22value-2%22%7D%5D,%22action_id%22:%22static_select-action%22%7D,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Label%22,%22emoji%22:true%7D%7D%5D%7D)がとても有能なので使いましょう。
直感的にbuildを組み立てることができます。
必須にする場合は前述の通りsectionを使わないように注意しましょう。

![スクリーンショット 2021-06-24 18.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441432/0b551ff4-2764-680a-ae22-2b6201207564.png)