1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

やりたいこと&その理由

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

実装方法

1: スラック上でブックマークしたメッセージをAPIで取得
2: fileが添付されているメッセージを特定
3: fetchを利用して、ファイルをダウンロード
4: ダウンロードしたファイルを、GoogleDriveにアップロード

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

完成系(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;
}

トリガーの設定

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

image.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"
        }
      }
    ]
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?