物品購入依頼管理システムについて

当研究室で使っている、「研究室予算を使用した物品購入依頼」の管理システムについての説明です。

購入を依頼したい研究室のメンバーが、購入依頼品についての情報をGoogleFormに入力するとTrelloにカードが作成され、
事務スタッフは、Trelloカードの情報を参照して大学の予算執行システムへの入力を行い、発注・納品等の進捗管理が行えます。

GoogleFormの入力必須機能を使用することで、大学の予算執行システム入力時に必要な情報や書類の不備を減らすことができます。
また、Slackとも連携させ、物品購入依頼があったことをスタッフに知らせることも可能です。


1. 購入依頼用Google formの作成

大学の予算執行システムへの入力事項に合わせ、Google formの質問作成やセクション設定を行います。
弊研究室で使用しているformの主な質問は下記のとおりです。

  • メールアドレス:依頼者に回答のコピーを送信する設定のため、入力必須。
  • 依頼者名:入力必須。
  • 物品名:入力必須。
  • 数量:入力必須。
  • 見積書の添付:特定のECサイト*の商品以外は、代理店の見積もり添付必須。
  • 特定ECサイト*の商品URL:見積もりを取得していない場合はこちらの入力が必須。
  • 購入予算:必須の選択式項目。研究室(奥田先生名義)の予算を使うか、購入者名義の予算を使うかを選択。
  • 連絡事項:自由入力。マウスの納品日や劇毒該当試薬があるなど、事務スタッフに伝えたいことがあるとき用。
  • *注:金大ナノ研では、モノタロウやアスクルの商品は代理店の見積なしで購入手続きできる。

作成後、回答がスプレッドシートに反映されるようにしておきます。


2. Trelloカードの自動作成

2.1 Trelloの"開発者向けAPIキー"と"個人用APIトークン"を取得する

Trelloにログインした状態で https://trello.com/1/appKey/generate にアクセスすると、下図のように"開発者向けAPIキー"が発行されるので保管します。

「トークン」のリンク(上図赤丸部分)をクリックするとアクセス許可を求められる(下図)ので、

「許可」(上図赤丸部分)をクリックすると"個人用APIトークン"が発行されます(下図)。こちらも保管します。


なお、このシステムで作成されるTrelloカードの作成者は、このキーとトークンを取得する際にログインしていたアカウントとなります。


2.2 カードを追加したいTrelloの"リストID"を取得する

2.1で取得したAPIキーとトークンを使って、Trelloのカード追加先となるリストのIDを取得します。

コマンドプロンプト(Win10以降)で、curlコマンドを使用してボードID→リストIDの順に取得していきます。
下記取得例の画像では、curlコマンド実行後の"[ ]"内に、各ボードやリストのIDと名前が"{ }"で区切られて羅列されています。

  1. ①TrelloボードID
     コマンド: curl "https://trello.com/1/members/<username>/boards?key=<Key>&token=<Token>&fields=name"
     取得例    :
  2. ②TrelloリストID
     コマンド: curl "https://trello.com/1/boards/<BoardのID>/lists?key=<Key>&token=<Token>&fields=name"
     取得例    :

Trelloカードを追加したいリストのIDを保管します。


2.3 Google App ScriptでFormの情報をTrelloカード化する

1.で作成した購入依頼用Google formの回答が反映されるスプレッドシートの、「拡張機能」>「Apps Script」からスクリプトエディタを開き、以下のコードを記述します。
各処理の説明はコード内のコメントを参照し、適宜修正してください。


function scriptName() {
//定数の定義
	//回答シート取得のための情報
	const sheetId = '******'; //スプレッドシートのアドレスの、"~~/d/"と"/edit#~~"の間の文字列
	const sheetName = 'OrderRequest'; //回答シートの名前
	//Trelloにカードを追加するための情報
	const api_key = '******'; //2.1で取得した、"開発者向けAPIキー"
	const api_token = '******'; //2.1で取得した、"個人用APIトークン"
	const listId = '******'; //2.2で取得した、カード追加したいTrelloリストのID

//GoogleFormの回答からTrelloカードのカード名と説明部分を作成する
	//情報を回答シートから取得
	let sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName); //回答シートの取得
	let lastRow = sheet.getLastRow(); //シートの最終行を取得
	//最新回答をそれぞれの変数に格納
	let client = sheet.getRange(lastRow, 2).getValue();
	let productName = sheet.getRange(lastRow, 3).getValue();
	let amount = sheet.getRange(lastRow, 4).getValue();
	let quote = sheet.getRange(lastRow, 5).getValue();
	let productURL = sheet.getRange(lastRow, 6).getValue();
	let budget = sheet.getRange(lastRow, 7).getValue();
	let info = sheet.getRange(lastRow, 8).getValue();

	// Trelloカードのカード名を作成
	let titleTrello = "【" + productName + "/" + client + "】";

	//Trelloカードの説明部分を作成
	let body = "■ 品名/" + productName + "\n"
	+ "■ 個数/" + amount + "\n";

	if(quote == ""){
		body = body + "■ URL/" + productURL + "\n";
	}else{
		body = body + "■ 見積書/" + withQuote + "\n";
	}

	body = body + "■ 予算/" + budget;

	if(info == ""){
		//連絡事項がなければ説明に何も追加しない
	}else{
		body = body + "\n■ 連絡事項/" + info;
	}

