GoogleAppsScript
Slack

【初心者向け】GASを使ったスプレッドシートとSlackの連携(bot制作)

ざっくりな概要

GASを利用して
Google SpreadsheetとSlackを連携させ
指定時刻にスプレッドシートの内容をSlackにリマインドするbotの制作

ことの経緯

日々スプレッドシートに記入しているタスクを
チームのSlackに投げることで自身のコミットを高めようと思い
また、何か動くモノをつくりたいよぉ!というモチベから動きました
偉大なる先達が残したサイトを参考にしながら取り組み、七転八倒しながらもなんとか完成へ

自身のつまづいた箇所や疑問点を盛り込んだ、初心者の初心者による初心者のための記事
かつ自身のアウトプットをかねたQiita初エントリーとなります

※プログラミング開始して2ヶ月のレベル感
 想定読者は制作前のjsをほぼ知らない私

できるようになること

・スプレッドシートとSlackの連携
・スプレッドシートの内容を自動でSlackのチャンネルに通知
・詳細な通知時間の設定

前提条件

・Slackアカウントあり 
・googleアカウントあり
・上記の基本操作問題なし

使用技術

GAS
 Googleが提供するJavaScriptベースの開発環境

・Google Spreadsheet

・Slack

Incoming Webhooks
  SlackのAPIで外部サービスからSlackにメッセージ送信することができます

手順

1  Slackにテスト用チャンネルを設定

  1. Slack画面の「チャンネル」横のプラスをクリック

スクリーンショット 2018-09-30 22.41.06.png

2. 適当な名前でチャンネルを作成
今回は「test-slack」で進めます

2  SlackのIncoming Webhooksの準備

  1. Slackでログインしている状態で下記URLにとび、先程作成したチャンネルを選択し追加します
    https://my.slack.com/services/new/incoming-webhook/
    スクリーンショット 2018-09-30 22.46.52.png

  2. 下にスクロールすると画像のような箇所がでます
    このWebhook URLは後に必要なのでメモしておきましょう
    また、ここからデフォルト設定をいじれるのでお好みでどぞ
    スクリーンショット 2018-09-30 22.54.38.png

  3. 設定を保存するとtest-slackにこんな通知がきます
    スクリーンショット 2018-09-30 23.06.00.png

3 スプレッドシートの準備

  1. Slackと連携させたいスプレッドシートを開き、URLの一部をコピー

    https://docs.google.com/spreadsheets/d/1a2s3d4f5g6h7j8k9l/edit#gid=1866794787 

    この部分 → 1a2s3d4f5g6h7j8k9l

  2. ツール → スクリプトエディタ で編集画面タブを開きます
    この編集画面にgasを記述していきます

    スクリーンショット 2018-09-30 23.12.49.png

  3. シート名はgasのコードに記述します!  今回は「Report-sheet」
    スクリーンショット 2018-10-01 10.45.51.png

4  GAS作成 第1段階 〜Slack連携〜

下記内容をスプレッドシートのエディタに添付(適宜変更をお願いします)

要所
 ①スプレッドシートのURLからコピーした文字列を入力
 ②連携したいシート名を入力
 ③Webhook URL (2-2.でコピーしたもの)

