48 lines
1.9 KiB
Python
48 lines
1.9 KiB
Python
"""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/<action>', 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)
|