Files
gitlab-instance-0a899031_ku…/main.py
hackrobot 121fcc094b dddd
2024-04-11 09:16:34 +08:00

476 lines
20 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
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.
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
# from . import crud, models, schemas
import crud, models, schemas
from database import SessionLocal, engine
# from .database import SessionLocal, engine
import json
import os
import threading
import time
from pydantic import BaseModel
from flask import request, Flask
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
import WXBotService
from planet import planetXml
from tengxunyun import tengxunyunXml
from lxml import etree
import xml.dom.minidom
from pydantic import BaseModel
import utils
import requests
import config
from urllib.parse import quote, unquote
import re
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# 默认首页
@app.get("/")
async def root():
return {"message": "Hello World"}
# 微信登录
@app.get("/login")
def read_users(code, wxid, db: Session = Depends(get_db)):
print('code--', code)
new_user = {}
# 异度星球-小程序
payload = {
'appid': config.appid,
'secret': config.secret,
'js_code': code,
'grant_type': 'authorization_code'
}
res = requests.get(config.tokenUrl, params=payload)
r = res.json()
# 返回参数 session_key/unionid/errmsg/openid/errcode
print('r----', r)
openId = r['openid']
print('openId----', openId)
db_user = crud.get_user_by_openId(db, openId=openId)
print('db_user----', db_user)
if db_user:
# 返回用户完整数据
new_user = db_user
else:
if wxid:
# 机器人id
account_wxid = config.account_wxid
# 新增用户
new_user = utils.saveWxidInfo(account_wxid, wxid, openId)
# "errmsg":r['errmsg'],,"errcode":r['errcode']
# return {"session_key":r['session_key'],"unionid":r['unionid'],"openid":r['openid']}
return new_user
# H5保存用户h5openid与wxid
@app.get("/addH5openid")
def addH5openid(h5openid, wxid, db: Session = Depends(get_db)):
db_user = crud.get_user_by_h5openid(db, h5openid=h5openid)
print('db_user----', db_user)
if db_user:
# 返回用户完整数据
new_user = db_user
else:
if wxid:
# 机器人id
account_wxid = config.account_wxid
# 新增用户
new_user = utils.saveWxidInfo(account_wxid=config.account_wxid,wxid=wxid, h5openid=h5openid)
# "errmsg":r['errmsg'],,"errcode":r['errcode']
# return {"session_key":r['session_key'],"unionid":r['unionid'],"openid":r['openid']}
return new_user
# 加入微信群
@app.get("/joingroup")
# 群-异度星球 49187487591@chatroom chatroom
def read_users(wxid, db: Session = Depends(get_db)):
# debug
# chatroomId = '49187487591@chatroom'
# 判断是否在群中
inGroup = False
groupList = WXBotService.get_group_members_list(
robot_wxid=config.account_wxid, from_wxid=config.chatroomId)
print('groupList', groupList)
for groupItem in groupList['data']:
if groupItem['wxid'] == wxid:
inGroup = True
if inGroup:
return {"code": 200, "success": "fail", "message": "已经在群聊中"}
else:
WXBotService.add_group_members_40_more(
robot_wxid=config.account_wxid,
from_wxid=config.chatroomId, #异度星球群
new_wxid=wxid)
print('wxid--', wxid)
return {"code": 200, "success": "ok", "message": "群聊邀请已发送"}
# 加入微信群
@app.get("/h5group")
# 群-异度星球 49187487591@chatroom chatroom
def h5group(nickname, db: Session = Depends(get_db)):
newtext = unquote(nickname, 'utf-8')
pattern = r'收到(\w+)的在看'
print(newtext)
matches = re.findall(pattern, newtext)
if matches:
print("匹配到的结果:", matches)
# 判断是否在群中
inGroup = False
groupList = WXBotService.get_group_members_list(
robot_wxid=config.account_wxid, from_wxid=config.chatroomId)
# print('groupList', groupList)
for groupItem in groupList['data']:
if groupItem['nickname'] == matches:
inGroup = True
if inGroup:
return {"code": 200, "success": "fail", "message": "已经在群聊中"}
else:
new_wxid = None
allFriend = WXBotService.get_address_list(config.account_wxid)
for friendItem in allFriend['data']["contactList"]:
if friendItem['nickname'] == matches:
new_wxid = friendItem['wxid']
else:
# print('通过nickname查不到wxid')
pass
if new_wxid:
WXBotService.add_group_members_40_more(
robot_wxid=config.account_wxid,
from_wxid=config.chatroomId, #异度星球群
new_wxid=new_wxid)
print('new_wxid--', new_wxid)
return {"code": 200, "success": "ok", "message": "群聊邀请已发送"}
else:
return {"code": 200, "success": "ok", "message": "查不到nickname"}
else:
print("未找到匹配项,或者有特殊字符")
# 创建用户
@app.post("/users")
# schemas.UserCreate决定了swagger文档
def create_user(user: schemas.User, db: Session = Depends(get_db)):
print('user', user)
print('typeuser', type(user))
# 检测是否存在wxid
db_user = crud.get_user_by_wxid(db, user.wxid)
print('db_user', db_user)
if db_user:
raise HTTPException(status_code=400, detail="wxid already registered")
return crud.create_user(db=db, user=user)
# 分页查询-用户
@app.get("/users")
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
# 根据openId查询用户
@app.post("/openId")
def read_user(user: schemas.User, db: Session = Depends(get_db)):
db_user = crud.get_user_by_openId(db, openId=user.openId)
if db_user is None:
raise HTTPException(status_code=404, detail="openId not found")
return db_user
# 根据wxid查询用户
@app.get("/users")
def read_user(wxid, db: Session = Depends(get_db)):
db_user = crud.get_user_by_wxid(db, wxid=wxid)
if db_user is None:
raise HTTPException(status_code=404, detail="User-wxid not found")
return db_user
# 监听机器人http-get消息
@app.get("/wxbot")
def helloget(q: dict):
data = q
t = threading.Thread(target=kp, args=(data, )) # 通过当前线程开启新的线程去执行
t.start()
return json.dumps({"Code": 0})
# 监听机器人post日志消息
@app.post("/wxbot")
# def hellopost(requestData:schemas.User):
def hellopost(requestData: dict):
print('requestData---', requestData)
data = requestData
t = threading.Thread(target=kp, args=(data, )) # 通过当前线程开启新的线程去执行
t.start()
return json.dumps({"Code": 0})
def kp(event_data):
# unicode [\\uxxxxx] 转 emoji 表情
event_data = json.loads(
WXBotService.unicode_to_emoji(
json.dumps(event_data, ensure_ascii=False), 'json'))
kp_log = '' # 定义鲲鹏日志消息
event_type = event_data.get('event_type') #事件类型
account_wxid = event_data.get('account_wxid') #机器人id
data = event_data.get('data')
msg_type = data.get('msgtype') #消息类型
msg = data.get('content')
to_wxid = data.get('to_wxid') #发送给
to_name = data.get('to_name')
filepath = data.get("filepath")
subtype = data.get('subtype') #类型
thumbpath = data.get('thumbpath') #图片,存在电脑绝对路径
wxid = data.get('final_from_wxid') #消息来源用户
wx_name = data.get('final_from_name')
group = None if data.get('from_wxid') == wxid else data.get('from_wxid')
group_name = None if data.get('from_name') == wx_name else data.get(
'from_name')
'''event类型判断'''
if event_type == 1001: # 1001 创建WeChat进程成功通讯连接成功
kp_log = f'创建WeChat进程成功通讯连接成功'
elif event_type == 1002: # 1002 登录成功
kp_log = f'登录成功 {data.get("nickname")}{data.get("wxid")}'
elif event_type == 1003: # 1003 账号注销登录
kp_log = f'账号注销登录 {data.get("wxid")} {data.get("reason")}'
elif event_type == 1004: # 1004 切换聊天对象事件
kp_log = f'切换聊天对象事件 {data.get("nickname")}{data.get("wxid")}'
elif event_type == 1005: # 1005 切换联系人事件
kp_log = f'切换联系人事件 {data.get("nickname")}{data.get("wxid")}'
elif event_type == 1007: # 1005 二维码刷新事件
kp_log = f'二维码刷新事件 {data.get("qrcode")}'
elif event_type == 1008: # 1008 连接断开
kp_log = f'连接断开'
elif event_type == 1009: # 1009 群员退群通知
member_list = []
for member in data.get('memberlist'):
member_list.append(
f'{member.get("nickname")}{member.get("wxid")}')
kp_log = f'群员退群通知 {"".join(member_list)} 退出了群聊 {data.get("roomname")}{data.get("roomid")} ' \
f'人数:{data.get("membercount")}'
elif event_type == 1010: # 1010 群员进群通知
member_list = []
for member in data.get('memberlist'):
member_list.append(
f'{member.get("nickName")}{member.get("userName")}')
kp_log = f'群员进群通知 {"".join(member_list)} 加入了群聊 {data.get("roomname")}{data.get("roomid")}'
elif event_type == 1011: # 1011 收款消息
pay_msg = ET.fromstring(msg).find('paymsg')
pay_msg_type = pay_msg.findtext('PayMsgType')
if pay_msg_type == '9': # 二维码收款
status = pay_msg.findtext('status')
username = pay_msg.findtext('username')
display_name = pay_msg.findtext('displayname')
fee = pay_msg.findtext('fee')
if status == '0':
kp_log = f'收款消息 {display_name}{username} 扫描收款二维码'
elif status == '1':
kp_log = f'收款消息 {display_name}{username} 付款成功 {int(fee) / 100}'
elif status == '2':
kp_log = f'收款消息 {display_name}{username} 取消付款'
elif pay_msg_type == '45': # 貌似有未收款转账或转账红包过期会触发 42 和 45 类型
pass # kp_log = f'收款消息 {pay_msg.findtext("fromusername")} {pay_msg.findtext("content")}'
elif event_type == 1040: # 1040 撤回消息事件
if not group:
kp_log = f'撤回消息事件 {wx_name}{wxid} 撤回了 {msg}'
else:
kp_log = f'撤回消息事件 {wx_name}{wxid} 从群 {group_name}{group} 撤回了 {msg}'
elif event_type == 1100: # 1100 同步消息
if group:
type_str = f'同步消息 群聊消息 群聊:{group_name}{group} 发送者:{wx_name}{wxid}'
elif 'gh_' in wxid:
type_str = f'同步消息 公众号消息 {wx_name}{wxid}'
elif '@openim' in wxid:
type_str = f'同步消息 企业微信消息 {wx_name}{wxid}'
else:
type_str = f'同步消息 私聊消息 {wx_name}{wxid}'
if data.get('isSender') == 1:
# 手机发送还是电脑发送这里判断不是很准确
if to_wxid == account_wxid:
type_str = f'机器人手机端 发送的 ' + type_str
else:
type_str = f'机器人电脑端 发送的 ' + type_str
if msg_type == 1: # 1 文本消息/自带表情
kp_log = f'{type_str} 文本消息 内容:{msg}'
if msg in ['加群']:
# 将好友信息=>保存到数据库
newFriendDict = WXBotService.get_friend_info(
account_wxid, wxid)
# print('newFriendDict[data]---',newFriendDict['data'])
userClass = models.User(**(newFriendDict['data']))
# print('userClass====',type(userClass))
# crud.create_user(db=SessionLocal(),user=userClass)
# 保存好友信息
# utils.saveWxidInfo(account_wxid, wxid)
# 直接邀请加群>40
# WXBotService.add_group_members_40_more(robot_wxid='wxid_sfvsru738v3122',
# from_wxid='49187487591@chatroom',
# new_wxid='wxid_4413224132412')
# 发送小程序
# utils.sendminiProgram(data, account_wxid, wxid, planetXml)
# H5链接
WXBotService.send_link_message(
account_wxid,
wxid,
title="欢迎加入微信群",
desc="请查看规则",
url=f'https://link.hackrobot.cn#/pages/index/index?wxid={wxid}',
pic=
"https://www.hackrobot.cn/wp-content/uploads/2023/05/cropped-cropped-Screenshot-2023-05-22-at-17.26.38.png"
)
# if msg in ['腾讯云']:
# # 发送小程序
# utils.sendminiProgram(data, account_wxid, wxid, tengxunyunXml)
elif msg_type == 3: # 3 图片消息
kp_log = f'{type_str} 图片消息 内容:{filepath}'
# 本地dat图片解密
decrypt_path = WXBotService.local_decrypt_image(
filepath, os.path.join(os.getcwd(), '解密图片'))
print(f'{type_str} 图片消息 解密路径:{decrypt_path}')
elif msg_type == 34: # 34 语言消息(需要在设置中打开语言自动转文字)
xml_msg = ET.fromstring(msg)
kp_log = f'{type_str} 语音消息 内容:{xml_msg.find("voicetrans").get("transtext")}'
# elif msg_type == 37: # 37 好友请求
# xml_msg = ET.fromstring(msg)
# kp_log = f'同步消息 好友请求 {xml_msg.get("fromnickname")}{xml_msg.get("fromusername")} ' \
# f'验证内容:{xml_msg.get("content")}'
# # 同意好友请求
# WXBotService.agree_friend_request(account_wxid,
# xml_msg.get('alias'),
# xml_msg.get('encryptusername'),
# xml_msg.get('ticket'),
# xml_msg.get('scene'))
# newFriendWxid = xml_msg.get('alias')
# # 将好友信息=>保存到数据库
# # newFriendDict=WXBotService.get_friend_info(account_wxid, newFriendWxid)
# # userClass=models.User(**(newFriendDict['data']))
# # crud.create_user(db= SessionLocal(),user=userClass)
# newMsg = f'''你好,本消息是bot回复,本人是一名开发者,副业跨境电商,爱折腾homelab,参与交流请回复: 加群'''
# WXBotService.send_text_message(robot_wxid=account_wxid,
# from_wxid=newFriendWxid,
# msg=newMsg)
elif msg_type == 42: # 42 名片消息
xml_msg = ET.fromstring(msg)
kp_log = f'{type_str} 企业微信名片消息 {xml_msg.get("nickname")}{xml_msg.get("username")}'
elif msg_type == 43: # 43 视频消息
kp_log = f'{type_str} 视频消息 内容:{filepath}'
elif msg_type == 47: # 47 表情包
kp_log = f'{type_str} 表情包消息 网址:{ET.fromstring(msg).find("emoji").get("cdnurl".replace("amp;", ""))}'
# 本地下载图片
down_path = WXBotService.local_download_image(
msg, os.path.join(os.getcwd(), '下载图片'))
print(f'{type_str} 表情包消息 下载路径:{down_path}')
elif msg_type == 48: # 48 地理位置
kp_log = f'{type_str} 地理位置 内容:{msg}'
elif msg_type == 49: # 49 xml消息
# 获取根节点
root = ET.fromstring(msg)
xml_appmsg = root.find('appmsg')
xml_title = xml_appmsg.findtext('title')
xml_type = xml_appmsg.findtext('type')
xml_des = xml_appmsg.findtext('des')
xml_url = xml_appmsg.findtext('url')
if xml_type == '1': # 1 文本
kp_log = f'收到 {wxid} xml文本消息'
elif xml_type == '3': # 3 歌曲
kp_log = f'{type_str} 音乐消息 歌曲:{xml_title} 歌手:{xml_des} 网址:{xml_url}'
elif xml_type == '5': # 5 链接
kp_log = f'{type_str} 链接消息 标题:{xml_title} 内容:{xml_des} 网址:{xml_url}'
print("kp_log--------------------------------", msg)
# 本身也是系统消息-link,会无线循环
# 判断是不是自己发的消息
# if data.get('isSender') != 1:
# WXBotService.send_link_message(
# account_wxid, "wxid_w2imh7ki5s4q12", "title", "dec",
# "https://www.baidu.com",
# "https://p1-q.mafengwo.net/s17/M00/E3/9C/CoUBXl_cawCAQWMcAAGGhEoBcRU77.jpeg")
elif xml_type == '6': # 6 文件
kp_log = f'{type_str} 文件消息 文件名:{xml_title} 文件大小:{xml_des} 文件路径:{filepath}'
elif xml_type == '19': # 19 合并转发聊天记录
kp_log = f'{type_str} 合并转发聊天记录 文件名:{xml_title} 文件大小:{xml_des} 文件路径:{filepath}'
elif xml_type == '33': # 33 小程序
kp_log = f'{type_str} 小程序消息 小程序名:{xml_appmsg.findtext("sourcedisplayname")} 标题:{xml_title} ' \
f'appid{xml_appmsg.findtext("weappinfo/appid")} ' \
f'pagepath{xml_appmsg.findtext("weappinfo/pagepath")}'
print("---------------------------kp_log", msg)
elif xml_type == '57': # 引用消息
kp_log = f'{type_str} 引用消息 内容:{msg}'
elif xml_type == '2000': # 2000 转账消息
money = xml_appmsg.findtext('wcpayinfo/feedesc').replace(
'', '')
pay_subtype = xml_appmsg.findtext('wcpayinfo/paysubtype')
transfer_id = xml_appmsg.findtext('wcpayinfo/transferid')
if pay_subtype == '1':
kp_log = f'{type_str} 转账消息 {money}'
# 自动接收转账
WXBotService.transfer_receipt(account_wxid, wxid,
transfer_id)
elif pay_subtype == '3':
kp_log = f'{type_str} 已收款 {money} 元 转账'
elif msg_type == 66: # 66 企业微信名片消息
xml_msg = ET.fromstring(msg)
kp_log = f'企业微信名片消息 {xml_msg.get("nickname")}{xml_msg.get("username")}'
elif msg_type == 10000: # 10000 系统消息
kp_log = f'系统消息 {wx_name}{wxid} {msg}'
#获取通讯录
# allFriends=WXBotService.get_address_list(account_wxid)
# print('allFriends',allFriends)
# 发送H5链接
if not kp_log:
print(
'===================================================================================='
)
print(event_data)
print(
'===================================================================================='
)
else:
print(kp_log)