座席管理ツールRobin Desksの製品選定からAPIの活用事例 - ZOZO TECH BLOG

座席管理ツールRobin Desksの製品選定からAPIの活用事例

OGP

こんにちは、コーポレートエンジニアリング部の竹田です。ZOZOテクノロジーズでは昨今の情勢を受け、日本全国どこに居住していても就業可能な全国在宅勤務制度を導入しています。また、ZOZOにおいてもアフターコロナを見据えた週2出社・週3リモートというハイブリッドな働き方の導入を予定しています。

座席管理システム導入の経緯

そのような新しい働き方に対応すべく、本社屋である西千葉オフィスはフリーアドレスを導入しています。異なるワークスタイルを持つ2社の社員が利用するオフィスですので、それぞれの要望を満たす座席管理システムの導入が必要となりました。例えば、テクノロジーズ社員であれば好きなときに好きな座席(テクノロジーズ社員に割り当てられたエリア内において)を予約できる。ZOZO社員であれば当月の出社予定日と、その日に割り当てられた座席が事前に確認できるといった具合です。

重視したポイント

システムの導入にあたって、利用者の目線と管理者の目線からそれぞれ以下のようなポイントを重視しました。

  • 利用者の目線

    • SSOでログインしたい
    • 直感的なUIで予約操作をしたい
    • 誰がどこの座席にいるか把握したい
  • 管理者の目線

    • 利用者の要望を満たしたい
    • アカウント管理を省力化したい
    • APIでシステマチックに管理したい

SSOでログインしたい

弊社ではAzure ADを認証基盤として利用しており、「マイ アプリ ポータル」から利用したいSaaSを選択してログインしています。

マイ アプリ ポータル

利用者は各SaaSの認証を意識することなくサービスを利用できるというメリットがあります。今回導入するシステムはSAML認証に対応しているというのが要件の1つとなります。

直感的なUIで予約操作をしたい

理想のイメージは、飛行機や映画館の座席予約システムです。建造物のアウトラインと座席配置が表示された画面上で、予約済み座席であれば灰色、空き座席であれば青色や緑色などで表現されてあれば、どこが空き座席なのかひと目でわかります。更に言えば、UIデザインがオシャレであると、なお良しです。

誰がどこの座席にいるか把握したい

フリーアドレスだと誰がどこにいるのかわからない状態になります。先の直感的なUIに通ずるものがありますが、座席配置が表示された画面上で、座席利用者の名前がわかるとそれが解消されます。また、特定人物に絞って検索するとその人の座席位置がピンポイントでわかる機能もあると便利です。

利用者の要望を満たしたい

利用者にとって使いやすい、わかりやすいというのは管理者にとってもメリットになります。準備するマニュアルもシンプルになり、システム導入後のヘルプデスク対応に費やす時間が大きく減少するためです。

アカウント管理を省力化したい

我々が管理するシステムは多岐に渡り、システムごとにアカウントが存在します。社員の入社・退社の度にアカウントの追加や削除を対応するのは大変ですし、対応漏れが発生する可能性も考えられます。そのような労力を少しでも省くために、SCIMプロビジョニングに対応していることを特に重視しました。

APIでシステマチックに管理したい

将来的に、座席の管理や予約の管理を省力化するため、API連携可能なシステムであることが望ましいです。Webインタフェースからでは手間のかかる大量のオペレーションも、APIが利用できれば迅速かつ正確に対応できます。

システムの選定

以上のポイントを簡潔にまとめると以下のようになります。

  • わかりやすいUIである
  • SAML認証に対応している
  • SCIMプロビジョニングに対応している
  • APIが用意されている

これらを満たしたシステムがRobin Desksです。

Robinとは

Robinは、米国Robin Powered社より提供されるオフィスの柔軟かつ効果的な利用を促進するプラットフォームです。Robinには大きく2つの機能があります。今回導入した座席管理を提供するRobin Desksと、会議室管理を提供するRobin Spacesです。弊社では、Robin Spacesをすでに導入しており、これもRobin Desksの導入に至った決め手の1つとなりました。

Robin Desksのイメージ

出典: Workplace management software for flexible offices | Robin

プランの選定

Robinには以下のプランが用意されています。

  • Basic
  • Pro
  • Premier

