From f913b87103747edcc6d35dfb7c9ed31dbcf55ad7 Mon Sep 17 00:00:00 2001 From: woni <320753691@qq.com> Date: Fri, 8 Mar 2024 17:46:12 +0800 Subject: [PATCH] add bulk send message --- app/utils/feishu.py | 164 ++++++++++++++++++++++++++++++++++++++++++++ app/utils/utils.py | 7 +- 2 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 app/utils/feishu.py diff --git a/app/utils/feishu.py b/app/utils/feishu.py new file mode 100644 index 0000000..846efa4 --- /dev/null +++ b/app/utils/feishu.py @@ -0,0 +1,164 @@ +import json +import os +import http +import requests +import lark_oapi as lark + +import lark_oapi as lark +from lark_oapi.api.contact.v3 import * + + +def search_department(client): + + request: SearchDepartmentRequest = ( + SearchDepartmentRequest.builder() + .page_size(20) + .request_body(SearchDepartmentRequestBody.builder().query("内容").build()) + .build() + ) + + option = ( + lark.RequestOption.builder() + .user_access_token("u-ddet2pz9R4ApKdl0ta.vAj1l6H_5ghX3h200ghK82KaD") + .build() + ) + response: SearchDepartmentResponse = client.contact.v3.department.search( + request, option + ) + + if not response.success(): + lark.logger.error( + f"client.contact.v3.department.search failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}" + ) + return + + lark.logger.info(lark.JSON.marshal(response.data, indent=4)) + + +def get_access_token(app_id, app_secret): + url = "open.feishu.cn" + api = "/open-apis/auth/v3/app_access_token/internal" + payload = json.dumps({"app_id": app_id, "app_secret": app_secret}) + headers = {"content-type": "application/json; charset=utf-8"} + + conn = http.client.HTTPSConnection(url) + conn.request("POST", api, payload, headers) + token = json.loads(conn.getresponse().read()).get("app_access_token") + assert token != None, "请检查 app_id app_secret 是否正确" + return token + + +def batch_send_message(token): + host = "open.feishu.cn" + url = "/open-apis/message/v4/batch_send/" + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json", + } + # open_ids + payload = { + "msg_type": {"card": {...}}, + "content": "", + "user_ids": [""], + } + + conn = http.client.HTTPSConnection(host) + conn.request("POST", url, json.dumps(payload), headers) + res = conn.getresponse().read() + res = json.loads(res) + print(res) + + +if __name__ == "__main__": + + app_id = os.environ["APP_ID"] + app_secret = os.environ["APP_SECRET"] + + client = ( + lark.Client.builder() + .app_id(app_id) + .app_secret(app_secret) + .log_level(lark.LogLevel.DEBUG) + .build() + ) + + detail_url = ( + "https://ying-dao.feishu.cn/wiki/UiydwSXoIi1w14ksJfQcaIP6nh6?from=from_copylink" + ) + + create_demand_url = ( + "https://ying-dao.feishu.cn/share/base/form/shrcnEI7Hhnhfdh0OXTyQcwGzEb" + ) + + app_list = [ + "企微群发消息: 在文件传输助手中根据群名单逐条转发信息", + "TEMU商品复制上架: TEMU商品多店铺一键铺货", + "Instagram关键词抓取红人信息: 根据条件抓取红人邮箱以及其他基本信息", + "TikTok关键词抓取红人信息: 根据条件筛选符合条件的红人,获取红人信息", + "查集装箱实际到港时间-6大航司: 根据船公司和提单号在对应的官网查询到港时间", + ] + + activity_list = [ + "云码验证码扩展: 通用轨迹验证, 通用单图滑块验证, 京东-旋转验证码", + "Excel 扩展操作: 设置筛选器", + ] + + app_text = "\n".join(f"🔹{item}" for item in app_list).strip() + activity_text = "\n".join(f"🔸{item}" for item in activity_list).strip() + + # 解决方案实施中心 4gge82cgb18f52af + # 电商事业部 8a612b6c9184b118 + # 技术支持部 d7g1374b1238d267 + # 杭州内容组 9fg37g65b1b5b24e + # Uerid 7g3756f4 + # "user_ids": [ + # "7g3756f4", + # ], + pyload = { + "department_ids": ["9fg37g65b1b5b24e"], + "msg_type": "interactive", + "card": { + "type": "template", + "data": { + "template_id": "AAq1lbVRQxYxG", + "template_variable": { + "app_text": app_text, + "activity_text": activity_text, + "detail_url": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": detail_url, + }, + "create_demand_url": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": create_demand_url, + }, + }, + }, + }, + } + + # 构造请求对象 + request: lark.BaseRequest = ( + lark.BaseRequest.builder() + .http_method(lark.HttpMethod.POST) + .uri("/open-apis/message/v4/batch_send/") + .token_types({lark.AccessTokenType.TENANT}) + .body(pyload) + .build() + ) + + # 发起请求 + response: lark.BaseResponse = client.request(request) + + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.request failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}" + ) + + # 处理业务结果 + lark.logger.info(str(response.raw.content, lark.UTF_8)) diff --git a/app/utils/utils.py b/app/utils/utils.py index cc8a974..249d798 100644 --- a/app/utils/utils.py +++ b/app/utils/utils.py @@ -200,7 +200,9 @@ def send_message(client, receive_id, content): lark.logger.info(lark.JSON.marshal(response.data, indent=4)) -def get_filtered_record_by_uuid(client, bitable_token, table_id, view_id, field_name, uuid): +def get_filtered_record_by_uuid( + client, bitable_token, table_id, view_id, field_name, uuid +): request: SearchAppTableRecordRequest = ( SearchAppTableRecordRequest.builder() .app_token(bitable_token) @@ -258,6 +260,7 @@ def get_filtered_record_by_uuid(client, bitable_token, table_id, view_id, field_ if response.data.total == 2: print("找到了多条记录") + if __name__ == "__main__": app_id = os.environ["APP_ID"] @@ -280,4 +283,4 @@ if __name__ == "__main__": .log_level(lark.LogLevel.DEBUG) .build() ) - get_filtered_record_by_uuid(client, bitable_token, table_id, view_id, uuid) +