「この業務は新人がやる」
誰が言い出したのか分かりませんが、どんな会社でも
「新人に担当させる仕事」
があると思います。
さらに、
「新人への評価は、仕事をいかに効率よく処理するかで決まる」
というのも間違いありません。
今回は、面倒なこと 特に雑務 が嫌いな私が楽をするために、新人業務を自動化したお話をご紹介します。
最後までお読みいただくと、以下のアウトプットを自動化するノウハウが得られます。
こちらは、MTGの時間になったら自動で議事録を準備してくれるアプリケーションです。
はじめに
この記事に興味を持っていただき、誠にありがとうございます。
私は訳あって2019年7月に新卒入社し、3ヶ月間の研修の後、10月に現場配属された新米エンジニアです。
2ヶ月ほど働いていると、
「いつも同じことやってるな」
「これって自動化できそうだな」
と感じるネタが溜まってきたので、それらを「自動化した話」をご紹介します。
新人の仕事 ≒「議事録の準備」を自動化したお話です。
新人 → 議事録の準備
社内外を問わず、MTGが開かれれば議事録、議事メモの準備は必須です。
私には「MTGが開かれる前までに、議事録のフォーマットを整備し、MTG開始後すぐにメモ取れる状況にする」というタスクが与えられたので、Googleカレンダーにリマインドをセットして、毎回手作業で議事録を準備していました。
手作業での準備手順は、大まかには以下のプロセスです。
- GoogleドライブにMTG用のフォルダを作成
- フォルダ内にGoogleドキュメントを新規作成
- ヘッダーとフッターに Credential を記入
- MTGの基本情報(日時、場所、出席者)を記入
- ドキュメントへのURLをSlackに投稿
配属当初は難なくこなしていたのですが
- だんだん面倒になってくる
- 移動がバタバタしていると、準備を忘れる
- いつも「前回のフォーマットをコピー」して流用している
というマンネリ状態になりました。
そこで、議事録の準備をオール自動化しました。
用意するもの
- Slack の Incoming webhook
- 議事録のテンプレート(Google ドキュメント)
- 議事録を作成する会議通知名の一覧(Google スプレッドシート)
- Google App Script の実行環境
- (このプログラム以降は、もう議事録は手動で準備しないという意思)
全体の流れ
大まかな処理の流れは、
- GAS を定期実行
- Google カレンダーの、直近のイベントを取得
- 議事録を作成する会議通知名の一覧を取得
- [2] == [3] となるイベントが存在したら、議事録準備開始
- 準備した議事録へのURLを Slack に投稿する
となります。
作業的に依存関係のない部分から順に説明します。
作業開始
以下、議事録の準備を自動化するための、環境整備についてです。
議事録を作る会議通知名の一覧
Googleアカウントと共に仕事をされる方であれば、Google カレンダーを確認すれば、多種多様な「会議通知」が登録されていると思います。それらの会議通知のうち、「議事録を作成するMTG」のイベント名をスプレットシートに書き出します。
ex)
議事録を作成する会議通知名が
この時、作成したスプレッドシートのURLは
https://docs.google.com/spreadsheets/d/abcedfg12345/edit?folder=hogefuga#gid=0
のようになります。この時の id
は abcedfg12345
になります。id は Google App Scriptとの連携時に用いるので、必要になり次第確認してください。
議事録のテンプレート
議事録は「毎回ゼロから」作成するのではなく「ある程度のフォーマットが決まって」おり、それに従って作成するものだと思います。過去の議事録を参照すれば「毎回必ず記入する部分」が見つかるので、それらを網羅した議事録のテンプレートを Google ドキュメントで作成します。
毎回必ず記入する部分の候補としては、以下が考えられます。
- ヘッダーとフッターのCredential
- ページ番号
- 会議名記入欄
- 会議場所記入欄
- 出席者記入欄
- 決定事項/TODOの記入欄
私が作成したテンプレートでは、「出席者記入欄」には MTGに出席する可能性のある全員の名前 を記入しています。それにより、実際のMTG中は「いない人を出席者から削除する」のみで済み「あの人誰?→ 名刺リストを確認 → この人か!」を回避できます。
Google ドキュメントで作成した議事録のテンプレートにも id
があります。
こちらも後の作業で利用しますので、必要になり次第確認してください。
Slack Incoming Webhook の発行
slack api から、incoming webhook を発行してください。
incoming webhook の値は厳重管理してください。
Google App Script のコーディング
事前準備が完了したので、議事録作成を代行してくれるコードの作成を開始します。
今回は GAS の処理を役割ごとに関数化したので、関数ごとに各機能を説明します。
- カレンダーから直近のイベント名を取得
- スプレッドシートから議事録を作る会議通知名を取得
- 議事録を作成するかの判定
- 議事録を新規作成し、slackにURLを投稿
カレンダーから直近のイベント名を取得
Google アカウントユーザの、直近1時間の予定一覧を取得します。
function getCalendarEventList() {
var now = new Date();
var oneHourFromNow = new Date(now.getTime() + (1 * 60 * 60 * 1000));
var events = CalendarApp.getDefaultCalendar().getEvents(now, oneHourFromNow);
var eventList = [];
for (i = 0; i < events.length; i++) {
eventList.push(events[i]);
}
// Googleカレンダーに登録された「直近1時間分」のイベントの配列を返す
return eventList;
}
スプレッドシートから議事録を作る会議通知名を取得
議事録を作成するMTG名が記入されたスプレッドシートから、そのMTG名一覧を取得します。スプレッドシートの読み込みは「関数の実行ごと」に行うので、MTG名の追加/削除は自由に実施できます。
function getEventTitleFromSpredsheet() {
// 議事録を作成するカレンダーの会議通知名一覧が記載されたスプレッドシートのID
var SPREDSHEETPATH = "<spredsheet_id>"
var ss = SpreadsheetApp.openById(SPREDSHEETPATH);
var sheet = ss.getSheets()[0];
var range = sheet.getRange(1, 1, ss.getLastRow());
var values = range.getValues();
var meethingList = [];
for (i = 0; i < values.length; i++) {
value = values[i];
meethingList.push(value[0]);
}
// スプレッドシートに記載されたMTG名の配列を返す
return meethingList;
}
議事録を作成するかの判定
「議事録を準備するか」を判定してくれるロジックを実装します。
会議1つに議事録1つが基本なので、会議の開始時間を判定軸としたロジックも追加します。
function start(){
// 議事録自動準備プログラムで、最初に起動する関数
// 「直近のイベント一覧」と「議事録を作成するMTG名」を取得し、一致する名前があれば議事録を準備する
meethingList = getEventTitleFromSpredsheet();
eventList = getCalendarEventList();
var createFlag = false;
var meethingName = '';
for (i = 0; i < meethingList.length; i++) {
for (j = 0; j < eventList.length; j++) {
if (meethingList[i] == eventList[j].getTitle()) {
var functionTriggeredTime = new Date();
var meethingStartTime = eventList[j].getStartTime();
// 会議の開始時間が、プログラム起動時間より後ならば、createFlag=trueにする。
// 会議中にプログラムが起動した場合には、議事録は作成されない。
if (functionTriggeredTime < meethingStartTime){
createFlag = true;
meethingName = eventList[j].getTitle();
}
}
}
}
if (createFlag) {
createMinutes(meethingName);
Logger.log('議事録を準備しました。');
Logger.log('MTG名:' + meethingName);
} else {
Logger.log('議事録は準備されませんでした。');
}
}
議事録を新規作成し、slackにURLを投稿
「議事録を作成する」と判定された場合の、議事録を作成するロジックを組みます。
<folder_id>
には、新規作成された議事録を保存するフォルダの id
を入力してください。
function prepareMinutes(meethingName){
// 議事録を作成するフォルダのID
var FOLDERID = '<folder_id>';
// 議事録のフォーマットファイルのID
var FILEID = '<document_id>';
// slack Incoming Webhook
var POSTURL = '<slack_incoming_webhook>';
// 議事録のフォーマット、作業フォルダを取得する
var folderPath = DriveApp.getFolderById(FOLDERID);
var formatFilePath = DriveApp.getFileById(FILEID);
// 現在時刻から「YYYYddmm_(会議名)」 の文字列を作成する
var today = new Date();
var year = today.getFullYear();
var month = '' + (today.getMonth() + 1);
var day = '' + today.getDate();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
var YYYYmmdd = year + month + day;
var minutesName = YYYYmmdd + '_' + meethingName; // 議事録のファイル名:「YYYYmmdd_MTG名」
// 議事録フォーマットをコピーして、指定のフォルダに議事録を新規作成する
var newFile = formatFilePath.makeCopy(minutesName, folderPath);
var fileUrl = newFile.getUrl();
// slackに議事録へのurlを投稿する
var message = '議事録を準備しました。' + '\n\n' + '会議名:' + minutesName + '\n' + 'URL : ' + fileUrl;
var jsonData = {
'text':message
};
var payload = JSON.stringify(jsonData);
var options = {
'method':'post',
'contentType':'application/json',
'payload':payload
};
UrlFetchApp.fetch(POSTURL, options);
}
以上の処理により、「議事録を自動で準備させる」プログラムの完成です。
最後に、プログラム定期実行の設定をします。
GAS の定期実行
Google App Script の Current project's triggers からプログラムの定期実行が設定できます。
Add Trigger で以下の項目を入力し、GAS を1時間ごとに起動させます。
slackへの議事録URLの投稿
正しく動作すれば、MTG時間になると、slackで以下の投稿が得られます。
まとめ
以上により、議事録の準備はオール自動化されました。
事前準備、コーディング作業は大変ですが、1度作ってしまえば、もう議事録準備に費やす工数は無くなると思われます。
以上、長文にお付き合いいただき、有難うございました。