function postSlack() {
  var obj = SpreadsheetApp.openById('①スプレッドシートのURLからコピーした文字列を入力'); 
  Logger.log(obj);

  var sheet = obj.getSheetByName("②連携したいシート名を入力"); 
  Logger.log(sheet);
  // 名前やメッセージを出力したい場合利用 (\nは改行の意味)
  var name = 'una\n'  

  // getRangeでスプレッドシートの連携したい箇所を指定 今回はB列の全てを指定  filter(String)で文字だけをフィルタリング
  var values = sheet.getRange("B:B").getValues().filter(String); 
  Logger.log(values);

  // 例 [a,b,c,d] 要素の数は4つ(length)  dのindex番号は3  dを抽出したい場合、 4(length)−1
  var last_row_array = values[values.length-1];  
  Logger.log(last_row_array);

  // 今回はB列の最終行(last_row)をslackに送りたい
  var text = last_row_array[0];
  Logger.log(text);

  // payload=データ本体のこと  Slackに送信(post)する内容
  var payload  = {
    'text'      :  name + text,    // 変数のため''はいらない nameは利用しない場合消す
    'username'  : 'タスクさん',      //botの名前
    'channel'   : 'test-slack',   //投稿するチャンネル名
    'icon_emoji': ':hedgehog:',   //botのアイコン 
  };

  // Slackに送信
  var options = {
    'method'      : 'post',
    'contentType' : 'application/json',
    'payload'     : JSON.stringify(payload), // jsの値をJSON文字列に変換
  };

  var url = '③Webhook URL (2-2.でコピーしたもの)';
  UrlFetchApp.fetch(url, options);
}
  1. では、さっそく ▶ をクリックしてテストをしてみましょう 
    スクリーンショット 2018-10-01 0.02.40.png

  2. 初回に限り承認画面がでると思いますが、内容を読みながら許可をして進めます

  3. 連携したslackチャンネルに投稿通知がながれるはずです
    スクリーンショット 2018-10-01 9.16.15.png

デフォルトで9~10時などの間に通知する設定が行えます
タイマーぽいのをクリックすると
スクリーンショット 2018-09-30 23.40.35.png
こんな画面が表れます
スクリーンショット 2018-09-30 23.43.22.png
アバウトな時間指定が行えます ※詳細な時間も可能ですが少し不便な仕様です

5  GAS作成 第2段階  〜詳細時刻指定〜

定時にタスクつぶやいてコミットしたいんだよぉ!
と意識だけは高い系なので毎日10:01に通知する設定にしたいと思います

トリガーを2つ設定します
①デフォルトのsetTriger (9~10時設定)
②10時01分に実行されるsetTriger

大雑把な流れとしては
②のトリガーを記述し、次に②のトリガーを消す関数を書きましょう
そして通知用の処理の実行コードの記載へ
①はデフォルトトリガ(タイマーぽいマークのやつ)を利用します
注意点:①のトリガーは②の時刻より早い設定にしてください

 // 10:01に起動するトリガー(setTrigger)を指定
function setTrigger() {

  var day = new Date();  
  day.setHours(10);      //時間を指定
  day.setMinutes(01);    //分を指定
  ScriptApp.newTrigger("postSlack").timeBased().at(day).create();  //指定された日付にpostSlackを実行
  Logger.log('postSlack')
}

// トリガーを除去する関数   「10:01」のトリガーを消去しないと残ってしまうため
function removeTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for(var i = 0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() === "postSlack") {       //トリガーに設定された関数名を取得
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}


function postSlack() {      // postSlackの処理
  removeTrigger();          //トリガーの除去

  //以下、第1段階のコードと同じのため省略
  var obj = SpreadsheetApp.openById('①スプレッドシートのURLからコピーした文字列を入力'); 
  Logger.log(obj);

6  あとがき

動くモノってこんなに愛いやつなんだと思いながら、日々タスクボットをながめています
jsもままならない中、気持ち先行でつくったものではありますが、アウトプットの大切さを実感しました
作りながら理解する・作ってから理解する
といったプログラミングの学び方もあるんだなーと新たな発見があり、充実したものとなりました!
制作では多くのサイトを参考にし、作り上げたものとなります
なので先達には感謝の念と共に、私も初学者フレンドリーなアウトプットを沢山行っていこうと思いを固めた次第であります

7  参考

GAS
https://daiiz.hatenablog.com/entry/2015/02/22/182359
https://www.minemura-coffee.com/entry/2016/06/15/070611
https://blog.zuckey17.org/entry/2018/04/29/235946
https://fukatsu.tech/gas-to-slack
https://tonari-it.com/google-apps-script-manual/
https://qiita.com/chihiro/items/d23692c308c89e1b1ee2

非常に助かりました!
ありがとうございます!