やりたいこと&その理由
スラックを使っている営業マンならよくあると思いますが、『あ、この資料どこかで使えそう!』って思うと、メッセージにブックマークのチェックしませんか? でも、色々なメッセージにブックマークをしてしまうと、いざ資料が必要だって時に探す手間が結構かかりますので、別途GoogleDriveに自動でアップロードして、整理できないかと思い、自動化しました。
実装方法
1: スラック上でブックマークしたメッセージをAPIで取得
2: fileが添付されているメッセージを特定
3: fetchを利用して、ファイルをダウンロード
4: ダウンロードしたファイルを、GoogleDriveにアップロード
色々と調べた結果、Slackで利用するAPIはstars.listというメソッドをコールして、お気に入りしたメッセージを取得しようと思う。設定時に参考にしたのは、@sew-sou19さんの記事。
[GAS]Slackのbotを作る方法を、お節介なほど丁寧に説明
完成系(gasのスクリプト)
以下が完成形
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時間おきにトリガーさせる。
改善点
とにかくコードが冗長すぎる、、、
ifの次にelse ifがあり、さらにtryの中にforEachがあり、さらにifがあるという、結構カオスな気がする。
不必要なデータは省いているが、返ってくるJsonのデータ構造は以下のような形になっている。
"type": "message"と、"type": "file"はデータ構造が微妙に違く、結果分かりにくいコードになってしまった。
もっと短く簡潔に書けるはずだが、とりあえず実装を優先。
アップロード時の処理も拡張子毎にフォルダ分けをしたりなど、もう少し工夫ができるかもしれない。
{
"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"
}
}
]
}