概要
手動で議事録の準備をするのが面倒で、自動でやりたかったので新人でも、楽がしたい! ~議事録の準備~を参考にして作ったが、要件が若干違っていた。
要件
- カレンダーから予定を見て、会議が始まる前に議事録の準備ができている
- SLACKにて通知する
- 会議がない場合は作成をしない
- 議事録ファイルは毎回作ってはいけない
- 議事録のファイルは同じファイルを利用する
- そのファイルの「以下議事録」の下からテンプレートを挿入する
最後の要件が意外と難しく、全て出来なかった。
議事録ファイルから「以下、議事録」を探して位置を見つけて、そこからテンプレートを挿入する。
ロジック
ほとんどが新人でも、楽がしたい! ~議事録の準備~と同じ。
- 1時間毎にGASバッチが起動
- カレンダーを見る。
- 朝会の予定が入っている場合
- 議事録ドキュメントの「以下、議事録」を見つける
- その位置にテンプレートから挿入する。
- SLACKに通知する
各ファイルの役割
-
朝会議事録テンプレートファイル
-
GASスクリプト本体
-
挿入するテンプレート
-
議事録ファイルID
-
議事録のファイルID
-
議事録が変わる場合、こちらも変更する
-
自動議事録作成会議名
-
カレンダーに登録している会議名
Webhookを発行
slack apiからwebhookを発行する。
GAS
8割が新人でも、楽がしたい! ~議事録の準備~です。本当にありがとうございます。
コード.gs
// 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]);
}
return eventList;
}
// スプレッドシートに記載された文字の配列を返す
function getEventTitleFromSpredsheet(spredsheetpath) {
var ss = SpreadsheetApp.openById(spredsheetpath);
var sheet = ss.getSheets()[0];
var range = sheet.getRange(1, 1, ss.getLastRow());
var values = range.getValues();
var meetingList = [];
for (i = 0; i < values.length; i++) {
value = values[i];
meetingList.push(value[0]);
}
// スプレッドシートに記載された文字の配列を返す
return meetingList;
}
function start(){
// 議事録自動準備プログラムで、最初に起動する関数
// 「直近のイベント一覧」と「議事録を作成するMTG名」を取得し、一致する名前があれば議事録を準備する
var SPREDSHEETPATH = "[自動議事録作成会議名のID]"
var meethingList = getEventTitleFromSpredsheet(SPREDSHEETPATH);
var eventList = getCalendarEventList();
var createFlag = false;
var meethingName = '';
for (var i = 0; i < meethingList.length; i++) {
for (var 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) {
prepareMinutes(meethingName);
Logger.log('議事録を準備しました。');
Logger.log('MTG名:' + meethingName);
} else {
Logger.log('議事録は準備されませんでした。');
}
}
//議事録を作成し、slackに通知する
function prepareMinutes(meethingName){
// slack Incoming Webhook
var POSTURL = '[WebhookのURL]';
var fileUrl = insertTemplate();
// slackに議事録へのurlを投稿する
var message = '議事録を準備しました。' + '\n\n' + '会議名:' + meethingName + '\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);
}
// 「以下議事録」の文字を探す
function getHorizontal(mininutes_doc) {
var LIMIT = 50; // もしも見つからなかった場合用
var listItems = mininutes_doc.getBody().getParagraphs();
for (var i = 0; i < LIMIT; i++) {
var value = listItems[i].getText();
if (value.indexOf("以下、議事録") != -1) {
return i + 1;
}
}
return i;
}
// 議事録ファイルにテンプレートを入れる
function insertTemplate() {
// 議事録ファイルのIDが入っているスプレッドシートから取得
var MININUTES_DOC_ID = '[議事録ファイルのID]'
var mininute_ids = getEventTitleFromSpredsheet(MININUTES_DOC_ID);
var mininute_id = mininute_ids[0]
var template_doc = DocumentApp.getActiveDocument();
var mininutes_doc = DocumentApp.openById(mininute_id);
var horizontal = getHorizontal(mininutes_doc);
mininutes_doc.getBody().insertHorizontalRule(horizontal);
horizontal++;
template_doc.getBody().getParagraphs().forEach(function(value, i) {
if (value.getType() == DocumentApp.ElementType.LIST_ITEM) { // 箇条書きの場合
mininutes_doc.getBody().insertListItem(horizontal + i, value.getText()).setGlyphType(DocumentApp.GlyphType.BULLET);
} else {
mininutes_doc.getBody().insertParagraph(horizontal + i, value.getText());
mininutes_doc.getBody().getParagraphs()[horizontal + i].setAttributes(value.getAttributes()); // 見出しなどの属性を設定
}
})
return mininutes_doc.getUrl();
}
出来たら動かして、動くことを確認する。
トリガを設定する
1時間毎に動かすトリガを設定します。時計のアイコンから設定が出来ます。
1時間毎に動くように設定します。
一応、これで完成です。
参考サイト
Google Apps Scriptで議事録テンプレ作成を楽にした
GASを利用した定例議事録作成の自動化
新人でも、楽がしたい! ~議事録の準備~
ありがとうございます。
課題
- テンプレートからコピーする際、以下が出来ない
- 箇条書きがネストしている場合
- 水平線がコピーできない
- 他にもたくさんコピーできないパターンはある
- 担当者が離れてこのスクリプトを止めなかった場合、延々とスクリプトが動いてしまい、ドキュメントが肥大化してしまう
- 自動的の止まる仕組みを入れたいよね〜
- GASの場合、設定ファイル的なものってどこに配置するのが適切なんだろう?
- 「以下、議事録」の設定も、外出にするべきなんだろうか。