ezKit 1.8.0__tar.gz → 1.8.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ezkit-1.8.0/ezKit.egg-info → ezkit-1.8.1}/PKG-INFO +2 -2
- ezkit-1.8.1/ezKit/qywx.py +186 -0
- {ezkit-1.8.0 → ezkit-1.8.1/ezKit.egg-info}/PKG-INFO +2 -2
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit.egg-info/SOURCES.txt +1 -0
- ezkit-1.8.1/ezKit.egg-info/requires.txt +1 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/setup.py +2 -2
- ezkit-1.8.0/ezKit.egg-info/requires.txt +0 -1
- {ezkit-1.8.0 → ezkit-1.8.1}/LICENSE +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/MANIFEST.in +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/README.md +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/__init__.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/bottle.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/bottle_extensions.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/cipher.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/database.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/http.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/mongo.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/redis.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/sendemail.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/token.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/utils.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit/xftp.py +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit.egg-info/dependency_links.txt +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/ezKit.egg-info/top_level.txt +0 -0
- {ezkit-1.8.0 → ezkit-1.8.1}/setup.cfg +0 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
"""
|
2
|
+
企业微信开发者中心
|
3
|
+
|
4
|
+
https://developer.work.weixin.qq.com/
|
5
|
+
https://developer.work.weixin.qq.com/document/path/90313 (全局错误码)
|
6
|
+
|
7
|
+
参考文档:
|
8
|
+
|
9
|
+
https://www.gaoyuanqi.cn/python-yingyong-qiyewx/
|
10
|
+
https://www.jianshu.com/p/020709b130d3
|
11
|
+
"""
|
12
|
+
import json
|
13
|
+
import time
|
14
|
+
|
15
|
+
import requests
|
16
|
+
from loguru import logger
|
17
|
+
|
18
|
+
from . import utils
|
19
|
+
|
20
|
+
|
21
|
+
class QYWX:
|
22
|
+
"""企业微信"""
|
23
|
+
|
24
|
+
url_prefix = "https://qyapi.weixin.qq.com"
|
25
|
+
work_id: str | None = None
|
26
|
+
agent_id: str | None = None
|
27
|
+
agent_secret: str | None = None
|
28
|
+
access_token: str | None = None
|
29
|
+
|
30
|
+
def __init__(self, work_id: str | None, agent_id: str | None, agent_secret: str | None):
|
31
|
+
"""Initiation"""
|
32
|
+
self.work_id = work_id
|
33
|
+
self.agent_id = agent_id
|
34
|
+
self.agent_secret = agent_secret
|
35
|
+
|
36
|
+
"""获取 Token"""
|
37
|
+
self.getaccess_token()
|
38
|
+
|
39
|
+
def getaccess_token(self) -> str | None:
|
40
|
+
try:
|
41
|
+
response = requests.get(f"{self.url_prefix}/cgi-bin/gettoken?corpid={self.work_id}&corpsecret={self.agent_secret}", timeout=10)
|
42
|
+
if response.status_code == 200:
|
43
|
+
result: dict = response.json()
|
44
|
+
self.access_token = result.get('access_token')
|
45
|
+
else:
|
46
|
+
self.access_token = None
|
47
|
+
return result.get('access_token')
|
48
|
+
except Exception as e:
|
49
|
+
logger.exception(e)
|
50
|
+
return None
|
51
|
+
|
52
|
+
def get_agent_list(self) -> dict | str | None:
|
53
|
+
try:
|
54
|
+
if self.access_token is None:
|
55
|
+
self.getaccess_token()
|
56
|
+
response = requests.get(f"{self.url_prefix}/cgi-bin/agent/list?access_token={self.access_token}", timeout=10)
|
57
|
+
if response.status_code == 200:
|
58
|
+
response_data: dict = response.json()
|
59
|
+
if response_data.get('errcode') == 42001:
|
60
|
+
self.getaccess_token()
|
61
|
+
time.sleep(1)
|
62
|
+
self.get_agent_list()
|
63
|
+
return response_data
|
64
|
+
return response.text
|
65
|
+
except Exception as e:
|
66
|
+
logger.exception(e)
|
67
|
+
return None
|
68
|
+
|
69
|
+
def get_department_list(self, eid: str | None = None) -> dict | str | None:
|
70
|
+
"""eid: Enterprise ID"""
|
71
|
+
try:
|
72
|
+
if self.access_token is None:
|
73
|
+
self.getaccess_token()
|
74
|
+
response = requests.get(f"{self.url_prefix}/cgi-bin/department/list?access_token={self.access_token}&id={eid}", timeout=10)
|
75
|
+
if response.status_code == 200:
|
76
|
+
response_data: dict = response.json()
|
77
|
+
if response_data.get('errcode') == 42001:
|
78
|
+
self.getaccess_token()
|
79
|
+
time.sleep(1)
|
80
|
+
self.get_department_list(eid)
|
81
|
+
return response_data
|
82
|
+
return response.text
|
83
|
+
except Exception as e:
|
84
|
+
logger.exception(e)
|
85
|
+
return None
|
86
|
+
|
87
|
+
def get_user_list(self, eid: str | None = None) -> dict | str | None:
|
88
|
+
"""eid: Enterprise ID"""
|
89
|
+
try:
|
90
|
+
if self.access_token is None:
|
91
|
+
self.getaccess_token()
|
92
|
+
response = requests.get(f"{self.url_prefix}/cgi-bin/user/list?access_token={self.access_token}&department_id={eid}", timeout=10)
|
93
|
+
if response.status_code == 200:
|
94
|
+
response_data: dict = response.json()
|
95
|
+
if response_data.get('errcode') == 42001:
|
96
|
+
self.getaccess_token()
|
97
|
+
time.sleep(1)
|
98
|
+
self.get_user_list(eid)
|
99
|
+
return response_data
|
100
|
+
return response.text
|
101
|
+
except Exception as e:
|
102
|
+
logger.exception(e)
|
103
|
+
return None
|
104
|
+
|
105
|
+
def get_user_id_by_mobile(self, mobile: str | None = None) -> dict | str | None:
|
106
|
+
try:
|
107
|
+
if self.access_token is None:
|
108
|
+
self.getaccess_token()
|
109
|
+
json_string = json.dumps({'mobile': mobile})
|
110
|
+
response = requests.post(f"{self.url_prefix}/cgi-bin/user/getuserid?access_token={self.access_token}", data=json_string, timeout=10)
|
111
|
+
if response.status_code == 200:
|
112
|
+
response_data: dict = response.json()
|
113
|
+
if response_data.get('errcode') == 42001:
|
114
|
+
self.getaccess_token()
|
115
|
+
time.sleep(1)
|
116
|
+
self.get_user_id_by_mobile(mobile)
|
117
|
+
return response_data
|
118
|
+
return response.text
|
119
|
+
except Exception as e:
|
120
|
+
logger.exception(e)
|
121
|
+
return None
|
122
|
+
|
123
|
+
def get_user_info(self, eid: str | None = None) -> dict | str | None:
|
124
|
+
"""eid: Enterprise ID"""
|
125
|
+
try:
|
126
|
+
if self.access_token is None:
|
127
|
+
self.getaccess_token()
|
128
|
+
response = requests.get(f"{self.url_prefix}/cgi-bin/user/get?access_token={self.access_token}&userid={eid}", timeout=10)
|
129
|
+
if response.status_code == 200:
|
130
|
+
response_data: dict = response.json()
|
131
|
+
if response_data.get('errcode') == 42001:
|
132
|
+
self.getaccess_token()
|
133
|
+
time.sleep(1)
|
134
|
+
self.get_user_info(eid)
|
135
|
+
return response_data
|
136
|
+
return response.text
|
137
|
+
except Exception as e:
|
138
|
+
logger.exception(e)
|
139
|
+
return None
|
140
|
+
|
141
|
+
def send_message_by_mobile(self, mobile: str | list, message: str) -> bool:
|
142
|
+
"""发送消息"""
|
143
|
+
|
144
|
+
# 参考文档:
|
145
|
+
# https://developer.work.weixin.qq.com/document/path/90235
|
146
|
+
|
147
|
+
try:
|
148
|
+
if self.access_token is None:
|
149
|
+
self.getaccess_token()
|
150
|
+
|
151
|
+
users: list = []
|
152
|
+
|
153
|
+
match True:
|
154
|
+
case True if utils.v_true(mobile, list):
|
155
|
+
users = mobile
|
156
|
+
case True if utils.v_true(mobile, str):
|
157
|
+
users.append(mobile)
|
158
|
+
case _:
|
159
|
+
return None
|
160
|
+
|
161
|
+
for user in users:
|
162
|
+
user_object = self.get_user_id_by_mobile(user)
|
163
|
+
json_dict = {
|
164
|
+
'touser': user_object.get('userid'),
|
165
|
+
'msgtype': 'text',
|
166
|
+
'agentid': self.agent_id,
|
167
|
+
'text': {'content': message},
|
168
|
+
'safe': 0,
|
169
|
+
'enable_id_trans': 0,
|
170
|
+
'enable_duplicate_check': 0,
|
171
|
+
'duplicate_check_interval': 1800
|
172
|
+
}
|
173
|
+
json_string = json.dumps(json_dict)
|
174
|
+
response = requests.post(f"{self.url_prefix}/cgi-bin/message/send?access_token={self.access_token}", data=json_string, timeout=10)
|
175
|
+
if response.status_code == 200:
|
176
|
+
response_data: dict = response.json()
|
177
|
+
if response_data.get('errcode') == 42001:
|
178
|
+
self.getaccess_token()
|
179
|
+
time.sleep(1)
|
180
|
+
self.send_message_by_mobile(mobile, message)
|
181
|
+
|
182
|
+
return True
|
183
|
+
|
184
|
+
except Exception as e:
|
185
|
+
logger.exception(e)
|
186
|
+
return False
|
@@ -0,0 +1 @@
|
|
1
|
+
loguru>=0.7
|
@@ -3,7 +3,7 @@ from setuptools import find_packages, setup
|
|
3
3
|
|
4
4
|
setup(
|
5
5
|
name='ezKit',
|
6
|
-
version='1.8.
|
6
|
+
version='1.8.1',
|
7
7
|
author='septvean',
|
8
8
|
author_email='septvean@gmail.com',
|
9
9
|
description='Easy Kit',
|
@@ -11,6 +11,6 @@ setup(
|
|
11
11
|
include_package_data=True,
|
12
12
|
python_requires='>=3.11',
|
13
13
|
install_requires=[
|
14
|
-
"loguru>=0.7
|
14
|
+
"loguru>=0.7"
|
15
15
|
]
|
16
16
|
)
|
@@ -1 +0,0 @@
|
|
1
|
-
loguru>=0.7.0
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|