鱼C论坛

 找回密码
 立即注册
查看: 1540|回复: 5

求助!想用钉钉API发送xlsx文件,遇到报错,请大神赐教!

[复制链接]
发表于 2023-8-14 10:47:15 | 显示全部楼层 |阅读模式
20鱼币
求助!想用钉钉API发送xlsx文件,遇到报错,请大神赐教!
本人比较小白,用的代码是网上摘的,遇到了报错,请大神讲解,万分感谢!
代码:
class Client():
    def __init__(self, app_key, app_secret, user_id):
        self.app_key = app_key
        self.app_secret = app_secret
        self.user_id = user_id
        self.domain = "api.dingtalk.com"
        self.token = self.get_access_token()
        self.operator_id = self.get_operator_id(user_id)
        self.unionId = self.operator_id

    def get_access_token(self):
        conn = http.client.HTTPSConnection(self.domain)
        payload = json.dumps({
            "appKey": self.app_key,
            "appSecret": self.app_secret
        })
        headers = {'Content-Type': 'application/json'}
        conn.request("POST", "/v1.0/oauth2/accessToken", payload, headers)
        res = json.load(conn.getresponse())
        token = res.get("accessToken")
        assert token != None, "请检查 appKey appSecret 是否正确"
        return token

    def validate_token(func):
        def inner(self, *args, **kwargs):
            try:
                res = func(self, *args, **kwargs)
            except Exception as e:
                self.token = self.get_access_token()
                res = func(self, *args, **kwargs)
            return res

        return inner

    @validate_token
    def request(self, method, url, payload={}):
        payload = json.dumps(payload)
        headers = {
            'Host': 'api.dingtalk.com',
            'x-acs-dingtalk-access-token': self.token,
            'Content-Type': 'application/json'
        }

        conn = http.client.HTTPSConnection(self.domain)
        conn.request(method, url, payload, headers)
        res = conn.getresponse().read()

        res = json.loads(res)
        print(res)
        return res

    def get_operator_id(self, user_id):
        conn = http.client.HTTPSConnection("oapi.dingtalk.com")
        payload = json.dumps({"language": "zh_CN", "userid": self.user_id})
        headers = {'Content-Type': 'application/json'}
        conn.request("POST", f"/topapi/v2/user/get?access_token={self.token}",
                     payload, headers)
        res = conn.getresponse().read()
        res = json.loads(res)
        print(res)
        assert res.get("errcode") == 0, "请检查 userId"
        return res.get("result").get("unionid")


class Spaces(Client):
    def __init__(self, app_key, app_secret, user_id, space_id) -> Client:
        super().__init__(app_key, app_secret, user_id)
        self.space_id = space_id
        self.url = f"/v1.0/storage/spaces/{space_id}/files"

    def _oss_headers(self, url, headers, filepath):
        result = requests.put(url, data=open(filepath, 'rb'), headers=headers)
        print(result)

    def _get_file_upload_info(self):
        url = f"{self.url}/uploadInfos/query?unionId={self.unionId}"
        payload = {
            "protocol": "HEADER_SIGNATURE",
            "multipart": False,
        }
        res = self.request("POST", url, payload=payload)
        print(res)
        return res["uploadKey"], res["headerSignatureInfo"][
            "resourceUrls"], res["headerSignatureInfo"]["headers"]

    def _commit_file(self, upload_key, filename):
        url = f"{self.url}/commit?unionId={self.unionId}"
        payload = {"uploadKey": upload_key, "name": filename, "parentId": "0"}
        res = self.request("POST", url, payload=payload)
        return res["dentry"]["id"]

    def upload_file(self, filepath):
        """
        上传文件
        """
        try:
            filename = os.path.basename(filepath)
            upload_key, urls, headers = self._get_file_upload_info()
            self._oss_headers(urls[0], headers, filepath)
            file_id = self._commit_file(upload_key, filename)
            return file_id
        except Exception as e:
            print(e)
            # raise Exception("")

    def send_file_to_group(self, dentry_id, open_conversation_id):
        """
        发送文件到群
        :param self:
        :param dentry_id: 文件id
        :param open_conversation_id: 目标会话id
        :return:
        """
        # POST  HTTP/1.1
        # url = f"{self.url}/send?unionId={self.unionId}"
        url = f"/v1.0/convFile/conversations/files/send?unionId={self.unionId}"
        payload = {
            "spaceId": self.space_id,
            "dentryId": dentry_id,
            "openConversationId": open_conversation_id
        }
        self.request("POST", url, payload=payload)

    def add_spaces(self, spaces_name):
        url = "/v1.0/drive/spaces"
        payload = {
            "name": spaces_name,
            "unionId": self.unionId
        }
        res = self.request("POST", url, payload)
        print("空间id", res["spaceId"])
        self.space_id = res["spaceId"]


