This commit is contained in:
Tomas Dvorak
2025-10-29 21:20:16 +01:00
parent 823fabee02
commit 16e4533202
61 changed files with 2308 additions and 942 deletions
+83 -25
View File
@@ -1099,15 +1099,15 @@ func (cc *ContactController) ForwardContactMessage(c *gin.Context) {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Message not found"})
} else {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch message"})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
}
return
}
// Prepare email data for forwarding
// Prepare email data for forwarding (Czech subject)
forwardData := &email.EmailData{
Subject: fmt.Sprintf("Fwd: Contact Form - %s", message.Subject),
To: []string{input.ToEmail},
Subject: fmt.Sprintf("Přeposláno: Kontaktní formulář - %s", message.Subject),
To: []string{input.ToEmail},
Template: "contact_form",
Data: struct {
Name string
@@ -1128,26 +1128,21 @@ func (cc *ContactController) ForwardContactMessage(c *gin.Context) {
},
}
// Send email asynchronously
go func() {
if err := cc.emailService.SendEmail(forwardData); err != nil {
logger.Error("Failed to forward contact message %d to %s: %v", id, input.ToEmail, err)
} else {
logger.Info("Contact message %d forwarded to %s", id, input.ToEmail)
}
}()
c.JSON(http.StatusOK, gin.H{"message": "Message is being forwarded to " + input.ToEmail})
if err := cc.emailService.SendEmail(forwardData); err != nil {
logger.Error("Failed to forward contact message %d to %s: %v", message.ID, input.ToEmail, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to forward message"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Message forwarded"})
}
// ForwardAllContactMessages forwards all contact messages to a specified email (admin only)
// @Summary Forward all contact messages
// @Description Forwards all contact messages to a specified email address (admin only)
// @Tags admin
// @Security Bearer
// @Accept json
// @Produce json
// @Param input body map[string]string true "{ to_email: string }"
// @Param input body map[string]string true "{ to_email: string, to_emails: []string, save_default: bool }"
// @Success 200 {object} map[string]string
// @Failure 400 {object} map[string]string
// @Failure 401 {object} map[string]string
@@ -1160,13 +1155,76 @@ func (cc *ContactController) ForwardAllContactMessages(c *gin.Context) {
}
var input struct {
ToEmail string `json:"to_email" binding:"required,email"`
ToEmail string `json:"to_email"`
ToEmails []string `json:"to_emails"`
SaveDefault bool `json:"save_default"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Valid email address is required"})
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid payload"})
return
}
// Build recipients list (supports comma/semicolon/space separated string or array)
recipients := make([]string, 0)
add := func(s string) {
v := strings.TrimSpace(s)
if v != "" {
recipients = append(recipients, v)
}
}
if len(input.ToEmails) > 0 {
for _, e := range input.ToEmails {
add(e)
}
}
if input.ToEmail != "" {
// split by common separators to allow multiple addresses in a single string
parts := strings.FieldsFunc(input.ToEmail, func(r rune) bool { return r == ',' || r == ';' || r == ' ' || r == '\n' || r == '\t' })
if len(parts) > 1 {
for _, p := range parts {
add(p)
}
} else {
add(input.ToEmail)
}
}
// Deduplicate
if len(recipients) == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "No recipient email provided"})
return
}
uniq := make(map[string]struct{})
out := make([]string, 0, len(recipients))
for _, e := range recipients {
v := strings.TrimSpace(strings.ToLower(e))
if v == "" {
continue
}
if _, ok := uniq[v]; ok {
continue
}
uniq[v] = struct{}{}
out = append(out, e)
}
recipients = out
// Optionally save as default auto-forward list in Settings
if input.SaveDefault {
var set models.Settings
if err := cc.DB.First(&set).Error; err != nil {
if err == gorm.ErrRecordNotFound {
set = models.Settings{}
set.ContactForwardEnabled = true
set.ContactForwardList = strings.Join(recipients, ", ")
_ = cc.DB.Create(&set).Error
}
} else {
set.ContactForwardEnabled = true
set.ContactForwardList = strings.Join(recipients, ", ")
_ = cc.DB.Save(&set).Error
}
}
// Fetch all messages
var messages []models.ContactMessage
if err := cc.DB.Order("created_at DESC").Find(&messages).Error; err != nil {
@@ -1180,12 +1238,12 @@ func (cc *ContactController) ForwardAllContactMessages(c *gin.Context) {
}
// Forward all messages asynchronously
go func(msgs []models.ContactMessage, toEmail string) {
go func(msgs []models.ContactMessage, dest []string) {
successCount := 0
for _, message := range msgs {
forwardData := &email.EmailData{
Subject: fmt.Sprintf("Fwd: Contact Form - %s", message.Subject),
To: []string{toEmail},
Subject: fmt.Sprintf("Přeposláno: Kontaktní formulář - %s", message.Subject),
To: dest,
Template: "contact_form",
Data: struct {
Name string
@@ -1207,16 +1265,16 @@ func (cc *ContactController) ForwardAllContactMessages(c *gin.Context) {
}
if err := cc.emailService.SendEmail(forwardData); err != nil {
logger.Error("Failed to forward contact message %d to %s: %v", message.ID, toEmail, err)
logger.Error("Failed to forward contact message %d to %v: %v", message.ID, dest, err)
} else {
successCount++
}
}
logger.Info("Forwarded %d of %d contact messages to %s", successCount, len(msgs), toEmail)
}(messages, input.ToEmail)
logger.Info("Forwarded %d of %d contact messages to %v", successCount, len(msgs), dest)
}(messages, recipients)
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("Forwarding %d message(s) to %s", len(messages), input.ToEmail),
"message": fmt.Sprintf("Přeposílám %d zpráv na: %s", len(messages), strings.Join(recipients, ", ")),
"count": len(messages),
})
}