package model import ( "database/sql/driver" "encoding/json" "fmt" "time" "gorm.io/datatypes" "gorm.io/gorm" ) // =========================== // Integration Hook types // =========================== // NOTE: HookType and HookStatus are declared in enums.go; additional HookType // constants for integration hooks (webhook/slack/shopify/linear/notion) are // also in enums.go. // IntegrationHook represents a third-party integration hook configuration. // Reference: Chatwoot Integrations::Hook — webhook/app integration bindings // Each hook belongs to an account and optionally to an inbox (for channel-specific integrations). // Hooks store provider-specific settings in the `settings` JSONB field. type IntegrationHook struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` AccountID uint `gorm:"not null;index" json:"account_id"` InboxID *uint `gorm:"index" json:"inbox_id,omitempty"` // nil = account-level hook HookType HookType `gorm:"size:50;not null;index" json:"hook_type"` // webhook/slack/shopify/linear/notion Status HookStatus `gorm:"size:20;default:'active'" json:"status"` // active/inactive URL string `gorm:"size:1024" json:"url"` // webhook callback URL AccessToken string `gorm:"size:256;uniqueIndex" json:"access_token,omitempty"` // API token for the hook Settings datatypes.JSON `gorm:"type:jsonb" json:"settings"` // provider-specific config (Slack channel_id, Shopify shop_domain, etc.) CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at,omitempty"` } // IntegrationApp represents an available integration app definition. // Reference: Chatwoot Integrations::App — catalog of supported integrations type IntegrationApp struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` Name string `gorm:"size:255;not null" json:"name"` Description string `gorm:"size:512" json:"description"` HookType HookType `gorm:"size:50;not null;uniqueIndex" json:"hook_type"` Icon string `gorm:"size:512" json:"icon"` // icon URL or CSS class ActionURL string `gorm:"size:1024" json:"action_url"` // frontend action URL for the integration setup page Enabled bool `gorm:"default:true" json:"enabled"` // whether the integration is available for installation CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } // SlackSettings holds Slack integration-specific configuration. // Reference: Chatwoot Integrations::SlackController settings type SlackSettings struct { ChannelID string `json:"channel_id"` ChannelName string `json:"channel_name"` SlackToken string `json:"slack_token,omitempty"` } // ShopifySettings holds Shopify integration-specific configuration. // Reference: Chatwoot Integrations::ShopifyController settings type ShopifySettings struct { ShopDomain string `json:"shop_domain"` AccessToken string `json:"access_token,omitempty"` } // LinearSettings holds Linear integration-specific configuration. // Reference: Chatwoot Integrations::LinearController settings type LinearSettings struct { TeamID string `json:"team_id"` TeamName string `json:"team_name"` AccessToken string `json:"access_token,omitempty"` ProjectID string `json:"project_id,omitempty"` } // NotionSettings holds Notion integration-specific configuration. type NotionSettings struct { DatabaseID string `json:"database_id,omitempty"` AccessToken string `json:"access_token,omitempty"` } // HookSettingsMap is a JSON type for IntegrationHook.Settings that implements driver.Valuer/sql.Scanner. type HookSettingsMap map[string]interface{} func (h HookSettingsMap) Value() (driver.Value, error) { if h == nil { return json.Marshal(map[string]interface{}{}) } return json.Marshal(h) } func (h *HookSettingsMap) Scan(value interface{}) error { if value == nil { *h = HookSettingsMap{} return nil } bytes, ok := value.([]byte) if !ok { return fmt.Errorf("failed to unmarshal HookSettingsMap: %v", value) } return json.Unmarshal(bytes, h) }