from rest_framework import serializers, status, views from rest_framework.response import Response from rest_framework.decorators import api_view from .models import Instance, MeetingInstanceMap from .webhook import register_instance, join_meeting import logging logger = logging.getLogger(__name__) class InstanceRegisterSerializer(serializers.Serializer): instance_id = serializers.CharField(max_length=100) instance_name = serializers.CharField(max_length=200) agent_ids = serializers.ListField(child=serializers.CharField()) webhook_url = serializers.URLField() class InstanceRegisterView(views.APIView): """ 实例注册接口 POST /api/v1/instances/register/ { "instance_id": "phospher-openclaw", "instance_name": "飞行侠的 OpenClaw", "agent_ids": ["flying_hero", "lobster_monitor"], "webhook_url": "http://192.168.1.100:8888/meeting-notify" } """ def post(self, request): serializer = InstanceRegisterSerializer(data=request.data) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) try: instance = register_instance( instance_id=serializer.validated_data['instance_id'], instance_name=serializer.validated_data['instance_name'], agent_ids=serializer.validated_data['agent_ids'], webhook_url=serializer.validated_data['webhook_url'] ) return Response({ 'status': 'success', 'instance_id': str(instance.id), 'message': f'实例 {instance.instance_name} 注册成功' }) except Exception as e: logger.error(f"注册失败:{e}") return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class MeetingJoinSerializer(serializers.Serializer): instance_id = serializers.CharField(max_length=100) meeting_id = serializers.UUIDField() agent_ids = serializers.ListField(child=serializers.CharField()) class MeetingJoinView(views.APIView): """ 实例加入会议 POST /api/v1/instances/join-meeting/ { "instance_id": "phospher-openclaw", "meeting_id": "xxx-xxx-xxx", "agent_ids": ["flying_hero"] } """ def post(self, request): serializer = MeetingJoinSerializer(data=request.data) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) try: join_meeting( instance_id=serializer.validated_data['instance_id'], meeting_id=serializer.validated_data['meeting_id'], agent_ids=serializer.validated_data['agent_ids'] ) return Response({'status': 'success', 'message': '已加入会议'}) except Instance.DoesNotExist: return Response({'error': '实例不存在'}, status=status.HTTP_404_NOT_FOUND) except Exception as e: logger.error(f"加入会议失败:{e}") return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class InstanceListView(views.APIView): """ 获取实例列表 GET /api/v1/instances/ """ def get(self, request): instances = Instance.objects.filter(is_active=True) data = [{ 'id': str(i.id), 'instance_id': i.instance_id, 'instance_name': i.instance_name, 'agent_ids': i.agent_ids, 'webhook_url': i.webhook_url, 'last_heartbeat': i.last_heartbeat.isoformat() if i.last_heartbeat else None } for i in instances] return Response(data) class WebhookNotifyView(views.APIView): """ Webhook 通知接收(测试用) POST /api/v1/instances/webhook-test/ """ def post(self, request): logger.info(f"📬 收到 Webhook 通知:{request.data}") return Response({'status': 'received'})