deleted: app.py
deleted: requirements.txt
deleted: run.bat
deleted: run.sh
deleted: src/__init__.py
deleted: src/mainprocess.py
This commit is contained in:
97
app.py
97
app.py
@ -1,97 +0,0 @@
|
|||||||
import logging
|
|
||||||
from flask import Flask, request, jsonify
|
|
||||||
from logging.handlers import RotatingFileHandler
|
|
||||||
from functools import wraps
|
|
||||||
from datetime import datetime
|
|
||||||
from src import mainprocess as src
|
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
#===rebot===#
|
|
||||||
# 处理私聊消息
|
|
||||||
# 处理群聊消息
|
|
||||||
@app.route('/', methods=["POST"])
|
|
||||||
def handle_event():
|
|
||||||
try:
|
|
||||||
event = request.get_json()
|
|
||||||
event_type = event.get('post_type')
|
|
||||||
|
|
||||||
# 1. 处理私聊消息
|
|
||||||
if event_type == 'message' and event.get('message_type') == 'private':
|
|
||||||
# 注意:私聊消息在顶层有 user_id
|
|
||||||
uid = event.get('user_id')
|
|
||||||
message = event.get('raw_message')
|
|
||||||
src.process_message(uid, None, message)
|
|
||||||
|
|
||||||
# 2. 处理群消息
|
|
||||||
elif event_type == 'message' and event.get('message_type') == 'group':
|
|
||||||
gid = event.get('group_id')
|
|
||||||
# 注意:群消息发送者在 sender 内
|
|
||||||
sender = event.get('sender', {})
|
|
||||||
uid = sender.get('user_id')
|
|
||||||
message = event.get('raw_message')
|
|
||||||
src.process_message(uid, gid, message)
|
|
||||||
|
|
||||||
# 3. 处理通知事件(如输入状态)
|
|
||||||
elif event_type == 'notice':
|
|
||||||
notice_type = event.get('notice_type')
|
|
||||||
|
|
||||||
if notice_type == 'notify' and event.get('sub_type') == 'input_status':
|
|
||||||
# 仅记录,不处理
|
|
||||||
logging.info(f"用户 {event.get('user_id')} 输入状态变化")
|
|
||||||
|
|
||||||
elif notice_type == 'group_recall':
|
|
||||||
# 示例:处理群消息撤回
|
|
||||||
logging.info(f"群 {event.get('group_id')} 撤回消息")
|
|
||||||
|
|
||||||
else:
|
|
||||||
# 其他通知类型
|
|
||||||
logging.info(f"Ignored notice: {event}")
|
|
||||||
|
|
||||||
# 通知事件直接返回成功
|
|
||||||
return jsonify({
|
|
||||||
"status": "ok",
|
|
||||||
"retcode": 0,
|
|
||||||
"data": None
|
|
||||||
})
|
|
||||||
|
|
||||||
# 4. 处理元事件(如心跳)
|
|
||||||
elif event_type == 'meta_event':
|
|
||||||
# 心跳等元事件直接返回成功
|
|
||||||
return jsonify({
|
|
||||||
"status": "ok",
|
|
||||||
"retcode": 0,
|
|
||||||
"data": None
|
|
||||||
})
|
|
||||||
|
|
||||||
# 5. 一切正常的消息事件返回成功
|
|
||||||
return jsonify({
|
|
||||||
"status": "ok",
|
|
||||||
"retcode": 0,
|
|
||||||
"data": "Processed successfully"
|
|
||||||
})
|
|
||||||
|
|
||||||
except KeyError:
|
|
||||||
logging.warning(f"Missing required field in event: {event}")
|
|
||||||
return jsonify({
|
|
||||||
"status": "failed",
|
|
||||||
"retcode": 10001,
|
|
||||||
"message": "Missing required field"
|
|
||||||
}), 400
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception(f"Error processing event: {str(e)}")
|
|
||||||
return jsonify({
|
|
||||||
"status": "failed",
|
|
||||||
"retcode": 20001,
|
|
||||||
"message": "Internal server error"
|
|
||||||
}), 500
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
port = 25580
|
|
||||||
app.run(debug=True, host='0.0.0.0', port=port)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"启动失败: {e}")
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
blinker==1.9.0
|
|
||||||
certifi==2025.8.3
|
|
||||||
charset-normalizer==3.4.2
|
|
||||||
click==8.2.1
|
|
||||||
colorama==0.4.6
|
|
||||||
Flask==3.1.1
|
|
||||||
idna==3.10
|
|
||||||
itsdangerous==2.2.0
|
|
||||||
Jinja2==3.1.6
|
|
||||||
MarkupSafe==3.0.2
|
|
||||||
packaging==25.0
|
|
||||||
pkg==0.2
|
|
||||||
requests==2.32.4
|
|
||||||
toml==0.10.2
|
|
||||||
urllib3==2.5.0
|
|
||||||
Werkzeug==3.1.3
|
|
||||||
74
run.bat
74
run.bat
@ -1,74 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
|
|
||||||
set PROJECT_DIR=%~dp0
|
|
||||||
set VENV_DIR=%PROJECT_DIR%.venv
|
|
||||||
|
|
||||||
|
|
||||||
if exist "%VENV_DIR%\Scripts\activate.bat" (
|
|
||||||
|
|
||||||
call "%VENV_DIR%\Scripts\activate.bat"
|
|
||||||
) else (
|
|
||||||
|
|
||||||
python -m venv "%VENV_DIR%"
|
|
||||||
call "%VENV_DIR%\Scripts\activate.bat"
|
|
||||||
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo error: fail to create env
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if "%VIRTUAL_ENV%" == "" (
|
|
||||||
echo error: fail to activate env
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
echo installing dependence...
|
|
||||||
|
|
||||||
pip install -r requirements.txt
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo error: fail to install dependence
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
pip install waitress
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo error: fail to install waitress
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
echo reading port from config...
|
|
||||||
for /f "usebackq tokens=*" %%P in (`python -c "from src.file_store_api import ConfigManager; config=ConfigManager().load_config(); print(config.get('app', {}).get('list_port', 25580))"`) do (
|
|
||||||
set PORT=%%P
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if "%PORT%"=="" (
|
|
||||||
set PORT=25580
|
|
||||||
echo can't read port,use custom port:25580
|
|
||||||
) else (
|
|
||||||
echo success read port: %PORT%
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
echo starting rebot_server...
|
|
||||||
echo listening at: %PORT%
|
|
||||||
|
|
||||||
|
|
||||||
waitress-serve --host=0.0.0.0 --port=%PORT% app:app
|
|
||||||
|
|
||||||
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo error,fail to start
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
pause
|
|
||||||
51
run.sh
51
run.sh
@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
PROJECT_DIR=$(cd "$(dirname "$0")"; pwd)
|
|
||||||
VENV_DIR="$PROJECT_DIR/.venv"
|
|
||||||
FLASK_APP="app:app"
|
|
||||||
|
|
||||||
|
|
||||||
echo "Activating virtual environment..."
|
|
||||||
|
|
||||||
if [ -f "$VENV_DIR/bin/activate" ]; then
|
|
||||||
source "$VENV_DIR/bin/activate"
|
|
||||||
else
|
|
||||||
echo "Creating new virtual environment..."
|
|
||||||
python3 -m venv "$VENV_DIR"
|
|
||||||
source "$VENV_DIR/bin/activate"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$VIRTUAL_ENV" ]; then
|
|
||||||
echo "Error: Failed to activate virtual environment"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Installing dependencies..."
|
|
||||||
pip install --upgrade pip
|
|
||||||
pip install -r requirements.txt
|
|
||||||
pip install gunicorn
|
|
||||||
|
|
||||||
echo "Reading port from configuration..."
|
|
||||||
|
|
||||||
PORT=$(python3 -c \
|
|
||||||
"
|
|
||||||
from src.file_store_api import ConfigManager
|
|
||||||
try:
|
|
||||||
config = ConfigManager().load_config()
|
|
||||||
port = config.get('app', {}).get('list_port')
|
|
||||||
print(str(port) if port else '')
|
|
||||||
except Exception as e:
|
|
||||||
print('ERROR: ' + str(e))
|
|
||||||
exit(1)
|
|
||||||
")
|
|
||||||
|
|
||||||
if [[ "$PORT" == ERROR:* ]] || [ -z "$PORT" ]; then
|
|
||||||
echo "Failed to get port from config: $PORT"
|
|
||||||
echo "Using default port 25580"
|
|
||||||
PORT=25580
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Starting rebot server..."
|
|
||||||
echo "Listening on port: $PORT"
|
|
||||||
|
|
||||||
gunicorn -w 4 -b 0.0.0.0:$PORT "$FLASK_APP" --access-logfile - --error-logfile -
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
import sys
|
|
||||||
import src.modules.user_modules as usermod
|
|
||||||
from src.modules.plugin_modules import BasePlugin, MessageContext
|
|
||||||
import src.file_store_api as file_M
|
|
||||||
import src.plugin_manager as plm
|
|
||||||
|
|
||||||
manager = plm.PluginManager()
|
|
||||||
config = file_M.ConfigManager()
|
|
||||||
rebot_id = config.load_config().get("rebot").get("id")
|
|
||||||
def process_message(uid: str, gid: str | None, message: str) -> str:
|
|
||||||
# 创建上下文
|
|
||||||
ctx = MessageContext(uid=uid, gid=gid, raw_message=message,id = rebot_id)
|
|
||||||
|
|
||||||
plugin_manager = manager
|
|
||||||
manager.scan_plugins()
|
|
||||||
# 阶段1: before_load 插件(加载数据前)
|
|
||||||
ctx.phase = "before_load"
|
|
||||||
early_plugins = []
|
|
||||||
for name, plugin_cls in plugin_manager._plugins.items():
|
|
||||||
plugin = plugin_cls(ctx)
|
|
||||||
if hasattr(plugin, 'before_load') and callable(plugin.before_load):
|
|
||||||
early_plugins.append(plugin)
|
|
||||||
|
|
||||||
for plugin in early_plugins:
|
|
||||||
try:
|
|
||||||
result = plugin.before_load()
|
|
||||||
if result is not None: # 拦截逻辑
|
|
||||||
return result
|
|
||||||
except Exception as e:
|
|
||||||
print(f"error:Plugin {plugin.__class__.__name__} before_load error: {str(e)}")
|
|
||||||
|
|
||||||
# 消息加载逻辑
|
|
||||||
if gid is not None:
|
|
||||||
ctx.group.messages = ctx.chat_manager.load_group_messages(ctx.group)
|
|
||||||
ctx.user.messages = ctx.chat_manager.load_user_group_messages(user=ctx.user, group=ctx.group)
|
|
||||||
else:
|
|
||||||
ctx.user.messages = ctx.chat_manager.load_private_messages(ctx.user)
|
|
||||||
|
|
||||||
# 阶段2: after_load 插件(加载数据后)
|
|
||||||
ctx.phase = "after_load"
|
|
||||||
loaded_plugins = []
|
|
||||||
for name, plugin_cls in plugin_manager._plugins.items():
|
|
||||||
plugin = plugin_cls(ctx)
|
|
||||||
if hasattr(plugin, 'after_load') and callable(plugin.after_load):
|
|
||||||
loaded_plugins.append(plugin)
|
|
||||||
|
|
||||||
for plugin in loaded_plugins:
|
|
||||||
try:
|
|
||||||
result = plugin.after_load()
|
|
||||||
if result is not None:
|
|
||||||
ctx.response = result
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
print(f"error:Plugin {plugin.__class__.__name__} after_load error: {str(e)}")
|
|
||||||
|
|
||||||
# 消息保存逻辑
|
|
||||||
if gid is not None:
|
|
||||||
ctx.chat_manager.save_group_message(ctx.group, role="user", content=ctx.raw_message, sender_id=ctx.user.user_id)
|
|
||||||
else:
|
|
||||||
ctx.chat_manager.save_private_message(ctx.user, role="user", content=ctx.raw_message)
|
|
||||||
|
|
||||||
# 阶段3: after_save 插件(保存数据后)
|
|
||||||
ctx.phase = "after_save"
|
|
||||||
saved_plugins = []
|
|
||||||
for name, plugin_cls in plugin_manager._plugins.items():
|
|
||||||
plugin = plugin_cls(ctx)
|
|
||||||
if hasattr(plugin, 'after_save') and callable(plugin.after_save):
|
|
||||||
saved_plugins.append(plugin)
|
|
||||||
|
|
||||||
for plugin in saved_plugins:
|
|
||||||
try:
|
|
||||||
result = plugin.after_save()
|
|
||||||
if result is not None and ctx.response is None:
|
|
||||||
ctx.response = result
|
|
||||||
except Exception as e:
|
|
||||||
print(f"error:Plugin {plugin.__class__.__name__} after_save error: {str(e)}")
|
|
||||||
plugin_manager.cleanup()
|
|
||||||
|
|
||||||
return ctx.response if ctx.response is not None else "ok"
|
|
||||||
Reference in New Issue
Block a user