【営業向け】スラックに投稿されたお気に入りの資料をGoogleDriveへ自動アップロードする

#やりたいこと＆その理由

スラックを使っている営業マンならよくあると思いますが、『あ、この資料どこかで使えそう！』って思うと、メッセージにブックマークのチェックしませんか？　でも、色々なメッセージにブックマークをしてしまうと、いざ資料が必要だって時に探す手間が結構かかりますので、別途GoogleDriveに自動でアップロードして、整理できないかと思い、自動化しました。


#実装方法
１：　スラック上でブックマークしたメッセージをAPIで取得
２：　fileが添付されているメッセージを特定
３：　fetchを利用して、ファイルをダウンロード
４：　ダウンロードしたファイルを、GoogleDriveにアップロード

色々と調べた結果、Slackで利用するAPIはstars.listというメソッドをコールして、お気に入りしたメッセージを取得しようと思う。設定時に参考にしたのは、@sew-sou19さんの記事。
 [[GAS]Slackのbotを作る方法を、お節介なほど丁寧に説明](https://qiita.com/sew_sou19/items/723feb39ea4aa7becfab)



#完成系（gasのスクリプト）
以下が完成形

```コード.js
function getStarFileFromSlack() {
  
  //Googleのファイルをダウンロードする用の設定
  const optionsForGoogleDownload = {
    method: "get",
    headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true
  };
  //Slackのファイルをダウンロードする用の設定  
  const token = PropertiesService.getScriptProperties().getProperty('slackUserToken');
  const optionsForSlackDownload = {
      "method" : "GET",
      "headers": {"Authorization": "Bearer " + token},
  };
  
  //GoogleDriveのフォルダへのアクセスの準備
  var folder = DriveApp.getFolderById("ドライブのフォルダのID");
  
  //slackのAPIを叩く用の設定
  var url = "https://slack.com/api/stars.list"
  var payload = {
    "token" : token,
    "limit" : "10"
  };
  var params = {
    "method" : "get",
    "payload" : payload
  };
  
  //SlackAPiを叩く
  var response = UrlFetchApp.fetch(url,params);
  var json     = response.getContentText();
  var data     = JSON.parse(json);
  
  
  //パースしたJsonデータを処理して、GoogleDriveへアップ
  for(let i = 0; i < data.items.length; i++){
    if(data.items[i].type == "file" && data.items[i].file.filetype == "gpres"){
      var dlData           = getDownloadDataFromGoogle(data.items[i].file.url_private,optionsForGoogleDownload);
      uploadToGoogleDrive(folder,dlData,data.items[i].file.name);
    }else if(data.items[i].type == "file" && data.items[i].file.url_private.match(/image/)){
      var dlData           = getDownloadDataFromSlack(data.items[i].file.url_private,optionsForSlackDownload)
      uploadToGoogleDrive(folder,dlData,data.items[i].file.name);
    }else if(data.items[i].type == "message"){
      try{
        data.items[i].message.files.forEach(function(file){
          if(file.url_private.match(/docs.google.com/)){
            var dlData           = getDownloadDataFromGoogle(file.url_private,optionsForGoogleDownload);
            uploadToGoogleDrive(folder,dlData,file.name);
          }else if(file.url_private.match(/files.slack.com/)){
            var dlData           = getDownloadDataFromSlack(file.url_private,optionsForSlackDownload);
            uploadToGoogleDrive(folder,dlData,file.name);
          }
        });
      }catch(e){
        console.log(e);
      }
    }
  }  
}


//googleDriveへアップロードするメソッド
function uploadToGoogleDrive(folder,dlData,fileName) {
  var files = folder.getFiles();
  var num = 0;
  //GoogleDriveにあるFile名と、アップロードしようとしているファイル名が一緒だった場合、1を代入する
  while (files.hasNext()) {
    var file = files.next();
    if(file.getName() == fileName){
      num += 1;
    }  
  }
  //変数numに数字が足されていたら、アップロードは行わない
  if(num == 0){
  dlData.setName(fileName);
    //Google Driveにファイルをアップロード
  folder.createFile(dlData);
  }
}


//Googleスライドのリンクから、データを取得するメソッド
function getDownloadDataFromGoogle(url_private,optionsForGoogleDownload){
  var arrDownloadUrl   = url_private.split("/");
  var downloadId       = arrDownloadUrl[5];
  var dlData           = UrlFetchApp.fetch("https://docs.google.com/presentation/d/" + downloadId + "/export/pptx",optionsForGoogleDownload).getBlob();
  return dlData;
}

//スラックのリンクから、データを取得するメソッド
function getDownloadDataFromSlack(url_private,optionsForSlackDownload){
  var arrDownloadUrl   = url_private.split("/");
  var downloadId       = arrDownloadUrl[4];
  var downloadFileType = arrDownloadUrl[5];
  var dlData           = UrlFetchApp.fetch("https://files.slack.com/files-pri/" + downloadId + "/" + downloadFileType,optionsForSlackDownload).getBlob();
  return dlData;
}
```




#トリガーの設定
最後に以下のキャプチャのようにトリガーをすれば、終了。
本当は新しくメッセージにスターを付けた瞬間にトリガーをしたいけど、やり方分からなかったので、とりあえず４時間おきにトリガーさせる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/f6c3737c-8561-3bdf-3912-a6bfc0c0c5ab.png)


#改善点
とにかくコードが冗長すぎる、、、

ifの次にelse ifがあり、さらにtryの中にforEachがあり、さらにifがあるという、結構カオスな気がする。
不必要なデータは省いているが、返ってくるJsonのデータ構造は以下のような形になっている。
"type": "message"と、"type": "file"はデータ構造が微妙に違く、結果分かりにくいコードになってしまった。
もっと短く簡潔に書けるはずだが、とりあえず実装を優先。
アップロード時の処理も拡張子毎にフォルダ分けをしたりなど、もう少し工夫ができるかもしれない。

```test.json
{
  "ok": true,
    "items": [
      {
        "type": "message",
        "message": {
          "type": "message",
          "files": [
            {
              "name": "hogehoge.pdf",
              "url_private": "https:\/\/files.slack.com\/files-pri\/hoge\/hoge.pdf"
            }
          ]
        }
      },
      {
        "type": "file",
        "file": {
          "name": "hogehoge",
          "url_private": "https:\/\/docs.google.com\/presentation\/d\/hogehoge\/edit?usp=sharing"
        }
      }
    ]
}
```