【システム連携】GASを活用し、Slackとスプレッドシートを連携!タスク漏れの回避を実現。無料でできる簡単システム連携方法についてのご紹介

こんにちは。
弊社のサイトに訪問いただき誠にありがとうございます。
株式会社SPALOの蒲原です。

さて、本日の題材ですが、前回の記事で実際に弊社で活用している取り組みをご紹介しました。

【タスク管理のコツ】期限までのスケジュールを可視化!GASを活用したアラート機能を実装!Slackなどのチャットツールに投稿しチーム内での共通認識が芽生えタスク漏れの回避に。

本日はその取り組みを行うために書いたGASのコードなど、連携方法を紹介したいと思います。
※まだ記事を呼んでいない方は先に記事を読んでいただくとより理解が深まると思います。

GAS(Google Apps Script)とは

Google Apps Script(略称GAS/ガス)とは、Googleによって開発されたスクリプトプラットフォームである軽量のアプリケーション開発のためのGoogleのワークスペースプラットフォーム。 主にGoogleのサービスを自動化するスクリプト言語である。JavaScriptがもとになっているため汎用性が高く、開発環境はGoogle Chromeだけでいいのでプログラミング初心者が始めやすい言語の1つである。

Google Apps Scriptは当初、Mike HarmがGoogleスプレッドシートの開発者として働いていたときに、サイドプロジェクトとして開発された。Google Apps Scriptは、2009年5月に、GoogleドキュメントのプロダクトマネージャーであったJonathanRochelleによってベータテストプログラムが発表されたときに初めて公開された。 その後、2009年8月にGoogle AppsScriptがすべてのGoogleAppsPremierおよびEducationEditionのお客様に利用可能になる。 これはJavaScript1.6に基づいているが、1.7と1.8の一部、およびECMAScript 5APIのサブセットも含まれている。Apps Scriptプロジェクトは、 Googleのインフラストラクチャで、サーバー側で実行される。 Googleによると、Apps Scriptは、「Google製品とサードパーティサービス全体のタスクを自動化する簡単な方法を提供します」。 Apps Scriptは、 Googleドキュメント、スプレッドシート、スライドのアドオンを強化するツールでもある。

引用元:引用: フリー百科事典『ウィキペディア(Wikipedia)』

と聞いても難しいですよね?
簡単に言うと、Googleが開発したプログラミング言語で、Googleの提供するGoogleカレンダーやスプレッドシートなどのサービスと連携するためのプログラミングを書くことができる無料のプラットフォームのことです。

実際にやっていた内容はこちら

タスク管理の仕方

Googleスプレッドシート(Googleが提供する無料の表計算ソフト。Excelみたいなもの。)にタスクを記入する。

タスクの詳細をSlackにつぶやく

タスクの期限日が5日以内のものと、期限日が過ぎているものをSlackのチャンネル(トークルーム)につぶやくボットを作成。

ステータスをSlackで変更する

つぶやいた内容に対し、指定のスタンプを押すことでスプレッドシートのステータスを変更する。

連携に必要なもの

タスク管理:Googleスプレッドシート
プログラミングのコードを書く場所:GAS(Google Apps Script)
チャットツール:Slack
ステータス変更:Slackのスタンプ

