"""Guest bootstrap and owner-checked human support adapters, separate from staff APIs.""" from flask import Blueprint, current_app, request from werkzeug.exceptions import RequestEntityTooLarge from .. import human_service, visitor_service bp = Blueprint('visitor', __name__) @bp.post('/api/visitor/session') def visitor_session(): request.max_content_length = 1024 try: return visitor_service.start_session(request.get_json(silent=True)) except RequestEntityTooLarge: return {'ok': False, 'error': '访客会话格式无效。'}, 413 @bp.route('/api/visitor/human/', methods=['GET', 'POST']) def visitor_human(action): methods = {'poll': 'GET', 'request': 'POST', 'send': 'POST', 'close': 'POST'} if action not in methods or request.method != methods[action]: return {'ok': False}, 404 data = request.get_json(silent=True) if request.method == 'POST' else {} if not isinstance(data, dict): return {'ok': False}, 400 if action == 'request': if not visitor_service.owns_conversation(data.get('conv_id')): return {'ok': False, 'error': 'conversation_not_found'}, 404 return human_service.human_request(data) sid = request.args.get('sid', type=int) if action == 'poll' else data.get('sid') if not visitor_service.owns_human_session(sid): return {'ok': False, 'error': 'session_not_found'}, 404 if action == 'poll': after = request.args.get('after', 0, type=int) if not 0 <= after <= 9223372036854775807: return {'ok': False}, 400 result = human_service.human_poll(sid, after, current_app.extensions['human_typing']) result.pop('note', None) return result if action == 'send': if data.get('side', 'customer') != 'customer': return {'ok': False}, 403 return human_service.human_send({**data, 'side': 'customer'}) return human_service.human_close(data)