diff --git a/docs/swagger/collections.yaml b/docs/swagger/collections.yaml index 42cb7e041..93b8f5d42 100644 --- a/docs/swagger/collections.yaml +++ b/docs/swagger/collections.yaml @@ -3321,6 +3321,8 @@ components: type: integer max_msg_retries: type: integer + retry_delay: + type: string idle_timeout: type: string wait_timeout: @@ -3355,6 +3357,8 @@ components: type: integer max_msg_retries: type: integer + retry_delay: + type: string idle_timeout: type: string wait_timeout: diff --git a/frontend/src/views/settings/messengers.vue b/frontend/src/views/settings/messengers.vue index d09c123c1..c7e62a9c4 100644 --- a/frontend/src/views/settings/messengers.vue +++ b/frontend/src/views/settings/messengers.vue @@ -63,6 +63,13 @@ controls-position="compact" placeholder="2" min="1" max="1000" /> + +
+ + +
@@ -111,6 +118,7 @@ export default Vue.extend({ password: '', max_conns: 25, max_msg_retries: 2, + retry_delay: '15s', timeout: '5s', }); diff --git a/frontend/src/views/settings/smtp.vue b/frontend/src/views/settings/smtp.vue index 420a91d40..74c53da7e 100644 --- a/frontend/src/views/settings/smtp.vue +++ b/frontend/src/views/settings/smtp.vue @@ -125,6 +125,13 @@ controls-position="compact" placeholder="2" min="1" max="1000" />
+
+ + + +
@@ -271,6 +278,7 @@ export default Vue.extend({ email_headers: [], max_conns: 10, max_msg_retries: 2, + retry_delay: '15s', idle_timeout: '15s', wait_timeout: '5s', tls_type: 'STARTTLS', diff --git a/i18n/en.json b/i18n/en.json index d4640c827..f08daf4cb 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -474,6 +474,8 @@ "settings.messengers.password": "Password", "settings.messengers.retries": "Retries", "settings.messengers.retriesHelp": "Number of times to retry when a message fails.", + "settings.messengers.retryDelay": "Retry delay", + "settings.messengers.retryDelayHelp": "Time to wait between retries.", "settings.messengers.skipTLSHelp": "Skip hostname check on the TLS certificate.", "settings.messengers.timeout": "Idle timeout", "settings.messengers.timeoutHelp": "Time to wait for new activity on a connection before closing it and removing it from the pool (s for second, m for minute).", @@ -538,6 +540,8 @@ "settings.smtp.name": "SMTP", "settings.smtp.retries": "Retries", "settings.smtp.retriesHelp": "Number of times to retry when a message fails.", + "settings.smtp.retryDelay": "Retry delay", + "settings.smtp.retryDelayHelp": "Time to wait between retries.", "settings.smtp.sendTest": "Send e-mail", "settings.smtp.setCustomHeaders": "Set custom headers", "settings.smtp.testConnection": "Test connection", diff --git a/internal/messenger/email/email.go b/internal/messenger/email/email.go index 50675edc2..db91aa773 100644 --- a/internal/messenger/email/email.go +++ b/internal/messenger/email/email.go @@ -190,6 +190,19 @@ func (e *Emailer) Flush() error { return nil } +// Retrieve the retry delay from the configuration +retryDelay := time.Duration(config.RetryDelay) * time.Second + +// Implement retry logic +var err error +for i := 0; i < maxRetries; i++ { + err = sendSMTPMail(...) + if err == nil { + break + } + time.Sleep(retryDelay) // Wait for the retry delay before the next attempt +} + // Close closes the SMTP pools. func (e *Emailer) Close() error { for _, s := range e.servers { diff --git a/models/settings.go b/models/settings.go index fd7ba1bdf..5bfcb4bf7 100644 --- a/models/settings.go +++ b/models/settings.go @@ -75,6 +75,7 @@ type Settings struct { EmailHeaders []map[string]string `json:"email_headers"` MaxConns int `json:"max_conns"` MaxMsgRetries int `json:"max_msg_retries"` + RetryDelay string `json:"retry_delay"` IdleTimeout string `json:"idle_timeout"` WaitTimeout string `json:"wait_timeout"` TLSType string `json:"tls_type"` @@ -91,6 +92,7 @@ type Settings struct { MaxConns int `json:"max_conns"` Timeout string `json:"timeout"` MaxMsgRetries int `json:"max_msg_retries"` + RetryDelay string `json:"retry_delay"` } `json:"messengers"` BounceEnabled bool `json:"bounce.enabled"` diff --git a/schema.sql b/schema.sql index ae3aa92ea..046f8caf0 100644 --- a/schema.sql +++ b/schema.sql @@ -269,8 +269,8 @@ INSERT INTO settings (key, value) VALUES ('upload.s3.bucket_type', '"public"'), ('upload.s3.expiry', '"167h"'), ('smtp', - '[{"enabled":true, "host":"smtp.yoursite.com","port":25,"auth_protocol":"cram","username":"username","password":"password","hello_hostname":"","max_conns":10,"idle_timeout":"15s","wait_timeout":"5s","max_msg_retries":2,"tls_type":"STARTTLS","tls_skip_verify":false,"email_headers":[]}, - {"enabled":false, "host":"smtp.gmail.com","port":465,"auth_protocol":"login","username":"username@gmail.com","password":"password","hello_hostname":"","max_conns":10,"idle_timeout":"15s","wait_timeout":"5s","max_msg_retries":2,"tls_type":"TLS","tls_skip_verify":false,"email_headers":[]}]'), + '[{"enabled":true, "host":"smtp.yoursite.com","port":25,"auth_protocol":"cram","username":"username","password":"password","hello_hostname":"","max_conns":10,"idle_timeout":"15s","wait_timeout":"5s","max_msg_retries":2,"retry_delay":"15s","tls_type":"STARTTLS","tls_skip_verify":false,"email_headers":[]}, + {"enabled":false, "host":"smtp.gmail.com","port":465,"auth_protocol":"login","username":"username@gmail.com","password":"password","hello_hostname":"","max_conns":10,"idle_timeout":"15s","wait_timeout":"5s","max_msg_retries":2,"retry_delay":"15s","tls_type":"TLS","tls_skip_verify":false,"email_headers":[]}]'), ('messengers', '[]'), ('bounce.enabled', 'false'), ('bounce.webhooks_enabled', 'false'),