@@ -1,11 +1,11 @@ | |||
from flask import Flask, send_from_directory, request,jsonify | |||
from flask_restful import Api,got_request_exception | |||
from resources.user_resource import UserResource | |||
from resources.messages_resource import MessagesResource | |||
from resources.contacts_resources import DeleteFriendResource,GetFriendsInfoResource | |||
from resources.config_reources import GetWxchatConfigResource ,SaveWxchatConfigResource | |||
from resources.groups_resources import GetGroupsInfoResource | |||
from resources.login_resources import GetLoginInfoResource | |||
from resources.sns_resources import SendSNSTextResource,SendSNSImageResource, SendSNSVideoResource | |||
from common.log import logger, log_exception | |||
from common.interceptors import before_request, after_request, handle_exception | |||
import threading | |||
@@ -196,8 +196,6 @@ app.after_request(after_request) | |||
app.register_error_handler(Exception, handle_exception) | |||
# 定义路由 | |||
flask_api.add_resource(UserResource, '/api/user', '/api/user/<int:user_id>') | |||
flask_api.add_resource(MessagesResource, '/messages') | |||
@@ -211,14 +209,14 @@ flask_api.add_resource(GetGroupsInfoResource, '/api/groups/getchatroominfo') | |||
flask_api.add_resource(GetLoginInfoResource, '/api/agent/getlogin') | |||
flask_api.add_resource(SendSNSTextResource, '/api/sns/sendtext') | |||
flask_api.add_resource(SendSNSImageResource, '/api/sns/sendimages') | |||
flask_api.add_resource(SendSNSVideoResource, '/api/sns/sendvideo') | |||
load_config() | |||
worker() | |||
if __name__ == '__main__': | |||
# 获取环境变量 | |||
environment = os.environ.get('environment', 'default') | |||
@@ -1,7 +1,9 @@ | |||
from functools import wraps | |||
import time | |||
from flask import request, g, jsonify, make_response,current_app | |||
from common.log import logger | |||
from datetime import datetime | |||
from common import utils,redis_helper | |||
# 定义生成失败响应的函数 | |||
def fail_response(code, error_message): | |||
@@ -53,3 +55,38 @@ def handle_exception(error): | |||
response = jsonify({'message': str(error)}) | |||
response.status_code = 500 | |||
return response | |||
def auth_required_time(f): | |||
@wraps(f) | |||
def decorated_function(*args, **kwargs): | |||
req = request.get_json() | |||
wxid = req.get("wxid") | |||
if not wxid: | |||
response=jsonify({'code': 400, 'message': '缺少wxid参数'}) | |||
response.status_code = 400 | |||
return response | |||
k, login_info = utils.get_login_info_by_wxid(wxid) | |||
if not login_info or login_info.get('status') == "0": | |||
response=jsonify({'code': 401, 'message': '用户没有登录'}) | |||
response.status_code = 401 | |||
return response | |||
# 获取登录信息的创建时间 | |||
creation_timestamp=int(login_info.get('create_at')) | |||
current_timestamp = time.time() | |||
three_days_seconds = 3 * 24 * 60 * 60 # 三天的秒数 | |||
diff_flag=(current_timestamp - creation_timestamp) >= three_days_seconds | |||
print(f"creation_timestamp:{creation_timestamp},current_timestamp:{current_timestamp},diff_flag:{diff_flag}") | |||
if not diff_flag: | |||
response=jsonify({'code': 401, 'message': '用户创建不够三天,不能使用该功能'}) | |||
response.status_code = 401 | |||
return response | |||
# # # 将认证信息注入请求环境变量 | |||
request.environ['token_id'] = login_info.get('tokenId') | |||
request.environ['app_id'] = login_info.get('appId') | |||
return f(*args, **kwargs) | |||
return decorated_function |
@@ -103,7 +103,8 @@ class MessagesResource(Resource): | |||
logger.warning(f'微信ID {wxid}在设备{app_id}已经离线') | |||
k,r=get_login_info_by_app_id(app_id) | |||
print(k) | |||
redis_helper.redis_helper.update_hash_field(k,'status',0) | |||
redis_helper.redis_helper.update_hash_field(k,'status',0) | |||
redis_helper.redis_helper.update_hash_field(k,'modify_at',int(time.time())) | |||
else: | |||
logger.warning(f"未知消息类型") | |||
@@ -1,6 +1,92 @@ | |||
from flask_restful import Resource, reqparse | |||
from common.interceptors import auth_required_time | |||
from flask import jsonify,request | |||
from common import redis_helper,utils | |||
from wechat import gewe_chat | |||
class SendSNSTextResource(Resource): | |||
def __init__(self): | |||
self.parser = reqparse.RequestParser() | |||
self.wxchat = gewe_chat.wxchat | |||
@auth_required_time | |||
def post(self): | |||
req = request.get_json() | |||
content = req.get("content") | |||
ret, msg, data = self.wxchat.send_text_sns(request.environ['token_id'], request.environ['app_id'], content) | |||
if ret != 200: | |||
response = jsonify({ | |||
'code': ret, | |||
'message': msg | |||
}) | |||
# response.status_code = ret | |||
return response | |||
return jsonify(data) | |||
class SendSNSImageResource(Resource): | |||
def __init__(self): | |||
self.parser = reqparse.RequestParser() | |||
self.wxchat = gewe_chat.wxchat | |||
@auth_required_time | |||
def post(self): | |||
req = request.get_json() | |||
content = req.get("content","") | |||
image_urls=req.get("imageUrls",[]) | |||
ret, msg, data = self.wxchat.upload_sns_image(request.environ['token_id'], request.environ['app_id'], image_urls) | |||
if ret != 200: | |||
response = jsonify({ | |||
'code': ret, | |||
'message': msg | |||
}) | |||
# response.status_code = ret | |||
return response | |||
ret, msg, data = self.wxchat.send_image_sns(request.environ['token_id'], request.environ['app_id'], content,data) | |||
if ret != 200: | |||
response = jsonify({ | |||
'code': ret, | |||
'message': msg | |||
}) | |||
# response.status_code = ret | |||
return response | |||
return jsonify(data) | |||
class SendSNSVideoResource(Resource): | |||
def __init__(self): | |||
self.parser = reqparse.RequestParser() | |||
self.wxchat = gewe_chat.wxchat | |||
@auth_required_time | |||
def post(self): | |||
req = request.get_json() | |||
content = req.get("content","") | |||
video_url=req.get("videoUrl","") | |||
video_thumb_url=req.get("videoThumbUrl","") | |||
ret, msg, data = self.wxchat.upload_sns_video(request.environ['token_id'], request.environ['app_id'], video_url,video_thumb_url) | |||
if ret != 200: | |||
response = jsonify({ | |||
'code': ret, | |||
'message': msg | |||
}) | |||
# response.status_code = ret | |||
return response | |||
ret, msg, data = self.wxchat.send_video_sns(request.environ['token_id'], request.environ['app_id'], content,data) | |||
if ret != 200: | |||
response = jsonify({ | |||
'code': ret, | |||
'message': msg | |||
}) | |||
# response.status_code = ret | |||
return response | |||
return jsonify(data) |
@@ -1,32 +0,0 @@ | |||
from flask_restful import Resource, reqparse | |||
from flask import jsonify | |||
class UserResource(Resource): | |||
def __init__(self): | |||
self.parser = reqparse.RequestParser() | |||
self.parser.add_argument('name', type=str, required=True, help='Name cannot be blank') | |||
self.parser.add_argument('email', type=str, required=True, help='Email cannot be blank') | |||
def get(self, user_id): | |||
# 模拟获取用户逻辑 | |||
# 在实际应用中,你可能会从数据库中获取用户数据 | |||
return jsonify({'user_id': user_id, 'name': 'John Doe', 'email': 'john@example.com'}) | |||
def post(self): | |||
args = self.parser.parse_args() | |||
# 模拟创建用户逻辑 | |||
# 在实际应用中,你可能会将用户数据插入数据库 | |||
print(args); | |||
# return jsonify({'message': 'User created', 'user': args}), 201 | |||
return jsonify({'message': 'User created', 'user': args}) | |||
def put(self, user_id): | |||
args = self.parser.parse_args() | |||
# 模拟更新用户逻辑 | |||
# 在实际应用中,你可能会更新数据库中的用户数据 | |||
return jsonify({'message': 'User updated', 'user_id': user_id, 'user': args}) | |||
def delete(self, user_id): | |||
# 模拟删除用户逻辑 | |||
# 在实际应用中,你可能会从数据库中删除用户数据 | |||
return jsonify({'message': 'User deleted', 'user_id': user_id}) |
@@ -315,11 +315,15 @@ def login_or_reconnect(wxchat:gewe_chat.GeWeChatCom, token_id, app_id, hash_key, | |||
# todo | |||
if flag == 2: | |||
logger.info(f"登录成功: {res}") | |||
head_img_url=res.get('headImgUrl','') | |||
login_info = res.get('loginInfo', {}) | |||
login_info.update({'appId': app_id, 'uuid': uuid, 'tokenId': token_id,'status': 1}) | |||
# cache_login_info=redis_helper.redis_helper.get_hash(hash_key) | |||
login_info.update({'appId': app_id, 'uuid': uuid, 'tokenId': token_id,'status': 1,'headImgUrl':head_img_url}) | |||
cache_login_info=redis_helper.redis_helper.get_hash(hash_key) | |||
if 'appId' not in cache_login_info: | |||
login_info.update({"create_at":int(time.time()),"modify_at":int(time.time())}) | |||
else: | |||
login_info.update({"modify_at":int(time.time())}) | |||
# if 'appId' in cache_login_info: | |||
# login_info.update({"reg_time":datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3],"login_time":datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]}) | |||
# else: | |||
@@ -543,6 +543,7 @@ class GeWeChatCom: | |||
return response_object.get('ret',None),response_object.get('msg',None),response_object.get('data',None) | |||
############################### 朋友圈模块 ################################### | |||
# 在新设备登录后的1-3天内,您将无法使用朋友圈发布、点赞、评论等功能。在此期间,如果尝试进行这些操作,您将收到来自微信团队的提醒。请注意遵守相关规定。 | |||
def sns_visible_scope(self, token_id, app_id,option): | |||
''' | |||
@@ -603,23 +604,52 @@ class GeWeChatCom: | |||
response_object = response.json() | |||
return response_object.get('ret',None),response_object.get('msg',None),response_object.get('data',None) | |||
def send_image_sns(self, token_id, app_id,infos:list): | |||
def send_image_sns(self, token_id, app_id,content,img_infos:list): | |||
''' | |||
发送图片朋友圈 | |||
''' | |||
api_url = f"{self.base_url}/v2/api/sns/sendImageSns" | |||
api_url = f"{self.base_url}/v2/api/sns/sendImgSns" | |||
print(api_url) | |||
headers = { | |||
'X-GEWE-TOKEN': token_id, | |||
'Content-Type': 'application/json' | |||
} | |||
data = { | |||
"appId": app_id, | |||
"imgInfos": infos # 通过上传朋友圈图片接口获取 | |||
"allowWxIds": [], | |||
"atWxIds": [], | |||
"disableWxIds": [], | |||
"content":content, | |||
"imgInfos": img_infos, # 通过上传朋友圈图片接口获取 | |||
"privacy": False | |||
} | |||
response = requests.post(url=api_url, headers=headers, data=json.dumps(data)) | |||
response_object = response.json() | |||
print(response_object) | |||
return response_object.get('ret',None),response_object.get('msg',None),response_object.get('data',None) | |||
def send_video_sns(self, token_id, app_id,content:str,video_info:object): | |||
''' | |||
发送视频朋友圈 | |||
''' | |||
api_url = f"{self.base_url}/v2/api/sns/sendVideoSns" | |||
headers = { | |||
'X-GEWE-TOKEN': token_id, | |||
'Content-Type': 'application/json' | |||
} | |||
data = { | |||
"appId": app_id, | |||
"content":content, | |||
"allowWxIds": [], | |||
"atWxIds": [], | |||
"disableWxIds": [], | |||
"videoInfo":video_info, | |||
"privacy": False | |||
} | |||
response = requests.post(url=api_url, headers=headers, data=json.dumps(data)) | |||
response_object = response.json() | |||
return response_object.get('ret',None),response_object.get('msg',None),response_object.get('data',None) | |||
def upload_sns_image(self, token_id, app_id,img_urls:list): | |||
''' | |||
上传朋友圈图片 | |||
@@ -637,7 +667,24 @@ class GeWeChatCom: | |||
response_object = response.json() | |||
return response_object.get('ret',None),response_object.get('msg',None),response_object.get('data',None) | |||
def upload_sns_video(self, token_id, app_id,video_url:str,video_thumb_url:str): | |||
''' | |||
上传朋友圈视频 | |||
''' | |||
api_url = f"{self.base_url}/v2/api/sns/uploadSnsVideo" | |||
headers = { | |||
'X-GEWE-TOKEN': token_id, | |||
'Content-Type': 'application/json' | |||
} | |||
data = { | |||
"appId": app_id, | |||
"thumbUrl": video_thumb_url, | |||
"videoUrl": video_url, | |||
} | |||
response = requests.post(url=api_url, headers=headers, data=json.dumps(data)) | |||
response_object = response.json() | |||
return response_object.get('ret',None),response_object.get('msg',None),response_object.get('data',None) | |||
############################### 其他 ############################### | |||
def save_session_messages_to_cache(self, hash_key,item:object)->list: | |||
''' | |||
@@ -667,7 +714,7 @@ class GeWeChatCom: | |||
messages.append(item) | |||
redis_helper.redis_helper.set_hash(hash_key,{"data":json.dumps(messages,ensure_ascii=False)},600) | |||
return messages | |||
def get_contacts_brief_from_cache(self, wxid)->list: | |||
""" | |||
获取联系人信息保存到 Redis 缓存。 | |||