SAML認証およびSCIMプロビジョニングに対応しているプランはPremierのみであるため、今回は必然的にPremierを採用しました。その他にもPremierであればカスタムロールによる細やかな制御が可能であったり、専属のカスタマーサクセスマネージャーがついたりと、一定以上の組織であれば欲しい機能が提供されます。担当者やサポート窓口とのやり取りは基本的に英語となりますが、私のように英語が苦手であってもGoogle翻訳でなんとかなっています。

実運用に至るまで

ここからはRobin Desksが実運用に至るまでに対応したことを記述します。Robin Desksについてのネット上の情報はRobin Spacesよりも圧倒的に少なく、日本語の情報に限っては2021/08/10時点でほぼ皆無でした。特に苦労したAzure ADにおけるRobinのSAML認証、およびSCIMプロビジョニング対応については、その詳細をここに残します。

SAML認証の設定

Robinのヘルプセンターと、Microsoftのドキュメントを参考に、以下のように設定を進めます。

  1. Azure ADの「エンタープライズアプリケーション」で「すべてのアプリケーション」>「新しいアプリケーション」と遷移し、ギャラリーからRobinを追加する

    AzureAD_アプリケーションの追加

  2. 「シングル サインオン」>「SAML」と遷移し、「フェデレーション メタデータXML」をダウンロードする

    AzureAD_SAMLの設定

  3. Robinの管理画面で「Manage」>「Integrations」と遷移し、下方にある「SAML 2.0」の「Add」をクリックする

    Robin_SAMLの有効化

  4. 「Import IDP Metadata」からさきほどダウンロードしたXMLファイルをインポートすると、各項目が自動で入力される

    Robin_フェデレーションメタデータのインポート

  5. 「Advanced Options」を開いて「Encrypt Assertion」のチェックを外し、「Windows」のチェックをつける

    Robin_SAMLの追加設定

  6. 「Save Configuration」で保存して完了

設定が完了したら、正常にSSOできるか確認してください。特にRobinの「Advanced Options」の設定がデフォルトのままだと、マイ アプリ ポータルからはサインイン可能ですが、Robinのサインイン画面からだと認証エラーとなりました。

SCIMプロビジョニングの設定

Robinのヘルプセンターと、Microsoftのドキュメントを参考に以下のように設定を進めます。

  1. Robinの管理画面で「Manage」>「Integrations」と遷移し、「SCIM Provisioning」の「Manage」をクリックする

    Robin_SCIMの有効化

  2. 「Generate Token for SCIM」でトークンをコピーしておく

    Robin_SCIMトークンの生成

  3. さきほどAzure ADで追加したRobinアプリの「プロビジョニング」から「作業の開始」をクリックする

    AzureAD_プロビジョニングの設定1

  4. プロビジョニングの画面で以下のように設定する

    • プロビジョニングモード: 自動
    • テナントのURL: https://api.robinpowered.com/v1.0/scim-2
    • シークレット トークン: さきほどRobinの管理画面で生成したトークン

    AzureAD_プロビジョニングの設定2

  5. マッピングを以下のように設定する

    • ユーザーのマッピング設定 AzureAD_ユーザーマッピングの設定
    • グループのマッピング設定 AzureAD_グループマッピングの設定
  6. エラーの通知先メールアドレスとスコープを設定して完了

    AzureAD_設定完了

設定が完了したらユーザーやグループを割り当て、プロビジョニングの初期サイクルが完了するまで待機します。設定が正しければ、Robin側にユーザーアカウントやグループが作成されます。

フロアマップと座席の設定

Robin上に手持ちのフロアマップデータを直接反映はできず、Robin Powered社の担当者にオフィスの設計図や間取り図のデータを渡す必要があります。渡したデータを元にRobin Powered社のマップチームが専用のフロアマップデータを作成してくれます。

データを渡してから数日後にオフィスのアウトラインを抽出したフロアマップがRobin上に反映されるので、このフロアマップに対して座席レイアウトを設定していきます。座席レイアウトは以下のような画面でドラッグ&ドロップによる直感的な操作が可能です。

フロアマップ_座席レイアウト

