-
Notifications
You must be signed in to change notification settings - Fork 7
/
app.py
178 lines (142 loc) · 5.42 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# encoding:utf-8
import os
import signal
import sys
import time
from channel import channel_factory
from common import const
from config import load_config
from plugins import *
import threading
from quart import jsonify,render_template,send_file
import concurrent.futures
import asyncio
from channel.wechat.wechat_message import *
from channel.wechat.wechat_channel import message_handler,WechatChannel
from quart import Quart, request, Response
import traceback
quart_app = Quart(__name__)
max_worker = 5
def sigterm_handler_wrap(_signo):
old_handler = signal.getsignal(_signo)
def func(_signo, _stack_frame):
logger.info("signal {} received, exiting...".format(_signo))
conf().save_user_datas()
if callable(old_handler): # check old_handler
return old_handler(_signo, _stack_frame)
sys.exit(0)
signal.signal(_signo, func)
def start_channel(channel_name: str):
channel = channel_factory.create_channel(channel_name)
if channel_name in ["wx", "wxy", "terminal", "wechatmp", "wechatmp_service", "wechatcom_app", "wework",
const.FEISHU, const.DINGTALK]:
PluginManager().load_plugins()
if conf().get("use_linkai"):
try:
from common import linkai_client
threading.Thread(target=linkai_client.start, args=(channel,)).start()
except Exception as e:
pass
channel.startup()
def run():
try:
# load config
load_config()
# ctrl + c
sigterm_handler_wrap(signal.SIGINT)
# kill signal
sigterm_handler_wrap(signal.SIGTERM)
# create channel
channel_name = conf().get("channel_type", "wx")
if "--cmd" in sys.argv:
channel_name = "terminal"
if channel_name == "wxy":
os.environ["WECHATY_LOG"] = "warn"
start_channel(channel_name)
#while True:
# time.sleep(1)
except Exception as e:
logger.error("App startup failed!")
logger.exception(e)
run()
@quart_app.route("/chat", methods=["POST"])
async def chat():
# 类常量
FAILED_MSG = '{"success": false}'
SUCCESS_MSG = '{"success": true}'
MESSAGE_RECEIVE_TYPE = "8001"
ch = WechatChannel()
try:
try:
msg = await request.get_json()
logger.debug(f"[Wechat] receive request: {msg}")
except Exception as e:
logger.error(e)
return FAILED_MSG
try:
cmsg = WechatMessage(msg, True)
except NotImplementedError as e:
logger.debug("[WX]group message {} skipped: {}".format(msg["msg_id"], e))
return None
with concurrent.futures.ThreadPoolExecutor(max_workers=max_worker):
asyncio.create_task(
#.handle_group(cmsg)
message_handler(cmsg, ch)
).add_done_callback(callback)
# return a response
return Response("Message received", mimetype='text/plain')
except Exception as error:
logger.error("".join(traceback.format_exc()))
traceback.print_exc()
logger.error(f"An error occurred: {error}")
return Response(str(error), mimetype='text/plain')
@quart_app.route('/pic/<path:filename>')
async def serve_pic(filename):
return await send_file(f'pic/{filename}')
def callback(worker):
worker_exception = worker.exception()
if worker_exception:
logger.error(worker_exception)
@quart_app.route("/rooms", methods=["GET"])
def rooms():
response_data = iPadWx().get_room_list() # assuming this returns a list of room names
data = response_data.get("data")
if data:
if isinstance(data,dict):
return render_template('dict.html', data=data)
elif isinstance(data,list):
#return render_template('list.html', data=data)
return jsonify(data)
else:
return jsonify({"code": 0,"response":"签到成功"})
return jsonify({"code": -1,"response":"获取房间列表失败"})
@quart_app.route("/send_msg", methods=["GET"])
def send_msg():
to_id = request.args.get('to_id')
text = request.args.get('text')
at_id = request.args.get('at_id')
if not to_id or not text:
return jsonify({"code": -1, "message": "Both 'to_id' and 'text' parameters are required."}), 400
if at_id:
displayName, nickname = iPadWx().get_chatroom_nickname(to_id, at_id)
content = "@"+nickname+" "+text
result = iPadWx().send_at_msg(to_id=to_id,at_ids=at_id,nickname=nickname, content=content)
else:
result = iPadWx().send_txt_msg(to_id=to_id, text=text)
if result:
return jsonify({"code": 0, "message": "Message sent successfully."})
else:
return jsonify({"code": -1, "message": "Failed to send message."}), 500
if __name__ == "__main__":
'''
todo 1 将web框架修改为flask 或者Quart OK
todo 2 接收图片时判断是否为空,如果为空,则发送提醒 OK
todo 3 发送超过1024时,要分段发送
todo 4 画图时,结果可以at 并显示提示词。yes
todo 5 画图时,先发送一个等待消息,提示正在处理中 NA
todo 6 help和菜单功能
todo 7 多个API接入点,如何切换和检查错误,主动屏蔽经常不可用服务器 。 功能和模型对应
todo 8 部署到香港服务器
'''
port = conf().get("wechatipad_port", 5711)
quart_app.run("0.0.0.0", port, use_reloader=False,debug=True)