タスク漏れ防止にGoogle Apps Script（GAS）でSlackに通知

## はじめに
[ｋ．ｓ．ロジャース](https://www.wantedly.com/companies/ks-rogers)の藤本です。

僕、タスク漏れが多いです。

弊社はGitLabを多く使用しているので
GitLabのissueでアサインされているものをSlackに通知してみようと思います。

前提として、
そもそもGitLabでissue一覧を見ることができるので
そちらを毎日見るよう癖づければ全く必要のない作業です。
僕は怠ってしまいがちなので一番目を通すSlackに通知することで対策しようと考えました。

## 準備

- GitLabのAPI
- SlackのWebhook
- スプレッドシート

上記3つを使用します。

## GitLab

APIでissue一覧を取得します。
まずinsomniaを使ってテストしました。

https://docs.gitlab.com/ee/api/issues.html

上記を参考にRequestを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/9e91d0f2-bbc2-763b-e923-30f6a9866fe8.png)

一部マスキングしていますが、問題なくアサインされているissueが取得できていることが確認できました。

## Slack

https://slack.com/services/new/incoming-webhook

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/edb19fd1-6d46-8879-9221-932315c09925.png)

通知したいチャンネルを設定します。
（当然#generalには通知しません、僕は個人のDMを選択しました）

webhookのURLが発行されるので、この後で使用します。

## スプレッドシート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/48471607-51f6-9614-b61a-ba469a06da39.png)

上記のスクリプトエディタを使用します。
書き方はほとんどJavaScriptです。ES6の書き方ではエラーが出ました。
期日が設定されていないものもあったので、`9999/01/01`としています。

タスクをSlack送るだけだと少し寂しいのと、curlコマンドをcronで設定すればGASを使う必要性がなくなるので
Gitlabスプレッドシートに記載 + スプレッドシートに記載されているタスクを一緒に通知しました。

```javascript
function callSlack() {
    // GitLabのAPIからissueを取得
    var url = 'https://gitlab.com/api/v4/issues?assignee_username=[ユーザーID]&scope=all&state=opened&private_token=[PricateToken]'

    // Gitlab用メッセージを作成
    var message = 'Gitlab' + '\n';
    var fetchIssueList = JSON.parse(UrlFetchApp.fetch(url).getContentText());
    var issueArray = fetchIssueList.map(function (issue) {
        message += addMessage(issue.title, issue.due_date ? issue.due_date : '9999-01-01', issue.web_url);
        return [issue.title,　issue.due_date, issue.web_url]
    })
    var headerRow = ['タイトル', '期日', 'URL']
    issueArray.unshift(headerRow);

    // 書き込むSheetを用意
    var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadSheet.getSheetByName('gitlab')
    sheet.clear()
    var range = sheet.getRange(1, 1, issueArray.length, headerRow.length)
    range.setValues(issueArray)

    // その他用メッセージを作成
    message += 'その他' + '\n';
    sheet = spreadSheet.getSheetByName('other');

    var otherRange = ("" + sheet.getRange(2, 1, 10).getValues()).split(',');
    var otherRowLength = otherRange.filter(Boolean).length;
    var titleList = sheet.getRange(2, 1, otherRowLength).getValues();
    var dueDateList = sheet.getRange(2, 2, otherRowLength).getValues();
    var urlList = sheet.getRange(2, 3, otherRowLength).getValues();
    for (var i = 0; i < otherRowLength; i++) {
        message += addMessage(titleList[i], dueDateList[i], urlList[i] != '' ? urlList[i] : 'https://ks-rogers.co.jp/');
    }

    postSlack(message);
}

function postSlack(message) {
    var webhook = "[WebhookURL]";
    var options =
    {
        "method": "post",
        "contentType": "application/json",
        "payload": JSON.stringify({ "text": message })
    };

    UrlFetchApp.fetch(webhook, options);
}

function addMessage(title, dueDate, url) {
    var date = new Date(dueDate);
    return '[' + date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate() + '] <' + url + '|' + title + '>' + '\n';
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/f7eda746-062a-a0ae-3bc5-1825082692a0.png)

シート `gitlab` にはこんな感じリストが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/ecbdbfbd-e55a-c9b8-981e-5fbcb14f353c.png)

シート 'other' はこのように用意

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/687205ab-3b7c-4794-a9e4-a67961dc570e.png)


指定したチャンネルにメッセージが送信されていることが確認できたので
毎日定期実行されるように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/66a7f40e-604f-9c36-c190-a083fe45624e.png)

僕は起きるのが遅いのでお昼ごろに設定しました。
仕事時間がいつでも良いのがKSRの魅力ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448157/21ad0708-6122-ec8f-05b9-d6cd84c813f2.png)

# 最後に

内容が短くなってしまいましたが、こちらで終わりです。


最初は期限近いもの、期限が切れているものだけを判定して通知させようと考えましたが
やはり全体が見れたほうがいいかなと思いすべて通知させることにしました。

アサインされているタスクの量があまりにも膨大になったときと感じたときには
朝に全体、昼に期限を判定とした何かを通知させる・・・など考えてみたいと思います。

「こんなことをしてタスク漏れを防止しているよ！」などがあればぜひ教えて頂きたいですm(_ _)m

### Wantedlyでもブログ投稿してます
Techブログに加えて会社ブログなどもやっているので、気になった方はぜひ覗いてみてください。
https://www.wantedly.com/companies/ks-rogers