Files
hossein-por-shop/backend/chat/views.py
T
2025-05-22 14:23:54 +03:30

162 lines
5.9 KiB
Python

from django.core.paginator import Paginator
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from django.db.models import Q
from time import sleep
import json
from drf_spectacular.utils import (
extend_schema,
extend_schema_view,
OpenApiParameter,
OpenApiExample,
)
from rest_framework import serializers
from rest_framework.pagination import LimitOffsetPagination
from .models import ProductModel, ProductChatModel
from utils.pagination import StructurePagination
import openai
from django.conf import settings
ASSISTANT_ID = 'asst_1wOnCKncEHkOfp0FjOIz4Xkp'
class NewMessageSerializer(serializers.Serializer):
new_message = serializers.CharField(
required=True,
help_text="The message content to send to the chat."
)
# Custom Pagination Class
class StructurePagination(LimitOffsetPagination):
default_limit = 10
max_limit = 100
# Documentation for the ProductChatView
@extend_schema_view(
get=extend_schema(
summary="Retrieve messages for a product chat",
parameters=[
OpenApiParameter(
name="limit",
description="Number of results to return per page.",
required=False,
type=int,
default=10,
),
OpenApiParameter(
name="offset",
description="The starting position of the results.",
required=False,
type=int,
default=0,
),
],
responses={
200: OpenApiExample(
"Chat messages retrieved",
value={
"messages": [
{"sender": "user", "content": "Hello!"},
{"sender": "assistant", "content": "How can I help you?"}
]
}
),
},
),
post=extend_schema(
summary="Send a new message in the product chat",
request=NewMessageSerializer,
responses={
200: OpenApiExample(
"Message sent successfully",
value={
"messages": [
{"sender": "user", "content": "Hello!"},
{"sender": "assistant", "content": "How can I help you?"}
]
}
),
400: OpenApiExample(
"Error example",
value={"detail": "پیام جدید نمی‌تواند خالی باشد"},
),
},
),
)
class ProductChatView(APIView):
permission_classes = [IsAuthenticated]
pagination_class = StructurePagination
def get(self, request, slug):
"""
Retrieve all messages for a product chat.
"""
user = request.user
product = get_object_or_404(ProductModel, slug=slug)
chat, created = ProductChatModel.objects.get_or_create(user=user, product=product)
client = openai.OpenAI(api_key=settings.OPENAI_API_KEY)
message_response = client.beta.threads.messages.list(thread_id=chat.thread)
# Format messages
formatted_messages = []
counter = 1
for message in message_response.data:
for content in message.content:
if content.type == "text" and 'this is the start of the chat greet the user this chat is about the product with given detail:' not in content.text.value:
sender = 'user' if message.role == 'user' else 'ai'
formatted_messages.append({'sender': sender, 'content': content.text.value, 'id': counter})
counter += 1
paginator = StructurePagination()
paginated_messages = paginator.paginate_queryset(formatted_messages, request)
return paginator.get_paginated_response(paginated_messages)
def post(self, request, pk):
"""
Send a new message in the product chat.
"""
user = request.user
product = get_object_or_404(ProductModel, id=pk)
chat, created = ProductChatModel.objects.get_or_create(user=user, product=product)
if created:
return Response({'detail': 'چت این کاربر با این محصول هنوز ساخته نشده'}, status=status.HTTP_400_BAD_REQUEST)
new_message = request.data.get('new_message', '').strip()
if not new_message:
return Response({'detail': 'پیام جدید نمی‌تواند خالی باشد'}, status=status.HTTP_400_BAD_REQUEST)
client = openai.OpenAI(api_key=settings.OPENAI_API_KEY)
# Send the user message
client.beta.threads.messages.create(
thread_id=chat.thread,
role="user",
content=new_message
)
# Start the assistant's run
run = client.beta.threads.runs.create(thread_id=chat.thread, assistant_id=ASSISTANT_ID)
while run.status != "completed":
run = client.beta.threads.runs.retrieve(thread_id=chat.thread, run_id=run.id)
sleep(1)
# Fetch the updated messages
message_response = client.beta.threads.messages.list(thread_id=chat.thread)
formatted_messages = []
for message in message_response.data:
for content in message.content:
if content.type == "text" and 'this is the start of the chat greet the user this chat is about the product with given detail:' not in content.text.value:
sender = 'user' if message.role == 'user' else 'ai'
formatted_messages.append({'sender': sender, 'content': content.text.value})
formatted_messages = formatted_messages[:2]
return Response(formatted_messages, status=status.HTTP_201_CREATED)