座席のタイプには以下の3つを設定できますが、フリーアドレスの場合はHotもしくはHoteledを設定することになると思います。基本的にはHoteledでユーザーに自由に座席を選択・予約させて、一部固定席の場合はAssignedで管理者が利用者を割り当てるといった運用が良いのではないでしょうか。

タイプ 予約期間 事前予約できるか 誰が予約できるか チェックイン対応か
Assigned 永続 できる 管理者もしくは委任者 対応
Hot 1日のみ 当日のみ 一般ユーザー 対応
Hoteled 1〜5日以上 できる 一般ユーザー 対応

APIの活用事例

RobinにはAPIが用意されています。今回はこのAPIを利用して、指定日に指定座席を一括で予約する事例をご紹介します。例えば、2週間後の水曜日にオフィス1Fのフロア半分をイベントで貸し切りたいといった依頼があったとします。そのような場合にWebインタフェースからポチポチと手作業で座席を確保するのは非効率です。管理画面上からCSVで座席を割り当てる機能があるものの、こちらの機能は座席タイプがAssignedでないと利用できません。今後、類似の依頼が発生することは明らかであったため、APIで解決に取り組みました。APIについてのドキュメントは以下に用意されています。

座席を予約するAPIはこちらです。必須パラメーターとなる座席IDの取得方法と、リソース構成を説明します。

リソースの構成

リソースは大きい順から以下のようになっています。 OrganizationはLoactionを内包し、LocationはSpaceを内包しているイメージです。

Organizaition

一番大きなくくりで、契約の単位でもある。例えば会社や組織といったものが該当する。

"data":{
    "id":<account_id>,
    "is_organization":true,
    "name":"ZOZO GROUP",
    "slug":"<slug>",
    "avatar":"https://static.robinpowered.com/reimagine/images/***.png",
    "created_at":"20YY-MM-DDTHH:MM:SS+0000",
    "updated_at":"20YY-MM-DDTHH:MM:SS+0000"
}

cf. https://docs.robinpowered.com/reference#get-organization

Location

物理的な場所のことで、住所で表現できるもの。例えばオフィスの入居するビルが該当する。

"data":[
    {
        "id":<location_id>,
        "account_id":<account_id>,
        "campus_id":<campus_id>,
        "name":"西千葉オフィス",
        "description":NULL,
        "image":NULL,
        "address":"日本、千葉県千葉市稲毛区緑町1丁目15",
        "latitude":35.6255103,
        "longitude":140.0988645,
        "time_zone":"Asia/Tokyo",
        "created_at":"20YY-MM-DDTHH:MM:SS+0000",
        "updated_at":"20YY-MM-DDTHH:MM:SS+0000",
        "working_hours":[...]
    },
    {
        ...
    }
]

cf. https://docs.robinpowered.com/reference#get-organization-locations

Space

建物内の部屋やエリアのこと。レベル(階層)情報もここにある。例えば2Fの会議室Bや3Fの営業部エリアといったものが該当する。

"data":[
    {
        "id":<space_id>,
        "location_id":<location_id>,
        "level_id":<level_id>,
        "name":"1F Area A",
        "description":NULL,
        "image":"https://static.robinpowered.com/reimagine/images/***.png",
        "discovery_radius":3.5,
        "capacity":NULL,
        "type":"work",
        "is_accessible":false,
        "is_managed":false,
        "is_disabled":false,
        "updated_at":"20YY-MM-DDTHH:MM:SS+0000",
        "created_at":"20YY-MM-DDTHH:MM:SS+0000",
        "behaviors":[...]
    },
    {
        ...
    }
]

cf. https://docs.robinpowered.com/reference#get-location-spaces

Zone / Desk

ゾーン(フロアマップ上でPodと表現されている、座席グループのようなもの)と座席。

"data":[
    {
        "id":<zone_id>,
        "space_id":<space_id>,
        "name":"Zone B",
        "type":"pod",
        "created_at":"20YY-MM-DDTHH:MM:SS+0000",
        "updated_at":"20YY-MM-DDTHH:MM:SS+0000"
    },
    {
        ...
    }
]

cf. https://docs.robinpowered.com/reference#spacesidzones

