Google form × Slack Appでインシデント問い合わせを効率化した話

システムに関わっていると逃げられないもの、、、それは障害。

ここではSREに所属している私が、実施したインフラ関係の障害対応に関する改善のおはなしをしていきます

※本記事は[「Develop fun!を体現する Works Human Intelligence Advent Calendar 2020」](https://qiita.com/advent-calendar/2020/whi)の12/8を担当したものです。
## なにをしたの？
タイトルの通り、Google formからの問い合わせをSlack Appを使用して特定のチャンネルに通知されるようにすることで、障害対応を効率化をしました。

## どうしてこんなことしたの？
もともとSlackの特定のチャンネルで問い合わせをしてもらう運用はしていました。
ただ、、、、この運用は問い合わせの内容が人によってバラバラだったので、内容によっては私たちから追加で質問をしないと対応を始められないなんてこともしばしば( ；∀；)
しかし、Slackじゃないとコンサルとスピード感のあるやりとりをすることが難しいので、Slackを問い合わせのやりとりの場としたい…！

そこで、たどり着いたのがGoogle formから問い合わせをあげてもらってその内容をSlackに通知する方法👏👏

## どんな実装したの？
実装したのは大きく2つ
①Google formでの投稿内容をSlackに通知する
②顧客名称を社内システムから取得して、Google formに反映させる(結構無理やり）

### Google formでの投稿内容をSlackに通知する

まず、google formを作成します。

#### フォーム作成で意識したこと
- 問い合わせのカテゴリを選択式にしました  
障害の問い合わせのやりとりをしているチャンネルでは、インフラ関連の質問対応も一緒に行っていました。そのため、障害対応なのか質問なのかを選択してもらうようにすることで、投稿後すぐに障害の問い合わせがきていることを把握できるようになりました。
-  顧客名称をリスト式で選択できるようにしました  
問い合わせの際にお客様名称をタイポしていたり、コンサル内での呼び方で記載されていたことがあり、顧客名称をすぐに把握できないことがあった。顧客名称を正式名称のリスト形式にすることですぐに把握できるようになった。  
⇨このリスト形式にしたことで、「顧客名称を社内システムから取得して、Google formに反映させること」が必要になりました…！

次に、Slack Appの作成を行います。作成する方法は以下の通り。
※ この後に紹介する記事ではwebhookのtokenを使用して作成していますが、社内のSlackで使用することができなかったためIncoming webhookのSlack Appを作成してます。
https://api.slack.com/messaging/webhooks

最後に、GASのスクリプトを作成していきます。
私は以下の記事を参考にスクリプトを作成しました。
[Googleformからのslack通知設定方法](https://qiita.com/pchan52/items/574e930a3cc42cf7f8b9)

### 顧客名称を社内システムから取得して、Google formに反映させる
なんでこれが必要になったのかというと、前述の通り **顧客名称をリスト式で選択できるようにした** からです。
しかも、当たり前といえば当たり前なのですが、インターネット公開されていない社内のシステムの情報を管理しているサービスのAPIはGASから実行することができません。
つまり、社内システムにアクセスできる端末から情報を取得した上で、Google formへ反映させる必要があります。

今はこんな感じでGoogle formへの反映を行っています。
![qiita用 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859226/ace10ff4-bdff-7af4-f0e3-d511557a76f2.png)

やっていることはこの4つです。
※ GAS関連は別の方のqiita記事を参考にやってるので、参考にした記事のURLを記載してます

##### 1. API実行して顧客情報が記載されたにcsvファイルを作成(Python)  
APIを実行している部分  

```python

# Basic認証用の文字列を作成.
basic_user_and_pasword = base64.b64encode('{}:{}'.format(user, password).encode('utf-8'))
response = requests.get('{APIのエンドポイント}', auth=(user, password))
customer_json = response.json()
```
↑で取得した情報をいい感じに編集して、以下のソースでCSVに書き込んでいます
※ コンプライアンス上の理由で一部変更してます

```python

now = datetime.datetime.now()
filename = 'customer_must_'+ now.strftime('%Y%m%d_%H%M%S') + '.csv'
with open(filename, 'w', newline="",encoding='UTF-8') as f:
    writer = csv.DictWriter(f, ['Column1', 'Column2', 'Column3'])
    for customer_info in customer_list:
        writer.writerow(customer_info)
```

##### 2. CSVファイルをGoogle driveにアップロード（Python）  
こんな感じの関数を作成して、1の処理の後に読んであげればできます

```python

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
def uploadCsvToGoogleDrive(file_name):
    gauth = GoogleAuth()
    gauth.CommandLineAuth()
    drive = GoogleDrive(gauth)
    folderid = '{ アップロード先のGoogle DriveのフォルダーID }'
    f = drive.CreateFile({'title': file_name, 'mimeType': 'text/csv','parents': [{'kind': 'drive#fileLink', 'id':folderid}]})
    f.SetContentFile(file_name)
    f.Upload()
```

この部分この記事を書いてる時にこんな記事も見つけたので3の部分の実装変えたら必要ないかもしれない（試してはない）
[google apps scriptでspreadsheetにローカルCSVファイルをインポート(SJIS対応＆高速版)](https://qiita.com/ms32/items/7e180c1c1d00fa8df647)

##### 3. アップロードされたcsvを元にGoogle Spread Sheet上にある顧客名称のリストを更新する（GAS）
参考記事
[Google Apps ScriptでCSVファイルをGoogleスプレッドシートにインポートする](https://qiita.com/YusukeKameyama/items/5ae840ec8d4382a215db)

##### 4. 更新されたGoogle Spread SheetをもとにGoogle formのリストの選択肢を更新する（GAS)
参考記事
[Googleフォームのプルダウンにスプレッドシートの内容を反映させる](https://qiita.com/kobaboy/items/610263087d9c85d8458e)
## フォームで投稿にしてよかったこととその展望
### よかったこと
- 無駄なやりとり減ったよね
- 緊急度が問い合わせが投稿された時にぱっとわかるようになったよね
- Google Formを使うようにしたことで、フォームの投稿内容をGoogle Spread Sheetにも記載されるようにしてるから月の問い合わせ件数とか集計しやすいよね

### 今後改善したいなと思ってること

- 自端末でやっている部分をLambdaに置き換えたい・・・！！
- 監視ツール上で何もアラート出てないときに環境が起動しているのかを自動で確認
- 監視ツール上で何もアラートが出ていないときに確認してほしいポイントの確認を促すBotの作成
- 障害発生時に監視ツールで検知しているアラートの内容が問い合わせのスレッドに投稿されるようにしたい。（異常値までサジェスト出来たら完璧）
- 速度遅延の問い合わせの場合、監視ツールで検知した時間がかかってる処理の内容が自動で投稿されるようにする
- 障害の顛末管理にRedmineというツールを使用しているので、上で挙げたような情報が連携されるようにしたい

## 最後に
初Qiita記事投稿なので、優しい目で見てくれると嬉しいな。
障害対応みんな頑張りましょうね( ・∇・)