import time import json from itertools import chain from celery import shared_task from celery import Task from app.utils.utils import * from app.utils.yd_utils import get_token, get_activity_info from app.utils.feishu import create_doc, get_doc_block, create_doc_block, get_messages, send_groud_message from app.utils.utils import update_record, add_record from app.utils.yd_utils import new_blank_robot, new_blank_activity def parse_history_message(data): sender_id = "" message_content_data = [] message_images_data = [] items = data.get("items") for index, item in enumerate(items): print("=======================") sender_id_item = item.get("sender").get("id") if index == 0: sender_id = sender_id_item print(f"raw msg: {item}") print("***************") item_content = json.loads(item.get("body").get("content")) print(item_content) print("***************") message_id = item.get("message_id") if item_content.get("text"): message_content_data.append(item_content.get("text")) print(item_content.get("text")) if ( sender_id.startswith("cli_") and item_content.get("text") == "@_user_1 记录问题" ): sender_id = sender_id_item continue if item_content.get("content"): tmp_message = [] message_content_content_data = item_content.get("content") tmp_content_data = [] for message_content_content_item in message_content_content_data: for message_content_content_item_item in message_content_content_item: tmp_content_data.append(message_content_content_item_item) for tmp_content_data_item in tmp_content_data: print(tmp_content_data_item) if tmp_content_data_item.get("tag") == "text": tmp_message.append(tmp_content_data_item.get("text")) message_content_data.append(tmp_content_data_item.get("text")) if tmp_content_data_item.get("tag") == "img": message_images_data.append( { "message_id": message_id, "image_id": tmp_content_data_item.get("image_key"), } ) print("\n".join(tmp_message)) continue if item_content.get("title"): tmp_message = [] tmp_content_data = list(chain(*item_content.get("elements"))) for tmp_content_data_item in tmp_content_data: if tmp_content_data_item.get("tag") == "text": tmp_message.append(tmp_content_data_item.get("text")) message_content_data.append(tmp_content_data_item.get("text")) # 忽略消息卡片的消息 # if tmp_content_data_item.get("tag") == "img": # message_images_data.append( # { # "message_id": message_id, # "image_id": tmp_content_data_item.get("image_key"), # } # ) print("\n".join(tmp_message)) continue return message_content_data, message_images_data, sender_id @shared_task(include_result=False) def process_message_callback( app_id, app_secret, bitable_token, table_id, cache_dir, data ) -> None: """ 记录问题到多维表格逻辑 """ # 如果 @机器人 等于"记录问题", 获取当前的话题 event_message = data.get("event") sender_info = event_message.get("sender") message_data = event_message.get("message") sender_id = sender_info.get("sender_id").get("open_id") thread_id = message_data.get("thread_id") message_type = message_data.get("message_type") content = message_data.get("content") message_id = message_data.get("message_id") if not message_data.get("mentions"): # 忽略非@人的消息 lark.logger.info("忽略非@人的消息") return mentions_data = message_data.get("mentions") if "官方应用指令" not in [mention.get("name") for mention in mentions_data]: # 忽略@官方应用指令的消息 lark.logger.info("忽略非@官方应用的消息") return if message_type != "text": # 忽略非文本消息 lark.logger.info("忽略非文本消息") return content = json.loads(message_data.get("content")) content_text = content.get("text") if "记录问题" not in content_text: # 忽略非记录问题的消息 lark.logger.info("忽略非记录问题的消息") return record_category = "官方指令" if "指令" in content_text else "官方应用" record = {} images = [] images_token = [] lark.logger.info(f"message_content: {content_text}") # 从话题中提取问题发起人的所有消息和图片, 记录到多维表格中, 记录发消息人 openid 并将处理人设置为@机器人的人 client = ( lark.Client.builder() .app_id(app_id) .app_secret(app_secret) .log_level(lark.LogLevel.DEBUG) .build() ) # record["创建人"] = [{"id": sender_id}] # record["处理人"] = [{"id": sender_id}] record["抄送"] = [{"id": sender_id}] record["反馈渠道"] = "应用" record["紧急程度"] = "一般" # record["分类"] = "官方应用" # print(f"分类: {record_category}") history_message_data = get_messages(client, "thread", thread_id) lark.logger.info(f"history_message_data: {history_message_data}") message_content_data, message_images_data, thread_sender_id = parse_history_message( history_message_data ) record["问题概述"] = "\n".join(message_content_data) for message_dict in message_images_data: image_path = get_message_resource( client, message_dict.get("message_id"), message_dict.get("image_id"), "image", cache_dir, ) print(f"下载文件成功: {image}, {image_path}") file_token = upload_media(client, image_path, "bitable_image", bitable_token) print("上传文件成功:", file_token) images_token.append(file_token) lark.logger.info(f"images_token: {images_token}") if message_images_data: record["附件"] = [{"file_token": image} for image in images_token] record_id = add_record(client, bitable_token, table_id, record) lark.logger.debug(f"record_id: {record_id}") time.sleep(1) # 回复消息 content = f'{{"text": "问题已经记录到多维表格, 及时更新工单状态💕"}}' send_group_message(client, message_id, content) # 表格触发器会自动设置 "创建人-售后专用" 为创建者, 使用接口调整 for _ in range(100): creator_names = get_record_creator_name_by_id( client, bitable_token, table_id, record_id ) if "官方应用指令" in creator_names: break time.sleep(2) update_data = {"创建人-售后专用": [{"id": thread_sender_id}]} update_record(client, bitable_token, table_id, record_id, update_data) @shared_task() def sync_xbot_activity_info(): app_id = os.environ["APP_ID"] app_secret = os.environ["APP_SECRET"] bitable_token = os.environ["OFFICE_XBOT_BITABLE_TOKEN"] table_id = os.environ["OFFICE_XBOT_TABLE_ID"] view_id = os.environ["OFFICE_XBOT_VIEW_ID"] xbot_username = os.environ["XBOT_USERNAME"] xbot_password = os.environ["XBOT_PASSWORD"] client = lark.Client.builder().app_id(app_id).app_secret(app_secret).build() token = get_token(xbot_username, xbot_password) handle_list = [] # 同步应用数据 # office_app_uuids = get_office_app_uuids() # print(f"office_activity_uuids count: {len(office_app_uuids)}") # 同步指令数据 office_activity_uuids = get_activity_info(token) print(f"office_activity_uuids count: {len(office_activity_uuids)}") for item in office_activity_uuids: robot_uuid = item.get("robotUuid") package_view_name = item.get("packageViewName") print("=====================================") print(f"同步信息: {robot_uuid}, {package_view_name}") record_id = get_filtered_record_by_uuid( client, bitable_token, table_id, view_id, "UUID", robot_uuid ) if record_id: print(f"{robot_uuid}已同步多维表格中") update_record( client, bitable_token, table_id, record_id, {"名称": package_view_name} ) else: handle_list.append(robot_uuid) print(f"{robot_uuid}: {package_view_name} 未同步多维表格中") add_record( client, bitable_token, table_id, {"UUID": robot_uuid, "名称": package_view_name, "分类": "官方指令"}, ) print(f"新增的数量: {len(handle_list)}") print("新增的uuid: ", handle_list) @shared_task() def check_activity_help_link(): """判断指令的帮助文档是否缺失, 并推送消息""" xbot_username = os.environ["XBOT_USERNAME"] xbot_password = os.environ["XBOT_PASSWORD"] app_id = os.environ["APP_ID"] app_secret = os.environ["APP_SECRET"] xbot_username = os.environ["XBOT_USERNAME"] xbot_password = os.environ["XBOT_PASSWORD"] chat_id = os.environ["FEISHU_GROUP_CHAT_ID"] client = lark.Client.builder().app_id(app_id).app_secret(app_secret).build() token = get_token(xbot_username, xbot_password) activities_info = get_activity_info(token) messages = [] messages.append("==========市场指令缺失文档==========") for activity_info in activities_info: package_viewN_name = activity_info.get("packageViewName") activities = activity_info.get("activities", "空") for activity in activities: name = activity.get("name") help_link = activity.get("helpLink", "") if not help_link: # print(f"{package_viewN_name}: {name} 缺失文档") messages.append(f"{package_viewN_name}: {name}") message_content = "\n".join(messages) send_groud_message(client, chat_id, message_content) @shared_task(include_result=False) def process_new_demand(app_id, app_secret, table_id, record_id, data): title = data.get("title") background = data.get("background") features = data.get("features") category = data.get("category") client = ( lark.Client.builder() .app_id(app_id) .app_secret(app_secret) .log_level(lark.LogLevel.DEBUG) .build() ) space_id = "7268552249415319554" bitable_token = os.environ["OFFICE_XBOT_BITABLE_TOKEN"] # 放官方应用下 if category == "opt5xydmUE": parent_node_token = "F4ivwKrgyiQ4zOkuLVFcTq9Bnee" # 放到官方指令下 if category == "optRTwYcra": parent_node_token = "SvWCwlWJ8iuFKpkXp1rcd9u2n3c" doc_node_token, doc_obj_token = create_doc( client, space_id, parent_node_token, title ) block_id = get_doc_block(client, doc_obj_token) create_doc_block(client, doc_obj_token, block_id, background, features) doc_node_url = f"https://ying-dao.feishu.cn/wiki/{doc_node_token}" update_data = {"需求文档链接": doc_node_url, "状态": "待评估"} update_record(client, bitable_token, table_id, record_id, update_data) @shared_task(include_result=False) def process_new_robot(app_id, app_secret, action_data): user_id = action_data["deal_person_id"] name = action_data["title"] category = action_data.get("category") robot_uuid = "" catagory_table_record = {"UUID": robot_uuid, "名称": name, "分类": "官方指令"} client = ( lark.Client.builder() .app_id(app_id) .app_secret(app_secret) .log_level(lark.LogLevel.DEBUG) .build() ) bitable_token = os.environ["OFFICE_XBOT_BITABLE_TOKEN"] if category == "optRTwYcra": robot_uuid = new_blank_robot(name, user_id) catagory_table_record["分类"] = "官方应用" catagory_table_record["UUID"] = robot_uuid table_id = "tblmoNGgIdEPumiU" develop_record = {"RobotUuid": robot_uuid} add_record(client, bitable_token, table_id, develop_record) elif category == "opt5xydmUE": robot_uuid = new_blank_activity(name, user_id) catagory_table_record["分类"] = "官方指令" catagory_table_record["UUID"] = robot_uuid # 在开发计划中创建记录 table_id = "tblvjiV4HB31FMgb" develop_record = {"RobotUuid": robot_uuid} add_record(client, bitable_token, table_id, develop_record) else: # 其他选项不创建记录 return # 更新多维表格分类管理 table_id = "tbl2GcBvkvMtOBnl" add_record(client, bitable_token, table_id, catagory_table_record)