見出し画像

【GAS】Google Apps Script 活用事例 Googleカレンダーの予定詳細蘭への記入を効率化

カレンダーの詳細欄に、コレとアレと、ついでにアレも書いておいて

転職して、一番変わったのは、Googleカレンダーの活用度です。以前は、定例ミーティングや外出の時しか、使用しなかったのに対し、今は、就業時間中、いつどこで何をしているか、みっちり書いて使い倒しています。

採用の事務補助という事で、面接日程の詳細欄に、採用管理ツールのURLだったり、管理表として使っているスプレッドシートの情報を書いたりしなければならず、めちゃくちゃ面倒なのです。なので...........自動化しました。

setDescriptionを実行する前に、

HRMOS上で面接日程を登録します。そうすると、連携した自分のGoogleカレンダーに予定が登録されます。その際、カレンダーの詳細に、自動でHRMOSの応募者のリンクが自動で入ります。

転職後、個人情報取り扱いの運用ルールが、異様に厳しくなり、Googleカレンダーの面接日程から、応募者の名前や情報を意図的に消しています。カレンダーに記載されているHRMOSのリンクを見ないと、誰の面接日程として登録してあるかが分からないようになっています。

今回のスクリプトでは、その予定の詳細にテンプレートを適用して、{}で囲まれた部分にシートの情報を流し込んで書き換えます。

スクリーンショット 2020-08-29 12.49.25

Googleカレンダーで検索って?

実は、このスクリプトを組むまで、予定を検索する事がなかったので、こんな機能があるなんて知りませんでした。HRMOS IDで検索すると、対象者の面接日程を見つける事が出来ます。

スクリーンショット 2020-08-29 13.05.31

スクリーンショット 2020-08-29 13.09.28

ソースコードがこちら。

/*
* プロンプトで入力する内容は、HRMOSのリンク
* 2020/08/30のスケジュールから、カレンダーの詳細を取得
* その内容がテンプレートとなっている
* 取得したテンプレートに変数を挿入して、適切なものに変更する
* 
* 管理表から、コンフルURLや希望する職種の情報を抽出、カレンダー内容に反映する
*
*/


function get_HRMOS_ID() {
 const ui       = DocumentApp.getUi();
 const response = ui.prompt(
   'HRMOSのURLを入力してください。',
   '(例)https://hrmos.co/applications#/123456789?tabId=interview',
   ui.ButtonSet.OK
 );
 
 const inputNumber = response.getResponseText().match(/[0-9]{19}/)[0];
 console.log(`入力された元の値: ${response.getResponseText()}`);
console.log(`正規表現で抽出後: ${inputNumber}`);

switch (response.getSelectedButton()) {
 case ui.Button.OK:
   console.log('%s と入力され、OKが押されました。',inputNumber);
   
   break;
   
 case ui.Button.CLOSE:
   console.log('閉じるボタンが押されました。');
   
}//switch

return inputNumber;
}




function getDescriptionTemplate() {
 const date        = new Date('2020/08/30');//テンプレートが保存してある日付
 const calendar    = CalendarApp.getDefaultCalendar();
 const events      = calendar.getEventsForDay(date);
 const eventId     = events[0].getId();
 const calTitle    = events[0].getTitle();
 const description = events[0].getDescription();
 
 console.log(calTitle, eventId);
 return description
}//end





//カレンダーの予定詳細を書き換える。
//使用想定シーンとしては、HRMOS上で予定を作成した際、自分のカレンダーに作成される
//その予定に対して、テンプレートをコピーし、変数を挿入する感じ

function setDescription() {

 //今日から1ヶ月後の日付
 const startTime = new Date();
 const endTime   = new Date();
 endTime.setMonth(endTime.getMonth() + 1);
 
 //自分のカレンダーの中から、HRMOS IDが含まれている予定を検索する。
 const HRMOS_ID  = get_HRMOS_ID();//HRMOSのID
 const calendar  = CalendarApp.getDefaultCalendar();
 const events    = calendar.getEvents(startTime, endTime, {search: HRMOS_ID});
 
 //テンプレートを取得
 const getTemplate = getDescriptionTemplate();
 //console.log(description);
 
 
 //管理表からプロジェクト名を取得
 const projects    = getInternTitle(HRMOS_ID);
 const job         = projects[0].match(/.*】/)[0];
 
 
//変更対象は、自分のカレンダーであるため、共有専用のカレンダーを
//誤って書き換える事故は起きない。
 for(const event of events){
   const eventTitle = event.getTitle();
   const date       = event.getStartTime();
   date.setMinutes(date.getMinutes() + 5);
   
   
   //なぜか、5分後スタート
   const stringDate = Utilities.formatDate(date, 'JST', 'HH:mm');
   console.log(eventTitle, stringDate);
   
   
   //HRMOSが自動挿入してくれるURL
   const originalDecripion = event.getDescription();
   
   
   //変数を挿入して、任意の説明文に変更する。
   //コンフルと、出席者、対象案件の入力が必要
   const newDescription    = getTemplate
   .replace('{5MinutesLater}', stringDate)//5分後スタート
   .replace('{confluenceUrl}', projects[2])//コンフルのURL
   .replace('{project1}', projects[0])//第一希望職種
   .replace('{project2}', projects[1])//第二希望職種
   .replace('{HRMOS}', originalDecripion);//HRMOS上でカレンダー予約すると、自動挿入されるリンク
   
   
   event.setDescription(newDescription);
   console.log(newDescription);
   event.setTitle(`22卒${job}採用面接`);
 }//for
}//end





