見出し画像

Googleフォームでzoomミーティングを自動設定する

とあるビジネスグループでは、1to1(ワントゥーワン)という自己紹介のような、ビジネスの商談のようなことが多く繰り広げられており、1対1での予定の調整が頻繁に発生しています。そしてzoomミーティングが標準のオンライン会議ツールとなっているため、この調整はこんな感じで行われています。
①メッセンジャーなどで1to1の依頼が来る
②自分のGoogleカレンダーで空き時間を見つける
③相手に空き時間の候補を提示する
④日時を指定され、OKする
⑤自分のカレンダーに予定を登録する
⑥ホスト(言い出した側)の場合、zoomのURLを発行する
⑦相手にそれを通知する

ここで、zoomとGoogleカレンダーを連携しておくことで、⑤と⑥は同時にできるようになっていると思います。

zoomミーティング設定画面

どちらかというと面倒なのは、自分のカレンダーのうち空いている時間を上げだして通知することでしょうか。同時に複数人と調整しているような場合、間違えてダブルブッキングしてしまうとさらに面倒なことになり、さらに出張の移動時間とかも考えると、しばらく調整できない状況になったりします。

Googleカレンダー

これを解決するために、TimeRexなどの日程調整ツールなども登場しており、②~⑦まで自動化されているものもそこそこあると思います。
今回はこの日程調整をGoogleフォームとカレンダーとGASというプログラミング言語で行ってみたということなのですが、何故同じような機能をわざわざ作ったのか?私なりにその意味はあると思っています。
既存のサービスは、サービスとして用意された機能の中で使う部分をプランから選択する形になりますが、お店の業態に合わせて予約システムとして利用したり、チームみんなの予定を調整したいといった、細かいカスタマイズがしづらいと思います。そのため、ここを自前のプログラムで実装しておけば、色んなお店の業態やシーンに特化した予約システムにできてしまうというわけです。また色んなサービスを覚えるのも大変ですが、Googleフォームはありふれたものでよく使われるため、使う人にとってもシンプルだという点も特徴かと思います。

TimeRexさんの画面

もちろん、BtoC企業にとって実用レベルとするにはいろんな運用を考えたりする必要がありますが、個人でやっているお店やサービス業であれば、十分応用が利くレベルかなと思います。

Googleツールで作るzoom日程調整

今回作ったフォーム機能は、自分のカレンダーとGmailと連携して、上記の②~⑦を自動化しています。図にすると以下のようなイメージです。

zoom日程調整ツール全体像

色々とごちゃごちゃしているように見えますが、実は大きく2つの部分からなっています。
一つは①と②で、Googleフォームの回答フィールドのうち、日時のリストを生成するという部分です。
もう一つは、④フォームが送信された後の⑤⑥で、カレンダーへの登録とメール送信をスプレッドシートから行うという部分です。③と④はGoogleフォームの標準機能のため、これはこのまま活かします。

仕組みの構造

Googleフォーム:空き時間の選択肢を作る

早速ですが、これらをGoogle App Scriptというプログラミング言語で実装していきます。まずはGoogleフォームのスクリプトエディタを起動して、下記を張り付けます。

function createSelectBox(){
  const weekList = new Array('日', '月', '火', '水', '木', '金', '土');
  // Googleフォームからスクリプトエディタを開いた場合、開いた元のGoogleフォームを取得する
  const form = FormApp.openById("[シートのID]");
  const item = form.getItems()[0];
  // プルダウンに設定する項目一覧
  const insertDataArr = [];

  //アクセス可能なカレンダーのIDを指定して、Googleカレンダーを取得する・・・➀
  let startDate = new Date();
  let endDate = new Date(Date.parse(startDate) + (7 * 60 * 60 * 24 * 1000));
  let checkCalender = CalendarApp.getCalendarById('[カレンダーID]');
  let myEvents = checkCalender.getEvents(startDate, endDate);

  for(let d=1; d <= 7; d++){          //・・・➁
    let from = new Date();
    from.setDate(from.getDate() + d);
    for(let i=9; i < 17; i++){
      let exist = false;
      //開始時間
      from.setHours(i);
      from.setMinutes(00);
      from.setSeconds(00);
      //終了時間
      let to = new Date(Date.parse(from) + (60 * 60 * 1000));
      if(isExsit(from, to, myEvents)){     //・・・➂
        exist = true;
      }
      if(!exist){
        insertDataArr.push(Utilities.formatDate(from, 'JST', 'yyyy/M/d')+ '('+ weekList[from.getDay()] + ')' + Utilities.formatDate(from, 'JST', 'H:mm') + '~' + Utilities.formatDate(to, 'JST', 'H:mm'));
      }
    }
  }
  item                                //・・・➄
    .asListItem()
    .setChoiceValues(insertDataArr)
    .setRequired(true);
}

