Slackからデモ環境のデータ作成リクエストを送る

# 環境
ruby 2.4
Rails 5.0
Redis 3.2
SlackAPI 2019年10月時点

### gem
[sidekiq](https://github.com/mperham/sidekiq) 5.2.7
[slack-notifier](https://github.com/stevenosloan/slack-notifier) 2.3.2

# 背景
デモ環境の一つのアカウントをHPからの問い合わせや、営業の際に使用するアカウントとして使いまわしていたために次のような問題が発生していました。

#### アカウント使いまわし問題
・いつの間にかアカウントがロックされている（ログインを複数回失敗でロック）
・データが他の誰かの手によって作成・更新・削除されている

お客様毎にアカウントを発行してお渡しすれば上記問題は発生しないのですが、そこでもまた次のような問題がありました。

#### データ手作成問題
・デモデータを自動作成する仕組みがない
・アカウントデータだけ作成しても、サービスの機能が十分に伝わらない可能性がある
・アカウントデータ以外の初期データも手作成とか時間がかかり過ぎる
・デモデータ作成作業は、Salesチームが行うので複雑な作業・コマンドを実行する事はできない

デモ環境のデータなので、データ自動作成の仕組みを作って社内のメンバーなら誰でも発行できるようにしたいと考えました。

ちょうど会社の開発合宿があったので一日でサクッと作成しました。

# 仕組み
チャットツールとしてSlackを使用していたので、Slackからデータを自動作成する仕組みを作ろうと考えました。

<img width="1060" alt="スクリーンショット 2019-12-27 17.49.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/780dc0a3-bea3-ab8f-f500-1696f24bd74f.png">

###### １． SlackAPIアプリのbotにメンションメッセージを投げる
###### 2． SlackAPIのEventに引っかかる
###### 3． アプリのPostURLを叩く
###### 4． データ作成のWorkerを実行
###### 5． IncomingWebhooksでID/PASSを通知する
###### 6． 特定のチャンネルにメッセージが送られる
###### 7． ID/PASSが通知される

# 実装していく
### １． Railsアプリ側にデモデータ作成用のエンドポイントを作成する
```ruby:config/routes.rb
  resource :demo_data, only: :create
```

### 2． コントローラを実装する
```ruby:app/controllers/demo_data_controller.rb
# frozen_string_literal: true

class DemoDataController < ActionController::Base
  def create
    if params[:challenge].present?
      render json: {challenge: params[:challenge]}
    else
      DemoData::CreateWorker.perform_async
    end
  end
end
```

この箇所ですが、

```ruby
if params[:challenge].present?
      render json: {challenge: params[:challenge]}
```
SlackAPIアプリで `Event Subscriptions` を設定する際にURLの存在確認の為にレスポンスを確認をされるので必要になります。
詳しくは下記参照
https://api.slack.com/events/url_verification


### 3． SlackAPIでアプリを作成する
以下のURLから `Create New App` を押下
https://api.slack.com/apps
<img width="718" alt="スクリーンショット 2019-12-27 18.54.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/0750b35f-e7cb-73a1-ecc9-80fe6eab9e0d.png">

`App Name` を入力
`Development Slack Workspace` を選択
使用するWorkspaceを間違えないように選択して `Create App` を押下
<img width="579" alt="スクリーンショット 2019-12-27 19.40.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/d7c3c4ad-ce47-e307-39f7-7f22512760d2.png">


### 4． 作成したSlackAPIアプリのBot Userを作成する
サイドメニューの `Bot Users` を押下
`Add a Bot User` を押下
任意の名前を入力して `Add Bot User` を押下
<img width="963" alt="スクリーンショット 2019-12-27 20.15.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/f5ccf0ff-2f7f-7f14-5912-0932578ca0c9.png">


### 5． SlackAPIアプリのEvent Subscriptionsを設定する
サイドメニューの `Event Subscriptions` を押下
`Enable Events` を `ON` に変更
`Request URL` に作成したエンドポイントを設定
`Subscribe to bot events` の `Add Bot User Event` から `app_mention` を選択
右下にある `Save Changes` を忘れずに押下
<img width="1129" alt="スクリーンショット 2019-12-27 20.51.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/531cbf45-ff4c-4f4b-60a8-94fd9c3b7b43.png">


### 6． SlackAPIアプリのIncoming Webhooksを設定する
サイドメニューの `Incoming Webhooks` を押下
`Activate Incoming Webhooks` を `ON` に変更
`Add New Webhook to Workspace` を押下
<img width="972" alt="スクリーンショット 2019-12-27 21.18.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/3dd4cd18-9501-dd70-5c18-b1e436886105.png">

別画面に飛ばされるので `チャンネル` を選択する
`許可する` を押下
<img width="555" alt="スクリーンショット 2019-12-27 21.19.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/6883eada-cebd-a1f3-6bff-87fcf1fc9cc4.png">


### 7． 作成したアプリをWorspaceにインストールする
サイドメニューの `Installed App` を押下
`Reinstall App` を押下
<img width="951" alt="スクリーンショット 2019-12-28 18.46.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/5f8f3af0-2868-2882-272a-1d6794e35d65.png">


別画面に飛ばされるので `ワークスペース` を選択する
`Reinstall App` を押下
<img width="515" alt="スクリーンショット 2019-12-28 18.14.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/22ec86ff-3b04-6877-5948-bc2acb74c8b6.png">

### 8． Worker側からSlack通知する処理を実装する
```ruby:app/workers/demo_data/create_worker.rb
# frozen_string_literal: true

class DemoData::CreateWorker
  include Sidekiq::Worker
  sidekiq_options queue: 'default'

  def perform
    # 好きなようにデモデータ作成処理
    send_slack
  end

  private

  def send_slack
    notifier = Slack::Notifier.new 'Webhook URL'

    begin
      notifier.post slack_params
    rescue Slack::Notifier::APIError => e
      Raven.capture_exception(e)
    end
  end

  def slack_params
    {
      attachments: [
        {
          title: "デモデータ作成が完了しました。",
          color: "#5F04B4",
          fields: [
              {
                  "title": "id",
                  "value": "ここにログインID"
              },
              {
                  "title": "password",
                  "value": "ここにログインPASSWORD"
              }
          ]
        }
      ]
    }
  end
end
```

この箇所の `Webhook URL` は、

```ruby

  def send_slack
    notifier = Slack::Notifier.new 'Webhook URL'
```

作成したWebhook URLをコピーしてきて置き換えてください
<img width="951" alt="スクリーンショット 2019-12-28 18.50.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/c2cdc2fe-c3b2-f98d-732d-d44d0a1fcac2.png">


### 9． 実際に使ってみる
アプリのボットユーザーに対してメンションを飛ばすだけです。

<img width="451" alt="スクリーンショット 2019-12-28 18.56.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/e5a85161-df5f-be22-a893-2a4122e855bf.png">


### 10． SlackAPIからのみPOSTリクエストを受け付ける
このままだとURLを知っていれば誰でもURLを叩けてしまうので
SlackAPIから送られてくるトークンを確認します。

```ruby:app/controllers/demo_data_controller.rb
# frozen_string_literal: true

class DemoDataController < ActionController::Base
  def create
    raise "This action needs a verification token." if params[:token].nil? || params[:token] != ENV['TOKEN']

    if params[:challenge].present?
      render json: {challenge: params[:challenge]}
    else
      DemoData::CreateWorker.perform_async
    end
  end
end
```

この箇所の `ENV['TOKEN']` は、

```ruby
    raise "This action needs a verification token." if params[:token].nil? || params[:token] != ENV['TOKEN']
```

サイドメニューの `Basic Information` を押下
`App Credentials` の `Verification Token` です
<img width="747" alt="スクリーンショット 2019-12-28 19.25.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226572/9325a917-0d04-bda8-2cb2-fec8385b386d.png">


以上です！