//HRMOS IDで、管理表を検索
//対象案件名を取得
function getInternTitle(targetId) {
 const url         = '********************************';
 const spreadsheet = SpreadsheetApp.openByUrl(url);
 const sheet       = spreadsheet.getSheetByName('DB');
 const values      = sheet.getDataRange().getValues();
 
 console.log(spreadsheet.getName());
 
 
 //見出し行を判定
 const headerRow   = values[1];
 const project     = '第一希望職種';
 
 
 //HRMOS IDが記載されているC列を取得、空白行を削除
 //先頭行に空白行があるため、generateArray は使用しない
 const HRMOS_ID_Column = sheet.getRange('C:C').getDisplayValues().flat();
 
 
 console.log(typeof HRMOS_ID_Column);//object
 console.log(`HRMOS IDが記載されている C列: ${HRMOS_ID_Column}`);
 
 //HRMOS IDで検索
 //配列は0スタートのため、 +1をしている
 const row     = HRMOS_ID_Column.indexOf(targetId) + 1;
 const column  = headerRow.indexOf(project) + 1;
 const column2 = headerRow.indexOf('コンフルURL') + 1;
 
 
 console.log(`行: ${row}`);
 console.log(`列: ${column}`);
 
 
 const targetRange  = sheet.getRange(row, column, 1, 4);
 const targetValues = targetRange.getValues().flat();
 console.log(`取得範囲: ${targetRange.getA1Notation()},${targetValues}`);


 const confulUrl    = sheet.getRange(row, column2).getValue();
 const newArray     = [targetValues[0], targetValues[2], confulUrl];
 console.log(`案件名のみ: ${newArray}`);

 return newArray
}

経由するFunctionが、3つ。結構長いですね.....。

こんな流れになっています。

1 . Googleドキュメントのスクリプトエディタで動作します。
2 . setDescriptionを実行する
3 . Googleドキュメント上に入力画面が表示される
4 . HRMOSの応募者のURLを入力する(コピペでOK)
5 . 入力されたURLから、19桁の数字のみを抽出する(←HRMOS ID)
6 . 19桁の数字で、Googleカレンダーとスプレッドシートを検索
7 . HRMOS IDが含まれている、該当イベントを取得。
8 . カレンダー詳細のテンプレを、2020/8/30から、取得。
9 . 取得したテンプレ内容に、シートの情報を流し込む。
10. 新しい内容を、該当する予定に上書きする。

同様に、HRMOSのリンクが、管理表のシートにも記載があるので、VLOOKUPと同じような要領で検索、同じ行のn列目を取得します。

その管理表、セルの結合だったりが一部、あり、空白行もきちんとカウントしないと、indexOfで適切な行を取得できないという問題がありまして、少し冗長な記述があります。

書き換えを試すミニマムなスクリプト

function myFunction() {
 const document = DocumentApp.getActiveDocument();
 const body     = document.getBody();
 
 body.replaceText('{project1}', 'YouTuber');
 
 const text     = body.getText();
 console.log(text);
}

{project1} を  YouTuberに書き換えます。このYouTuberの部分に、シートから取得した値とかにする事も出来ます。

スクリーンショット 2020-08-29 13.25.47

スクリーンショット 2020-08-29 13.28.31

書き換えが出来ると、会社名と名前を差し込んだ請求書や送付状の発行などがすごく楽ちんになります。今回は、同じ仕組みをカレンダーに使いました。

カレンダーの出席者のメールアドレスをシートに書き出すスクリプト

自動化の過程で、面接出席者のメールアドレスを書き出すスクリプトを書いてみました。

function calAttendant() {
 const startTime = new Date('2020/08/01');
 const endTime   = new Date();
 const calendar  = CalendarApp.getCalendarById('**************');
 const events    = calendar.getEvents(startTime, endTime);
 
 let mailAddressArray = [];
 
 for(const event of events){
   const people   = event.getGuestList();
   console.log(people);
   
   for(const person of people){
     console.log(person.getEmail());//Emailアドレスでしか取れない。
     mailAddressArray.push([person.getEmail()]);
   }//for person
 }//for events
 return mailAddressArray
}//end


function exportMailAddress() {
 const spreadsheet = SpreadsheetApp.openByUrl('************');
 const sheet       = spreadsheet.getSheetByName('Email');
 const lastRow     = sheet.getLastRow() + 1;
 const values      = calAttendant();
 
 sheet.getRange(lastRow, 1, values.length, values[0].length).setValues(values);

}

//連絡先からインポートする方法もあるよ。
function exportEmails() {
 
 //Google連絡先から連絡先一覧を取得
 const contacts = ContactsApp.getContacts();
 
 //連絡先の登録件数分ループする
 for (let i = 0; i < contacts.length; i++) {
   
   const emails = contacts[i].getEmails(); //Emailフィールド
   //console.log(emails);
   
   for(const email of emails){
     console.log(email.getAddress());
   }//for
 }
}

過去エントリーでは、こんなの書いています。

Googleカレンダーの自動化


この記事が参加している募集

#習慣にしていること

130,786件

この記事が気に入ったらサポートをしてみませんか?