Slackから一瞬でGoogle MeetのURLを取得できるAppをAppsScriptを使って作る

#はじめに

こんにちは。NTTドコモの栗原と申します。
普段は開発のマネジメントをしていますが、働く環境をより良くするための（楽するための）環境整備のための開発は自分で行ったりしています。

弊社ではSlackが全社的に導入され、またコロナでのリモートワーク環境化も進み、Slack上で仕事を進めることがかなり中心的になってきています。

今日は、その一環で作ったSlackとGoogle Meetの連携について解説を行うことで、

- 実際にSlackで動くbotを作ってみれる
- SlackのSlashコマンドとbotについて理解を深める
- そして似たような環境の人はハッピーになれる

を目指す内容となっています。

#本記事の内容
下記のような課題を解決するために、SlackとGoogle Apps Scriptで会議を簡単に開ける環境を作ります。

## Slackで気軽にミーティングをしたいときにすること
ハドルミーティングがまず候補に上がってきますが、ちょこっと話したいだけなのに

- 参加（して欲しい）メンバーとチャンネルの関係を気にする

のが結構大変です。

ハドルミーティングの場合は、

1. 会議が開かれていることが、そのチャンネル参加者には伝わってしまう（呼ばれてない・・参加した方がいいの？みたいな配慮が発生してしまう）
1. そのハドルで何の会話されているかわかりにくいことがある（これからxxをハドルで会話します！みたいなコメントが必要になり、ハドルの頻度が上がると少し混乱してくる。）
1. 同じチャンネルで複数のハドルが開けない

と言ったような課題もちらほら

と、一生懸命ネガティブ要素を書きましたが、このスクリプトを組んだ時点ではハドルだとモバイルに対して画面シェアできなかったのが一番の理由で、正直上記の理由は後付けです。

## ではどうすれば良いのか
シンプルにSlackでコマンドを叩くとGoogle MeetのURLが発行されたら便利じゃないですか？ということで、作っていきたいと思います。

出来上がるものとしては下記になります。

:::note info
Slackのスラッシュコマンドで/mewとコマンドを打つと、Google MeetのURLを返答するbot
:::

# 構成
下記のような流れで説明をしていきます。

1. Slack Appの作成
1. 会議設定をするApps Scriptの作成
1. Slashコマンドの作成
1. Appのワークスペースへのインストール

## 1.Slack Appの作成
早速ですが、下記URLにアクセスし「Create New App」を選択、From Scratchで作り始めます。

https://api.slack.com/apps/

![P2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/11fcabde-7984-bd91-881e-60a475225653.png)


アプリ名と設定先のワークスペースを選択します。
ここでは、MeetとNewをかけてMewという名前で進めます。
![P3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/e827c084-4a6f-fadd-119e-2770a16d7e16.png)


アプリが出来上がると、下記のような画面になります。
![P4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/1575d620-a9bd-90b6-1c23-aba2ba04c74f.png)

最終的には
Slashコマンドに対応させるために「Slash Commands」
上記の権限設定のために「Permissions」
を設定します。

下の方にスクロールしていくと、アプリのアイコンなどを設定できるので設定しておきましょう。

## 2.会議設定をするAppsScriptの作成
アプリの設定は一旦ここで中断して、Scirpt側を準備していきます。
### 2.1.Google カレンダーの下準備
早速AppsScriptに向かいたいところですが、下準備として、まずはカレンダーの準備をします。
なぜなら、ミーティングが設定されるたびにイベントが作られるので、専用のカレンダーを作ることでカレンダーが見にくくならないようにするためです。
+ボタンから「新しいカレンダーを作成」し、作成後、カレンダーのメニューの「設定と共有」からカレンダーIDを取得します。

![P12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/714a8505-2c4e-e2f6-6e9e-4b92101ce62d.png)
![P13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/ae12d7b2-11d5-314f-2e5c-d86d9944775b.png)

### 2.2.Apps Scriptの作成と動作チェック
Apps Scriptは以下から作成することができます。

https://script.google.com/home/start

まずは、プロジェクト名を設定し、左側メニューの「サービス」からGoogleカレンダーを追加します。

![P9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/647d86d2-2cbc-b711-a5f0-fa1a0c6752d9.png)


