【初心者向け】GASと連携して定期的に当番メッセージを送るslack botを作る


## 前提
slackアプリを作るには有料アカウントの必要あり。
個人用アカウントでは１ヶ月無料で有料アカウント状態になれるので、その期間で自己学習するのもアリ
JSで実装

### 実装するslackアプリ
ここで実装するプログラムの仕様は以下のような感じ
・週に１回メッセージを送信
・その週の当番をメンションしてメッセージ
・当番を担当するメンバーは決まっていて、週替わりでローテーションする

### ざっくり手順

1.Create New Appでslackアプリ作成
2.Basic Information設定(bot名・画像)
3.Webhook設定(botの権限・メッセージ先チャンネル)
4.GASでプログラム作成
5.GASで定期実行トリガー設定

### Create New Appでslackアプリ作成
このステップでアプリをどうやって作るか・アプリ名・アプリ導入するワークフローを決める。

[slack APIのコンソール画面から](https://api.slack.com/apps)アプリを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/d4f004fa-269d-4598-77b1-c119920a4886.png)
雛形から作る方法もあるけど、GAS連携する場合はFrom Scratchを選択(作り方)

その後にApp Nameでアプリ名、
Pick a workspace to develop your app in: で「どのワークスペースにアプリを入れるのか」を選択する
会社のslackで使う用のアプリを作る場合、アプリ導入のために別の課(総務課とか)の承認が必要なことがあったりする。


### Basic Information設定
アプリの中身の実質的な設定を行っていく。

#### botユーザ作成
・botユーザの名前
・botユーザの画像
を設定

Create New Appを終えると↓のような画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/9a498228-50c0-a858-7c04-61b4f496bf81.png)

サイドバーからApp Homeを選択し、遷移した先のApp Display Nameを編集。
ここでメッセージする時のbotユーザ名を設定する。
＊設定を忘れるとWebhookでメッセージ送信先を設定する時に「xxxにはインストールするボットユーザーがありません」と出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/fb90d6c2-8bb7-af25-5a19-2e78126521da.png)


### Webhook設定
・何をきっかけにメッセージを投稿するか
・メッセージの投稿先チャンネル
を設定

画面のIncoming Webhooksを選択、遷移した先の Activate Incoming Webhooksをonに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/e38bb99f-9f95-4c09-b499-2bcecb09ddef.png)

Onにした後に下に表示されるUIからAdd New Webhook workspaceを選択
↓のような表示になるので、メッセージを投稿するチャンネルを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/52247b91-7079-0869-7444-6e234dbffd14.png)

設定するとwebhookURLリストに連携用のURLが追加されているのが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/b0540d98-c53d-44a4-2665-c89e9d9c5839.png)


ここの設定をしたタイミングで、メッセージ投稿先チャンネルに「added an integration to this channel: 当番ですよ」みたいな通知メッセージが届く。

## GASでプログラム作成

chromeの右メニュー > ドライブ > 新規作成 > その他 > Goole Apps Script を選択
遷移した先に新しいプロジェクトを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/d4555e69-b3f4-7dc9-fb59-518c50c76a3b.png)

### コーディング
以下のような感じでコーディングする。

```.js
function announceMessage() {
  const memberList = ['当番候補ユーザーのID', '当番候補ユーザーのID2'];
  const message =  `次の当番は<@${memberList[0]}>さんです`;

  // format for sending...
  const options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : JSON.stringify(
      {
        "text" : message,
        link_names: 1
      }
    )
  };
  // exec send
  UrlFetchApp.fetch("webhookのURL", options); 
}

```
上記のうち、作成するごとに値を設定する箇所が2つある。
1つ目がmemberListの値。ここにはslackでメンションするユーザーのメンバーIDを入力する。
文字列で  <@メンバーID>とすれば、slackメッセージでメンションすることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/1975dde9-f6b7-ba00-0c30-0640b353b797.png)

2つ目がwebhookURL
こちらは連携用のURLをコピペすればOK

コーディングが終わったら、画面上部の[実行]を押す。

承認を求められるので。承認してあげる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/89c99628-71be-fe7a-def2-b6b3f7da87b2.png)

メッセージが投稿できたら、次へ進む

### 定期通知の設定
定期的な通知の設定はGAS側でしていく。
GASのサイドバー トリガー > トリガーの追加

トリガーの設定モーダルが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/8c067415-e1c4-2ab6-7be6-dbe9646b3677.png)

項目はパッと見で大体分かるが、いくつか補足。
・実行するデプロイを選択
GASは何度かコードをデプロイすると古いバージョンをデプロイすることも可能になる)。 HEADは最新のコードを実行する設定なので、特に理由がなければHEADにする。
・イベントソースの選択
一定時間ごとに実行するなら時間手動型、間隔がまばらで特定の日にちに実行したい時はカレンダー型で設定

今回は週単位の当番を想定して、画像のような時間手動型で設定しています。
1分おきに送信されるのを確認したら、改めて実運用で実行したい間隔に調整する。

### 当番のローテーション設定
[Class PropertiesService](https://developers.google.com/apps-script/reference/properties/properties-service)で前回メンションしたメンバーを管理,ローテーションしてメッセージするようにする。

```.js
function announceMessage() {
  // get last time person
  var properties = PropertiesService.getScriptProperties();
  // 取得する値は常に文字列。数値と比較するためキャスト
  var lastTime = Number(properties.getProperty('lastTime'));
  var next = null;
  const memberList = ['memberID', 'memberID2'];
;
  // 初回実行時を想定
  if (lastTime !== null) {
    next = (lastTime + 1) === memberList.length ? 0 : ++lastTime;
  } else {
    next = 0;
  }
  properties.setProperty('lastTime', next);

  const message =  `次の当番は<@${memberList[next]}>さんです`;
  // format for sending...
  const options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : JSON.stringify(
      {
        "text" : message,
        link_names: 1
      }
    )
  };
  // exec send
  UrlFetchApp.fetch("webhookURL", options); 
}
```
複数回実行して、ローテーションしているのを確認できたら完成!

### こんなのやりたいな

・何らかの事情で当番できない場合は何らかのアクション(パスボタンを押す?)で別のメンバーを代番になるようメッセージしてくれる
・代わった相手が当番をした場合、代わってもらった相手は代わってくれた人の当番をする

当番って何かの事情で当初の担当者をスキップしたりすることもあると思うので、
それをふまえると↑の方な機能もしたいですね〜。
近々このあたりも実装したいな〜と思います。

### 参考資料
[【雑学】SlackとGASで定期的に通知を送るBotを作成する](https://tektektech.com/slack-gas-auto-notice-bot/#GAS)
[Google Apps Script (GAS) で Slack 連携を実装する前に知っておくとよい 5 つのこと](https://qiita.com/seratch/items/2158cb0abed5b8e12809)
[GAS ビギナーが GAS を使いこなすために知るべきこと 10 選](https://qiita.com/tanabee/items/2c51681396fe12b6a0e4)
[【2021年版】GASとSlack APIでボットを作成しチャンネルにメッセージを自動投稿する方法](https://auto-worker.com/blog/?p=2904#toc_id_4_1)