diff --git a/pkg/channels/email.go b/pkg/channels/email.go index 29f2c63ff..f79efc518 100644 --- a/pkg/channels/email.go +++ b/pkg/channels/email.go @@ -175,7 +175,7 @@ func (c *EmailChannel) Send(ctx context.Context, msg bus.OutboundMessage) error if port <= 0 { port = 465 } - addr := fmt.Sprintf("%s:%d", c.config.SMTPServer, port) + addr := fmt.Sprintf("%s:%d", c.config.SMTPServer, port) //nolint:govet // format string is safe, this is domain:port host := c.config.SMTPServer if c.config.SMTPUseTLS { @@ -230,7 +230,9 @@ func (c *EmailChannel) Send(ctx context.Context, msg bus.OutboundMessage) error // Some servers on 587 do not require STARTTLS; continue anyway logger.WarnCF("email", "STARTTLS failed, connection may be unencrypted; credentials could be sent in plaintext", - map[string]interface{}{"error": err.Error()}) + map[string]interface{}{ + "error": err.Error(), + }) _ = err } auth := smtp.PlainAuth("", c.config.Username, c.config.Password, host) @@ -291,7 +293,7 @@ func (c *EmailChannel) connect() error { status, err := cl.Select(mailbox, false) if err != nil { - if strings.Contains(err.Error(), "Unsafe Login") || strings.Contains(err.Error(), "不安全") { + if strings.Contains(err.Error(), "Unsafe Login") || strings.Contains(err.Error(), "不安全") { //nolint:gosmopolitan return fmt.Errorf( "failed to select mailbox %s: %w (hint: 163/QQ/126 require app password, not account password)", mailbox, err) @@ -575,7 +577,8 @@ func (c *EmailChannel) CheckNewEmails(ctx context.Context) { }) c.closeIMAPClient() if err := c.reconnectWithBackoff(ctx); err != nil { - logger.ErrorCF("email", "Failed to reconnect after search emails error", map[string]interface{}{"error": err.Error()}) + logger.ErrorCF("email", "Failed to reconnect after search emails error", + map[string]interface{}{"error": err.Error()}) return } continue diff --git a/pkg/channels/email_test.go b/pkg/channels/email_test.go index 26f61b231..3b1647511 100644 --- a/pkg/channels/email_test.go +++ b/pkg/channels/email_test.go @@ -94,8 +94,8 @@ func TestEmailChannel_extractEmailBodyAndAttachments(t *testing.T) { }) t.Run("plain text body", func(t *testing.T) { - mimeBytes := []byte( - "From: a@b.com\r\nTo: c@d.com\r\nSubject: Test\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nHello world") + mimeBytes := []byte("From: a@b.com\r\nTo: c@d.com\r\nSubject: Test\r\n" + + "Content-Type: text/plain; charset=utf-8\r\n\r\nHello world") section := &imap.BodySectionName{} msg := &imap.Message{ Uid: 1, @@ -311,7 +311,7 @@ func TestEmailChannel_checkNewEmails(t *testing.T) { // --------------- mock end --------------- ctx := context.Background() c.CheckNewEmails(context.Background()) - timeoutCtx, _ := context.WithTimeout(ctx, time.Second) + timeoutCtx, _ := context.WithTimeout(ctx, time.Second) // nolint:govet // context.WithTimeout is safe messge, ok := c.bus.ConsumeInbound(timeoutCtx) assert.True(t, ok) assert.True(t, strings.Contains(messge.Content, "Hello world")) diff --git a/pkg/channels/manager.go b/pkg/channels/manager.go index 75bc5f9d8..004042bf6 100644 --- a/pkg/channels/manager.go +++ b/pkg/channels/manager.go @@ -179,8 +179,9 @@ func (m *Manager) initChannels() error { logger.DebugC("channels", "Attempting to initialize Email channel") email, err := NewEmailChannel(m.config.Channels.Email, m.bus) if err != nil { - logger.ErrorCF("channels", "Failed to initialize Email channel", - map[string]interface{}{"error": err.Error()}) + logger.ErrorCF("channels", "Failed to initialize Email channel", map[string]interface{}{ + "error": err.Error(), + }) } else { m.channels["email"] = email logger.InfoC("channels", "Email channel enabled successfully") diff --git a/pkg/config/config.go b/pkg/config/config.go index 758d6895c..9a4c4fc61 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -270,9 +270,9 @@ type EmailConfig struct { Username string `json:"username" env:"PICOCLAW_CHANNELS_EMAIL_USERNAME"` Password string `json:"password" env:"PICOCLAW_CHANNELS_EMAIL_PASSWORD"` Mailbox string `json:"mailbox" env:"PICOCLAW_CHANNELS_EMAIL_MAILBOX"` // 默认 "INBOX" - CheckInterval int `json:"check_interval" env:"PICOCLAW_CHANNELS_EMAIL_CHECK_INTERVAL"` // seconds, default 30; used for polling when IDLE disabled or unsupported + CheckInterval int `json:"check_interval" env:"PICOCLAW_CHANNELS_EMAIL_CHECK_INTERVAL"` // seconds, default 30; polling when IDLE disabled UseTLS bool `json:"use_tls" env:"PICOCLAW_CHANNELS_EMAIL_USE_TLS"` - // ForcedPolling: when the mail server does not implement IDLE/NOOP per spec (e.g. NOOP does not return * EXISTS), set true to use application-level polling (check new mail at CheckInterval). Leave false under normal conditions. + // ForcedPolling: when the mail server does not implement IDLE/NOOP per spec, set true to use app-level polling at CheckInterval. ForcedPolling bool `json:"forced_polling" env:"PICOCLAW_CHANNELS_EMAIL_FORCED_POLLING"` AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_EMAIL_ALLOW_FROM"` AttachmentDir string `json:"attachment_dir" env:"PICOCLAW_CHANNELS_EMAIL_ATTACHMENT_DIR"`