# fs_chat_robot **Repository Path**: fyxzq/fs_chat_robot ## Basic Information - **Project Name**: fs_chat_robot - **Description**: 飞书机器人提取群里消息到表格 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-04-07 - **Last Updated**: 2023-06-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 飞书话题群运营机器人 ## 1 背景介绍 ### 1.1 飞书话题群介绍 很多公司内部的日常社交办公软件使用的是字节开发的飞书。飞书的功能特别强大,植入了各种各样的功能,其中之一就是话题群。话题群类似于群里,但和群聊又有点区别。如下图所示就是一个话题群: ![输入图片说明](images/image-20230509081306449.png) 飞书话题群的使用方式是由某个人发起一个群聊话题,如图中的话题X,话题创建完毕以后会自动新建一个新的会话窗口。话题创建完毕以后,话题群里的每个可在这个话题下进行评论,评论人第一次评论以后也会新建一个会话窗口。 ### 1.2 具体业务需求介绍介绍 现有一个运营话题群,主要用于公司某个业务线的管理运营,话题群里的人员包括业务、产品、运维以及研发,一般业务人员在使用系统时可能会发现部分问题,因此业务人员会针对发现的问题新建一个话题并@相关人员进行处理,相关人员收到消息后会在该话题下进行讨论并解决该问题,解决该问题后,解决问题的人员会关闭该话题。这里所说的关闭是逻辑上的关闭,具体方式为在该话题下发送一种标准格式的消息,消息格式定义为:Closed#系统类型#问题类型#解决方案#耗时#优先级#。 现在的具体需求为统计该话题群的消息到飞书表格,方便观察统计分析,统计的表格效果如下: ![输入图片说明](images/image-20230509090909324.png) ## 2 飞书应用机器人介绍 应用机器人需要在 [开发者后台](https://open.feishu.cn/app) 中创建,申请发布并经过租户的应用管理员审核通过后,即可使用。在应用发布范围内的用户,可以直接与你创建的机器人单聊,或在 **群设置>群机器人** 面板中将这个机器人添加进群聊使用。应用机器人受本租户的应用管理员管控。在应用管理员进行权限审核后,应用机器人可以调用飞书丰富的开放接口,获取、使用用户和租户资源。你可以参考教程:[开发一个可以互动的监控报警机器人](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-development-tutorial/introduction),了解开发一个可直接在聊天里互动的机器人的基本开发过程。 ### 2.1 创建飞书机器人并测试 1. 打开网址https://open.feishu.cn/,点击开发者后台,使用飞书账号进行登陆 ![输入图片说明](images/image-20230509091825027.png) 2. 点击创建自建应用 ![输入图片说明](images/image-20230509091931418.png) 3. 添加机器人 ![输入图片说明](images/image-20230509092101711.png) 4. 返回到开发者后台首页,进入服务端API调试台 ![image-20230509092818127](images/image-20230509092818127.png) 5. 在API列表里找到:**消息->消息管理->发送消息**。这是飞书提供的API接口,对于这个接口的具体使用方法,可以点击开发文档查看。 ![image-20230509093246643](images/image-20230509093246643.png) 6. 请求头点击左侧的刷新按钮即可获取,查询参数选择open_id,请求体如下 ```json { "receive_id": "ou_7d8a6e6df7621556ce0d21922b676706ccs", "msg_type": "text", "content": "{\"text\":\"test content\"}", "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204" } ``` 只需要修改请求体的receive_id,receive_id相当于飞书个人账号的ID,获取方式参考:https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-openid,另外删除uuid键值对,删除原因可参考开发文档。 7. 点击开始测试,从飞书应用中可以观察到效果如下 ![image-20230509094711596](images/image-20230509094711596.png) ### 2.2 飞书接口(开发需求所需要的) 1. 获取口令:https://open.feishu.cn/document/ukTMukTMukTM/ukDNz4SO0MjL5QzM/auth-v3/auth/tenant_access_token_internal 该接口时一个post请求,请求体如下: ```json { "app_id": "cli_slkdjalasdkjasd", "app_secret": "dskLLdkasdjlasdKK" } ``` app_id和app_secret需要从开发者后台界面获取,如下图 ![image-20230509154125469](images/image-20230509154125469.png) 2. 获取会话历史消息:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/list ![image-20230509154156404](images/image-20230509154156404.png) 该接口是一个get请求,其参数的传入可以参考开发文档,有很详细的解释 3. 向表格新增记录:https://open.feishu.cn/api-explorer/cli_a4d323aba379500b?apiName=batch_create&from=op_doc_tab&project=bitable&resource=app.table.record&version=v1 ![image-20230509154628295](images/image-20230509154628295.png) 这里的路径参数包括app_token和table_id,app_token和table_id的获取方式需要打开对应的表格,然后就可以得到app_token和app_id,如下图 ![image-20230509154859649](images/image-20230509154859649.png) 4. 向表格更新记录:https://open.feishu.cn/api-explorer/cli_a4d323aba379500b?apiName=batch_update&from=op_doc_tab&project=bitable&resource=app.table.record&version=v1 ![image-20230509155343282](images/image-20230509155343282.png) ## 3 需求开发设计 ### 3.1 数据库开发设计 chat_table_mapping表,用于记录群聊和表格的映射关系,此表主要是为了话题群的扩展,使多个群里也可以接入该系统 ```sql CREATE TABLE `chat_table_mapping` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `chat_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '群聊id', `chat_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '群聊名称', `app_token` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表格token', `table_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表格id', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; ``` chat_messge表,群聊话题与表格记录的映射表,每个话题对应表格的一行 ```sql CREATE TABLE `chat_message` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', `message_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '消息ID', `record_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '记录ID', `chat_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '群聊ID', `chat_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '群聊名称', `create_time` timestamp NULL DEFAULT NULL COMMENT '话题创建时间', `owner_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '所属人ID', `closed` int(11) NULL DEFAULT NULL COMMENT '是否关闭', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; ``` business_attribute_config表,业务属性配置表,用于配置不同群聊所需的不同业务属性。 ```sql CREATE TABLE `business_attribute_config` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', `chat_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '群聊id', `attribute_id` int(11) NULL DEFAULT NULL COMMENT '业务属性id', `attribute_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '业务属性名', `chat_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '群聊名称', `attribute_type` int(11) NULL DEFAULT NULL COMMENT '属性类型 0为string,1为int 等', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; ``` ### 3.2 需求开发设计 1. 查询数据库的chat_table_mapping表格,得到所有接入该系统的群聊id以及对应的表格id,针对每一个群聊执行以下步骤 2. 调用飞书获取会话历史消息的接口得到群聊的历史记录,接口具体详情参考:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/list,需要注意查询参数的start_time和end_time是秒级的时间戳 3. 将获取到的每一条消息封装为DetailMessageEntity对象 4. 过滤掉消息类型为"system"类型的消息,关于消息的类型可以参考:**https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/im-v1/message/events/message_content** 5. 将获取到的所有消息分为两类,一类消息的rootId为空,该消息表示创建话题的初始消息,需要插入到表格新的一行。另一类消息消息rootId不为空,该消息属于回复消息,隶属于某个会话,此类消息可能是标准的关闭话题的消息,因此可能需要更新表格的字段,关于消息ID的说明可参考:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/intro#ac79c1c2 6. 对rootId为空的所有消息进行处理,尝试插入到表格。首先需要查询数据库的chat_message表,校验该消息(话题)是否已经插入到表格(message_id作为唯一键判断),如果已经插入则过滤掉。对于未插入的消息(话题),提取出消息的具体内容,然后调用飞书插入表格的接口:https://open.feishu.cn/api-explorer/cli_a4d323aba379500b?apiName=batch_create&from=op_doc_tab&project=bitable&resource=app.table.record&version=v1 将话题消息插入到表格 7. 调用飞书消息插入到表格的接口后会得到响应,我们需要从响应体中得到插入的表格记录ID,从而构建消息ID和表格ID的映射关系,并将映射关系插入到数据库的chat_message表中。 8. 对rootId不为空的消息进行处理,尝试更新表格。首先按照rootId进行分组,对每一组的消息进行筛选,筛选得到消息格式是以Closed开头,以#结尾的消息,只有此类消息才代表逻辑上关闭话题,并且需要以#分割得到一些业务信息。 9. 更新表格时需要得到表格的记录ID,而表格记录ID需要查询chat_message映射表,通过message_id唯一确定一个record_id得到唯一的记录ID 10. 调用更新飞书表格的接口:https://open.feishu.cn/api-explorer/cli_a4d323aba379500b?apiName=batch_update&from=op_doc_tab&project=bitable&resource=app.table.record&version=v1 更新表格的记录,代表该话题已经关闭,补充表格中缺失的字段。 补充内容: 1. 在调用飞书的每个接口时都需要在请求头中添加Authorization,相当于一个口令,而获取口令需要调用飞书的接口:https://open.feishu.cn/document/ukTMukTMukTM/ukDNz4SO0MjL5QzM/auth-v3/auth/tenant_access_token_internal 2. 在调用插入表格和更新表格的飞书接口时需要了解请求体的构建,可以先浏览开发文档,然后查看代码中具体的构建方式。 ## 4 新增需求 1. 表格中需要新增一个字段响应时间,该字段表示一个话题发出后,第一条回复消息的回复时间,可以尝试完成