18
6

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.

LeveragesAdvent Calendar 2019

Day 5

GASを使ってSlackのチャンネルの情報を楽に共有しよう!

Last updated at Posted at 2019-12-04

Top.png

はじめに

こんにちは、18卒のおでんとよばれているものです。
今回は弊社で実際に使われているGASを使ってSlackのチャンネル情報を楽に共有する方法を紹介したいと思います。

こんな感じで共有しています

全社員がアクセスできるスプレッドシートにGASでチャンネルの情報を書き込んで共有をしています。
お見せできる例として、こんな感じでクラブ活動のチャンネルをまとめたシートをパッと一覧で見れるようにしてあります!

List.png

どうやってやるの?

手順としてこの3つことを行いました。

  1. 全てのプライベートチャンネルにシステム用のアカウントが入っている状態にする
  2. SlackAppの作成
  3. GASを実行
    これに関してどうやってやったかを紹介させていただきます。

1. 全てのプライベートチャンネルにシステム用のアカウントが入っている状態にする

今回 conversations.list APIを使って実装をしたのですが、APIの仕様上Privateチャンネルの情報は、Access Tokenを発行したユーザーが入っているチャンネルしか獲得できなかったです。
Legacy tokenで対応することも検討したのですが、全ての権限を持っているtokenは、全てのSlackの操作ができてしまう危険な物なので、
channels:read (Publicチャンネルの情報)groups:read(Privateチャンネルの情報) に絞ってAccess Tokenを発行しました。
皆さんに協力していただき、全てのプライベートチャンネルにシステム用のアカウントが入っている状態にした結果、Legacy tokenを使わずに、Privateチャンネルの情報も全社員が見ることができるようになりました。

2. Access Tokenの発行

次にAccess Tokenを発行するための準備をします。

Appの作成

システム用のアカウントでSlackにログインしていることを確認して、https://api.slack.com/ にアクセスして Start Buildingを選択します。

content_1.png

選択した後、Create a Slack Appが表示されますので、任意の名前と導入するワークスペースを選択して Creat Appで作成をします。
※ 2. Access Tokenの発行に載せている画像は自分のプライベートSlackにインストールした例になります。

content_2.png

Tokenの発行

OAuth & PermissionsScopes で今回利用するchannels:read (Publicチャンネルの情報)groups:read(Privateチャンネルの情報) を選択します。
Scopesで上記2つの権限が与えられていることを確認して、Install App to Workspace を選択します。

content_8.png

Install App to Workspaceを選択したら、許可しても良いかが表示されるので、許可するを選択してワークスペースにアプリをインストールします。
content_3.png

インストールが完了したら、画像のように xoxp-から始まるAccess Tokenが発行されます。
APIを利用する際にこのAccess Tokenを利用します。

content_4_fix.png

3. GASを実行

GASの準備

こんな感じでスプレッドシートを作成して、スクリプトエディタを開いてGASを作っていきます。
content_5.png

実行方法

利用する関数は3つです。

  1. slackApi //SlackのAPIから情報を取ってくる
  2. getChannelList //特定のシートにPublicチャンネルリストを書き込む
  3. getPrivateChannelList //特定のシートにPrivateチャンネルリストを書き込む

slackApi関数を用意しておけば、他のAPIを利用するときも使い回せるので一度作ってしまえば超便利です!!

プログラム

