39
22

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 5 years have passed since last update.

フューチャーAdvent Calendar 2019

Day 13

新人でも、楽がしたい! ~議事録の準備~

Last updated at Posted at 2019-12-13

「この業務は新人がやる」
誰が言い出したのか分かりませんが、どんな会社でも
「新人に担当させる仕事」
があると思います。

さらに、
「新人への評価は、仕事をいかに効率よく処理するかで決まる」
というのも間違いありません。

今回は、面倒なこと 特に雑務 が嫌いな私が楽をするために、新人業務を自動化したお話をご紹介します。

最後までお読みいただくと、以下のアウトプットを自動化するノウハウが得られます。
こちらは、MTGの時間になったら自動で議事録を準備してくれるアプリケーションです。
Screen Shot 2019-12-12 at 1.58.31.png

はじめに

この記事に興味を持っていただき、誠にありがとうございます。
私は訳あって2019年7月に新卒入社し、3ヶ月間の研修の後、10月に現場配属された新米エンジニアです。

2ヶ月ほど働いていると、
「いつも同じことやってるな」
「これって自動化できそうだな」
と感じるネタが溜まってきたので、それらを「自動化した話」をご紹介します。

新人の仕事 ≒「議事録の準備」を自動化したお話です。

新人 → 議事録の準備

社内外を問わず、MTGが開かれれば議事録、議事メモの準備は必須です。

私には「MTGが開かれる前までに、議事録のフォーマットを整備し、MTG開始後すぐにメモ取れる状況にする」というタスクが与えられたので、Googleカレンダーにリマインドをセットして、毎回手作業で議事録を準備していました。

手作業での準備手順は、大まかには以下のプロセスです。

  1. GoogleドライブにMTG用のフォルダを作成
  2. フォルダ内にGoogleドキュメントを新規作成
  3. ヘッダーとフッターに Credential を記入
  4. MTGの基本情報(日時、場所、出席者)を記入
  5. ドキュメントへのURLをSlackに投稿

配属当初は難なくこなしていたのですが

  • だんだん面倒になってくる
  • 移動がバタバタしていると、準備を忘れる
  • いつも「前回のフォーマットをコピー」して流用している

というマンネリ状態になりました。
そこで、議事録の準備をオール自動化しました。

用意するもの

  • Slack の Incoming webhook
  • 議事録のテンプレート(Google ドキュメント)
  • 議事録を作成する会議通知名の一覧(Google スプレッドシート)
  • Google App Script の実行環境
  • (このプログラム以降は、もう議事録は手動で準備しないという意思)

全体の流れ

大まかな処理の流れは、

  1. GAS を定期実行
  2. Google カレンダーの、直近のイベントを取得
  3. 議事録を作成する会議通知名の一覧を取得
  4. [2] == [3] となるイベントが存在したら、議事録準備開始
  5. 準備した議事録へのURLを Slack に投稿する

となります。
作業的に依存関係のない部分から順に説明します。

作業開始

以下、議事録の準備を自動化するための、環境整備についてです。

議事録を作る会議通知名の一覧

Googleアカウントと共に仕事をされる方であれば、Google カレンダーを確認すれば、多種多様な「会議通知」が登録されていると思います。それらの会議通知のうち、「議事録を作成するMTG」のイベント名をスプレットシートに書き出します。

ex)
議事録を作成する会議通知名が

  • インフラ進捗報告
  • アプリ進捗報告
  • 【PJ】週次定例会
  • 【内部】隔週会
    の場合
    Screen Shot 2019-12-12 at 0.23.40.png

この時、作成したスプレッドシートのURLは
https://docs.google.com/spreadsheets/d/abcedfg12345/edit?folder=hogefuga#gid=0
のようになります。この時の idabcedfg12345 になります。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時間ごとに起動させます。

Screen Shot 2019-12-12 at 1.32.59.png

slackへの議事録URLの投稿

正しく動作すれば、MTG時間になると、slackで以下の投稿が得られます。
Screen Shot 2019-12-12 at 1.58.31.png

まとめ

以上により、議事録の準備はオール自動化されました。
事前準備、コーディング作業は大変ですが、1度作ってしまえば、もう議事録準備に費やす工数は無くなると思われます。

以上、長文にお付き合いいただき、有難うございました。

39
22
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
39
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?