function isExsit(start, end, events) {   //・・・➃
  for(let i = 0 ; i < events.length ; i++ ){
    if(!events[i].isAllDayEvent()){
      if((start <= events[i].getStartTime() && end <= events[i].getStartTime()) || (start >= events[i].getEndTime() && end >= events[i].getEndTime())){
      }else{
        return true;
      }
    }
  }
  return false;
}

簡単に解説すると、①の部分は自分のGoogleカレンダーから、登録されているイベントを1週間分取得しています。
そして②の部分では、フォームの選択肢リストを生成するために、1週間分の日時のリストを作っています。そのリストに対し、イベント登録済かどうかを③でチェックを行い、未登録であれば選択肢として追加していく処理を➄で行っています。④は③から呼ばれる関数で、渡された時間が空いているかどうかを判定する関数となります。

続いてこれを起動するタイミングをトリガーとして設定します。スクリプトエディタのトリガーを選択すると、フォームの起動時というトリガーもありますが、これは編集モードが起動されたという意味のようで、実用的ではありません。
より適しているのは、イベントのソースをカレンダーとし、詳細でカレンダー更新済みとすると、カレンダーに予定が追加されたり、変更されるたびにこのスクリプトが実行されますので、常に最新の日時のリストを、フォームへ設定することが可能となります。

トリガーの設定
Googleフォームのスクリプトのトリガー設定

上記で設定した内容でスクリプトが実行されると、以下のように選択肢フィールドが自動で生成されました。これでフォームとしてはいったん完成です。

生成されたフォームの日時選択肢

SpreadSheet:カレンダー登録とメール通知を自動化する

次に、SpreadSheetのスクリプトの実装です。Googleフォームで送信されると、まずSpreadSheetに記載されますが、それらの情報を受け取ってから実行するため、SpreadSheetのスクリプトとして実行することになります。
先ほどと同様に、スクリプトエディタを起動して以下を貼り付けます。

function sendmail(e) {
  [timestamp, date, name, company,mail, comment] = e.values;   //・・・➀
  const hostMail = '[自分のメールアドレス]'
  const subject = 'ミーティング予約フォーム:'+name+'様'; 
  const contactHost = '[自分の名前]'
  body = '以下のミーティングが設定されました。\n\n\n';

  body = body                                                  //・・・➁
   + 'ミーティングのご予約ありがとうございます。' + '\n'
   + '以下の通り承りました。' + '\n'
   + '登録日時:' + timestamp + '\n'
   + '実施予定:' + date + '\n'
   + 'お名前:' + name + '\n'
   + '会社名:' + company + '\n'
   + 'メール:' + mail + '\n'
   + 'コメント:' + comment + '\n\n\n'
   + '当日は以下のzoomリンクよりお入りください。\n'
   + 'https://us02web.zoom.us/j/[自分のミーティングID]' + '\n\n';

  //日付書式に修正
  targetDate = new Date(date.split("~")[0]);
  detail = 'ミーティングURL:'+'https://us02web.zoom.us/j/[自分のミーティングID]';

  mainBody = body                                              //・・・➂
   + '以下のリンクからGoogleカレンダーに登録できます。' +'\n'
   + '<https://www.google.com/calendar/render?action=TEMPLATE&text=' + 'zoomミーティング&dates='+Utilities.formatDate(targetDate, 'JST', 'yyyyMMdd')+'T'+ Utilities.formatDate(targetDate, 'JST', 'HHmmss')+'/'+Utilities.formatDate(targetDate, 'JST', 'yyyyMMdd') + 'T' +Utilities.formatDate(new Date(Date.parse(targetDate)+ (60 * 60  * 1000)), 'JST', 'HHmmss')+'&details=' + detail + '>\n'
   + 'それでは当日宜しくお願い致します。' + '\n'
   + '予定を変更したい場合は、恐れ入りますがメールでご連絡をお願い致します。' +'\n\n'
   + '---------------------------' + '\n'
   + contactHost + '\n'
   + hostMail ;

  //予約者へメール送信
  GmailApp.sendEmail(mail, subject, mainBody);                 //・・・➃

  //カレンダーへ登録
  registerSchedule(name,targetDate, body)                      //・・・➄
}

