HH-469: close WebSocket fanout contract gaps (#109)
* HH-469: close websocket fanout contract gaps * fix: unify message sender contracts --------- Co-authored-by: Rogee <rogee@ipao.vip>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Attachment represents a file attachment on a message.
|
||||
// Reference: Chatwoot Attachment model + P2B M3 spec
|
||||
type Attachment struct {
|
||||
@@ -21,4 +27,29 @@ type Attachment struct {
|
||||
Account Account `gorm:"foreignKey:AccountID" json:"account,omitempty"`
|
||||
}
|
||||
|
||||
func (Attachment) TableName() string { return "attachments" }
|
||||
func (Attachment) TableName() string { return "attachments" }
|
||||
|
||||
// PushEventData matches Chatwoot's attachment payload shared by HTTP and WebSocket messages.
|
||||
func (a *Attachment) PushEventData() map[string]any {
|
||||
dataURL := a.FileURL
|
||||
if dataURL == "" {
|
||||
dataURL = a.ExternalURL
|
||||
}
|
||||
payload := map[string]any{
|
||||
"id": a.ID,
|
||||
"message_id": a.MessageID,
|
||||
"file_type": a.FileType,
|
||||
"account_id": a.AccountID,
|
||||
"data_url": dataURL,
|
||||
"thumb_url": a.ThumbURL,
|
||||
"file_size": a.FileSize,
|
||||
"extension": strings.TrimPrefix(filepath.Ext(a.FileName), "."),
|
||||
"width": a.Width,
|
||||
"height": a.Height,
|
||||
}
|
||||
metadata := map[string]any{}
|
||||
if json.Unmarshal([]byte(a.Metadata), &metadata) == nil && len(metadata) > 0 {
|
||||
payload["metadata"] = metadata
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package model
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/pgvector/pgvector-go"
|
||||
)
|
||||
@@ -89,6 +91,19 @@ type CaptainAssistant struct {
|
||||
|
||||
func (CaptainAssistant) TableName() string { return "captain_assistants" }
|
||||
|
||||
// PushEventData matches Chatwoot's public message-sender contract.
|
||||
func (a *CaptainAssistant) PushEventData() map[string]any {
|
||||
avatarURL := strings.TrimRight(os.Getenv("FRONTEND_URL"), "/") + "/assets/images/dashboard/captain/logo.svg"
|
||||
return map[string]any{
|
||||
"id": a.ID,
|
||||
"name": a.Name,
|
||||
"avatar_url": avatarURL,
|
||||
"description": a.Description,
|
||||
"created_at": a.CreatedAt,
|
||||
"type": "captain_assistant",
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultAssistantConfig returns the default configuration for a new Captain Assistant.
|
||||
// Reference: Chatwoot Captain::Assistant default config values
|
||||
func DefaultAssistantConfig() map[string]interface{} {
|
||||
|
||||
@@ -34,6 +34,22 @@ type Contact struct {
|
||||
|
||||
func (Contact) TableName() string { return "contacts" }
|
||||
|
||||
// PushEventData matches Chatwoot's public message-sender contract.
|
||||
func (c *Contact) PushEventData() map[string]any {
|
||||
return map[string]any{
|
||||
"additional_attributes": jsonMap(c.AdditionalAttributes),
|
||||
"custom_attributes": jsonMap(c.CustomAttributes),
|
||||
"email": c.Email,
|
||||
"id": c.ID,
|
||||
"identifier": c.Identifier,
|
||||
"name": c.Name,
|
||||
"phone_number": c.PhoneNumber,
|
||||
"thumbnail": c.AvatarURL,
|
||||
"blocked": c.Blocked,
|
||||
"type": "contact",
|
||||
}
|
||||
}
|
||||
|
||||
// BeforeSave syncs location/country_code from additional_attributes and upgrades contact_type.
|
||||
// Reference: Chatwoot before_save :sync_contact_attributes → Contacts::SyncAttributes
|
||||
func (c *Contact) BeforeSave(tx *gorm.DB) error {
|
||||
|
||||
@@ -47,6 +47,27 @@ type User struct {
|
||||
|
||||
func (User) TableName() string { return "users" }
|
||||
|
||||
// PushEventData matches Chatwoot's public message-sender contract.
|
||||
func (u *User) PushEventData() map[string]any {
|
||||
availableName := u.DisplayName
|
||||
if availableName == "" {
|
||||
availableName = u.Name
|
||||
}
|
||||
availabilityStatus := "offline"
|
||||
if u.Available {
|
||||
availabilityStatus = "online"
|
||||
}
|
||||
return map[string]any{
|
||||
"id": u.ID,
|
||||
"name": u.Name,
|
||||
"available_name": availableName,
|
||||
"avatar_url": u.AvatarURL,
|
||||
"type": "user",
|
||||
"availability_status": availabilityStatus,
|
||||
"thumbnail": u.AvatarURL,
|
||||
}
|
||||
}
|
||||
|
||||
// BeforeCreate mirrors Chatwoot's Pubsubable concern by assigning every user a cable token.
|
||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
||||
if u.PubsubToken == "" {
|
||||
|
||||
Reference in New Issue
Block a user