def dingding_csv(args):
    # 下面是测试
    app_key = args["app_key"]  # dingmxap65f1nswaigt7
    app_secret = args["app_secret"]  # sLwzEHiONPMYVgexjXeG05h4MZlcILUmv3vvWLg-hMj5vCyWexssXOvzMohtIwBa
    user_id = args["user_id"]  # 01065236080226423576
    space_id = args["space_id"]  # 22049120347
    spaces = Spaces(app_key, app_secret, user_id, space_id)
    # spaces.add_spaces("新的空间")
    file_id = spaces.upload_file(args["file_id"])
    open_conversation_id = args['open_conversation_id']  # cidvSKvQIGl8zXnx1DJRlahRw==
    # file_id = "95294040408"
    spaces.send_file_to_group(file_id, open_conversation_id)
遇到的问题:
{'errcode': 0, 'errmsg': 'ok', 'result': {'active': True, 'admin': False, 'avatar': '', 'boss': False, 'dept_id_list': [1], 'dept_order_list': [{'dept_id': 1, 'order': 176227112446945512}], 'email': '', 'exclusive_account': False, 'hide_mobile': False, 'job_number': '', 'leader_in_dept': [{'dept_id': 1, 'leader': False}], 'mobile': '13691255250', 'name': '梁圣垚', 'real_authed': False, 'remark': '', 'senior': False, 'state_code': '86', 'telephone': '', 'title': '', 'unionid': '3aOSoG0L1elLDOusbHagCQiEiE', 'userid': '01065236080226423576', 'work_place': ''}, 'request_id': '15rddatxj82xa'}
{'protocol': 'HEADER_SIGNATURE', 'uploadKey': 'hgHPAAAABSI64FsCzwAAABpNzmwGAwEEoTcF2gA4I2lBRUhBcVJtYVd4bEE2aDVkVzVrYVhOck1BVE9JUWQ1RUFYTkNva0dhZ2ZPWk5tUzFRak5EbWcGqERJTkdUQUxL', 'storageDriver': 'DINGTALK', 'headerSignatureInfo': {'headers': {'Authorization': 'OSS LTAIjmWpzHta71rc:NLzJtL8II+jixf+DyZqE5akQDL8=', 'x-oss-date': 'Mon, 14 Aug 2023 02:35:01 GMT'}, 'resourceUrls': ['https://zjk-dualstack.trans.dingtalk.com/yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file'], 'expirationSeconds': 900, 'internalResourceUrls': ['lippi-space-zjk.oss-cn-zhangjiakou-internal.aliyuncs.com/yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file'], 'region': 'ZHANGJIAKOU'}}
{'protocol': 'HEADER_SIGNATURE', 'uploadKey': 'hgHPAAAABSI64FsCzwAAABpNzmwGAwEEoTcF2gA4I2lBRUhBcVJtYVd4bEE2aDVkVzVrYVhOck1BVE9JUWQ1RUFYTkNva0dhZ2ZPWk5tUzFRak5EbWcGqERJTkdUQUxL', 'storageDriver': 'DINGTALK', 'headerSignatureInfo': {'headers': {'Authorization': 'OSS LTAIjmWpzHta71rc:NLzJtL8II+jixf+DyZqE5akQDL8=', 'x-oss-date': 'Mon, 14 Aug 2023 02:35:01 GMT'}, 'resourceUrls': ['https://zjk-dualstack.trans.dingtalk.com/yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file'], 'expirationSeconds': 900, 'internalResourceUrls': ['lippi-space-zjk.oss-cn-zhangjiakou-internal.aliyuncs.com/yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file'], 'region': 'ZHANGJIAKOU'}}
HTTPSConnectionPool(host='zjk-dualstack.trans.dingtalk.com', port=443): Max retries exceeded with url: /yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:1129)')))
{'code': 'MissingdentryId', 'requestid': '9F71FA7C-DD36-76EF-80EB-65FA7B525C51', 'message': 'dentryId is mandatory for this action.'}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-14 10:47:49 | 显示全部楼层
问题分析:
根据代码和报错信息,可以看出问题出现在发送文件到群的过程中。具体报错信息为: HTTPSConnectionPool(host='zjk-dualstack.trans.dingtalk.com', port=443): Max retries exceeded with url: /yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:1129)'))) 和 {'code': 'MissingdentryId', 'requestid': '9F71FA7C-DD36-76EF-80EB-65FA7B525C51', 'message': 'dentryId is mandatory for this action.'} 。