slackApi.gs
function slackApi(token, path, options) {
  if (!options) options = {};
  var url = "https://slack.com/api/" + path;
  var q = "?token=" + encodeURIComponent( token );
  for (var key in options) {
    q += "&" + encodeURIComponent( key ) + "=" + encodeURIComponent( options[ key ] );
  }
  url += q;
  var res = UrlFetchApp.fetch(url);
  var ret = JSON.parse(res.getContentText());
  if (ret.error) {
    throw "GET " + path + ": " + ret.error;
  }
  return ret;
}
getChannelList.gs
function getChannelList() {
  const token = PropertiesService.getScriptProperties().getProperty("slackApiToken");
  var options = { "limit" : 200 };
  var channels = slackApi(token, "conversations.list", options);
  
  const spreadsheet = SpreadsheetApp.openById('スプレッドシートのID入れてね!');
  const sheet = spreadsheet.getSheetByName('PublicList');
  const archivedSheet = spreadsheet.getSheetByName('アーカイブPublicList');
  
  sheet.getRange("A1").setValue("チャンネル名");
  sheet.getRange("B1").setValue("目的");
  sheet.getRange("C1").setValue("トピック");
  
  archivedSheet.getRange("A1").setValue("チャンネル名");
  archivedSheet.getRange("B1").setValue("目的");
  archivedSheet.getRange("C1").setValue("トピック");
  
  var targetCellNumber = 2;
  var targetArchivedCellNumber = 2;
  
  while (true) {
    channels.channels.forEach( function (ch) {
      if(!ch.is_archived) {
        sheet.getRange("A"+targetCellNumber).setValue(ch.name);
        sheet.getRange("B"+targetCellNumber).setValue(ch.purpose.value);
        sheet.getRange("C"+targetCellNumber).setValue(ch.topic.value);
        targetCellNumber = targetCellNumber + 1;
      } else {
        archivedSheet.getRange("A"+targetArchivedCellNumber).setValue(ch.name);
        archivedSheet.getRange("B"+targetArchivedCellNumber).setValue(ch.purpose.value);
        archivedSheet.getRange("C"+targetArchivedCellNumber).setValue(ch.topic.value);
        targetArchivedCellNumber = targetArchivedCellNumber + 1;
      }
    });
    
    if (channels.response_metadata.next_cursor == "") break;

    options = { "limit" : 200, "cursor" : channels.response_metadata.next_cursor };
    channels = slackApi(token, "conversations.list", options);
  }
}
getPrivateChannelList.gs
function getPrivateChannelList() {
  const token = PropertiesService.getScriptProperties().getProperty("slackApiToken");
  var options = { "limit" : 200, "types" : "private_channel" };
  var channels = slackApi(token, "conversations.list", options);
  
  const spreadsheet = SpreadsheetApp.openById('スプレッドシートのID入れてね!');
  const sheet = spreadsheet.getSheetByName('PrivateList');
  const archivedSheet = spreadsheet.getSheetByName('アーカイブPrivateList');
  
  sheet.getRange("A1").setValue("チャンネル名");
  sheet.getRange("B1").setValue("目的");
  sheet.getRange("C1").setValue("トピック");
  
  archivedSheet.getRange("A1").setValue("チャンネル名");
  archivedSheet.getRange("B1").setValue("目的");
  archivedSheet.getRange("C1").setValue("トピック");

  var targetCellNumber = 2;
  var targetArchivedCellNumber = 2;
  
  while(true) {
    channels.channels.forEach( function (ch) {
      if(!ch.is_archived) {
        sheet.getRange("A"+targetCellNumber).setValue(ch.name);
        sheet.getRange("B"+targetCellNumber).setValue(ch.purpose.value);
        sheet.getRange("C"+targetCellNumber).setValue(ch.topic.value);
        targetCellNumber = targetCellNumber + 1;
      } else {
        archivedSheet.getRange("A"+targetArchivedCellNumber).setValue(ch.name);
        archivedSheet.getRange("B"+targetArchivedCellNumber).setValue(ch.purpose.value);
        archivedSheet.getRange("C"+targetArchivedCellNumber).setValue(ch.topic.value);
        targetArchivedCellNumber = targetArchivedCellNumber + 1;
      }
    });
    
    if(channels.response_metadata.next_cursor == "") break;
    
    options = { "limit" : 200, "types" : "private_channel", "cursor" : channels.response_metadata.next_cursor };
    channels = slackApi(token, "conversations.list", options);
  }
}

プログラムの注意事項

Access Tokenをコードに乗せるのは危ないので、GASのスクリプトのプロパティにTokenを置くようにして、getProperty から読みだすようにしてあります。

const token = PropertiesService.getScriptProperties().getProperty("slackApiToken");

以下の画像のように【2. Access Token】の発行で獲得したAccess Tokenの値を入れてあげればプログラムを実行することができます。

content_6.png

トリガーを設定して自動で更新をしよう!

毎日手動で実行するのは手間なので、GASの特権であるトリガーで毎日実行するようにしましょう!!
画像のように、実行したい関数を選んで保存をすれば、毎日スプレッドシートにSlackのチャンネルのリストが更新されます。

content_7.png

終わりに

いかがでしたでしょうか。
GASは、サーバー代もかからないかつスプレッドシートと連携がしやすいので、一覧化して全社員に共有するのに凄く簡単にできます。
皆さんも是非試していただけると嬉しいです!!

18
6
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
18
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?