連携までの流れ

  1. Googleスプレッドシートにタスク管理表を作成します。
  2. GASを開きます
  3. スプレッドシート⇒ツール⇒スクリプトエディタで開くことができます。

  4. タスクの詳細をSlackにつぶやく
  5. ▼書いたコードはこちら

    
    function slack_tsubuyaku(){
    //スプレッドシートを指定
    const ss = SpreadsheetApp.openById('※スプレッドシートのURL');
    
    //シートを指定
    const sheet = ss.getSheetByName("※シート名");
    
    //シートの最終行を取得
    
    let lastrow = sheet.getLastRow();
    
    //範囲をまるっと取得する※1行ずつ取得しているとAPIでつながっているため効率悪い
    //範囲を入れる配列※複数セルを選択してコピーするイメージ
    //let hairetu = sheet.getRange(row最初の行, column最初の列, numRows,そっから最後の行 numColumnsそっから最後の列)
    let hairetu = sheet.getRange(17, 2, lastrow-17, 11).getValues();
    let message = "";//あとでつぶやく内容を入れる
    let channel = "スラックのチャンネル名"
    let username = "敏腕秘書のカモ姉さん"
    let icon_emoji = ":スラックのスタンプ名:"
    
    //まず、範囲の1行目(配列の0行目に対して考える  //hairetu.length=配列の長さの分だけ
    for(let i = 0; i< hairetu.length;i++){
    //期限日
    let kigenbi = Moment.moment(hairetu[i][3]);
    
    //今日の日付
    let kyou = Moment.moment(new Date());
    
    //明日の日付
    let ashita = Moment.moment(new Date());
    ashita.add(1,'days'); //getDateは日付形式の中から月日を取り出す
    
    //日付を比べる
    let kyoukana = Moment.moment(kigenbi).isSame(kyou,'day');
    /*
    Moment.moment(日付1).isSame(日付,'単位');
    日付1と日付2が単位で等しいかどうか比べる
    true・false
    */
    let ashitakana = Moment.moment(kigenbi).isSame(ashita,'day');
    
    //ifで日付を比べて今日か明日ならログを出す
    if(kyoukana||ashitakana){
    let tantousya = hairetu[i][0];//担当者
    let naiyou = hairetu[i][7];//内容
    let status = hairetu[i][10];//ステータス
    
    //ステータスが完了の時だけスラックにつぶやく
    if(status !="完了"){
    message = ":おばけ:" + ":jack_o_lantern:" + ":おばけ:" + "残タスク報告" + ":おばけ:" + ":jack_o_lantern:" + ":おばけ:" + "\n" + "\n" + "【担当者】" + tantousya + "\n" + "【タスク内容】" + naiyou + "\n" + "【進捗状況】" + status + "\n"  + "\n" + "忘れていませんか?" + "毎日タスクは更新してね♪";
    slack(message,channel,username,icon_emoji);
    }
    }
    }
    
    }
    
    function slack(message,channel,username,icon_emoji) {
    // 各所必要な項目をセットします
    var url        = 'https://slack.com/api/chat.postMessage';
    var token      = '※スラックのトークン';
    // var channel    = 'スラックのチャンネル名';
    var text       = message;
    var method     = 'post'
    var payload = {
    'token'      : token,
    'channel'    : channel,
    'text'       : text,
    'username'   : username,
    //  'parse'      : parse,
    'icon_emoji' : icon_emoji,
    };
    var params = {
    'method' : method,
    'payload' : payload
    };
    var response = UrlFetchApp.fetch(url, params);
    }
    

    ※スプレッドシートのURL…画像の赤枠部分

    ※シート名…const sheet = ss.getSheetByName(“SPALO営業チームタスク表【改】”);

    ※スラックのチャンネル名

    ※スラックのスタンプ名…Slackのスタンプの名前を「:」と「:」の間に記載する

  6. ステータスをSlackで変更する
  7. ▼書いたコードはこちら

    
    function doPost(e){
    // event parametersの取得
      let params = JSON.parse(e.postData.getDataAsString()).event;
      // SlackApp インスタンスの取得
      let token = PropertiesService.getScriptProperties().getProperty('SLACK_ACCESS_TOKEN');
      let slackApp = SlackApp.create(token);
      let channel = 'CQBKH26BB';
      let kanryou = "完了";
      let tyakusyu = "着手中";
      let mityakusyu = "未着手";
      let machi = "待ち";
      let message = ""  ;//先に変数を定義
      let status = "";
      Logger.log(params.type);
      Logger.log(params.reaction);
      if(params.type === "reaction_added") {
      //絵文字の内容で場合分け
        if(params.reaction === kanryou){
        //完了の時の処理
        status = "完了";
        }else if(params.reaction === tyakusyu){
        //着手中のときの処理
        status = "着手中";
        }else if(params.reaction === mityakusyu ){
        //未着手のとき
        status = "未着手";
        }else if(params.reaction === machi){
        //まちのとき
        status = "待ち";
        }else{
        exit;
        };
        //スタンプがついたメッセージの内容を取得
        let ts = params.item.ts; //タイムスタンプ
        let getUrl = 'https://slack.com/api/conversations.replies?token=' + token + '&channel=' + channel + '&ts=' + ts + '&pretty=1';
        let toukou = UrlFetchApp.fetch(getUrl); //URLに接続する
        let toukouJSON = JSON.parse(toukou);  //配列に変換する  
        let toukoutext = toukouJSON.messages[0].text; //投稿内容
        let reg_tantousya = /【担当者】([\s\S]*?)\n/ ;
        let reg_task =  /【タスク内容】([\s\S]*?)\n/;
        let tantousya = toukoutext.match(reg_tantousya);
        tantousya = tantousya[1];
        let task = toukoutext.match(reg_task);
        task = task[1];
        supusihenkou(task,tantousya,status); 
        message = '担当者は' + tantousya + 'だよ:heart:内容は' + task + 'を【' + status + '】に変えたぴょん:kamokamo::sumi:';
      let options = {
        channelId: "SPALO営業部",              //チャンネル名
        userName: "てすとだよ", //投稿するbotの名前
        emoji: ":おばけ:",           //iconのemoji
        message: message    //投稿するメッセージ
      };
      Logger.log(message);
      let res = slackApp.postMessage(options.channelId, options.message, {username: options.userName, icon_emoji: options.emoji});
      };
    /*
      // Slackバリデーション用
      let params = JSON.parse(e.postData.getDataAsString());
      return ContentService.createTextOutput(params.challenge);
    */
    }
    function supusihenkou(task,tantousya,status) {
    //スプレッドシートを指定
    const ss = SpreadsheetApp.openById('※スプレッドシートのURL');
    //シート名を指定
    const sheet = ss.getSheetByName("※スプレッドシートのシート名");
    //範囲を丸っと指定
    let lastrow = sheet.getLastRow();   //シートの最終行を取得
    let hairetu = sheet.getRange(17, 2, lastrow - 17, 11).getValues(); //範囲をいれる配列
    //配列の最初(0番目)から、最後まで繰り返し
    for(i=0;i<hairetu.length;i++){
      if(hairetu[i][7] == task && hairetu[i][0] == tantousya){
      //iがiの時タスク管理表はi+17行目
      sheet.getRange(i+17,12).setValue(status);
      }
    }  
    }
    
  8. GASを実行する
  9. 公開⇒ウェブアプリケーションとして導入⇒Project version:をNewにする⇒更新
    でGASが実行されます。

  10. 毎日決められた時刻につぶやく設定をする

毎朝9時から10時にGASを実行させるスケジュールを設定します。
すると毎朝タスク管理表から直近のタスクと期限が過ぎているタスクをSlackに自動でつぶやいてくれる設定のできあがりです。

まとめ

どうでしょうか???ちなみに私はGAS初心者です。
GASを週に1回30分だけ時間を取って学び始め半年ぐらいで書きました。
プログラミングを少し学ぶようになってから、何かをするときに手順(ストーリー)を考える癖ができました。例えば、提案資料を作るときにもすぐにパワーポイントに向かおうとせずにどんな流れでどんな結果に持っていきたいか?などです。
今回はスプレッドシートとSlackの連携方法についての記事でしたが、今後またGASの記事も上げたいと思います。最後まで読んでいただきありがとうございました。

参考サイト

【初心者向けGAS】本当の最初の一歩!スクリプトエディタでプロジェクトを開く(最終更新:2021年2月4日)

初心者がGASでSlack Botをつくってみた(投稿日:2015年12月12日)