UUUMエンジニアブログ

UUUMのエンジニアによる技術ブログです

第2回オンラインハッカソンで作成した拡張機能の裏話

こんにちは。エンジニアのendo_shizukaです。

UUUMに入社して1年半が経ちました。

「入社して1年半経ったとか時間の流れ早すぎん!?」って感じで日々業務に勤しんでいます。

さて、今回ブログを書くにあたりネタをいろいろ探していたのですが、

個人的にかなり大変だけど楽しかった第2回オンラインハッカソンで作成した機能でつまずいたポイントについて書いていきたいと思います。

第2回のオンラインハッカソンについてまだご存じない方は、

弊社の新進気鋭なエンジニア、久保寺君が書いてくれた記事がありますので見てみてください。 system.blog.uuum.jp

それではどうぞ。

 

そもそもGoogle Meetの出欠席確認機能って何?

前提としてGoogle Workspaceを使用している会社・チームが対象になります。

もしかしたら既に経験ある方もいるかと思いますが、会議の開催時刻になると招待されたメンバーは続々とGoogle Meet(以下、Meet)に参加します。

ファシリテーターは招待者の出欠確認を行うのですが、Meetの標準機能だと現在参加中のメンバーしか表示されていないので、Google Calendar(以下、Calendar)とMeetの参加者を照らし合わせながら確認するという手間が発生します。

もし、会議に招待しているメンバーが参加するのか否か、また現在Meetに参加しているか否かがMeet上で一目で分かれば出欠確認の手間が大幅に削減されるのでは?ということを目的に開発されました。

f:id:endo_shizuka:20220225192228p:plain
出欠席確認機能

  さて、ここから本題です。    

つまずきポイント

参加中のMeetからどの会議に参加してるかが判断できない...

会議で使用するMeet URLはCalendar上から確認できますが、

f:id:endo_shizuka:20220225160039p:plain
Calendar画面

Meet上からだとMeetのURLと入室前の会議タイトルしか情報が無く、どの会議に参加してるかが判断できません。

f:id:endo_shizuka:20220225160036p:plain
Meet画面

 

解決策

以下の手順で参加中のMeetの会議情報が取得できました。

  1. JavaScriptのlocation.pathnameを用いてMeet URLのhttps://meet.google.com/以下の文字列を取得

  2. CalendarAPIのEvents.listを用いて本日入っている自分の会議を全て取得

  3. 2で取得した会議の中にconferenceDataオブジェクト *1 があるので、その中のconferenceIdと1の文字列が一致するものを開催中の会議として取得する

参考1 developers.google.com

参考2 conferenceDataオブジェクトのデータ構造(2022/02/25現在)

conferenceData: 
{ entryPoints: [ [Object], [Object], [Object] ],
    signature: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    conferenceSolution: 
    { key: [Object],
    name: 'Google Meet',
    iconUri: 'https://xxxxxxxxxxxx' },
    conferenceId: 'yer-necw-rbs' },

 

会議室もゲスト扱いになって参加者一覧として表示されてしまう...

組織内で会議室もCalendarに作成して管理していた場合、

その会議室を使用した会議を作成するとゲストの1人として会議室も表示されてしまいます。

解決策

会議室のゲストのメールアドレスはドメインが@resource.calendar.google.comで設定される事を発見しました。

会議のゲストリストを取得する際に上記ドメインのゲストを弾くことで解決しました。

 

同じ会議IDで同じ予定が2つ取得されてしまう...

CalendarAPIのEvents.listでその日に開催される会議を取得した際に、同じ会議名で2つのオブジェクトが取得される場合があります。

これは定期的な会議の場合に発生するもので、実際に取得できたオブジェクトをそれぞれ確認してみると、 一方は定期的な会議の初回開催時の情報が入ったオブジェクト、もう一方は本日開催の情報が入ったオブジェクトであることがわかりました。

解決策

オブジェクト内を詳しく見てみると以下のような違いがありました。

  • 初回開催時の情報: recurrence: [ 'RRULE:FREQ=WEEKLY;WKST=SU;BYDAY=FR' ] *2

  • 本日開催の情報: recurringEventId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',

なぜ、定期的な会議の場合2つオブジェクトが流れてくるかの理由については調べきれていませんが、 実装としては本日開催の会議情報が得られればいいのでrecurringEventIdが含まれるオブジェクトを取得することで解決しました。

 

参加者のフルネームや招待ステータスなど参加者にまつわる情報を取得したいけど...

こちらは自分の完全な見当違いだったのですが、 CalendarAPIのEvents.listで会議情報を取得したら参加者のメールアドレスやフルネーム、招待ステータス *3 などが全て一括で取得できるものだと思っていました。

Events.listはあくまで会議自体の情報しか取得できず、参加者については別途APIを叩く必要がありました。

解決策

画面表示には 参加者のフルネーム メールアドレス 招待ステータス サムネイル画像 の値が必要だったので、

メールアドレス 招待ステータスをCalendarEventのgetGuestListを使用して取得しました。

const guests = event.getGuestList(true)

developers.google.com

参加者のフルネーム サムネイル画像 についてはAdmin SDK Directory Serviceを使用する事で、会議の参加者のフルネームやサムネイル画像を取得することができました。

  do {
    page = AdminDirectory.Users.list({
      domain: DOMAIN,
      viewType: 'domain_public',
      maxResults: 500,
      pageToken: pageToken
    });

developers.google.com

注意点として、AdminDirectory.Users.listを実行する際にviewType: 'domain_publicを書かないとエラーになります。

GoogleJsonResponseException: API call to directory.users.list failed with error: Not Authorized to access this resource/api))

 

まとめ

拡張機能はストアでの公開を目標にアップデートしていますが、頑張って対応中ですので公開までもうしばらくお待ちくださいmm

なお、実装した当時はここまでで紹介した解決策でなんとか乗り切れましたが、

現在や今後の仕様変更でもっと簡易に実装できたり同じやり方では解決できない場合も出てきますので、参考にされる際は自己責任かつその時その時の一番いい方法で実装して頂ければと思います。

*1:conferenceDataオブジェクトはMeet URLが発行されている場合のみ含まれるので、Meet URLを発行していない場合はオブジェクト自体存在しません。

*2:毎週金曜開催の場合このような値が入っています。

*3:はい / いいえ / 未回答