作者:飞书专业服务团队
推荐理由
本文档是会议室与Pad集成方案,通过飞书开放平台,将会议室与Pad互通,使会议室的空闲状态信息可在Pad展示。
一、需求概述
1.会议室状态展示:在会议室Pad上显示该会议室当前的闲忙状态,当天的会议预定时间表
2.释放会议室:未按时签到自动释放会议室或提前结束手动释放会议室
3.快速占用会议室:临时在会议室Pad上创建一个短时间的会议(15分钟、30分钟等等)
二、数据表
room_pad
会议室和Pad的关系映射表,用于Pad查找绑定的会议室数据
meeting_schedule
会议室预定的会议时间表,用于Pad显示时间表,获取会议室闲忙状态信息和释放会议室时更新该表
para_conf
参数配置表,可用于记录日历id等配置数据,用于快速占用会议室时创建会议。
背景:Pad上未有个人账号登录飞书,临时使用Pad创建会议室时,使用的是应用机器人创建日程,相当于日程的创建者是机器人,而日程需要挂在日历上,因此需要给机器人创建个日历( 创建一次即可),机器人的日历相关信息就存储在此参数配置表中。
三、新建企业自建应用
目的:此方案通过飞书开放平台能力实现集成,调用飞书开放平台API需要新建自建应用,开通接口权限,订阅飞书事件;
1、创建企业自建应用
250px|700px|reset
250px|700px|reset
新创建的应用必须要更换应用图标,否则无法应用发布。进入应用后,在凭证与基础信息页面,点击综合信息边上的按钮可更换应用图标。
2、开启机器人
开启机器人(必须):需要启用机器人调飞书开放平台接口,所以必须启用。启用方式:应用功能-》机器人,点击启用机器人按钮即完成开启;
250px|700px|reset
3、开通接口权限
需要开通接口权限,才可以调用飞书开放平台的接口。
接口说明里写清楚了调用此接口需要的权限要求和字段权限要求,然后在飞书开放平台后台权限管理搜索框搜索,勾选授权.
如下所示创建群接口,需要的权限要求:获取与更新群组信息,字段权限要求:获取用户 user ID:
250px|700px|reset
本集成中涉及需开通的接口:
250px|700px|reset
4、订阅事件
(1)配置请求地址:
250px|700px|reset
(2)添加事件:
配置好请求地址后,添加事件按钮才可以点击
本集成中需要订阅的事件:
250px|700px|reset
5、机器人通讯录权限
需要开通机器人通讯录权限,机器人才可读取对应人员的信息,权限范围根据需要配置。
250px|700px|reset
6、应用发布
以上步骤选择的事件订阅、接口权限的开通,需要申请发布后才会正式生效,因此还需要创建版本申请应用发布。
进入应用发布-》版本管理与发布,点击界面创建版本按钮。
进入创建版本界面,有如下两项输入:
应用版本号:输入应用版本号,应用版本号可自定义,建议从1.0.0开始;
可用范围:,默认的可用范围是创建者,只有创建者可见应用。
250px|700px|reset
然后点击按钮申请线上发布,发布之后需要管理员在飞书后台审核。
250px|700px|reset
管理员进入飞书管理后台,飞书管理后台可在飞书IM界面,点击头像-》管理后台点击进入,然后在工作台-》应用审核界面,点击审核。审核完成之后,申请飞书应用步骤完成。
四、基础数据维护
目的:维护会议室和Pad的关系映射表room_pad,预定某会议室时在对应的Pad上展示预定信息。可通过以下两种方式维护:
(1)线下整理数据,脚本初始化;(适用于会议室数量少、变动少的场景)
(2)开发功能界面,在界面操作绑定映射;(适用于会议室数量大、改动频率较大场景)
步骤:
250px|700px|reset
1、录入会议室信息数据
进入飞书管理后台,录入会议室信息,支持单个手动添加和excel批量导入创建。【推荐excel导入:层级和会议室可以一起创建;注意:会议室最大层级支持新建5层】
250px|700px|reset
2、调用飞书开放平台api,获取会议室的id(room_id);
根据维护会议室id和Pad id映射的方式不同,可分开处理:
线下整理数据,初始化脚本:
此种方式只需要获取到所有的会议室id,然后在线下与Pad id做映射,再初始化进映射表room_pad,只需要调查询会议室列表接口,参数层级id(room_level_id)传空,查出所有的会议室id即可;
开发功能界面,绑定映射:
{ "code": 0, "data": { "has_more": false, "items": [ { "has_child": false, "name": "53", "parent_id": "omb_7ec50dfe4192de00b1ee1b47a91335dd", "path": [ "omb_3f236d51e5680e22bce6c3905419f4d4", "omb_d65f028ab85df8fa20544ec0f0485344", "omb_f170bc789ec3f22266b602826115190f", "omb_7ec50dfe4192de00b1ee1b47a91335dd", "omb_9ee6fc9948e43017b35d499ce1294dfc" ], "room_level_id": "omb_9ee6fc9948e43017b35d499ce1294dfc" // 层级id } ] }, "msg": ""}}}}
{ "code": 0, "data": { "has_more": false, "page_token": "100", "rooms": [ { "capacity": 10, "custom_room_id": "", "description": "单纯备注", "display_id": "FM151077637", "name": "听天会议室", "path": [ // 层级路径 "omb_3f236d51e5680e22bce6c3905419f4d4", "omb_d65f028ab85df8fa20544ec0f0485344", "omb_f170bc789ec3f22266b602826115190f", "omb_7ec50dfe4192de00b1ee1b47a91335dd", "omb_9ee6fc9948e43017b35d499ce1294dfc" ], "room_id": "omm_4f3a1ae70d8351b2ca6b9f4747439457", // 会议室id "room_level_id": "omb_9ee6fc9948e43017b35d499ce1294dfc", // 层级id "room_status": { "status": true } }, { "capacity": 20, "custom_room_id": "", "description": "单纯备注", "display_id": "FM689649017", "name": "由命会议室", "path": [ "omb_3f236d51e5680e22bce6c3905419f4d4", "omb_d65f028ab85df8fa20544ec0f0485344", "omb_f170bc789ec3f22266b602826115190f", "omb_7ec50dfe4192de00b1ee1b47a91335dd", "omb_9ee6fc9948e43017b35d499ce1294dfc" ], "room_id": "omm_ead18f97e06b3185dc35e19e77328b93", "room_level_id": "omb_9ee6fc9948e43017b35d499ce1294dfc", "room_status": { "status": true } } ] }, "msg": ""}}}}
3、通过内部系统接口获取所有pad_id,最终Pad id 和room id完成映射,映射关系保存入库room_pad;
五、会议室闲忙状态信息获取
目的:拉取各个会议室当天的状态数据,存储在会议预定表meeting_schedule中,在Pad展示会议预定信息;
A:定时任务保证准确性
url:https://open.feishu.cn/open-apis/meeting_room/freebusy/batch_get?room_ids=omm_4f3a1ae70d8351b2ca6b9f4747439457&time_min=2022-12-15T00%3A00%3A00%2B08%3A00&time_max=2022-12-15T23%3A59%3A00%2B08%3A00出参:{ "code": 0, "data": { "error_room_ids": [], "free_busy": { //free_busy里面数据是各会议室预定时间 "omm_4f3a1ae70d8351b2ca6b9f4747439457": [ //对应meeting_schedule表room_id { "end_time": "2022-12-15T23:00:00+08:00",//对应meeting_schedule表end_time "organizer_info": { "name": "谢波", "open_id": "ou_8e1496cafafdf605b60bbe0b95ad5142" }, "original_time": 0, "start_time": "2022-12-15T22:30:00+08:00", //对应meeting_schedule表start_time "uid": "a1c01492-c0d6-4ba8-8e9c-df680de982fb" // 对应meeting_schedule表的uid }, { "end_time": "2022-12-16T00:30:00+08:00", "organizer_info": { "name": "谢波", "open_id": "ou_8e1496cafafdf605b60bbe0b95ad5142" }, "original_time": 0, "start_time": "2022-12-15T23:30:00+08:00", "uid": "7c85c754-101d-4a09-9b74-e25479d59b23" } ] }, "time_max": "2022-12-15T23:59:00+08:00", "time_min": "2022-12-15T00:00:00+08:00" }, "msg": "success"}}}}
如需显示各段时间预定的会议的主题,还需通过以下api获取:
(不建议显示会议主题,有泄密风险)
入参:{ "EventUids":[ { "uid":"a1c01492-c0d6-4ba8-8e9c-df680de982fb", // 日程id "original_time":0 } ]}出参数:{ "code": 0, "data": { "ErrorEventUids": [], "EventInfos": [ { "original_time": 0, "summary": "会议室预定", // 日程主题 "uid": "a1c01492-c0d6-4ba8-8e9c-df680de982fb", //日程id "vchat": { "meeting_url": "https://vc.feishu.cn/j/108850719", "vc_type": "vc" } } ] }, "msg": ""}}}}
B:订阅事件保证实时性
{ "schema":"2.0", "header":{ "event_id":"1fd74109f28d81b077396ca7084d2057", "token":"xutwFueXFaANznrhYO9Rebimi4vhUSAK", "create_time":"1671169817000", "event_type":"meeting_room.meeting_room.status_changed_v1", "tenant_key":"2eb744f56c0f1652", "app_id":"cli_a2f1e38a007c900c" }, "event":{ "room_id":"omm_4f3a1ae70d8351b2ca6b9f4747439457", // 会议室id "room_name":"听天会议室" // 会议室名称 }}}}}
最优方案:
A+B,同时保证准确性和实时性。
需注意防止重复写入数据,以主键uid保证数据唯一性。
不建议的方案:
只做A时Pad的更新显示存在一定的延迟。
只做B可能导致数据不一致。会议室状态变更了,但事件触发失败导致Pad没有更新显示。
六、释放会议室
目的:调用以下飞书开放平台api结束日程中的会议,释放会议室资源,修改会议预定表meeting_schedule,更新Pad的显示
1、未按时签到释放会议室资源
预定会议后飞书会一直锁定会议室资源,不会自动释放。如需实现未按时签到则释放会议室,则需要调用飞书接口释放会议室资源,然后更新Pad的显示
请求体:
{ "room_id":"会议室id", "uid":"当前日程id", "original_time":0, // 非重复日程必为0,重复日程0表示回复所有实例,非0表示回复单个实例 "status":"NOT_CHECK_IN"}}}}
响应体:
{ "code":0, "msg":""}}}}
2、提前结束会议释放会议室资源
点击Pad结束会议按钮,调用飞书接口释放会议室资源,然后更新Pad的显示
请求体:
{ "room_id":"会议室id", "uid":"当前日程id", "original_time":0, // 非重复日程必为0,重复日程0表示回复所有实例,非0表示回复单个实例 "status":"ENDED_BEFORE_DUE"}}}}
响应体:
{ "code":0, "msg":""}}}}
七、快速占用会议室
在会议室临时创建一个短时间的会议,在Pad上操作,选择占用时长,快速占用会议室资源
飞书预定会议室流程:
1、前期准备:
使用飞书开放平台的应用创建一个公共日历(一次性动作后续不用创建),保存日历id在配置表para_conf中供后续使用。
创建日历的API:
请求体:
{ "summary": "测试日历", "description": "使用开放接口创建日历", "permissions": "show_only_free_busy", "color": -1, "summary_alias": "日历备注名"}}}}
响应体:
{ "code": 0, "msg": "success", "data": { "calendar": { // 日历id,需要保存起来 "calendar_id": "feishu.cn_xxxxxxxxxx@group.calendar.feishu.cn", "summary": "测试日历", "description": "使用开放接口创建日历", "permissions": "show_only_free_busy", "color": -1, "type": "shared", "summary_alias": "日历备注名", "is_deleted": false, "is_third_party": false, "role": "owner" } }}}}}
2、后期操作:
在Pad上选择占用会议室的时间,应用计算会议的开始时间和结束时间,调用创建日程API创建本次会议的日程
请求体:
{ "summary": "日程标题", "description": "日程描述", "start_time": { "timestamp": "1624240800", "timezone": "Asia/Shanghai" }, "end_time": { "timestamp": "1624273200", "timezone": "Asia/Shanghai" }, "free_busy_status": "busy"}}}}
响应体:
{ "code": 0, "data": { "event": { "attendee_ability": "can_see_others", "color": -1, "description": "日程描述", "end_time": { "timestamp": "1624273200", "timezone": "Asia/Shanghai" }, "event_id": "8f81637d-2b4f-4b28-b074-60f22a1b0975_0", "free_busy_status": "busy", "is_exception": false, "location": { "address": "地点地址", "latitude": 0, "longitude": 0, "name": "地点名称" }, "recurrence": "", "reminders": [ { "minutes": 5 } ], "start_time": { "timestamp": "1624240800", "timezone": "Asia/Shanghai" }, "status": "confirmed", "summary": "日程标题", "visibility": "default" } }, "msg": "success"}}}}
日程创建成功后,应用调用以下API邀请会议室加入日程参与人,即可锁定会议室
请求体:
{ "attendees": [ { "type": "resource", "room_id": "omm_xxxxxxxx" } ]}}}}
成功响应体:
{ "code": 0, "data": { "attendees": [ { "attendee_id": "resource_6973921618166874114", "display_name": "10-Pad测试会议室(5) 测试大厦", "is_organizer": false, "room_id": "omm_c3ad38bb07c879c619808f74d57aeb2e", //needs_action 会议室预约中 // accept 会议室预约成功 //decline 会议室预约失败 "rsvp_status": "accept", "type": "resource" } ] }, "msg": "success"}}}}
如果锁定会议室成功,还需按照第四章的方式获取一次该会议室的状态信息,得到会议室的日程 ID(uid),uid在提前结束会议时需要用到。
然后修改会议预定表meeting_schedule,更新Pad的显示,如果锁定会议室失败则提示用户失败