"data":[
    {
        "id":<desk_id>,
        "name":"Desk 3",
        "space_id":<space_id>,
        "zone_id":<zone_id>,
        "is_reservable":true,
        "is_disabled":false,
        "disabled_at":NULL,
        "created_at":"20YY-MM-DDTHH:MM:SS+0000",
        "updated_at":"20YY-MM-DDTHH:MM:SS+0000"
    },
    {
        ...
    }
]

cf. https://docs.robinpowered.com/reference#spacesidseats

「株式会社ZOZO > 西千葉オフィス > 1F > 座席エリアA > ゾーンB > 座席No.3」というような情報をもって初めて座席を特定可能となります。そのため、座席IDを取得するためには、大きなくくりから順番にたどる必要があります。

  1. 対象となるオフィスのlocation_idを取得
  2. 取得したlocation_idを元に、対象となるエリアのspace_idを取得
  3. 取得したspace_idを元に、対象となる座席のdesk_idを取得

座席予約のAPI

座席IDを取得できたらようやく座席予約が可能となります。こちらにあるように、以下パラメーターを指定します。

  • id: 予約する座席のID
  • title: 予約のタイトル
  • type: 予約のタイプ
  • start: 予約の開始日時
    • date_time: ISO 8601形式の時刻表記
    • time_zone: タイムゾーン
  • end: 予約の終了日時
    • date_time: ISO 8601形式の時刻表記
    • time_zone: タイムゾーン
  • reservee: 被予約者
    • email : 被予約者のメールアドレス
    • user_id : 被予約者のユーザーID
  • reserver_id: 予約操作するユーザーのID

一例として、Pythonで日本時間の2021年8月15日午前9時30分から2021年8月18日午後8時まで座席を予約したい場合は、以下のようにPOSTします。

url = "https://api.robinpowered.com/v1.0/seats/" + <desk_id> + "/reservations"
headers = {
    "Authorization":"Access-Token " + <APIトークン>,
    "Content-Type":"application/json"
}
payload = {
    "type":"hoteled",
    "start":{
        "date_time":"2021-08-15T09:30:00+09:00",
        "time_zone":"Asia/Tokyo"
    },
    "end":{
        "date_time":"2021-08-18T20:00:00+09:00",
        "time_zone":"Asia/Tokyo"
    },
    "reservee":{
        "user_id":<被予約者のユーザーID> # emailかuser_idのいずれかを指定する必要がある
    },
    "reserver_id":<予約者のユーザーID> # reserveeと異なる場合は、reserverが代理で予約したような扱いとなる
}
response = requests.post(url, headers=headers, json=payload)

事前に座席IDと名前の一覧をリスト化し、フロアマップと並べるなどして実運用しやすいインタフェースを準備しておくと便利です。実際に、私達は以下のようなものを用意して運用しています。

運用例

その他の機能

Robinには他にも便利な機能があります。そのいくつかをご紹介します。

Slack App

Robin公式のSlack Appが用意されており、会議室の空き状況や特定人物の座席などを問い合わせることができます。弊社ではSlackをスタンダードなコミュニケーションツールとして採用しており、ツールの切替が発生しないことは大きな利点です。

  • 会議室の空き状況確認

    Slack_会議室の空き状況

  • 特定人物の座席確認

    Slack_特定人物の座席

座席の確認では、フロアマップも一緒に表示してくれるため、非常にわかりやすいです。

Analytics

会議室や座席の利用状況を可視化できます。特に昨今はソーシャルディスタンスが重要視されているため、オフィスの人口密度が視覚的にわかることで、感染予防など健康への応用も考えられます。

  • 西千葉オフィス: 6月1日〜7月25日の座席の利用状況

    Analytics_座席の利用状況

このご時勢ですので、基本的にオフィス利用率は非常に低くなっています。いくつか微妙に利用率が上昇している日がありますが、これは先にご紹介した座席の一括予約で制御した日です。

まとめ

昨今の情勢に適応したオフィスの柔軟かつ効果的な利用を促進するプラットフォームであるRobin。その中でも座席管理のRobin Desksにフォーカスを当て、実運用に至るまでの準備やAPIを活用した座席予約の事例をご紹介しました。今後オフィスの利用が今よりも活発化することを見据えて、Robinのさらなる活用を模索したいと思います。

ZOZOテクノロジーズでは、一緒にスタッフや組織の課題をテクノロジーの力で解決してくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください!

tech.zozo.com

カテゴリー