Files
gitlab-instance-0a899031_ku…/WXBotService.py
hackrobot 7f8deddeee init
2024-03-20 11:00:53 +08:00

922 lines
31 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import hashlib
import json
import os
import re
import time
import traceback
from io import BytesIO
from typing import Union
import xml.etree.cElementTree as ET
import emoji
import requests
import config
def initialize(app_id: str, app_name: str, app_ver: str, app_key: str) -> dict:
r"""初始化[K10001]
:param app_id: 软件唯一id暂时随意
:param app_name: 软件名称
:param app_ver: 软件版本号
:param app_key: 软件Key暂时随意
"""
api_json = {'api': 'K10001', 'appId': app_id, 'appName': app_name, 'appVer': app_ver, 'appKey': app_key}
return api_request(api_json)
def add_log(api_type: str, msg: str) -> dict:
r"""添加日志[K10002]
:param api_type: 1调试2警告3提示
:param msg: 日志内容
"""
api_json = {'api': 'K10002', 'type': api_type, 'msg': msg}
return api_request(api_json)
def follow_official_account(robot_wxid: str, from_wxid: str) -> dict:
r"""关注公众号[K10003]
:param robot_wxid: 机器人的wxid
:param from_wxid: 公众号的wxid
"""
api_json = {'api': 'K10003', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def transfer_receipt(robot_wxid: str, from_wxid: str, transfer_id: str) -> dict:
r"""转账收款[K10004]
:param robot_wxid: 机器人的wxid
:param from_wxid: 转账人的wxid
:param transfer_id: 收到的转账transferid
"""
api_json = {'api': 'K10004', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'transferid': transfer_id}
return api_request(api_json)
def transfer_refund(robot_wxid: str, from_wxid: str, transfer_id: str) -> dict:
r"""转账退款[K10005]
:param robot_wxid: 机器人的wxid
:param from_wxid: 转账人的wxid
:param transfer_id: 收到的转账transferid
"""
api_json = {'api': 'K10005', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'transferid': transfer_id}
return api_request(api_json)
def agree_group_invite(robot_wxid: str, from_wxid: str, url: str) -> dict:
r"""同意群聊邀请[K10006]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param url: 收到的消息里获取
"""
api_json = {'api': 'K10006', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'url': url}
return api_request(api_json)
def message_not_disturb(robot_wxid: str, from_wxid: str, is_flag: str) -> dict:
r"""消息免打扰[K10007]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param is_flag: 是否免打扰0/1
"""
api_json = {'api': 'K10007', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'isFlag': is_flag}
return api_request(api_json)
def set_chat_top(robot_wxid: str, from_wxid: str, is_flag: str) -> dict:
r"""置顶聊天[K10008]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param is_flag: 是否置顶0/1
"""
api_json = {'api': 'K10008', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'isFlag': is_flag}
return api_request(api_json)
def change_chat(robot_wxid: str, from_wxid: str) -> dict:
r"""切换当前聊天对象[K10009]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
"""
api_json = {'api': 'K10009', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def get_group_members_list(robot_wxid: str, from_wxid: str) -> dict:
r"""获取群成员列表[K10010]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
"""
api_json = {'api': 'K10010', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def get_wecom_group_members_list(robot_wxid: str, from_wxid: str) -> dict:
r"""获取企业群成员列表[K10011]
:param robot_wxid: 机器人的wxid
:param from_wxid: 企业群的id
"""
api_json = {'api': 'K10011', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def create_group(robot_wxid: str, from_wxid: str) -> dict:
r"""创建群聊[K10012]
:param robot_wxid: 机器人的wxid
:param from_wxid: wxid用英文逗号分隔
"""
api_json = {'api': 'K10012', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def update_group_name(robot_wxid: str, from_wxid: str, new_name: str) -> dict:
r"""修改群聊名称[K10013]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param new_name: 新的群名称
"""
api_json = {'api': 'K10013', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'newName': new_name}
return api_request(api_json)
def publish_group_announcement(robot_wxid: str, from_wxid: str, new_msg: str) -> dict:
r"""发布群公告[K10014]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param new_msg: 公告内容
"""
api_json = {'api': 'K10014', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'newMsg': new_msg}
return api_request(api_json)
def add_group_members_40_more(robot_wxid: str, from_wxid: str, new_wxid: str) -> dict:
r"""邀请群成员40人以上[K10015]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param new_wxid: 邀请进群的wxid
"""
api_json = {'api': 'K10015', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'newWxid': new_wxid}
return api_request(api_json)
def add_group_members_40_less(robot_wxid: str, from_wxid: str, new_wxid: str) -> dict:
r"""添加群成员40人以下[K10016]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param new_wxid: 邀请进群的wxid
"""
api_json = {'api': 'K10016', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'newWxid': new_wxid}
return api_request(api_json)
def drop_group_member(robot_wxid: str, from_wxid: str, old_wxid: str) -> dict:
r"""删除群成员[K10017]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param old_wxid: 群成员的wxid
"""
api_json = {'api': 'K10017', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'oldWxid': old_wxid}
return api_request(api_json)
def quit_group(robot_wxid: str, from_wxid: str) -> dict:
r"""退出群聊[K10018]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
"""
api_json = {'api': 'K10018', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def get_group_member_nickname(robot_wxid: str, from_wxid: str, old_wxid: str) -> dict:
r"""获取群内昵称[K10019]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param old_wxid: 群成员的wxid
"""
api_json = {'api': 'K10019', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'oldWxid': old_wxid}
return api_request(api_json)
def update_nickname_in_group(robot_wxid: str, from_wxid: str, new_msg: str) -> dict:
r"""修改群内昵称[K10020]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param new_msg: 新的群内昵称
"""
api_json = {'api': 'K10020', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'newMsg': new_msg}
return api_request(api_json)
def hide_group_member_nickname(robot_wxid: str, from_wxid: str, is_flag: str) -> dict:
r"""显示或隐藏群成员昵称[K10021]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param is_flag: 是否隐藏0/1
"""
api_json = {'api': 'K10021', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'isFlag': is_flag}
return api_request(api_json)
def save_to_address(robot_wxid: str, from_wxid: str, is_flag: str) -> dict:
r"""保存到通讯录[K10022]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
:param is_flag: 是否保存0/1
"""
api_json = {'api': 'K10022', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'isFlag': is_flag}
return api_request(api_json)
def get_group_member_invite_information(robot_wxid: str, from_wxid: str) -> dict:
r"""获取群成员邀请信息[K10023]
:param robot_wxid: 机器人的wxid
:param from_wxid: 群聊的id
"""
api_json = {'api': 'K10023', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def get_address_list(robot_wxid: str) -> dict:
r"""获取通讯录列表[K10024],此处获取的好友+群等(具体自己测试)
:param robot_wxid: 机器人的wxid
"""
api_json = {'api': 'K10024', 'robotWxid': robot_wxid}
return api_request(api_json)
def get_wecom_friend_list(robot_wxid: str) -> dict:
r"""获取企业好友列表[K10025]
:param robot_wxid: 机器人的wxid
"""
api_json = {'api': 'K10025', 'robotWxid': robot_wxid}
return api_request(api_json)
def get_friend_info(robot_wxid: str, from_wxid: str) -> dict:
r"""获取指定好友信息[K10026]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
"""
api_json = {'api': 'K10026', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def get_net_friend_info(robot_wxid: str, from_wxid: str) -> dict:
r"""网络获取指定好友信息[K10027]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
"""
api_json = {'api': 'K10027', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def del_friend(robot_wxid: str, from_wxid: str) -> dict:
r"""删除好友[K10028]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
"""
api_json = {'api': 'K10028', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def update_friend_remark(robot_wxid: str, from_wxid: str, remark: str) -> dict:
r"""修改好友备注[K10029]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param remark: 备注
"""
api_json = {'api': 'K10029', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'newMsg': remark}
return api_request(api_json)
def agree_friend_request(robot_wxid: str, from_wxid: str, v3: str, v4: str, sence: str) -> dict:
r"""同意好友请求[K10030]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param v3: 接收到的消息里获取
:param v4: 接收到的消息里获取
:param sence: 接收到的消息里获取
"""
api_json = {'api': 'K10030', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'v3': v3, 'v4': v4, 'sence': sence}
return api_request(api_json)
def friend_status_detection(robot_wxid: str, from_wxid: str) -> dict:
r"""好友状态检测[K10031]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
"""
api_json = {'api': 'K10031', 'robotWxid': robot_wxid, 'fromWxid': from_wxid}
return api_request(api_json)
def add_blacklist(robot_wxid: str, from_wxid: str, is_flag: str) -> dict:
r"""拉黑好友[K10032]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param is_flag: 是否拉黑0/1
"""
api_json = {'api': 'K10032', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'isFlag': is_flag}
return api_request(api_json)
def send_text_message(robot_wxid: str, from_wxid: str, msg: str) -> dict:
r"""发送文本信息[K10033]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg: 消息内容
"""
api_json = {'api': 'K10033', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msg': msg}
return api_request(api_json)
def send_image_message(robot_wxid: str, from_wxid: str, msg: str) -> dict:
r"""发送图片信息[K10034]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg: 图片路径,支持网址(直链http://127.0.0.1/tp.jpg)
"""
api_json = {'api': 'K10034', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msg': msg}
return api_request(api_json)
def send_file_message(robot_wxid: str, from_wxid: str, msg: str) -> dict:
r"""发送文件信息[K10035]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg: 文件路径,本地(鲲鹏机器人所在电脑/服务器)
"""
api_json = {'api': 'K10035', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msg': msg}
return api_request(api_json)
def send_gif_message(robot_wxid: str, from_wxid: str, msg: str) -> dict:
r"""发送GIF信息[K10036]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg: GIF路径支持网址(直链http://127.0.0.1/tp.gif)
"""
api_json = {'api': 'K10036', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msg': msg}
return api_request(api_json)
def send_at_message(robot_wxid: str, from_wxid: str, msg: str, wx_list: str) -> dict:
r"""发送艾特信息[K10037]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg: 消息内容
:param wx_list: 艾特的wxid列表用英文逗号隔开
"""
api_json = {'api': 'K10037', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msg': msg, 'list': wx_list}
return api_request(api_json)
def send_card_message(robot_wxid: str, from_wxid: str, tj_wxid: str, tj_name: str) -> dict:
r"""发送名片信息[K10038]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param tj_wxid: wxid和v4都可以
:param tj_name: 推荐昵称
"""
api_json = {'api': 'K10038', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'tjWxid': tj_wxid, 'tjName': tj_name}
return api_request(api_json)
def send_link_message(robot_wxid: str, from_wxid: str, title: str, desc: str, url: str, pic: str) -> dict:
r"""发送链接信息[K10039]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param title: 标题
:param desc: 描述
:param url: 链接
:param pic: 图片路径,支持网址(直链http://127.0.0.1/tp.jpg)
"""
api_json = {'api': 'K10039', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'title': title, 'desc': desc,
'url': url, 'pic': pic}
return api_request(api_json)
def send_applet_message(robot_wxid: str, from_wxid: str, xml: str, pic: str) -> dict:
r"""发送小程序信息[K10040]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param xml: xml
:param pic: 略缩图路径,支持网址(直链http://127.0.0.1/tp.jpg)
"""
api_json = {'api': 'K10040', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'xml': xml, 'pic': pic}
return api_request(api_json)
def relay_message(robot_wxid: str, from_wxid: str, msg_id: str) -> dict:
r"""转发信息[K10041]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg_id: 消息IdSvrId
"""
api_json = {'api': 'K10041', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msgId': msg_id}
return api_request(api_json)
def get_login_status(robot_wxid: str) -> dict:
r"""取登录状态[K10042]
:param robot_wxid: 机器人的wxid
"""
api_json = {'api': 'K10042', 'robotWxid': robot_wxid}
return api_request(api_json)
def withdraw_message(robot_wxid: str, from_wxid: str, msg_id: str) -> dict:
r"""撤回信息[K10043]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param msg_id: 消息IdSvrId
"""
api_json = {'api': 'K10043', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'msgId': msg_id}
return api_request(api_json)
def get_personal_info(robot_wxid: str) -> dict:
r"""获取个人信息[K10044]
:param robot_wxid: 机器人的wxid
"""
api_json = {'api': 'K10044', 'robotWxid': robot_wxid}
return api_request(api_json)
def get_login_list() -> dict:
r"""取登录账号列表[K10045]"""
api_json = {'api': 'K10045'}
return api_request(api_json)
def download_image(robot_wxid: str, xml: str, path: str) -> dict:
r"""下载图片[K10046]
:param robot_wxid: 机器人的wxid
:param xml: 接收到的消息xml
:param path: 保存路径,绝对路径,带后缀
"""
api_json = {'api': 'K10046', 'robotWxid': robot_wxid, 'xml': xml, 'path': path}
return api_request(api_json)
def decrypt_image(robot_wxid: str, filepath: str, path: str) -> dict:
r"""解密图片[K10047]
:param robot_wxid: 机器人的wxid
:param filepath: 接收消息里的filepath字段
:param path: 保存路径,绝对路径,带后缀
"""
api_json = {'api': 'K10047', 'robotWxid': robot_wxid, 'filepath': filepath, 'path': path}
return api_request(api_json)
def send_xml_message(robot_wxid: str, from_wxid: str, xml: str) -> dict:
r"""发送XML信息[K10048]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param xml: XML信息
"""
api_json = {'api': 'K10048', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'xml': xml}
return api_request(api_json)
def refresh_moments(robot_wxid: str) -> dict:
r"""刷新朋友圈[K10049]
:param robot_wxid: 机器人的wxid
"""
api_json = {'api': 'K10049', 'robotWxid': robot_wxid}
return api_request(api_json)
def get_moments_next_page(robot_wxid: str, circle_id: str) -> dict:
r"""获取朋友圈下一页[K10050]
:param robot_wxid: 机器人的wxid
:param circle_id: itemid朋友圈ID获取从该ID的下一条开始的一页
"""
api_json = {'api': 'K10050', 'robotWxid': robot_wxid, 'circleId': circle_id}
return api_request(api_json)
def get_personal_moments(robot_wxid: str, from_wxid: str, circle_id: str) -> dict:
r"""获取个人朋友圈[K10051]
:param robot_wxid: 机器人的wxid
:param from_wxid: 目标的wxid
:param circle_id: itemid朋友圈ID获取从该ID的下一条开始的一页
"""
api_json = {'api': 'K10051', 'robotWxid': robot_wxid, 'fromWxid': from_wxid, 'circleId': circle_id}
return api_request(api_json)
def moments_like(robot_wxid: str, circle_id: str) -> dict:
r"""朋友圈点赞[K10052]
:param robot_wxid: 机器人的wxid
:param circle_id: itemid朋友圈ID获取从该ID的下一条开始的一页
"""
api_json = {'api': 'K10052', 'robotWxid': robot_wxid, 'circleId': circle_id}
return api_request(api_json)
def moments_cancel_like(robot_wxid: str, circle_id: str) -> dict:
r"""朋友圈取消点赞[K10053]
:param robot_wxid: 机器人的wxid
:param circle_id: itemid朋友圈ID获取从该ID的下一条开始的一页
"""
api_json = {'api': 'K10053', 'robotWxid': robot_wxid, 'circleId': circle_id}
return api_request(api_json)
def local_download_image(xml, path):
r"""本地下载图片
:param xml: 接收到的消息xml
:param path: 保存文件夹的绝对路径
:return: 下载图片的绝对路径
"""
emoji_msg = ET.fromstring(xml).find('emoji')
url = emoji_msg.get('cdnurl').replace('amp;', '')
r = requests.get(url)
if os.path.exists(path) is False:
os.mkdir(path)
xo, j = image_format(r.content) # 判断图片格式 并计算返回异或值 函数
if j == 1:
mat = '.png'
elif j == 2:
mat = '.gif'
else:
mat = '.jpg'
file_name = re.findall(r'm=(.*?)&', url)[0]
out = os.path.join(path, file_name + mat)
with open(out, 'wb') as f:
f.write(r.content)
f.close()
return out
def local_decrypt_image(filepath: str, path: str) -> str:
r"""本地解密dat图片
:param filepath: 接收消息里的filepath字段
:param path: 保存文件夹的绝对路径
:return: 解密图片的绝对路径
"""
file_splitext = os.path.splitext(filepath)
file_type = file_splitext[1]
file_name = os.path.split(file_splitext[0])[1]
if file_type != '.dat':
return '不支持处理非.dat文件'
if '.' in path:
return 'path参数为保存文件夹的绝对路径'
if os.path.exists(path) is False:
os.mkdir(path)
for i in range(30):
if os.path.exists(filepath) is True:
break
time.sleep(2)
if os.path.exists(filepath) is False:
return '微信下载dat图片超时'
dat_read = open(filepath, "rb") # 读取.dat 文件
xo, j = image_format(filepath) # 判断图片格式 并计算返回异或值 函数
if j == 1:
mat = '.png'
elif j == 2:
mat = '.gif'
else:
mat = '.jpg'
out = os.path.join(path, file_name + mat)
png_write = open(out, "wb") # 图片写入
dat_read.seek(0) # 重置文件指针位置
for now in dat_read: # 循环字节
for nowByte in now:
new_byte = nowByte ^ xo # 转码计算
png_write.write(bytes([new_byte])) # 转码后重新写
dat_read.close()
png_write.close()
return out
def image_format(f):
"""
计算异或值
各图片头部信息
png89 50 4e 47
gif 47 49 46 38
jpegff d8 ff
"""
if isinstance(f, str):
dat_r = open(f, "rb")
elif isinstance(f, bytes):
dat_r = BytesIO(f)
else:
return print('不支持的类型', type(f))
try:
a = [(0x89, 0x50, 0x4e), (0x47, 0x49, 0x46), (0xff, 0xd8, 0xff)]
for now in dat_r:
j = 0
for xor in a:
j = j + 1 # 记录是第几个格式 1png 2gif 3jpeg
i = 0
res = []
now2 = now[:3] # 取前三组判断
for nowByte in now2:
res.append(nowByte ^ xor[i])
i += 1
if res[0] == res[1] == res[2]:
return res[0], j
except:
pass
finally:
dat_r.close()
# 表情代码
WC_EMOTICON_CONVERSION = {
'[微笑]': '😃', '[Smile]': '😃',
'[撇嘴]': '😖', '[Grimace]': '😖',
'[色]': '😍', '[Drool]': '😍',
'[发呆]': '😳', '[Scowl]': '😳',
'[得意]': '😎', '[Chill]': '😎',
'[流泪]': '😭', '[Sob]': '😭',
'[害羞]': '☺️', '[Shy]': '☺️', '[Blush]': '☺️',
'[闭嘴]': '🤐', '[Shutup]': '🤐',
'[睡]': '😴', '[Sleep]': '😴',
'[大哭]': '😣', '[Cry]': '😣',
'[尴尬]': '😰', '[Awkward]': '😰',
'[发怒]': '😡', '[Pout]': '😡',
'[调皮]': '😜', '[Wink]': '😜',
'[呲牙]': '😁', '[Grin]': '😁',
'[惊讶]': '😱', '[Surprised]': '😱',
'[难过]': '🙁', '[Frown]': '🙁',
'[囧]': '☺️', '[Tension]': '☺️',
'[抓狂]': '😫', '[Scream]': '😫',
'[吐]': '🤢', '[Puke]': '🤢',
'[偷笑]': '🙈', '[Chuckle]': '🙈',
'[愉快]': '☺️', '[Joyful]': '☺️',
'[白眼]': '🙄', '[Slight]': '🙄',
'[傲慢]': '😕', '[Smug]': '😕',
'[困]': '😪', '[Drowsy]': '😪',
'[惊恐]': '😱', '[Panic]': '😱',
'[流汗]': '😓', '[Sweat]': '😓',
'[憨笑]': '😄', '[Laugh]': '😄',
'[悠闲]': '😏', '[Loafer]': '😏',
'[奋斗]': '💪', '[Strive]': '💪',
'[咒骂]': '😤', '[Scold]': '😤',
'[疑问]': '', '[Doubt]': '',
'[嘘]': '🤐', '[Shhh]': '🤐',
'[晕]': '😲', '[Dizzy]': '😲',
'[衰]': '😳', '[BadLuck]': '😳',
'[骷髅]': '💀', '[Skull]': '💀',
'[敲打]': '👊', '[Hammer]': '👊',
'[再见]': '🙋\u200d', '[Bye]': '🙋\u200d',
'[擦汗]': '😥', '[Relief]': '😥',
'[抠鼻]': '🤷\u200d', '[DigNose]': '🤷\u200d',
'[鼓掌]': '👏', '[Clap]': '👏',
'[坏笑]': '👻', '[Trick]': '👻',
'[左哼哼]': '😾', '[BahL]': '😾',
'[右哼哼]': '😾', '[BahR]': '😾',
'[哈欠]': '😪', '[Yawn]': '😪',
'[鄙视]': '😒', '[Lookdown]': '😒',
'[委屈]': '😣', '[Wronged]': '😣',
'[快哭了]': '😔', '[Puling]': '😔',
'[阴险]': '😈', '[Sly]': '😈',
'[亲亲]': '😘', '[Kiss]': '😘',
'[可怜]': '😻', '[Whimper]': '😻',
'[菜刀]': '🔪', '[Cleaver]': '🔪',
'[西瓜]': '🍉', '[Melon]': '🍉',
'[啤酒]': '🍺', '[Beer]': '🍺',
'[咖啡]': '', '[Coffee]': '',
'[猪头]': '🐷', '[Pig]': '🐷',
'[玫瑰]': '🌹', '[Rose]': '🌹',
'[凋谢]': '🥀', '[Wilt]': '🥀',
'[嘴唇]': '💋', '[Lip]': '💋',
'[爱心]': '❤️', '[Heart]': '❤️',
'[心碎]': '💔', '[BrokenHeart]': '💔',
'[蛋糕]': '🎂', '[Cake]': '🎂',
'[炸弹]': '💣', '[Bomb]': '💣',
'[便便]': '💩', '[Poop]': '💩',
'[月亮]': '🌃', '[Moon]': '🌃',
'[太阳]': '🌞', '[Sun]': '🌞',
'[拥抱]': '🤗', '[Hug]': '🤗',
'[强]': '👍', '[Strong]': '👍',
'[弱]': '👎', '[Weak]': '👎',
'[握手]': '🤝', '[Shake]': '🤝',
'[胜利]': '✌️', '[Victory]': '✌️',
'[抱拳]': '🙏', '[Salute]': '🙏',
'[勾引]': '💁\u200d', '[Beckon]': '💁\u200d',
'[拳头]': '👊', '[Fist]': '👊',
'[OK]': '👌',
'[跳跳]': '💃', '[Waddle]': '💃',
'[发抖]': '🙇', '[Tremble]': '🙇',
'[怄火]': '😡', '[Aaagh!]': '😡',
'[转圈]': '🕺', '[Twirl]': '🕺',
'[嘿哈]': '🤣', '[Hey]': '🤣',
'[捂脸]': '🤦\u200d', '[Facepalm]': '🤦\u200d',
'[奸笑]': '😜', '[Smirk]': '😜',
'[机智]': '🤓', '[Smart]': '🤓',
'[皱眉]': '😟', '[Concerned]': '😟',
'[耶]': '✌️', '[Yeah!]': '✌️',
'[红包]': '🧧', '[Packet]': '🧧',
'[鸡]': '🐥', '[Chick]': '🐥',
'[蜡烛]': '🕯️', '[Candle]': '🕯️',
'[糗大了]': '😥',
'[Thumbs Up]': '👍', '[Pleased]': '😊',
'[Rich]': '🀅',
'[Pup]': '🐶',
'[吃瓜]': '🙄\u200d🍉', '[Onlooker]': '🙄\u200d🍉',
'[加油]': '💪\u200d😁',
'[加油加油]': '💪\u200d😷',
'[汗]': '😓',
'[天啊]': '😱',
'[Emm]': '🤔',
'[社会社会]': '😏',
'[旺柴]': '🐶\u200d😏', '[Awesome]': '🐶\u200d😏',
'[好的]': '😏\u200d👌',
'[哇]': '🤩',
'[打脸]': '😟\u200d🤚',
'[破涕为笑]': '😂', '[破涕為笑]': '😂', '[Lol]': '😂',
'[苦涩]': '😭',
'[翻白眼]': '🙄',
'[爆竹]': '🧨',
'[烟花]': '🎆',
'[裂开]': '[裂开]',
'[福]': '🧧',
'[發]': '🀅',
'[礼物]': '🎁',
'[庆祝]': '🎉',
'[合十]': '🙏',
'[叹气]': '😮‍💨', '[Sigh]': '😮‍💨',
'[让我看看]': '👀',
'[666]': '6⃣6⃣6',
'[无语]': '😑',
'[失望]': '😞',
'[恐惧]': '😨',
'[脸红]': '😳',
'[生病]': '😷',
'[笑脸]': '😁',
}
def unicode_escape(chars, data_dict):
"""emoji 替换 unicode 格式 "[\\u1f602],请勿主动调用"""
if chars in WC_EMOTICON_CONVERSION.values():
return [k for k, v in WC_EMOTICON_CONVERSION.items() if v == chars][0]
else:
chars_str = chars.encode('unicode-escape').decode().replace('U000', 'u')
chars_unicode_list = chars_str.split('\\')
chars_unicode_list.pop(0)
for i in range(len(chars_unicode_list)):
chars_unicode_list[i] = '[\\\\{}]'.format(chars_unicode_list[i])
return ''.join(chars_unicode_list)
def emoji_to_unicode(message: str) -> str:
"""将msg中的emoji表情转为鲲鹏 unicode 格式 "[\\u1f602]"
"""
return emoji.replace_emoji(message, replace=unicode_escape)
def unicode_to_emoji(message: Union[str, dict, list], msg_type='str') -> Union[str, dict, list]:
"""将msg中的鲲鹏unicode格式 "[\\u1f602]" 转为emoji表情
:param message: 建议传入json字符串虽然提供了dict和list的解析方法但递归遍历影响运行速度
:param msg_type: 默认为str'json字符串请传入json区别在于json的转义符多dict和list通常情况下保持默认即可
"""
if isinstance(message, str):
return de_emoji(message, msg_type)
elif isinstance(message, dict) or isinstance(message, list):
return ergodic(message)
else:
return '暂不支持此类型'
def ergodic(message: Union[dict, list]) -> Union[dict, list]:
"""递归遍历将鲲鹏unicode格式 "[\\u1f602]" 转为emoji表情不建议使用此方法且请勿主动调用"""
if isinstance(message, dict):
for key in message.keys():
message[key] = de_emoji(message[key])
return message
elif isinstance(message, list):
for i in range(len(message)):
message[i] = de_emoji(message[i])
return message
print(message)
return message
def de_emoji(message, msg_type='str'):
"""将鲲鹏unicode格式 "[\\u1f602]" 转为emoji表情请勿主动调用"""
if not message:
return message
if msg_type == 'json':
zyf = '\\'
else:
zyf = ''
if isinstance(message, dict) or isinstance(message, list):
return ergodic(message)
elif isinstance(message, str):
emoji_list = re.findall(zyf + zyf + r'\\u[0-9a-fA-F]{5}', message)
# print(emoji_list)
for emoji_unicode in emoji_list:
chars = str(str.replace(emoji_unicode, zyf + '\\u', '\\U000')).encode('ASCII').decode('unicode-escape')
# print(chars)
message = message.replace(f'[{emoji_unicode}]', chars)
message = message.replace('[' + zyf + '\\u200d]', '\\u200d'.encode('ASCII').decode('unicode-escape'))
message = message.replace('[' + zyf + '\\ufe0f]', '\\ufe0f'.encode('ASCII').decode('unicode-escape'))
chars_list = re.findall(r'\[\w+]', message)
for chars in chars_list:
try:
message = message.replace(chars, WC_EMOTICON_CONVERSION[chars])
except KeyError:
pass
unicode_text_list = re.findall(zyf + zyf + r'\\u[0-9a-fA-F]{4}', message)
for unicode_text in unicode_text_list:
message = message.replace(f'[{unicode_text}]', unicode_text.replace(zyf, '', 1))
return message
else:
return message
def crypt_md5(message: Union[dict, str]) -> str:
"""鉴权算法"""
if isinstance(message, str):
message = json.loads(message)
crypt_text = f"{config.SECRET_KEY}{''.join(message.values())}{config.SECRET_KEY}"
jm = hashlib.md5()
jm.update(crypt_text.encode("utf8"))
crypt_text_2 = jm.hexdigest()
jm2 = hashlib.md5()
jm2.update(crypt_text_2.encode("utf8"))
return jm2.hexdigest()
def api_request(api_json: dict) -> dict:
r"""请求api接口请勿主动调用
:param api_json: 请求参数
"""
if api_json.get('api') != 'K10002': # 添加日志不转emoji
api_json = emoji_to_unicode(json.dumps(api_json, ensure_ascii=False))
if isinstance(api_json, str): # str解析json
api_json = json.loads(api_json)
api_json.update({'sign': crypt_md5(api_json)}) # 增加鉴权
r = requests.post(config.wxbot_url, headers={'content-type': 'application/json'},
data=json.dumps(api_json, ensure_ascii=False).encode('utf-8')).json()
return r