Я создал чат-бота. Я хочу сохранить беседу в JSONField ('question1': 'answer1', 'question2': 'answer2' ...), когда канал отключается, или пользователь завершает чат или через 5 минут бездействия. Я использую django каналы. Все работает, но я не знаю, как сохранить разговор после окончания чата.
Моя модель для сохранения разговора:
class ChatHistory(models.Model):
question = models.TextField(null=True) # not required. added just to test
answer = models.TextField(null=True) # not required. added just to test
conversation = JSONField()
customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING, related_name='customer_chat')
date_time = models.DateTimeField(auto_now_add=True)
talker = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name='user_chat', null=True)
потребителей. py
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['secret_key']
self.user_email = self.scope['url_route']['kwargs']['user_email']
self.room_group_name = 'chat_%s' % self.room_name + self.user_email
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
dir_name = text_data_json['dir_name']
reply = bot_reply(message, dir_name)
secret_key = text_data_json['secret_key']
u_id = text_data_json['user_id']
customer = Customer.objects.get(u_field=u_id)
company = Company.objects.get(secret_key=secret_key)
conversation = {}
# I tried to save every question/answer when talker asked and bot responded. Please igore fields.
# ChatHistory.objects.create(
# company=company,
#
# question=message,
# answer=reply,
#
# talker=company.company_name
# )
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'reply': reply
}
)
# Receive message from room group
def chat_message(self, event):
message = event['message']
reply = event['reply']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message,
'reply': reply
}))
При необходимости. Это шаблон. Я удалил несколько строк, чтобы сделать его короче. Это работает нормально.
var roomName = "{{ secret_key|escapejs }}";
var userEmail = "{{ u_id|escapejs }}";
var chatSocket = new ReconnectingWebSocket(
'ws://' + window.location.host +
'/ws/chat/' + roomName +'/'+ userEmail + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data['message'];
var author = data['author'];
var name = data['name']
var reply = data['reply']
if (reply == 'not found 404') {
var rep = 404
reply = 'System can not answer this question. Would you like to talk to our customer care service.'
}
$(".messages").animate({
scrollTop: $(document).height()
}, "fast");
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-submit').onclick = function(e) {
$(".messages").animate({
scrollTop: $(document).height()
}, "fast");
chatSocket.send(JSON.stringify({
'message': message,
'command': 'new_message',
'dir_name': '{{ dir_name }}',
'secret_key': '{{ secret_key }}',
'user_id': '{{ u_id }}',
}));
messageInputDom.value = '';
};
Редактировать
Модель для сохранения чата
class ChatHistory(models.Model):
TYPE = (
('bot_chat', 'bot_chat'),
('user_chat', 'user_chat')
)
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='company_chat')
customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING, related_name='customer_chat')
date_time = models.DateTimeField(auto_now_add=True)
Модель для сохранения сообщений в чате
class Conversation(models.Model):
history = models.ForeignKey(ChatHistory, on_delete=models.CASCADE, related_name='chat_history')
question = models.TextField(null=True)
answer = models.TextField(null=True)
time = models.TimeField(auto_now_add=True)
Я пробовал это. Когда канал подключается, он создает экземпляр ChatHistory
и сохраняет его, и каждый раз, когда пользователь говорит, я сохраняю сообщение (Q и A) в Conversation
с экземпляром ChatHistory.