//Trelloにカード追加リクエストを送る
	let cardPos = 'top';

	let url = 'https://api.trello.com/1/cards/?key=' + api_key + '&token=' + api_token;
	let options = {
		'method' : 'post',
		'muteHttpExceptions' : true,
		'payload' : {
			'name'      : titleTrello,
			'desc'      : body,
			'pos'       : cardPos,
			'due'       : '',
			'idList'    : listId,
			'urlSource' : ''
		}
	}
	let response = UrlFetchApp.fetch(url, options);
}

記述できたら、スクリプトを保存してから左端のカラムからトリガー編集ページを開き、右下の「+トリガーを追加」から下記の通り設定を行います。

  • 実行する関数を選択:scriptName(スクリプトにあるfunction名の一覧から選択)
  • 実行するデプロイを選択:Head(デフォルトのまま)
  • イベントのソースを選択:スプレッドシートから
  • イベントの種類を選択:フォーム送信時
  • エラー通知設定は好きに設定して下さい。

トリガー設定時に「このアプリは確認されていません」のようなダイアログが出た場合は、
ダイアログ上の「詳細」→「scriptName(安全ではないページ)へ移動」から、アクセス許可を行います。

これで、1.で作成したGoogle Formに回答すると、その内容を反映して下記のようなカードが追加されます。

事務スタッフにわかりやすいよう、Trelloのラベル機能を利用して複数ある研究室予算の何を使うかを明示しています。


3. Slackにメッセージを送る

3.1 メッセージ送信用SlackAppを作成する

Slackにログインした状態で、slack api にアクセスします。
右上の「Create New App」をクリックし、ダイアログの「From scratch」からAppの名前と使用するワークスペースを設定して、Appを作成します。

作成したApp Nameをクリックして設定画面を開き、下記の設定を行っていきます。

  1. ①表示名の設定
    Settings>Basic Information画面の下部の、「Display Information」を設定します。最低限「App name」が設定されていればOKです。
  2. ②Incoming Webhookの有効化
    Features>Incoming Webhooks画面で、まず「Activate Incoming Webhooks」の横にあるトグルスイッチを「On」にします。
    次に、同画面下部の「Add New Webhook to Workspace」をクリックし、遷移先の画面でメッセージを投稿したいチャンネルを選択し、「許可する」をクリック。

ここまで設定後、Features>Incoming Webhooks画面の「Webhook URLs for Your Workspace」>「Webhook URL」に表示されているURLをコピーして保管します。


3.2 Google App ScriptでFormの情報をSlackbotに送る

2.3で作成したスクリプトの61行目: let response = UrlFetchApp.fetch(url, options);の後に、以下のコードを追加します。
こちらもコード内のコメント説明を参照し、送信メッセージの内容などを適宜修正してください。


//Slack送信情報を定数定義
	const slackInfo = 'https://hooks.slack.com/******/'; //3.1でコピーした、Webhook URL

//メッセージの内容を作成、2.3のスクリプト内の変数を流用している
	let slackMessage = "購入依頼がありました。\n■ 品名/" + productName + "\n■ 依頼者/" + client;

//SlackAppにメッセージの内容を送信する
	let jsonData =
	{
		"text" : slackMessage
	};

	let optionslack =
	{
		"method" : "post",
		"contentType" : "application/json",
		"payload" : JSON.stringify(jsonData)
	};

	UrlFetchApp.fetch(slackInfo, optionslack);

なお、弊研究室ではSlackへの購入依頼通知自体は行っていませんが、「研究室メンバーによる週1掃除当番の完了通知」などのシステムに応用しています。



参考文献