136 lines
3.4 KiB
Go
136 lines
3.4 KiB
Go
|
|
package websocket
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
type MessageType string
|
||
|
|
|
||
|
|
const (
|
||
|
|
MsgTypeNewMessage MessageType = "new_message"
|
||
|
|
MsgTypeTyping MessageType = "typing"
|
||
|
|
MsgTypeReadReceipt MessageType = "read_receipt"
|
||
|
|
MsgTypeEditMessage MessageType = "edit_message"
|
||
|
|
MsgTypeDeleteMessage MessageType = "delete_message"
|
||
|
|
MsgTypePing MessageType = "ping"
|
||
|
|
|
||
|
|
MsgTypeNewMessageResp MessageType = "new_message"
|
||
|
|
MsgTypeUserTyping MessageType = "user_typing"
|
||
|
|
MsgTypeMessageRead MessageType = "message_read"
|
||
|
|
MsgTypeMessageEdited MessageType = "message_edited"
|
||
|
|
MsgTypeMessageDeleted MessageType = "message_deleted"
|
||
|
|
MsgTypeUserOnline MessageType = "user_online"
|
||
|
|
MsgTypeUserOffline MessageType = "user_offline"
|
||
|
|
MsgTypePong MessageType = "pong"
|
||
|
|
MsgTypeError MessageType = "error"
|
||
|
|
)
|
||
|
|
|
||
|
|
type WSMessage struct {
|
||
|
|
Type MessageType `json:"type"`
|
||
|
|
Data json.RawMessage `json:"data,omitempty"`
|
||
|
|
Timestamp time.Time `json:"timestamp"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type NewMessageRequest struct {
|
||
|
|
ChatID int64 `json:"chat_id"`
|
||
|
|
Plaintext string `json:"plaintext"`
|
||
|
|
AttachmentID *int64 `json:"attachment_id,omitempty"`
|
||
|
|
TempID string `json:"temp_id,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type NewMessageResponse struct {
|
||
|
|
ID int64 `json:"id"`
|
||
|
|
ChatID int64 `json:"chat_id"`
|
||
|
|
SenderID int64 `json:"sender_id"`
|
||
|
|
Plaintext string `json:"plaintext"`
|
||
|
|
Attachment *AttachmentInfo `json:"attachment,omitempty"`
|
||
|
|
CreatedAt time.Time `json:"created_at"`
|
||
|
|
TempID string `json:"temp_id,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type AttachmentInfo struct {
|
||
|
|
ID int64 `json:"id"`
|
||
|
|
FileName string `json:"file_name"`
|
||
|
|
FileSize int64 `json:"file_size"`
|
||
|
|
MimeType string `json:"mime_type"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type TypingRequest struct {
|
||
|
|
ChatID int64 `json:"chat_id"`
|
||
|
|
IsTyping bool `json:"is_typing"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type TypingResponse struct {
|
||
|
|
ChatID int64 `json:"chat_id"`
|
||
|
|
UserID int64 `json:"user_id"`
|
||
|
|
IsTyping bool `json:"is_typing"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type ReadReceiptRequest struct {
|
||
|
|
MessageID int64 `json:"message_id"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type ReadReceiptResponse struct {
|
||
|
|
MessageID int64 `json:"message_id"`
|
||
|
|
UserID int64 `json:"user_id"`
|
||
|
|
ReadAt time.Time `json:"read_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type EditMessageRequest struct {
|
||
|
|
MessageID int64 `json:"message_id"`
|
||
|
|
Plaintext string `json:"plaintext"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type EditMessageResponse struct {
|
||
|
|
MessageID int64 `json:"message_id"`
|
||
|
|
NewPlaintext string `json:"new_plaintext"`
|
||
|
|
EditedAt time.Time `json:"edited_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type DeleteMessageRequest struct {
|
||
|
|
MessageID int64 `json:"message_id"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type DeleteMessageResponse struct {
|
||
|
|
MessageID int64 `json:"message_id"`
|
||
|
|
DeletedAt time.Time `json:"deleted_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type UserOnlineResponse struct {
|
||
|
|
UserID int64 `json:"user_id"`
|
||
|
|
IsOnline bool `json:"is_online"`
|
||
|
|
LastSeen *time.Time `json:"last_seen,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type ErrorResponse struct {
|
||
|
|
Code int `json:"code"`
|
||
|
|
Message string `json:"message"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func ParseMessage(raw []byte) (*WSMessage, error) {
|
||
|
|
var msg WSMessage
|
||
|
|
if err := json.Unmarshal(raw, &msg); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &msg, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func CreateMessage(msgType MessageType, data interface{}) ([]byte, error) {
|
||
|
|
var dataBytes json.RawMessage
|
||
|
|
if data != nil {
|
||
|
|
bytes, err := json.Marshal(data)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
dataBytes = bytes
|
||
|
|
}
|
||
|
|
|
||
|
|
msg := WSMessage{
|
||
|
|
Type: msgType,
|
||
|
|
Data: dataBytes,
|
||
|
|
Timestamp: time.Now(),
|
||
|
|
}
|
||
|
|
|
||
|
|
return json.Marshal(msg)
|
||
|
|
}
|