Files
gochat/internal/model/webhook_subscription.go
T

77 lines
3.5 KiB
Go

package model
import (
"encoding/json"
"time"
"gorm.io/gorm"
)
// WebhookSubscription represents an account-level webhook subscription for outgoing events.
// Reference: Chatwoot webhook integration + P2B M8 spec
type WebhookSubscription struct {
ID uint `gorm:"primaryKey" json:"id"`
AccountID uint `gorm:"not null;index" json:"account_id"`
InboxID *uint `gorm:"index" json:"inbox_id,omitempty"`
Name string `gorm:"size:255" json:"name,omitempty"`
URL string `gorm:"size:2048;not null" json:"url"`
Events json.RawMessage `gorm:"type:jsonb;not null" json:"subscriptions"` // JSON array of event types, e.g. ["conversation_created","message_created"]
Secret string `gorm:"size:128;not null" json:"secret,omitempty"` // HMAC-SHA256 signing secret
WebhookType int `gorm:"default:0" json:"webhook_type,omitempty"`
Active bool `gorm:"default:true" json:"active"`
VerifiedAt *time.Time `json:"verified_at,omitempty"`
LastDeliveryStatus string `gorm:"size:50" json:"last_delivery_status,omitempty"` // success/failed/pending
LastDeliveryAt *time.Time `json:"last_delivery_at,omitempty"`
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"`
Account Account `gorm:"foreignKey:AccountID" json:"account,omitempty"`
Inbox Inbox `gorm:"foreignKey:InboxID" json:"inbox,omitempty"`
}
func (WebhookSubscription) TableName() string { return "webhook_subscriptions" }
// WebhookDeliveryStatus constants for delivery tracking.
const (
WebhookDeliveryStatusPending = "pending"
WebhookDeliveryStatusSuccess = "success"
WebhookDeliveryStatusFailed = "failed"
WebhookDeliveryStatusRetrying = "retrying"
)
// IsEventSubscribed checks whether the subscription includes a given event type.
// The Events field is a JSON array of event type strings, e.g. ["conversation_created","message_created"].
func (s *WebhookSubscription) IsEventSubscribed(eventType string) bool {
var events []string
if err := json.Unmarshal(s.Events, &events); err != nil {
return false
}
for _, e := range events {
if e == eventType {
return true
}
}
return false
}
// WebhookDelivery represents a single webhook delivery attempt.
// Reference: Chatwoot webhook delivery tracking + P2B M8 spec
type WebhookDelivery struct {
ID uint `gorm:"primaryKey" json:"id"`
SubscriptionID uint `gorm:"not null;index" json:"subscription_id"`
EventType string `gorm:"size:100;not null;index" json:"event_type"`
Payload json.RawMessage `gorm:"type:jsonb" json:"payload"`
ResponseCode int `json:"response_code,omitempty"`
ResponseBody string `gorm:"size:4096" json:"response_body,omitempty"`
Status string `gorm:"size:50;not null;index" json:"status"` // success/failed/retrying
Attempts int `gorm:"default:0" json:"attempts"`
NextAttemptAt *time.Time `json:"next_attempt_at,omitempty"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
Subscription WebhookSubscription `gorm:"foreignKey:SubscriptionID" json:"subscription,omitempty"`
}
func (WebhookDelivery) TableName() string { return "webhook_deliveries" }