function registerSchedule(visitor,date, body) {                //・・・➅
  const calendar = CalendarApp.getCalendarById('[登録先のカレンダーID]');

  //登録内容を設定
  const title = "1to1:" + visitor + "様";  //予定のタイトル
  const startTime = date; //開始時間
  const endTime = new Date(Date.parse(date)+ (60 * 60  * 1000)); //終了時間
  
  const options = {
    description: body //詳細
  };
  //Googleカレンダーに予定を登録
  calendar.createEvent(title, startTime, endTime,options);
}

こちらも解説していくと、①で、フォームから送信された情報をプログラムが受け取っています。次に、変数としてメール本文を組み立てていきます。②のbodyは、メール本文とカレンダーに使う変数で、①で取得したフォームの送信内容と固定文言を組み合わせて本文を作っています。
③のmainBodyは、bodyがカレンダー登録でも使えるように、メール用の本文と切り離して使うために別の変数としています。そしてこの中で、メール受信者のGoogleカレンダーへ登録するためのリンクを生成しています。
ソースを追っていくと、こんな感じの内容となっていますが、action、text、dates、detailsというパラメーターを以下の書式で設定していくと、リンクを押すだけでカレンダーに登録できるようになります。

<https://www.google.com/calendar/render?action=TEMPLATE&text=' + 'zoomミーティング&dates='+Utilities.formatDate(targetDate, 'JST', 'yyyyMMdd')+'T'+ Utilities.formatDate(targetDate, 'JST', 'HHmmss')+'/'+Utilities.formatDate(targetDate, 'JST', 'yyyyMMdd') + 'T' +Utilities.formatDate(new Date(Date.parse(targetDate)+ (60 * 60 * 1000)), 'JST', 'HHmmss')+'&details=' + detail + '>\n'

Googleカレンダー登録リンクの抜粋

そして➃がGmailでメールを送信する処理になっています。
続いて➄⑥は、カレンダーを登録する関数の呼び出しとその本体となっています。⑥が本体となりますが、googleCalendarのAPIとしてcreateEventという関数にタイトル、開始時間、終了時間、詳細内容を渡すことで、登録が完了するようになります。
こちらのトリガーですが、スプレッドシートからフォームが送信された時にしておくことで、新規予約が入るたびに動くことになります。

スクリプトのトリガー

さて、実際にフォームから実行すると、以下のようなメールを受信しました。

受信メール

そして、カレンダーの方も以下の通り登録されました。

自動登録されたカレンダー

なお、このプログラムで追加されたカレンダーをトリガーに、またフォーム側のスクリプトも動きますので、ほぼ自動化が実現できるようになりました。


いかがでしたでしょうか。
今回は1対1の打ち合わせを調整するイメージで作成しましたが、予約の変更やキャンセル、またはお店の予約として使おうとすると、もう少し改良が必要になります。また、既存システムのAPIを通してオンラインで予定を連携すれば、Googleカレンダーを使っていない組織でも応用することができます。
是非皆さんでも、色々と弄ってみて、オリジナルの機能を作ってみてください!




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