求助!想用钉钉API发送xlsx文件,遇到报错,请大神赐教!
求助!想用钉钉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, 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:
"""
# POSTHTTP/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': , '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.'}
问题分析:
根据代码和报错信息,可以看出问题出现在发送文件到群的过程中。具体报错信息为: 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函数时传入了正确的参数。 根据您提供的代码和报错信息,有几个问题可能导致报错:
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证书的配置或验证,确保配置正确。
希望以上信息对您有帮助,如果问题仍然存在,请提供更多的代码和错误信息,以便我能够更好地帮助您解决问题。
如果问题已经解决,请设置最佳答案 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) 已经解决了!是dingding权限问题 本帖最后由 wuliangtdi 于 2023-8-15 08:55 编辑
13691255250 发表于 2023-8-14 15:49
已经解决了!是dingding权限问题
那能把最佳给我嘛?(口气模仿来自【学习编程中的Ben】不用真给我,开个玩笑){:10_335:}
如图
https://ice.frostsky.com/2023/08/15/83e355f45a0c25b7e6382f42d035cebb.png
页:
[1]