162 lines
5.9 KiB
Go
162 lines
5.9 KiB
Go
package channel
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
// ChannelEmail represents an Email (SMTP/IMAP) channel configuration.
|
|
// Reference: Chatwoot app/models/channel/email.rb
|
|
//
|
|
// Chatwoot's ChannelEmail model attributes:
|
|
// - email: The inbound email address (e.g. support@acme.com)
|
|
// - forward_to_address: Email address for forwarding (alternative to IMAP)
|
|
// - imap_enabled: Whether IMAP polling is enabled
|
|
// - imap_address: IMAP server hostname
|
|
// - imap_port: IMAP server port (typically 993 for SSL)
|
|
// - imap_login: IMAP login/username
|
|
// - imap_password: IMAP password
|
|
// - imap_ssl: Whether to use SSL for IMAP connection
|
|
// - smtp_enabled: Whether SMTP sending is enabled
|
|
// - smtp_address: SMTP server hostname
|
|
// - smtp_port: SMTP server port (typically 587 for TLS)
|
|
// - smtp_login: SMTP login/username
|
|
// - smtp_password: SMTP password
|
|
// - smtp_ssl: Whether to use SSL/TLS for SMTP
|
|
//
|
|
// Chatwoot lifecycle hooks:
|
|
// - before_validation :ensure_forward_to_address (sets default forwarding address)
|
|
// - before_create :ensure_imap_connection (validates IMAP credentials)
|
|
// - before_create :ensure_smtp_connection (validates SMTP credentials)
|
|
//
|
|
// gochat enhancements beyond Chatwoot:
|
|
// - mailbox_name: Friendly name for the mailbox (for display)
|
|
// - imap_ssl_mode: Explicit SSL mode (none/starttls/ssl) instead of boolean
|
|
// - smtp_ssl_mode: Explicit SSL mode instead of boolean
|
|
// - domain: Email domain for routing (e.g. "acme.com")
|
|
// - use_reply_to: Whether to use Reply-To header for contact identification
|
|
|
|
// ChannelEmail stores Email channel configuration for SMTP/IMAP.
|
|
type ChannelEmail struct {
|
|
model.Base
|
|
|
|
// Account foreign key — links to the Account that owns this channel
|
|
AccountID uint `gorm:"index;not null" json:"account_id"`
|
|
|
|
// Inbox foreign key — links to the Inbox that wraps this channel
|
|
InboxID uint `gorm:"not null;uniqueIndex" json:"inbox_id"`
|
|
|
|
// Inbound email address — the address customers send emails to
|
|
// Reference: Chatwoot EDITABLE_ATTRS = [:email]
|
|
Email string `gorm:"size:255;not null" json:"email"`
|
|
|
|
// Friendly name for the mailbox (e.g. "Acme Support")
|
|
MailboxName string `gorm:"size:255" json:"mailbox_name,omitempty"`
|
|
|
|
// Email domain for routing (extracted from Email, e.g. "acme.com")
|
|
Domain string `gorm:"size:255;index" json:"domain"`
|
|
|
|
// === IMAP Configuration ===
|
|
|
|
// Whether IMAP polling is enabled
|
|
IMAPEnabled bool `gorm:"default:false" json:"imap_enabled"`
|
|
|
|
// IMAP server hostname (e.g. "imap.gmail.com")
|
|
IMAPAddress string `gorm:"size:255" json:"imap_address,omitempty"`
|
|
|
|
// IMAP server port (typically 993 for SSL, 143 for plain)
|
|
IMAPPort int `gorm:"default:993" json:"imap_port,omitempty"`
|
|
|
|
// IMAP login/username
|
|
IMAPLogin string `gorm:"size:255" json:"imap_login,omitempty"`
|
|
|
|
// IMAP password (stored encrypted at application level)
|
|
IMAPPassword string `gorm:"size:255" json:"imap_password,omitempty"`
|
|
|
|
// IMAP SSL mode: "none", "starttls", "ssl"
|
|
IMAPSSLMode string `gorm:"size:20;default:ssl" json:"imap_ssl_mode,omitempty"`
|
|
|
|
// IMAP mailbox folder to monitor (e.g. "INBOX")
|
|
IMAPFolder string `gorm:"size:255;default:INBOX" json:"imap_folder,omitempty"`
|
|
|
|
// === SMTP Configuration ===
|
|
|
|
// Whether SMTP sending is enabled
|
|
SMTPEnabled bool `gorm:"default:false" json:"smtp_enabled"`
|
|
|
|
// SMTP server hostname (e.g. "smtp.gmail.com")
|
|
SMTPAddress string `gorm:"size:255" json:"smtp_address,omitempty"`
|
|
|
|
// SMTP server port (typically 587 for STARTTLS, 465 for SSL, 25 for plain)
|
|
SMTPPort int `gorm:"default:587" json:"smtp_port,omitempty"`
|
|
|
|
// SMTP login/username
|
|
SMTPLogin string `gorm:"size:255" json:"smtp_login,omitempty"`
|
|
|
|
// SMTP password (stored encrypted at application level)
|
|
SMTPPassword string `gorm:"size:255" json:"smtp_password,omitempty"`
|
|
|
|
// SMTP SSL mode: "none", "starttls", "ssl"
|
|
SMTPSSLMode string `gorm:"size:20;default:starttls" json:"smtp_ssl_mode,omitempty"`
|
|
|
|
// === Behavioral Configuration ===
|
|
|
|
// Whether to use Reply-To header for contact identification
|
|
// When true, the Reply-To address is used instead of From address
|
|
UseReplyTo bool `gorm:"default:false" json:"use_reply_to,omitempty"`
|
|
|
|
// Whether to automatically group emails into conversations by thread
|
|
AutoThread bool `gorm:"default:true" json:"auto_thread,omitempty"`
|
|
|
|
// Maximum attachment size in bytes (0 = no limit)
|
|
MaxAttachmentSize int64 `gorm:"default:0" json:"max_attachment_size,omitempty"`
|
|
}
|
|
|
|
func (ChannelEmail) TableName() string { return "channel_emails" }
|
|
|
|
// GetChannelBase returns the ChannelBase for this channel.
|
|
func (c *ChannelEmail) GetChannelBase() ChannelBase {
|
|
return ChannelBase{
|
|
AccountID: c.AccountID,
|
|
InboxID: c.InboxID,
|
|
ChannelType: "email",
|
|
}
|
|
}
|
|
|
|
// GetChannelType returns the channel type identifier.
|
|
func (c *ChannelEmail) GetChannelType() string { return "email" }
|
|
|
|
// IsIMAPConfigured returns true if IMAP connection parameters are set.
|
|
func (c *ChannelEmail) IsIMAPConfigured() bool {
|
|
return c.IMAPEnabled && c.IMAPAddress != "" && c.IMAPLogin != "" && c.IMAPPassword != ""
|
|
}
|
|
|
|
// IsSMTPConfigured returns true if SMTP connection parameters are set.
|
|
func (c *ChannelEmail) IsSMTPConfigured() bool {
|
|
return c.SMTPEnabled && c.SMTPAddress != "" && c.SMTPLogin != "" && c.SMTPPassword != ""
|
|
}
|
|
|
|
// IMAPConnectionString returns a human-readable IMAP connection summary.
|
|
func (c *ChannelEmail) IMAPConnectionString() string {
|
|
if !c.IsIMAPConfigured() {
|
|
return "IMAP not configured"
|
|
}
|
|
return c.IMAPLogin + "@" + c.IMAPAddress + ":" + formatPort(c.IMAPPort)
|
|
}
|
|
|
|
// SMTPConnectionString returns a human-readable SMTP connection summary.
|
|
func (c *ChannelEmail) SMTPConnectionString() string {
|
|
if !c.IsSMTPConfigured() {
|
|
return "SMTP not configured"
|
|
}
|
|
return c.SMTPLogin + "@" + c.SMTPAddress + ":" + formatPort(c.SMTPPort)
|
|
}
|
|
|
|
// formatPort converts port int to string, using defaults if zero.
|
|
func formatPort(port int) string {
|
|
if port == 0 {
|
|
return "default"
|
|
}
|
|
return fmt.Sprintf("%d", port)
|
|
} |