```javascript:コード.gs
const CALENDAR_ID = 'xxxx@group.calendar.google.com' //TODO:ここに2.1で取得したカレンダーIDを設定してください。
const EVENT_TITLE = 'instant meeting' //自動生成されるミーティング名。お好みで。

function doPost(e) {
  // ミーティング日時の設定
  let startTime = new Date();
  let endTime = new Date();
  //終了時間を1時間後に設定
  //30分が良い場合などは、startTime.getMinutes()+30などを指定
  endTime.setHours(startTime.getHours()+1); 

  // Calendarに登録するデータの設定
  // conferenceDataが含まれたデータをconferenceDataVerion:1で指定するとGoogle Meet付きのイベントを作成可能
  const detail = {
    summary: EVENT_TITLE,
    start: {
      dateTime: startTime.toISOString()
    },
    end: {
      dateTime: endTime.toISOString()
    },
    attendees: "",
    conferenceData: {
      createRequest: {
        conferenceSolutionKey: {
          type: "hangoutsMeet"
        },
        requestId: Math.random().toString(32).substring(2)
      }
    }
  };
  
  //Google Calendarにイベントの登録
  const event = Calendar.Events.insert(detail, CALENDAR_ID,{ conferenceDataVersion: 1 });

  response = {
     response_type : "in_channel",
     text: event.hangoutLink //会議URL
   };
 
   //responseで設定された文字列を応答
   return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}
```
（各コードがどんなことをしているかはコード内のコメントを参照ください。）

上記のコードを貼り付けて、実行を押すとGoogleカレンダーのアクセス権限を求められます。「権限を承認」を押すとログイン画面になりますので、Googleアカウントにログインしてください。すると下記の画面が出てきますので、「詳細を表示」→「GoogleCalendarToSlack（安全でないページへ移動）」を選んでください。

![P11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/10a2927f-60d3-6882-81df-b57ee83adf29.png)

すると、アクセス許可を求めるページが表示されるので「許可」をしてください。

![P11-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/0db35ea0-66d3-cc42-beb7-e2f313fc5a77.png)

この状態で実行ボタンを押すと、カレンダーにイベントが追加されたことが確認できたと思います。

### 2.4.Apps Scriptのデプロイ
右上の「デプロイ」→「新しいデプロイ」からデプロイ（公開）します。
種類の選択→「ウェブアプリ」を選択して以下のように設定します。
![P14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/38af8a8e-0412-bacb-630a-1d1a3ba97b29.png)

「説明文」・・・任意で構いません。初回リリースと書いておくのが無難です。
「次のユーザーとして実行」・・・自分のアカウントを設定
「アクセスできるユーザー」・・・全員

![P16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/d4f1ad23-92a8-eb9d-54d7-ccd1bee471d5.png)

デプロイが完了すると、ScriptのURLが発行されるため、それをコピーします。
これは次のステップで利用します。

## 3.Slashコマンドの作成
SlackのAppページに戻り、先ほどコピーしたURLを使ってSlashコマンドを設定します。
「Slash Command」→「Create New Command」でコマンドを作成します。

![P17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/8fd7d97d-6fb1-9dfa-4c8a-d4135f27a8d2.png)

以下のように設定をします。
「Command」→ 実際にこのbotを呼び出すときのコマンドを設定します。今回はmewと設定しました。
「Request URL」→2.4で取得したURLを設定します
「Short Description」→わかりやすい説明を書いておきます

## 4.Appのワークスペースへのインストール
SlackのAppページの「Install your app」からアプリをインストールして完成です。

チャンネルで/mewとコマンドを打つと無事会議URLが払い出されます。

![SS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/b2904e7f-c332-882c-a0c1-ca88ecb68a34.png)



## 5.環境によっては追加で実施する必要がある改善
ここまでで作られたGoogleMeetの会議ですが、GSuiteアカウントがホストになる必要があります。このため、GSuiteアカウントでない環境の場合は、参加者を設定する必要が出てきます。
[この辺り](https://cloud-ace.jp/column/detail87/)のページを参考に、

1. コマンドを打つ際に、Slack上でメンションを行うようにして
1. そのメンションのユーザーIDを元にSlackAPIを通してメールアドレスを取得し
1. 取得したメールアドレスを参加者（attendees）として会議情報にあらかじめ付与する

とすると、会議をメンションしながら、呼ばれた人は参加できる会議を作ることができます。

## 6.さいごに
とここまで書いてみましたが・・・
1:1でちょっと会話したいとき、（コロナ前はよく行われていた「１分いいですか？」というアレ）/mew とコマンドを打つのでも良いですが、相手が忙しかったりなんだりするかもしれないし・・・と相手の様子が気になると思います。

そんなときは気軽にノックして話せるnockというサービスがおすすめです。
詳しくは下記ページで確認してみてください。

![nock.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277131/632d6494-f73a-d7a8-2504-228b4e06ba3e.png)


https://nock-app.com/?source=rd