URL для всего вебсокет-релейтед - /ws/
В данный момент есть только 1 Consumer (т.е. View, но для вебсокетов). Это ChatConsumer, живет на /ws/chat/.
/ws/chat/
Чтобы законнектиться, укажите в хедерах авторизацию по Bearer токену (как и для всех других запросов в REST API).
Есть два типа ивентов, которые можно кидать - general events и chat-related events. Первые состоят только из user_online и user_offline, вторые содержат все остальное: новое сообщение, печатание, чтение и удаление (пока без редактирования)
Структура любого Event, который должен кидаться на вебсокет выглядит так:
class Event:
type: EventType
content: dictИ соответственно EventType вот такой:
# эти строки указывать в {"type": event_type}
class EventType(str, Enum):
# CHAT RELATED EVENTS
NEW_MESSAGE = "new_message"
DELETE_MESSAGE = "delete_message"
READ_MESSAGE = "message_read"
TYPING = "user_typing"
EDIT_MESSAGE = "edit_message"
# GENERAL EVENTS
SET_ONLINE = "set_online"
SET_OFFLINE = "set_offline"Пример того, как выглядит Event на новое сообщение
{
"type": "new_message",
"content": {
"chat_type": "direct",
"chat_id": "12_23",
"message": "hello world",
"reply_to": 54,
"is_edited": false
}
}Без параметров.
chat_type: str
"direct"или"project", зависит от типа чатаchat_id: int/str
Если тип"project", то тип будетintи это айди проекта, которому принадлежит чат. Если тип"direct", то этоstr. Выглядит как{user1_id}_{user2_id}, где первое число всегда меньше второго.message: strтекст сообщенияreply_to: Optional[int]айди сообщения, на которое кидается ответ. Если его нет, то обязательно кидатьNone
chat_type: strchat_idсм вышеmessage_id: intайди сообщение, которое прочиталиmessage: strтекст сообщения
chat_typeсм вышеchat_idсм выше
chat_typeсм вышеchat_idсм вышеmessage_id: intайди сообщение, которое прочитали
- EventType.SET_ONLINE
- EventType.SET_OFFLINE
Структура этих event'ов одинаковая.
{
"type": "set_offline",
"content": {
}
}{
"type": "new_message",
"content": {
"chat_type": {{"direct" | "project"}},
"chat_id": {{"id1"_"id2"}}, // например: 1_2
"message": {{string}},
"reply_to": number | null
}
}{
"type": "typing",
"content": {
"chat_type": {{"direct" | "project"}},
"chat_id": {{"id1"_"id2"}}, // например: 1_2
}
}{
"type": "typing",
"content": {
"chat_type": {{"direct" | "project"}},
"chat_id": {{"id1"_"id2"}}, // например: 1_2
"message_id": {{number}}
}
}{
"type": "typing",
"content": {
"chat_type": {{"direct" | "project"}},
"chat_id": {{"id1"_"id2"}}, // например: 1_2
"message_id": {{number}}
}
}{
"type": "edit_message",
"content": {
"chat_type": {{"direct" | "project"}},
"chat_id": {{"id1"_"id2"}}, // например: 1_2
"message_id": {{number}},
"message": {{string}}
}
}