问题解答:
第一个报错是由于 SSL 协议错误导致的连接异常。这可能是由于网络问题或 SSL 证书配置错误导致的。可以尝试检查网络连接是否正常,或者尝试更新 SSL 证书。

第二个报错是由于缺少  dentryId  参数导致的。根据代码可以看出,在发送文件到群的函数  send_file_to_group  中,需要传入文件的  dentryId  参数。可以检查代码中是否正确获取了文件的  dentryId ,并确保在调用函数时传入了正确的参数。

综上所述,解决这个问题的步骤如下:
1. 检查网络连接是否正常。
2. 检查 SSL 证书配置是否正确。
3. 检查代码中是否正确获取了文件的  dentryId 。
4. 确保在调用  send_file_to_group  函数时传入了正确的参数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-14 10:48:16 | 显示全部楼层
根据您提供的代码和报错信息,有几个问题可能导致报错:

1. 错误信息:HTTPSConnectionPool(host='zjk-dualstack.trans.dingtalk.com', port=443): Max retries exceeded with url: /yundisk0/iAEHAqRmaWxlA6h5dW5kaXNrMATOIQd5EAXNCokGagfOZNmS1QjNDmg.file (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:1129)')))

这个错误可能是由于SSL连接问题导致的。请确保您的代码中使用的钉钉API请求的URL、域名以及端口号都是正确的,并且确保网络连接正常。

2. 错误信息:{'code': 'MissingdentryId', 'requestid': '9F71FA7C-DD36-76EF-80EB-65FA7B525C51', 'message': 'dentryId is mandatory for this action.'}

这个错误信息显示缺少dentryId参数,对于该操作是必需的。请确认您在调用spaces.send_file_to_group方法时是否正确传递了dentry_id参数,确保参数值不为空。

针对以上问题,请检查以下几点:

1. 确保您的API请求URL、域名和端口号都是正确的,可以在钉钉开发者文档中查找正确的API地址和端口号。

2. 确保在调用spaces.send_file_to_group方法时正确传递了dentry_id参数,并且确保参数值不为空。

3. 如果您的网络连接正常,但仍然遇到SSL连接问题,请检查您的代码中是否有关于SSL证书的配置或验证,确保配置正确。

希望以上信息对您有帮助,如果问题仍然存在,请提供更多的代码和错误信息,以便我能够更好地帮助您解决问题。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-8-14 10:51:56 | 显示全部楼层
debug发现是在upload_file时以下代码请求失败
    def _get_file_upload_info(self):
        url = f"{self.url}/uploadInfos/query?unionId={self.unionId}"
        payload = {
            "protocol": "HEADER_SIGNATURE",
            "multipart": False,
        }
        res = self.request("POST", url, payload=payload)
        print(res)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-8-14 15:49:52 | 显示全部楼层
已经解决了!是dingding权限问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-15 08:52:11 | 显示全部楼层
本帖最后由 wuliangtdi 于 2023-8-15 08:55 编辑
13691255250 发表于 2023-8-14 15:49
已经解决了!是dingding权限问题


那能把最佳给我嘛?(口气模仿来自【学习编程中的Ben】不用真给我,开个玩笑)

如图


                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 10:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表