Slackで使える在宅勤務の勤怠アプリを作ってみた

Writer: &nbsp; &nbsp; &nbsp; Van Minh Tri
Translator: Yosuke Okusa
Director: &nbsp;&nbsp; Yosuke Okusa
First Post:&nbsp; 2020-08-06

## 高まるリモートワーク需要に合わせて。

某C-ウィルスの影響で、世界中で在宅勤務の機運が高まっています。
リモートワークやテレワークなどなど呼び方は様々ですが、往々にして__『勤怠管理や進捗報告が面倒』__という側面は共通していそうです。
GREVOも同様の悩みに直面したので、以下の要素を満たすアプリを作ってみました。

- フリーツールを使って、Slackなど会社で使うチャットツールから勤怠と進捗の報告をしたい。
- 複数のチャンネルへ一斉報告したい。（複数のプロジェクト等に関係している人の「ランチ行ってきます！」を１度の送信だけで済ませたい）
- 設定やインストールも簡単で便利だとなお良し。

では早速、手順を見ていきましょう。
コピペでもできる、わりと初心者向けの新設設計になっている・・・はずなので、「Slack Apps？なにそれおいしいの？」「スクリプトよく分かんない」という人も安心してください。
今回はGoogle Spread Sheet、Google Apps Scriptを使いました。

## Part 1. セットアップのための準備（Google Driveでの操作）

#### 1-1. Google Driveに新規フォルダを作成

