🦥

【GAS】GASとSlackAPIで貸出管理簿を作成

2022/04/28に公開

制作背景

今回は、社内でIT系の書籍を管理するにあたり、せっかくなら自動化しよう言うことになりました!
社内連絡はSlackでやりとりしていることから、Slackに絡めて自動化をしたいということと、極力運用コストや実装コストを低くしたいということから、JavaScriptでコードが書けるGASにチャレンジしました。

仕様ツール等

  • GAS(SlackAppのライブラリを用います)
  • Slack API
  • Google SpreadSheet

アプリ概要

主要機能

  1. 貸出管理
  2. 書籍購入アンケート(定期)
  3. 未返却者へのリマインド

GASの役割とSpreadSheetの役割

GAS

SpreadSheetから情報の受け取り+Slackへの通知処理

Spreadsheet

定期連絡のトリガー設定
マスターデータ管理
セルに対して権限設定(運営以外触ってほしくない部分にロックをする)

実装

それでは、実装部分について説明を記載します。
SpreadSheetについては、記事説明用に別途作成したため、まずは以下のリンクを参照してみてください。
https://docs.google.com/spreadsheets/d/1qXDQhYRsLAiicC-2yriiixZb4vbSOclh6yZijvkxbQs/edit?usp=sharing

それでは、各機能面についてです。

SlackAPIについて

申し訳ありませんが、今回はGASメインのためSlackAPIの部分については説明を割愛します。
代わりに、公式のドキュメントと参考記事のリンクを添付しておきます。
https://api.slack.com/lang/ja-jp#tutorials
https://zenn.dev/kou_pg_0131/articles/slack-api-post-message

SpreadSheetの設定

マスターシートの構成

マスターシートの構成

  • A列:社員名
  • B列:社員のSlackメンバーID
  • E1セル:定期アンケートのURL
    (GAS本文に入れもいい気がします・・・)
  • E3セル:書籍のマスターは別の購入リストシートで管理しています。

SpreadSheetの機能

SpreadSheet側でも、運用のためにいくつか作業をしています。
知っているよって方はスルーしてください。

マスターのリストからセレクトボックスを作成

マスターの一覧からセレクトボックスを作成するには以下の手順で可能です。

セレクトを入れたいセルを選択
「データ」タブから「データの入力規則」を選択
「条件:」を「リストを範囲で指定」を選択
マスターの範囲を選択
「無効なデータの場合」は「入力を拒否」を選択

別のスプレッドシートの情報を参照

書籍一覧で扱っていますが、別のスプレッドシートから情報を参照したい(コピーしたい)場合は以下のコードで可能です。スプレッドシートのリンクは共有で取得できるもので実装可能です。

=IMPORTRANGE("https://docs.google.com/spreadsheets/d/1t7_oJ3i9Yqpo3CQ_FKfbhW7dm-uhGoRmVpisL51AZ5U/edit?usp=sharing", "書籍購入リスト!D3:D50")

# 使い方
=IMPORTRANEG("ファイルのURL", "リンク先のシート名!セル範囲")

権限設定

マスターデータや、上記の関数部分、貸出日返却日など、一般社員にがうっかり触ってしまった場合困る領域がたくさんあった為、貸出状況シートのD列G列以外は全て権限設定をして編集できないようにしました。

権限設定したい列や行、セルを選択
「データ」タブから「シートの範囲と保護」を選択
「権限を付与したいユーザー」を選択して完了

GASの機能(コード以外の設定)

コードは最後に説明するので、まずはGASのコード以外の設定について解説します。

そもそもGASのはじめ方

GASは、SpreadSheetを用いている場合、「拡張機能」 タブから App Script を選択することで簡単に始めることができます。コード.gsというファイルがあるのでそちらにコードを書いていくことで機能の実装ができます。

SlackAppライブラリの設定

App Script画面のサイドバーにあるライブラリの追加(+ボタン)を選択しましょう。
「スクリプトID」を要求されるため、ここに追加したいライブラリのスクリプトIDを入れることで追加が可能です。
なお、今回利用したいSlackAppのスクリプトIDは以下の通りです。

