优化工单模块,增加企微模块
This commit is contained in:
44
sg_wechat_enterprise/we_api/enterprise/client/__init__.py
Normal file
44
sg_wechat_enterprise/we_api/enterprise/client/__init__.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from wechatpy.client.base import BaseWeChatClient
|
||||
from wechatpy.enterprise.client import api
|
||||
|
||||
|
||||
class WeChatClient(BaseWeChatClient):
|
||||
|
||||
API_BASE_URL = 'https://qyapi.weixin.qq.com/cgi-bin/'
|
||||
|
||||
user = api.WeChatUser()
|
||||
department = api.WeChatDepartment()
|
||||
menu = api.WeChatMenu()
|
||||
message = api.WeChatMessage()
|
||||
tag = api.WeChatTag()
|
||||
media = api.WeChatMedia()
|
||||
misc = api.WeChatMisc()
|
||||
agent = api.WeChatAgent()
|
||||
batch = api.WeChatBatch()
|
||||
jsapi = api.WeChatJSAPI()
|
||||
material = api.WeChatMaterial()
|
||||
oauth = api.WeChatOAuth()
|
||||
shakearound = api.WeChatShakeAround()
|
||||
service = api.WeChatService()
|
||||
chat = api.WeChatChat()
|
||||
|
||||
def __init__(self, corp_id, secret, access_token=None,
|
||||
session=None, timeout=None, auto_retry=True):
|
||||
super(WeChatClient, self).__init__(
|
||||
corp_id, access_token, session, timeout, auto_retry
|
||||
)
|
||||
self.corp_id = corp_id
|
||||
self.secret = secret
|
||||
|
||||
def fetch_access_token(self):
|
||||
""" Fetch access token"""
|
||||
return self._fetch_access_token(
|
||||
url='https://qyapi.weixin.qq.com/cgi-bin/gettoken',
|
||||
params={
|
||||
'corpid': self.corp_id,
|
||||
'corpsecret': self.secret
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from wechatpy.enterprise.client.api.department import WeChatDepartment # NOQA
|
||||
from wechatpy.enterprise.client.api.media import WeChatMedia # NOQA
|
||||
from wechatpy.enterprise.client.api.message import WeChatMessage # NOQA
|
||||
from wechatpy.enterprise.client.api.menu import WeChatMenu # NOQA
|
||||
from wechatpy.enterprise.client.api.tag import WeChatTag # NOQA
|
||||
from wechatpy.enterprise.client.api.user import WeChatUser # NOQA
|
||||
from wechatpy.enterprise.client.api.misc import WeChatMisc # NOQA
|
||||
from wechatpy.enterprise.client.api.agent import WeChatAgent # NOQA
|
||||
from wechatpy.enterprise.client.api.batch import WeChatBatch # NOQA
|
||||
from wechatpy.enterprise.client.api.jsapi import WeChatJSAPI # NOQA
|
||||
from wechatpy.enterprise.client.api.material import WeChatMaterial # NOQA
|
||||
from wechatpy.enterprise.client.api.oauth import WeChatOAuth # NOQA
|
||||
from wechatpy.enterprise.client.api.shakearound import WeChatShakeAround # NOQA
|
||||
from wechatpy.enterprise.client.api.service import WeChatService # NOQA
|
||||
from wechatpy.enterprise.client.api.chat import WeChatChat # NOQA
|
||||
71
sg_wechat_enterprise/we_api/enterprise/client/api/agent.py
Normal file
71
sg_wechat_enterprise/we_api/enterprise/client/api/agent.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from optionaldict import optionaldict
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatAgent(BaseWeChatAPI):
|
||||
|
||||
def get(self, agent_id):
|
||||
"""
|
||||
获取企业号应用
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=获取企业号应用
|
||||
|
||||
:param agent_id: 授权方应用 id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get(
|
||||
'agent/get',
|
||||
params={
|
||||
'agentid': agent_id
|
||||
}
|
||||
)
|
||||
|
||||
def set(self,
|
||||
agent_id,
|
||||
name=None,
|
||||
description=None,
|
||||
redirect_domain=None,
|
||||
logo_media_id=None,
|
||||
report_location_flag=0,
|
||||
is_report_user=True,
|
||||
is_report_enter=True):
|
||||
"""
|
||||
设置企业号应用
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=设置企业号应用
|
||||
|
||||
:param agent_id: 企业应用的 id
|
||||
:param name: 企业应用名称
|
||||
:param description: 企业应用详情
|
||||
:param redirect_domain: 企业应用可信域名
|
||||
:param logo_media_id: 企业应用头像的mediaid,通过多媒体接口上传图片获得mediaid
|
||||
:param report_location_flag: 企业应用是否打开地理位置上报 0:不上报;1:进入会话上报;2:持续上报
|
||||
:param is_report_user: 是否接收用户变更通知
|
||||
:param is_report_enter: 是否上报用户进入应用事件
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
agent_data = optionaldict()
|
||||
agent_data['agentid'] = agent_id
|
||||
agent_data['name'] = name
|
||||
agent_data['description'] = description
|
||||
agent_data['redirect_domain'] = redirect_domain
|
||||
agent_data['logo_mediaid'] = logo_media_id
|
||||
agent_data['report_location_flag'] = report_location_flag
|
||||
agent_data['isreportuser'] = 1 if is_report_user else 0
|
||||
agent_data['isreportenter'] = 1 if is_report_enter else 0
|
||||
return self._post(
|
||||
'agent/set',
|
||||
data=agent_data
|
||||
)
|
||||
|
||||
def list(self):
|
||||
"""
|
||||
获取应用概况列表
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=获取应用概况列表
|
||||
|
||||
:return: 应用概况列表
|
||||
"""
|
||||
res = self._get('agent/list')
|
||||
return res['agentlist']
|
||||
134
sg_wechat_enterprise/we_api/enterprise/client/api/batch.py
Normal file
134
sg_wechat_enterprise/we_api/enterprise/client/api/batch.py
Normal file
@@ -0,0 +1,134 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from optionaldict import optionaldict
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
from wechatpy.utils import to_text
|
||||
|
||||
|
||||
class WeChatBatch(BaseWeChatAPI):
|
||||
|
||||
def invite_user(self, url, token, encoding_aes_key, user_ids=None,
|
||||
party_ids=None, tag_ids=None, invite_tips=None):
|
||||
"""
|
||||
邀请成员关注
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=异步任务接口
|
||||
|
||||
:param url: 企业应用接收企业号推送请求的访问协议和地址,支持http或https协议
|
||||
:param token: 用于生成签名
|
||||
:param encoding_aes_key: 用于消息体的加密,是AES密钥的Base64编码
|
||||
:param user_ids: 可选,成员ID列表,多个接收者用‘|’分隔,最多支持1000个。
|
||||
:param party_ids: 可选,部门ID列表,多个接收者用‘|’分隔,最多支持100个。
|
||||
:param tag_ids: 可选,标签ID列表,多个接收者用‘|’分隔。
|
||||
:param invite_tips: 可选,推送到微信上的提示语
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
data = optionaldict()
|
||||
data['callback'] = {
|
||||
'url': url,
|
||||
'token': token,
|
||||
'encodingaeskey': encoding_aes_key
|
||||
}
|
||||
if isinstance(user_ids, (tuple, list)):
|
||||
user_ids = '|'.join(map(to_text, user_ids))
|
||||
if isinstance(party_ids, (tuple, list)):
|
||||
party_ids = '|'.join(map(to_text, party_ids))
|
||||
if isinstance(tag_ids, (tuple, list)):
|
||||
tag_ids = '|'.join(map(to_text, tag_ids))
|
||||
data['touser'] = user_ids
|
||||
data['toparty'] = party_ids
|
||||
data['totag'] = tag_ids
|
||||
data['invite_tips'] = invite_tips
|
||||
return self._post(
|
||||
'batch/inviteuser',
|
||||
data=data
|
||||
)
|
||||
|
||||
def sync_user(self, url, token, encoding_aes_key, media_id):
|
||||
"""
|
||||
增量更新成员
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=异步任务接口
|
||||
|
||||
:param url: 企业应用接收企业号推送请求的访问协议和地址,支持http或https协议
|
||||
:param token: 用于生成签名
|
||||
:param encoding_aes_key: 用于消息体的加密,是AES密钥的Base64编码
|
||||
:param media_id: 上传的csv文件的media_id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'batch/syncuser',
|
||||
data={
|
||||
'media_id': media_id,
|
||||
'callback': {
|
||||
'url': url,
|
||||
'token': token,
|
||||
'encodingaeskey': encoding_aes_key
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def replace_user(self, url, token, encoding_aes_key, media_id):
|
||||
"""
|
||||
全量覆盖成员
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=异步任务接口
|
||||
|
||||
:param url: 企业应用接收企业号推送请求的访问协议和地址,支持http或https协议
|
||||
:param token: 用于生成签名
|
||||
:param encoding_aes_key: 用于消息体的加密,是AES密钥的Base64编码
|
||||
:param media_id: 上传的csv文件的media_id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'batch/replaceuser',
|
||||
data={
|
||||
'media_id': media_id,
|
||||
'callback': {
|
||||
'url': url,
|
||||
'token': token,
|
||||
'encodingaeskey': encoding_aes_key
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def replace_party(self, url, token, encoding_aes_key, media_id):
|
||||
"""
|
||||
全量覆盖部门
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=异步任务接口
|
||||
|
||||
:param url: 企业应用接收企业号推送请求的访问协议和地址,支持http或https协议
|
||||
:param token: 用于生成签名
|
||||
:param encoding_aes_key: 用于消息体的加密,是AES密钥的Base64编码
|
||||
:param media_id: 上传的csv文件的media_id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'batch/replaceparty',
|
||||
data={
|
||||
'media_id': media_id,
|
||||
'callback': {
|
||||
'url': url,
|
||||
'token': token,
|
||||
'encodingaeskey': encoding_aes_key
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def get_result(self, job_id):
|
||||
"""
|
||||
获取异步任务结果
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=异步任务接口
|
||||
|
||||
:param job_id: 异步任务id,最大长度为64字符
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get(
|
||||
'batch/getresult',
|
||||
params={
|
||||
'jobid': job_id
|
||||
}
|
||||
)
|
||||
273
sg_wechat_enterprise/we_api/enterprise/client/api/chat.py
Normal file
273
sg_wechat_enterprise/we_api/enterprise/client/api/chat.py
Normal file
@@ -0,0 +1,273 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from optionaldict import optionaldict
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatChat(BaseWeChatAPI):
|
||||
|
||||
def create(self, chat_id, name, owner, user_list):
|
||||
"""
|
||||
创建会话
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param chat_id: 会话id。字符串类型,最长32个字符。只允许字符0-9及字母a-zA-Z,
|
||||
如果值内容为64bit无符号整型:要求值范围在[1, 2^63)之间,
|
||||
[2^63, 2^64)为系统分配会话id区间
|
||||
:param name: 会话标题
|
||||
:param owner: 管理员userid,必须是该会话userlist的成员之一
|
||||
:param user_list: 会话成员列表,成员用userid来标识。会话成员必须在3人或以上,1000人以下
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'chat/create',
|
||||
data={
|
||||
'chatid': chat_id,
|
||||
'name': name,
|
||||
'owner': owner,
|
||||
'userlist': user_list,
|
||||
}
|
||||
)
|
||||
|
||||
def get(self, chat_id):
|
||||
"""
|
||||
获取会话
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param chat_id: 会话 ID
|
||||
:return: 会话信息
|
||||
"""
|
||||
res = self._get('chat/get', params={'chatid': chat_id})
|
||||
return res['chat_info']
|
||||
|
||||
def update(self, chat_id, op_user, name=None, owner=None,
|
||||
add_user_list=None, del_user_list=None):
|
||||
"""
|
||||
修改会话
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param chat_id: 会话 ID
|
||||
:param op_user: 操作人 userid
|
||||
:param name: 会话标题
|
||||
:param owner: 管理员userid,必须是该会话userlist的成员之一
|
||||
:param add_user_list: 会话新增成员列表,成员用userid来标识
|
||||
:param del_user_list: 会话退出成员列表,成员用userid来标识
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
data = optionaldict(
|
||||
chatid=chat_id,
|
||||
op_user=op_user,
|
||||
name=name,
|
||||
owner=owner,
|
||||
add_user_list=add_user_list,
|
||||
del_user_list=del_user_list,
|
||||
)
|
||||
return self._post('chat/update', data=data)
|
||||
|
||||
def quit(self, chat_id, op_user):
|
||||
"""
|
||||
退出会话
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param chat_id: 会话 ID
|
||||
:param op_user: 操作人 userid
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'chat/quit',
|
||||
data={
|
||||
'chatid': chat_id,
|
||||
'op_user': op_user,
|
||||
}
|
||||
)
|
||||
|
||||
def clear_notify(self, op_user, type, id):
|
||||
"""
|
||||
清除会话未读状态
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param op_user: 会话所有者的userid
|
||||
:param type: 会话类型:single|group,分别表示:单聊|群聊
|
||||
:param id: 会话值,为userid|chatid,分别表示:成员id|会话id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'chat/clearnotify',
|
||||
data={
|
||||
'op_user': op_user,
|
||||
'chat': {
|
||||
'type': type,
|
||||
'id': id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def set_mute(self, user_mute_list):
|
||||
"""
|
||||
设置成员新消息免打扰
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param user_mute_list: 成员新消息免打扰参数,数组,最大支持10000个成员
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'chat/setmute',
|
||||
data={'user_mute_list': user_mute_list}
|
||||
)
|
||||
|
||||
def send_text(self, sender, receiver_type, receiver_id, content):
|
||||
"""
|
||||
发送文本消息
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver_type: 接收人类型:single|group,分别表示:单聊|群聊
|
||||
:param receiver_id: 接收人的值,为userid|chatid,分别表示:成员id|会话id
|
||||
:param content: 消息内容
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
data = {
|
||||
'receiver': {
|
||||
'type': receiver_type,
|
||||
'id': receiver_id,
|
||||
},
|
||||
'sender': sender,
|
||||
'msgtype': 'text',
|
||||
'text': {
|
||||
'content': content,
|
||||
}
|
||||
}
|
||||
return self._post('chat/send', data=data)
|
||||
|
||||
def send_single_text(self, sender, receiver, content):
|
||||
"""
|
||||
发送单聊文本消息
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver: 接收人成员 ID
|
||||
:param content: 消息内容
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self.send_text(sender, 'single', receiver, content)
|
||||
|
||||
def send_group_text(self, sender, receiver, content):
|
||||
"""
|
||||
发送群聊文本消息
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver: 会话 ID
|
||||
:param content: 消息内容
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self.send_text(sender, 'group', receiver, content)
|
||||
|
||||
def send_image(self, sender, receiver_type, receiver_id, media_id):
|
||||
"""
|
||||
发送图片消息
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver_type: 接收人类型:single|group,分别表示:单聊|群聊
|
||||
:param receiver_id: 接收人的值,为userid|chatid,分别表示:成员id|会话id
|
||||
:param media_id: 图片媒体文件id,可以调用上传素材文件接口获取
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
data = {
|
||||
'receiver': {
|
||||
'type': receiver_type,
|
||||
'id': receiver_id,
|
||||
},
|
||||
'sender': sender,
|
||||
'msgtype': 'image',
|
||||
'image': {
|
||||
'media_id': media_id,
|
||||
}
|
||||
}
|
||||
return self._post('chat/send', data=data)
|
||||
|
||||
def send_single_image(self, sender, receiver, media_id):
|
||||
"""
|
||||
发送单聊图片消息
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver: 接收人成员 ID
|
||||
:param media_id: 图片媒体文件id,可以调用上传素材文件接口获取
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self.send_image(sender, 'single', receiver, media_id)
|
||||
|
||||
def send_group_image(self, sender, receiver, media_id):
|
||||
"""
|
||||
发送群聊图片消息
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver: 会话 ID
|
||||
:param media_id: 图片媒体文件id,可以调用上传素材文件接口获取
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self.send_image(sender, 'group', receiver, media_id)
|
||||
|
||||
def send_file(self, sender, receiver_type, receiver_id, media_id):
|
||||
"""
|
||||
发送文件消息
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=企业会话接口说明
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver_type: 接收人类型:single|group,分别表示:单聊|群聊
|
||||
:param receiver_id: 接收人的值,为userid|chatid,分别表示:成员id|会话id
|
||||
:param media_id: 文件id,可以调用上传素材文件接口获取, 文件须大于4字节
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
data = {
|
||||
'receiver': {
|
||||
'type': receiver_type,
|
||||
'id': receiver_id,
|
||||
},
|
||||
'sender': sender,
|
||||
'msgtype': 'file',
|
||||
'file': {
|
||||
'media_id': media_id,
|
||||
}
|
||||
}
|
||||
return self._post('chat/send', data=data)
|
||||
|
||||
def send_single_file(self, sender, receiver, media_id):
|
||||
"""
|
||||
发送单聊文件消息
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver: 接收人成员 ID
|
||||
:param media_id: 文件id,可以调用上传素材文件接口获取, 文件须大于4字节
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self.send_file(sender, 'single', receiver, media_id)
|
||||
|
||||
def send_group_file(self, sender, receiver, media_id):
|
||||
"""
|
||||
发送群聊文件消息
|
||||
|
||||
:param sender: 发送人
|
||||
:param receiver: 会话 ID
|
||||
:param media_id: 文件id,可以调用上传素材文件接口获取, 文件须大于4字节
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self.send_file(sender, 'group', receiver, media_id)
|
||||
117
sg_wechat_enterprise/we_api/enterprise/client/api/department.py
Normal file
117
sg_wechat_enterprise/we_api/enterprise/client/api/department.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from optionaldict import optionaldict
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatDepartment(BaseWeChatAPI):
|
||||
|
||||
def create(self, name, parent_id=1, order=None, id=None):
|
||||
"""
|
||||
创建部门
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理部门
|
||||
|
||||
:param name: 部门名称,长度限制为 1~64 个字符
|
||||
:param parent_id: 父亲部门 id ,根部门 id 为 1
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
department_data = optionaldict()
|
||||
department_data['name'] = name
|
||||
department_data['parentid'] = parent_id
|
||||
department_data['order'] = order
|
||||
department_data['id'] = id
|
||||
return self._post(
|
||||
'department/create',
|
||||
data=dict(department_data)
|
||||
)
|
||||
|
||||
def update(self, id, name=None, parent_id=None, order=None):
|
||||
"""
|
||||
更新部门
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理部门
|
||||
|
||||
:param id: 部门 id
|
||||
:param name: 部门名称
|
||||
:param parent_id: 父亲部门 id
|
||||
:param order: 在父部门中的次序,从 1 开始,数字越大排序越靠后
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
department_data = optionaldict()
|
||||
department_data['id'] = id
|
||||
department_data['name'] = name
|
||||
department_data['parentid'] = parent_id
|
||||
department_data['order'] = order
|
||||
return self._post(
|
||||
'department/update',
|
||||
data=dict(department_data)
|
||||
)
|
||||
|
||||
def delete(self, id):
|
||||
"""
|
||||
删除部门
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理部门
|
||||
|
||||
:param id: 部门 id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get(
|
||||
'department/delete',
|
||||
params={
|
||||
'id': id
|
||||
}
|
||||
)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
获取部门列表
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理部门
|
||||
|
||||
:return: 部门列表
|
||||
"""
|
||||
res = self._get('department/list')
|
||||
return res['department']
|
||||
|
||||
def get_users(self, id, status=0, fetch_child=0):
|
||||
"""
|
||||
获取部门成员列表
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
|
||||
:param id: 部门 id
|
||||
:param status: 0 获取全部员工,1 获取已关注成员列表,
|
||||
2 获取禁用成员列表,4 获取未关注成员列表。可叠加
|
||||
:param fetch_child: 1/0:是否递归获取子部门下面的成员
|
||||
:return: 部门成员列表
|
||||
"""
|
||||
fetch_child = 1 if fetch_child else 0
|
||||
res = self._get(
|
||||
'user/simplelist',
|
||||
params={
|
||||
'department_id': id,
|
||||
'status': status,
|
||||
'fetch_child': fetch_child
|
||||
}
|
||||
)
|
||||
return res['userlist']
|
||||
|
||||
def get_users_list(self, id, status=0, fetch_child=0):
|
||||
"""
|
||||
获取部门成员详情列表
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
|
||||
:param id: 部门 id
|
||||
:param status: 0 获取全部员工,1 获取已关注成员列表,
|
||||
2 获取禁用成员列表,4 获取未关注成员列表。可叠加
|
||||
:param fetch_child: 1/0:是否递归获取子部门下面的成员
|
||||
:return: 部门成员列表
|
||||
"""
|
||||
fetch_child = 1 if fetch_child else 0
|
||||
res = self._get(
|
||||
'user/list',
|
||||
params={
|
||||
'department_id': id,
|
||||
'status': status,
|
||||
'fetch_child': fetch_child
|
||||
}
|
||||
)
|
||||
return res['userlist']
|
||||
48
sg_wechat_enterprise/we_api/enterprise/client/api/jsapi.py
Normal file
48
sg_wechat_enterprise/we_api/enterprise/client/api/jsapi.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
import time
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
from wechatpy.utils import WeChatSigner
|
||||
|
||||
|
||||
class WeChatJSAPI(BaseWeChatAPI):
|
||||
|
||||
def get_ticket(self):
|
||||
"""
|
||||
获取微信 JS-SDK ticket
|
||||
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS%E6%8E%A5%E5%8F%A3
|
||||
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get('get_jsapi_ticket')
|
||||
|
||||
def get_jsapi_ticket(self):
|
||||
"""
|
||||
获取微信 JS-SDK ticket
|
||||
|
||||
该方法会通过 session 对象自动缓存管理 ticket
|
||||
|
||||
:return: ticket
|
||||
"""
|
||||
ticket = self.session.get('jsapi_ticket')
|
||||
expires_at = self.session.get('jsapi_ticket_expires_at', 0)
|
||||
if not ticket or expires_at < int(time.time()):
|
||||
jsapi_ticket = self.get_ticket()
|
||||
ticket = jsapi_ticket['ticket']
|
||||
expires_at = int(time.time()) + int(jsapi_ticket['expires_in'])
|
||||
self.session.set('jsapi_ticket', ticket)
|
||||
self.session.set('jsapi_ticket_expires_at', expires_at)
|
||||
return ticket
|
||||
|
||||
def get_jsapi_signature(self, noncestr, ticket, timestamp, url):
|
||||
data = [
|
||||
'noncestr={noncestr}'.format(noncestr=noncestr),
|
||||
'jsapi_ticket={ticket}'.format(ticket=ticket),
|
||||
'timestamp={timestamp}'.format(timestamp=timestamp),
|
||||
'url={url}'.format(url=url),
|
||||
]
|
||||
signer = WeChatSigner(delimiter=b'&')
|
||||
signer.add_data(*data)
|
||||
return signer.signature
|
||||
201
sg_wechat_enterprise/we_api/enterprise/client/api/material.py
Normal file
201
sg_wechat_enterprise/we_api/enterprise/client/api/material.py
Normal file
@@ -0,0 +1,201 @@
|
||||
# encoding: utf-8
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
import requests
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatMaterial(BaseWeChatAPI):
|
||||
|
||||
def add_articles(self, articles):
|
||||
"""
|
||||
新增永久图文素材
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param articles: 图文素材数组
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
articles_data = []
|
||||
for article in articles:
|
||||
articles_data.append({
|
||||
'thumb_media_id': article['thumb_media_id'],
|
||||
'title': article['title'],
|
||||
'content': article['content'],
|
||||
'author': article.get('author', ''),
|
||||
'content_source_url': article.get('content_source_url', ''),
|
||||
'digest': article.get('digest', ''),
|
||||
'show_cover_pic': article.get('show_cover_pic', '0')
|
||||
})
|
||||
return self._post(
|
||||
'material/add_mpnews',
|
||||
data={
|
||||
"mpnews": {
|
||||
"articles": articles_data
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def add(self, agent_id, media_type, media_file):
|
||||
"""
|
||||
新增其它类型永久素材
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:param media_type: 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)普通文件(file)
|
||||
:param media_file: 要上传的文件,一个 File-object
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
params = {
|
||||
'agentid': agent_id,
|
||||
'type': media_type,
|
||||
}
|
||||
return self._post(
|
||||
url='material/add_material',
|
||||
params=params,
|
||||
files={
|
||||
'media': media_file
|
||||
}
|
||||
)
|
||||
|
||||
def get_url(self, agent_id, media_id):
|
||||
"""
|
||||
获取永久素材下载地址
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:param media_id: 媒体文件 ID
|
||||
:return: 临时素材下载地址
|
||||
"""
|
||||
parts = (
|
||||
'https://qyapi.weixin.qq.com/cgi-bin/material/get',
|
||||
'?access_token=',
|
||||
self.access_token,
|
||||
'&media_id=',
|
||||
media_id,
|
||||
'&agentid=',
|
||||
agent_id,
|
||||
)
|
||||
return ''.join(parts)
|
||||
|
||||
def get(self, agent_id, media_id):
|
||||
"""
|
||||
获取永久素材
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:param media_id: 媒体文件 ID
|
||||
:return: requests 的 Response 实例
|
||||
"""
|
||||
res = requests.get(self.get_url(agent_id, media_id))
|
||||
|
||||
return res
|
||||
|
||||
def get_articles(self, agent_id, media_id):
|
||||
"""
|
||||
获取永久素材:图文消息素材
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:param media_id: 媒体文件 ID
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get(
|
||||
'material/get',
|
||||
params={
|
||||
'agentid': agent_id,
|
||||
'media_id': media_id,
|
||||
}
|
||||
)
|
||||
|
||||
def delete(self, agent_id, media_id):
|
||||
"""
|
||||
删除永久素材
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E5%88%A0%E9%99%A4%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:param media_id: 媒体文件 ID
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get(
|
||||
'material/del',
|
||||
params={
|
||||
'agentid': agent_id,
|
||||
'media_id': media_id,
|
||||
}
|
||||
)
|
||||
|
||||
def update_articles(self, agent_id, media_id, articles):
|
||||
"""
|
||||
修改永久图文素材
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BF%AE%E6%94%B9%E6%B0%B8%E4%B9%85%E5%9B%BE%E6%96%87%E7%B4%A0%E6%9D%90
|
||||
|
||||
:param media_id: 要修改的图文消息的 id
|
||||
:param index: 要更新的文章在图文消息中的位置(多图文消息时,此字段才有意义),第一篇为 0
|
||||
:param articles: 图文素材数组
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
articles_data = []
|
||||
for article in articles:
|
||||
articles_data.append({
|
||||
'thumb_media_id': article['thumb_media_id'],
|
||||
'title': article['title'],
|
||||
'content': article['content'],
|
||||
'author': article.get('author', ''),
|
||||
'content_source_url': article.get('content_source_url', ''),
|
||||
'digest': article.get('digest', ''),
|
||||
'show_cover_pic': article.get('show_cover_pic', '0')
|
||||
})
|
||||
return self._post(
|
||||
'material/update_news',
|
||||
data={
|
||||
'agentid': agent_id,
|
||||
'media_id': media_id,
|
||||
'articles': articles_data
|
||||
}
|
||||
)
|
||||
|
||||
def get_count(self, agent_id):
|
||||
"""
|
||||
获取素材总数
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E6%80%BB%E6%95%B0
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._get(
|
||||
'material/get_count',
|
||||
params={
|
||||
'agent_id': agent_id,
|
||||
}
|
||||
)
|
||||
|
||||
def batchget(self, agent_id, media_type, offset=0, count=20):
|
||||
"""
|
||||
批量获取永久素材列表
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E5%88%97%E8%A1%A8
|
||||
|
||||
:param agent_id: 企业应用的id
|
||||
:param media_type: 媒体文件类型,分别有图文(mpnews)、图片(image)、
|
||||
语音(voice)、视频(video)和文件(file)
|
||||
:param offset: 从全部素材的该偏移位置开始返回,0 表示从第一个素材返回
|
||||
:param count: 返回素材的数量,取值在1到20之间
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'material/batchget',
|
||||
data={
|
||||
'agent_id': agent_id,
|
||||
'type': media_type,
|
||||
'offset': offset,
|
||||
'count': count
|
||||
}
|
||||
)
|
||||
73
sg_wechat_enterprise/we_api/enterprise/client/api/media.py
Normal file
73
sg_wechat_enterprise/we_api/enterprise/client/api/media.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
import requests
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatMedia(BaseWeChatAPI):
|
||||
|
||||
def upload(self, media_type, media_file):
|
||||
"""
|
||||
上传临时素材文件
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6
|
||||
|
||||
:param media_type: 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和普通文件(file)
|
||||
:param media_file: 要上传的文件,一个 File-object
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'media/upload',
|
||||
params={
|
||||
'type': media_type
|
||||
},
|
||||
files={
|
||||
'media': media_file
|
||||
}
|
||||
)
|
||||
|
||||
def upload_image(self, media_file):
|
||||
"""
|
||||
上传卡券logo
|
||||
:param media_file: 要上传的文件
|
||||
:return:
|
||||
"""
|
||||
return self._post(
|
||||
'media/uploadimg',
|
||||
params={
|
||||
'type': 'card_logo'
|
||||
},
|
||||
files={
|
||||
'media': media_file
|
||||
}
|
||||
)
|
||||
|
||||
def download(self, media_id):
|
||||
"""
|
||||
获取临时素材文件
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6
|
||||
|
||||
:param media_id: 媒体文件 ID
|
||||
:return: requests 的 Response 实例
|
||||
"""
|
||||
return requests.get(self.get_url(media_id))
|
||||
|
||||
def get_url(self, media_id):
|
||||
"""
|
||||
获取临时素材下载地址
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6
|
||||
|
||||
:param media_id: 媒体文件 ID
|
||||
:return: 临时素材下载地址
|
||||
"""
|
||||
parts = (
|
||||
'https://qyapi.weixin.qq.com/cgi-bin/media/get',
|
||||
'?access_token=',
|
||||
self.access_token,
|
||||
'&media_id=',
|
||||
media_id
|
||||
)
|
||||
return ''.join(parts)
|
||||
43
sg_wechat_enterprise/we_api/enterprise/client/api/menu.py
Normal file
43
sg_wechat_enterprise/we_api/enterprise/client/api/menu.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
from wechatpy.exceptions import WeChatClientException
|
||||
|
||||
|
||||
class WeChatMenu(BaseWeChatAPI):
|
||||
|
||||
def create(self, agent_id, menu_data):
|
||||
return self._post(
|
||||
'menu/create',
|
||||
params={
|
||||
'agentid': agent_id
|
||||
},
|
||||
data=menu_data
|
||||
)
|
||||
|
||||
def get(self, agent_id):
|
||||
try:
|
||||
return self._get(
|
||||
'menu/get',
|
||||
params={
|
||||
'agentid': agent_id
|
||||
}
|
||||
)
|
||||
except WeChatClientException as e:
|
||||
if e.errcode == 46003:
|
||||
# menu not exist
|
||||
return None
|
||||
else:
|
||||
raise e
|
||||
|
||||
def delete(self, agent_id):
|
||||
return self._get(
|
||||
'menu/delete',
|
||||
params={
|
||||
'agentid': agent_id
|
||||
}
|
||||
)
|
||||
|
||||
def update(self, agent_id, menu_data):
|
||||
self.delete(agent_id)
|
||||
return self.create(agent_id, menu_data)
|
||||
161
sg_wechat_enterprise/we_api/enterprise/client/api/message.py
Normal file
161
sg_wechat_enterprise/we_api/enterprise/client/api/message.py
Normal file
@@ -0,0 +1,161 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from optionaldict import optionaldict
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatMessage(BaseWeChatAPI):
|
||||
|
||||
def _send_message(self, agent_id, user_ids, party_ids='',
|
||||
tag_ids='', msg=None):
|
||||
msg = msg or {}
|
||||
if isinstance(user_ids, (tuple, list)):
|
||||
user_ids = '|'.join(user_ids)
|
||||
if isinstance(party_ids, (tuple, list)):
|
||||
party_ids = '|'.join(party_ids)
|
||||
if isinstance(tag_ids, (tuple, list)):
|
||||
tag_ids = '|'.join(tag_ids)
|
||||
|
||||
data = {
|
||||
'touser': user_ids,
|
||||
'toparty': party_ids,
|
||||
'totag': tag_ids,
|
||||
'agentid': agent_id
|
||||
}
|
||||
data.update(msg)
|
||||
return self._post(
|
||||
'message/send',
|
||||
data=data
|
||||
)
|
||||
|
||||
def send_text(self, agent_id, user_ids, content,
|
||||
party_ids='', tag_ids='', safe=0):
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'text',
|
||||
'text': {'content': content},
|
||||
'safe': safe
|
||||
}
|
||||
)
|
||||
|
||||
def send_image(self, agent_id, user_ids, media_id,
|
||||
party_ids='', tag_ids='', safe=0):
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'image',
|
||||
'image': {
|
||||
'media_id': media_id
|
||||
},
|
||||
'safe': safe
|
||||
}
|
||||
)
|
||||
|
||||
def send_voice(self, agent_id, user_ids, media_id,
|
||||
party_ids='', tag_ids='', safe=0):
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'voice',
|
||||
'voice': {
|
||||
'media_id': media_id
|
||||
},
|
||||
'safe': safe
|
||||
}
|
||||
)
|
||||
|
||||
def send_video(self, agent_id, user_ids, media_id, title=None,
|
||||
description=None, party_ids='', tag_ids='', safe=0):
|
||||
video_data = optionaldict()
|
||||
video_data['media_id'] = media_id
|
||||
video_data['title'] = title
|
||||
video_data['description'] = description
|
||||
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'video',
|
||||
'video': dict(video_data),
|
||||
'safe': safe
|
||||
}
|
||||
)
|
||||
|
||||
def send_file(self, agent_id, user_ids, media_id,
|
||||
party_ids='', tag_ids='', safe=0):
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'file',
|
||||
'file': {
|
||||
'media_id': media_id
|
||||
},
|
||||
'safe': safe
|
||||
}
|
||||
)
|
||||
|
||||
def send_articles(self, agent_id, user_ids, articles,
|
||||
party_ids='', tag_ids=''):
|
||||
articles_data = []
|
||||
for article in articles:
|
||||
articles_data.append({
|
||||
'title': article['title'],
|
||||
'description': article['description'],
|
||||
'url': article['url'],
|
||||
'picurl': article['image']
|
||||
})
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'news',
|
||||
'news': {
|
||||
'articles': articles_data
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def send_mp_articles(self, agent_id, user_ids, articles,
|
||||
party_ids='', tag_ids='', safe=0):
|
||||
articles_data = []
|
||||
for article in articles:
|
||||
articles_data.append({
|
||||
'thumb_media_id': article['thumb_media_id'],
|
||||
'author': article['author'],
|
||||
'title': article['title'],
|
||||
'content': article['content'],
|
||||
'content_source_url': article['content_source_url'],
|
||||
'digest': article['digest'],
|
||||
'show_cover_pic': article['show_cover_pic']
|
||||
})
|
||||
return self._send_message(
|
||||
agent_id,
|
||||
user_ids,
|
||||
party_ids,
|
||||
tag_ids,
|
||||
msg={
|
||||
'msgtype': 'mpnews',
|
||||
'mpnews': {
|
||||
'articles': articles_data
|
||||
},
|
||||
'safe': safe
|
||||
}
|
||||
)
|
||||
15
sg_wechat_enterprise/we_api/enterprise/client/api/misc.py
Normal file
15
sg_wechat_enterprise/we_api/enterprise/client/api/misc.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatMisc(BaseWeChatAPI):
|
||||
|
||||
def get_wechat_ips(self):
|
||||
"""
|
||||
获取微信服务器 IP 列表
|
||||
|
||||
:return: IP 地址列表
|
||||
"""
|
||||
res = self._get('getcallbackip')
|
||||
return res['ip_list']
|
||||
51
sg_wechat_enterprise/we_api/enterprise/client/api/oauth.py
Normal file
51
sg_wechat_enterprise/we_api/enterprise/client/api/oauth.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# encoding: utf-8
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
import six
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatOAuth(BaseWeChatAPI):
|
||||
|
||||
OAUTH_BASE_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize'
|
||||
|
||||
def authorize_url(self, redirect_uri, state=None):
|
||||
"""
|
||||
获取授权地址
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=OAuth%E9%AA%8C%E8%AF%81%E6%8E%A5%E5%8F%A3
|
||||
|
||||
:param redirect_url: 授权后重定向的回调链接地址
|
||||
:param state: 重定向后会带上 state 参数
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
redirect_uri = six.moves.urllib.parse.quote(redirect_uri)
|
||||
url_list = [
|
||||
self.OAUTH_BASE_URL,
|
||||
'?appid=',
|
||||
self._client.corp_id,
|
||||
'&redirect_uri=',
|
||||
redirect_uri,
|
||||
'&response_type=code&scope=snsapi_base',
|
||||
]
|
||||
if state:
|
||||
url_list.extend(['&state=', state])
|
||||
url_list.append('#wechat_redirect')
|
||||
return ''.join(url_list)
|
||||
|
||||
def get_user_info(self, code):
|
||||
"""
|
||||
根据 code 获取用户信息
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=OAuth%E9%AA%8C%E8%AF%81%E6%8E%A5%E5%8F%A3
|
||||
|
||||
:param code: 通过成员授权获取到的code
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
|
||||
return self._get(
|
||||
'user/getuserinfo',
|
||||
params={
|
||||
'code': code,
|
||||
}
|
||||
)
|
||||
45
sg_wechat_enterprise/we_api/enterprise/client/api/service.py
Normal file
45
sg_wechat_enterprise/we_api/enterprise/client/api/service.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatService(BaseWeChatAPI):
|
||||
|
||||
def get_provider_token(self, provider_secret):
|
||||
"""
|
||||
获取应用提供商凭证
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=获取应用提供商凭证
|
||||
|
||||
:param provider_secret: 提供商的secret,在提供商管理页面可见
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'service/get_provider_token',
|
||||
data={
|
||||
'corpid': self._client.corp_id,
|
||||
'provider_secret': provider_secret,
|
||||
}
|
||||
)
|
||||
|
||||
def get_login_info(self, provider_access_token, auth_code):
|
||||
"""
|
||||
获取企业号管理员登录信息
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=获取企业号管理员登录信息
|
||||
|
||||
:param provider_access_token: 服务提供商的 accesstoken
|
||||
:param auth_code: OAuth 2.0 授权企业号管理员登录产生的 code
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
return self._post(
|
||||
'service/get_login_info',
|
||||
params={
|
||||
'provider_access_token': provider_access_token,
|
||||
},
|
||||
data={
|
||||
'auth_code': auth_code,
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatShakeAround(BaseWeChatAPI):
|
||||
|
||||
def get_shake_info(self, ticket):
|
||||
"""
|
||||
获取摇周边的设备及用户信息
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=获取设备及用户信息
|
||||
|
||||
:param ticket: 摇周边业务的ticket,可在摇到的 URL 中得到,ticket 生效时间为30分钟
|
||||
:return: 设备及用户信息
|
||||
"""
|
||||
res = self._post(
|
||||
'shakearound/getshakeinfo',
|
||||
data={
|
||||
'ticket': ticket
|
||||
}
|
||||
)
|
||||
return res['data']
|
||||
61
sg_wechat_enterprise/we_api/enterprise/client/api/tag.py
Normal file
61
sg_wechat_enterprise/we_api/enterprise/client/api/tag.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatTag(BaseWeChatAPI):
|
||||
|
||||
def create(self, name):
|
||||
return self._post(
|
||||
'tag/create',
|
||||
data={
|
||||
'tagname': name
|
||||
}
|
||||
)
|
||||
|
||||
def update(self, tag_id, name):
|
||||
return self._post(
|
||||
'tag/update',
|
||||
data={
|
||||
'tagid': tag_id,
|
||||
'tagname': name
|
||||
}
|
||||
)
|
||||
|
||||
def delete(self, tag_id):
|
||||
return self._get(
|
||||
'tag/delete',
|
||||
params={
|
||||
'tagid': tag_id
|
||||
}
|
||||
)
|
||||
|
||||
def get_users(self, tag_id):
|
||||
return self._get(
|
||||
'tag/get',
|
||||
params={
|
||||
'tagid': tag_id
|
||||
}
|
||||
)
|
||||
|
||||
def add_users(self, tag_id, user_ids):
|
||||
return self._post(
|
||||
'tag/addtagusers',
|
||||
data={
|
||||
'tagid': tag_id,
|
||||
'userlist': user_ids
|
||||
}
|
||||
)
|
||||
|
||||
def delete_users(self, tag_id, user_ids):
|
||||
return self._post(
|
||||
'tag/deltagusers',
|
||||
data={
|
||||
'tagid': tag_id,
|
||||
'userlist': user_ids
|
||||
}
|
||||
)
|
||||
|
||||
def list(self):
|
||||
res = self._get('tag/list')
|
||||
return res['taglist']
|
||||
160
sg_wechat_enterprise/we_api/enterprise/client/api/user.py
Normal file
160
sg_wechat_enterprise/we_api/enterprise/client/api/user.py
Normal file
@@ -0,0 +1,160 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from optionaldict import optionaldict
|
||||
|
||||
from wechatpy.client.api.base import BaseWeChatAPI
|
||||
|
||||
|
||||
class WeChatUser(BaseWeChatAPI):
|
||||
|
||||
def create(self, user_id, name, department=None, position=None,
|
||||
mobile=None, gender=0, tel=None, email=None,
|
||||
weixin_id=None, extattr=None, avatar_mediaid=None, to_invite=True):
|
||||
"""
|
||||
创建成员
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
"""
|
||||
user_data = optionaldict()
|
||||
user_data['userid'] = user_id
|
||||
user_data['name'] = name
|
||||
user_data['gender'] = gender
|
||||
user_data['department'] = department
|
||||
user_data['position'] = position
|
||||
user_data['mobile'] = mobile
|
||||
user_data['tel'] = tel
|
||||
user_data['email'] = email
|
||||
user_data['weixinid'] = weixin_id
|
||||
user_data['extattr'] = extattr
|
||||
user_data['avatar_mediaid'] = avatar_mediaid
|
||||
user_data['to_invite'] = to_invite
|
||||
|
||||
return self._post(
|
||||
'user/create',
|
||||
data=user_data
|
||||
)
|
||||
|
||||
def update(self, user_id, name=None, department=None, position=None,
|
||||
mobile=None, gender=None, tel=None, email=None,
|
||||
weixin_id=None, enable=None, extattr=None, avatar_mediaid=None):
|
||||
"""
|
||||
更新成员
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
"""
|
||||
user_data = optionaldict()
|
||||
user_data['userid'] = user_id
|
||||
user_data['name'] = name
|
||||
user_data['gender'] = gender
|
||||
user_data['department'] = department
|
||||
user_data['position'] = position
|
||||
user_data['mobile'] = mobile
|
||||
user_data['tel'] = tel
|
||||
user_data['email'] = email
|
||||
user_data['weixinid'] = weixin_id
|
||||
user_data['extattr'] = extattr
|
||||
user_data['enable'] = enable
|
||||
user_data['avatar_mediaid'] = avatar_mediaid
|
||||
|
||||
return self._post(
|
||||
'user/update',
|
||||
data=user_data
|
||||
)
|
||||
|
||||
def delete(self, user_id):
|
||||
"""
|
||||
删除成员
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
"""
|
||||
return self._get(
|
||||
'user/delete',
|
||||
params={
|
||||
'userid': user_id
|
||||
}
|
||||
)
|
||||
|
||||
def get(self, user_id):
|
||||
"""
|
||||
获取成员
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
"""
|
||||
return self._get(
|
||||
'user/get',
|
||||
params={
|
||||
'userid': user_id
|
||||
}
|
||||
)
|
||||
|
||||
def verify(self, user_id):
|
||||
return self._get(
|
||||
'user/authsucc',
|
||||
params={
|
||||
'userid': user_id
|
||||
}
|
||||
)
|
||||
|
||||
def get_info(self, agent_id, code):
|
||||
return self._get(
|
||||
'user/getuserinfo',
|
||||
params={
|
||||
'agentid': agent_id,
|
||||
'code': code
|
||||
}
|
||||
)
|
||||
|
||||
def batch_delete(self, user_ids):
|
||||
"""
|
||||
批量删除成员
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
"""
|
||||
return self._post(
|
||||
'user/batchdelete',
|
||||
data={
|
||||
'useridlist': user_ids
|
||||
}
|
||||
)
|
||||
|
||||
def list(self, department_id, fetch_child=False, status=0):
|
||||
"""
|
||||
批量获取部门成员
|
||||
详情请参考 http://qydev.weixin.qq.com/wiki/index.php?title=管理成员
|
||||
"""
|
||||
res = self._get(
|
||||
'user/list',
|
||||
params={
|
||||
'department_id': department_id,
|
||||
'fetch_child': 1 if fetch_child else 0,
|
||||
'status': status
|
||||
}
|
||||
)
|
||||
return res['userlist']
|
||||
|
||||
def convert_to_openid(self, user_id, agent_id=None):
|
||||
"""
|
||||
user_id 转成 openid
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=Userid%E4%B8%8Eopenid%E4%BA%92%E6%8D%A2%E6%8E%A5%E5%8F%A3
|
||||
|
||||
:param user_id: 企业号内的成员 ID
|
||||
:param agent_id: 可选,需要发送红包的应用ID,若只是使用微信支付和企业转账,则无需该参数
|
||||
:return: 返回的 JSON 数据包
|
||||
"""
|
||||
data = optionaldict()
|
||||
data['userid'] = user_id
|
||||
data['agentid'] = agent_id
|
||||
return self._post('user/convert_to_openid', data=data)
|
||||
|
||||
def convert_to_user_id(self, openid):
|
||||
"""
|
||||
openid 转成 user_id
|
||||
|
||||
详情请参考
|
||||
http://qydev.weixin.qq.com/wiki/index.php?title=Userid%E4%B8%8Eopenid%E4%BA%92%E6%8D%A2%E6%8E%A5%E5%8F%A3
|
||||
|
||||
:param openid: 在使用微信支付、微信红包和企业转账之后,返回结果的openid
|
||||
:return: 该 openid 在企业号中对应的成员 user_id
|
||||
"""
|
||||
res = self._post(
|
||||
'user/convert_to_userid',
|
||||
data={'openid': openid}
|
||||
)
|
||||
return res['userid']
|
||||
Reference in New Issue
Block a user