まず、[Google Drive](https://drive.google.com/)に新規フォルダを作成します。
フォルダ名は分かりやすさ重視で「WFH」とかにしておきます。

#### 1-2. Google Apps Scriptを新規作成

作成した「WFH」フォルダ内に、Google Apps Scriptを新規作成します。
Google Apps Script の項目が見つからない場合は、次のように設定します。

>「新規」から「その他」 → 「アプリを追加」と進む。
表示されるポップアップウィンドウ内で、「Google Apps Script」を検索。
![create_new_gas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/3121329e-dce3-c5fe-9774-24afc03af98e.png)


__ちなみに：なぜGoogle Apps Scriptなのか？__

- 入力されたデータの受信・保管・出力に必要なサーバとしての役割、アプリとしての役割を一手に担うことができるため。
- 広く利用されているGoogle Accountとの親和性も高いため。
- フリーで使えるので経費・維持費がかからないため。

端的に言えば、GASを使うのが簡単で便利ということですね。
普段Google Driveを使っている場合はむしろ利用しない手はないんじゃないでしょうか。
後述のスクリプトを改修したい場合は、[GASの開発者向け情報](https://developers.google.com/apps-script)を参照してください。

さて、本題に戻ります。


`a) 新規作成された Google Apps Scriptを開きます。`

GASを開くと、Apps Script Editorが表示されます。
ここでGoogle Appsの設定を調整したり、スクリプトを書き換えることができます。
![config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/32ef81e4-acd8-092e-95c2-05ab2ec73f77.png)



`b) Apps Script Editor上で、 ５種類のスクリプトファイルを作成します。`

続いて、画面上部のツールバーにて、「ファイル」 → 「New」から「スクリプト ファイル」を選択することで、ひとつのScript内にスクリプトファイルを新規作成できます。
__今回はこれを５回行い、スクリプトファイルを５種類生成します。__

それぞれのファイル名とコードは、[GREVOのGitHub](https://github.com/grevo-vn/Work-From-Home/tree/master/GoogleAppsScript)で公開しているものを使います。
上記リンク先から、対応するファイル名とコードをコピー＆ペーストしましょう。
![create_new_file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/a441a574-819a-eadf-9633-0fb53bb64421.png)



`c) 完成したスクリプトをウェブアプリとして公開します。`

再度、上部ツールバーにて「公開」 → 「ウェブアプリケーションとして導入...」を選択します。
アプリの公開範囲を設定するポップアップが開くので、「アプリケーションにアクセスできるユーザー」を __「全員(匿名)」__ に設定します。

最後に「導入」をクリックすることで、ウェブアプリとしての利用する準備は完了です。
![deploy_as_web_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/61288aa8-93d1-d7c3-b4c7-db6ca8a54416.png)
*※導入完了後に表示される「現在のウェブアプリケーションのURL」は、後ほど[Slack Appsの設定](#2-2-/-コマンドを設定する)で必要になるので、コピーやメモしておきましょう。*



#### 1-3. スプレッドシートを新規作成
各メンバーからの報告を記録するための受けとして、「WFH」フォルダ内に下記のような２種類のスプレッドシートを作成します。

`a) 「WFH working time」`
![google_sheet_working_time.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/88270250-4416-53ef-a816-8feccca7c6e3.png)


`b) 「WFH report」`
![google_sheet_report.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/0b5d917b-13a2-789d-c2aa-7223a8d01c33.png)


新たなメンバーが追加される際、シートを複製して使う前提のため、__一番左のシートはテンプレートとして入力もしない__でおきます。

さて、ここまででセットアップ前のGAS側の準備は完了となります。
このままではアプリは機能しませんが、[後の工程](#3-1-スプレッドシートIDを指定する)で再びGASに戻ってスクリプトを編集することになります。
その際、<font color="Crimson">ここで作成したスプレッドシート２種類のID（URL上の d/ と /editの間の文字列）が必要</font>になります。


## Part 2. Slack Appsセットアップ（Web版Slackでの操作）

#### 2-1. Slack Apps を新規作成する

GASの準備ができたので、Slackの準備をしていきます。
[Slack Apps設定ページ](​https://api.slack.com/apps?new_app=1​) にて、必要な情報を埋めます。
　*※アプリ版ではなく、Web版からのみ編集可能です。*

「App Name」 にアプリ名を入れ、「Development Slack Workspace」" にはアプリを利用したいSlack ワークスペースを選択します。
最後に "Create App" をクリックすると、Slack内で動作するアプリが作成されます。
<img src="https://a.slack-edge.com/80588/img/api/start/app_creation_dialog.png" width=500/>
<font color="Gray">（こちらの画像はSlackより拝借）</font>
この時点では、なんの機能も設定されていないので、コマンドなどを追加していきます。
Slack Apps の詳細な仕様については、[公式ページ](​https://api.slack.com/start/overview​)から確認できます。


#### 2-2. スラッシュコマンドを設定する
Slack上でのコマンド入力によって、アプリが動作するように設定していきます。

`a) 「Add features and functionality」の項目内にある「Slash Commands」 をクリック。
します。`
![setup_slash_command1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/a6c1bc01-2813-c457-ecbb-2874ccc47040.png)


`b) 「Create New Command」 をクリックし、それぞれコマンドを作成します。`
![setup_slash_command2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/15568def-0451-302c-bb47-e51842a6dbff.png)


`c) コマンド設定に必要な情報を入力します。`
![setup_slash_command3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/aed44096-748a-6aa9-1b9c-a925dcde0781.png)


- Command
コマンドとして機能する文字列を入力します。
ここで設定した「/wfh」をSlackで入力することで、現在設定しているアプリがSlack内で起動するようになります。

- Request URL
[セットアップ準備​の項目](#1-2-Google-Apps-Scriptを新規作成)で新規作成した、Google Apps Scriptの「*現在のウェブアプリケーションのURL*」 を入力します。
これによって、アプリとGASが紐づけられます。

- Short Description
アプリの簡単な説明を入れることができます。
Slack上では他のユーザーの目にも触れるので、分かりやすい簡潔な内容がいいでしょう。

- Usage Hint
必ずしも必要ではありませんが、特定のコマンドが設定されている場合は、ユーザーガイドとしてそれぞれ記載できます。
今回のWFH Appでは、作業の開始・休憩・終了時など、特定のタイミングに文字列を投稿する下記のコマンドが使用可能です。

>・作業開始時のコマンド
　start -msg [文字列]

>・休憩時開始時のコマンド
　rest -msg [文字列]

>・休憩終了時のコマンド
　rest_end -msg [文字列]

>・タスクの進捗報告用コマンド
　task [ID] -msg [文字列]

>・タスク終了時のコマンド
　task_end [ID] -msg [文字列]

>・作業終了時のコマンド
　end -msg [文字列]

最後に「Save」をクリックすれば、コマンドの設定は完了です。


#### 2-3. Slack Apps をワークスペースに追加する

「Install your app to your workspace」の項目内にある「Install App to Workspace」をクリックします。
![install_apps_to_workspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/915c45f3-f62f-7e1a-9f42-060e2a0f33cc.png)

これで、現在のワークスペースに/wfhコマンドで動くアプリが追加されました。



#### 2-4. WebHook を登録する
文言を各チャンネルに投稿するためには、Slack側にWebhook（特定のコマンド実行などによって、指定されたURLにデータを追記する仕組み）を設定する必要があります。
Slack AppsはGUIが最適化されているので、__ここでコーディングなどは必要ない__です。楽ちん！

`a) 「Add features and functionality」にある「Incoming Webhooks」をクリック。`
![setup_incomming_webhook1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/9a01e79c-f681-4adf-2eb6-a2e81fc7a123.png)



`b) 右上の「Active Incoming Webhooks」のノブを On にします。`
![setup_incomming_webhook2 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/47cd97e0-f7e7-79b3-ccab-5bd77db8ae60.png)



`c) 「Add new Webhook to Workspace」をクリックして、Slackのどのチャンネル上でWebhookを機能させるか設定します。`
![setup_incomming_webhook3 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/5c0fc6f8-0a3f-f955-9acf-36e6489325e4.png)



`d) 作業状況を投稿したいチャンネルを選択し、「Allow」をクリックします。`
![setup_incomming_webhook4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/4bd152ab-d6ba-03ae-3827-2f2864c463dd.png)


以上でSlack Appsでの設定は完了したので、いよいよアプリの機能を編集していきます。


## Part 3. Config.gs セットアップ（GASでの操作）

再びGoogle Apps Scriptに戻ってきます。
Slack Appsのコマンドが有効に機能するよう、__「Config.gs」__ を編集して、Webhookとスプレッドシートの紐づけを行います。
![config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/5321f3b1-2326-19a6-0aa3-faf6f0b0c230.png)


#### 3-1. スプレッドシートIDを指定する
以下の変数に、​[セットアップ準備​で新規作成した](#1-3-スプレッドシートを新規作成)スプレッドシートのIDを代入します。
　*<font color="Crimson">※IDはスプレッドシートURLの ~d/......./edit で挟まれた箇所の文字列</font>*

    var googleSheetWorkingTimeID = "WFH working timeシートのID"
    var googleSheetReportID = "WFH reportシートのID"


#### 3-2. 利用ユーザー情報を入力する

次に、連想配列 __dSlackUsers__ に、以下３種のユーザー情報を入力します。

- SlackユーザーID
- 利用者名
- 利用チャンネル名（複数可）

__var dSlackUsers = {...}__ のカッコ内に、以下のフォーマットで入力します。

    "SlackのユーザーID": {"userName": "利用者名", "sheetName": "利用者名", "channel": ["利用チャンネル1", "利用チャンネル2", "利用チャンネル3"]}

また、カンマで区切って同じフォーマットを追加すれば、下記のように複数メンバー分の情報を追記できます。

    var dSlackUsers = {
      "U010Q8EMU5P": {"userName": "Van Minh Tri", "sheetName": "Van Minh Tri", "channel": ["general",
      "random", "remote_helper_testing"]},
      "U000X0XXX0X": {"userName": "Owlcat", "sheetName": "Owlcat", "channel": ["general", "random", 
      "remote_helper_testing"]},
      ...
      ..
      .
    };


__それぞれの値について__

- `SlackのユーザーID`
「U010Q8EMU5P」のような文字列で、各Slackアカウントのプロフィール画面から確認できます。

- `userName`
Slackのユーザー名を入力します。

- `sheetName`
スプレッドシート上に出力される利用者名を設定します。

- `channel`
コマンドを入力した際に投稿が行われるチャンネルを指定します。複数チャンネルを指定できます。


#### 3-3. Webhook URL の反映
最後に、連想配列 __dSlackChannels__ にアプリが稼働するチャンネル名とWebhook URLを代入していきます。
いずれも[Slack Appsの設定画面](​https://api.slack.com/apps​) で確認できます。
見つからない場合はメニューから「Features」 → 「Incoming Webhook」と洗濯していけば表示されます。
![setup_incomming_webhook3 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/ed7cf303-9f46-8ae4-ad34-99184de4ae82.png)



それぞれの情報は __var dSlackChannels = {...}__ のカッコ内に、以下のフォーマットで入力します。

    "Channel名": "WebhookのURL"

こちらも利用ユーザーの情報と同様に、カンマで区切って同じフォーマットを追加すれば、複数チャンネル分の情報を追記できます。

    var dSlackChannels = {
      "general": "https://hooks.slack.com/services/ABC...jklm1",
      "random": "https://hooks.slack.com/services/DEF...nopq2",
      "remote_helper_testing": "https://hooks.slack.com/services/GHI...rstu3",
      ...
      ..
      .
    };`

さて、以上でSlackから勤怠を入力するWork From Homeアプリが完成しました！
やったぜ！


## Part 4. 諸注意

`スクリプトを編集した際は、再度「公開」するまで編集内容が反映されません。`

セットアップ準備の時と同じく、ツールバーから「公開」→「ウェブアプリケーションとして導入...」と選択していきます。
ポップアップ内で 「プロジェクトパージョン」を「新規作成」にし、「更新」をクリックすることで内容が反映されます。
![update_gas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/ad6eccb8-4192-b515-9d6c-f1d832274dbc.png)



`Slackのエラーログ`

実際にSlack上で /wfh コマンドを実行したとき、__「operation_timeout」__ というエラーログが返ってくることがあります。
これはバグではなくSlack側の仕様で、コマンド実行から３秒経過しても何も起こらない場合、実行失敗と判定されることによるものです。

つまり、実際のスクリプト上は問題なくコマンドが機能しているので、WFH APP の動作に影響はありません。紛らわしいですね。
![operation_timeout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677497/43b8ff04-d723-26a4-fa95-c3d7c6b4e06d.png)

エラーを吐かれても、実行結果が正しく表示されていれば、問題ありません。


## さいごに
さて、ここまでWFHアプリの設定方法を細かくみてきましたが、実は同じ内容がGREVOのGitHub上、WFHアプリのページから確認できます。
内容は堅めですが、マニュアルも掲載しており、日本語・英語それぞれPDFでのダウンロードもできるので、必要に応じてご利用ください！

リモートワークを余儀なくされると、どうしても普段は感じないストレスを受けることもありますよね。
WFHアプリを使えば、ウェブカメラやボイスチャットによる進捗報告などの必要性も下がりますし、勤怠管理をする人の手間を省くこともできるはずです。
GASやSlack Botなどありもので作れるので、お金もかからないんですよ！（ココ重要）
スクリプトとかWebhookはよくわからない、怖いから触りたくない、という方もいらっしゃるかと思いますが、このアプリはあると便利なので、導入を検討してみてはいかがでしょうか。

というわけで、ストレスなく仕事ができればというささやかな願いもあって、今回のアプリを開発しました。
先の読めないコロナ禍ですが、どんな状況にも対応できるように備えておきたいデスネ。