1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq

追加をするとバージョンを聞かれますが、最新バージョンを選択すれば問題ありません。

トリガーの設定

GASは、いつ関数を実行するかについて、「トリガー」を設定することで定期連絡やバッチ処理のようなことが気軽にできます。実行については、関数単位で実行することが可能です。

App Script左の時計マーク⏰
実行する関数を選択
イベントのソースを選択で、時間手動型を選択
週ベース、月ベース、時間ベースなど目的ごと設定する

以上のように、トリガー設定をしてあげれば定期連絡はすごく簡単に設定できてしまいます。

コード解説

SpreadSheetからのデータ取得について

共通設定

let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let data = spreadsheet.getSheetByName("貸出状況");
let master = spreadsheet.getSheetByName("マスターシート");

データの受け取り

データの受け取りや入力について、何か既視感があるなぁと思ったらPHP SpreadsheetというPHPでExcel操作するライブラリとすごく使い方が似ていたので、この辺は個人的に扱いやすかったです。

// 例:貸出状況シートのA3セルを取得したい場合
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getSheetByName("貸出状況");
let data = sheet.getRange("A3").getValue();

データの入力

// 例:貸出状況シートのA5列にデータを入れたい場合
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getSheetByName("貸出状況");
sheet.getRange("A5").setValue('入力データ');

// チェックボックスについては関数があります
sheet.getRange("D5").check();
sheet.getRange("D5").uncheck();

セレクト変更時、チェックオンオフ時に処理をしたい場合

〜の時というのは、トリガーで設定できますが、実はトリガーで設定しなくてもonEdit()という名前のメソッドを用いることで自動的にトリガーが設定されます。こうした自動で動くトリガーを「シンプルトリガー」と言い、シンプルトリガーの一覧は以下を参考にしてください。
https://developers.google.com/apps-script/guides/triggers

また、onEditで変更されたセル情報の取得はこのようにできます。

// 引数で情報受け取りも可能
function onEdit(e) {
  // アクティブなシート・セルを取得
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadSheet.getSheetByName("貸出状況");
  // 変更されたセル情報
  let activeCell = sheet.getActiveCell();
  // 引数から情報受け取りも可能です。
  let row = e.range.getRow();
}

ちなみに、以下のメソッドに対してトリガー設定した上でデバッグするとこのようになります。

function onEdit(e){
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadSheet.getSheetByName("貸出状況");
  let info = sheet.getActiveCell();
  Logger.log(info.getValue());
  Logger.log('----------------------------');
  Logger.log(e.value);
}

ログ

// 実行ログ
2022/04/28 1:39:13	情報	sample
2022/04/28 1:39:13	情報	----------------------------
2022/04/28 1:39:13	情報	sample

引数eにはオブジェクトが入っている状態となっています。
なので、e.range.getRow()などでセル情報、列情報など取得することができます。

SlackAPPライブラリについて

SlackAPPライブラリを用いれば、簡単にSlackにメッセージを送ったり、Slackからメッセージを受け取ったりすることが可能になります。今回は、メッセージを送るだけなので送る部分に関連した解説をします。

共通設定

// SlackAPIで発行されたトークン
const token = "xoxb-1452582367283-xxxxXXXXxxxxXXXX-xxxxXXXXxxxxXXXX";
// トークンを元に作成
const slackApp = SlackApp.create(token);

基本のメッセージ送信

// メッセージを定義
let message = '送信するメッセージ';
//Slackボットがメッセージを投稿するチャンネルを定義する
let channelId = "C0229509JN"; #SlackのチャンネルID
// 通知のオプションが設定できる(なしでもよい)
let options = {
  "as_user": true, // トークン発行者の名前が設定できる
}
// メッセージ通知
var access = slackApp.postMessage(channelId, message, options);
// 実行結果についてログで確認
Logger.log(access);

終了

コードの解説を細かく記載すると長くなってしまうため、メインで使っている機能のみピックアップして説明をしました。
詳しいコード等についてはGithubに載せているので気になった方は参照してみてください。
https://github.com/Kurogoma939/GAS-SlackAPI-LendingManagement

Discussion