Send HTML forms via email https://jlelse.dev/projects/mailygo/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.5 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "net/smtp"
  6. "sort"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. func sendForm(values *FormValues) {
  12. recipient := findRecipient(values)
  13. sendMail(recipient, buildMessage(recipient, time.Now(), values))
  14. }
  15. func buildMessage(recipient string, date time.Time, values *FormValues) string {
  16. msgBuffer := &bytes.Buffer{}
  17. _, _ = fmt.Fprintf(msgBuffer, "From: Forms <%s>", appConfig.Sender)
  18. _, _ = fmt.Fprintln(msgBuffer)
  19. _, _ = fmt.Fprintf(msgBuffer, "To: %s", recipient)
  20. _, _ = fmt.Fprintln(msgBuffer)
  21. if replyTo := findReplyTo(values); replyTo != "" {
  22. _, _ = fmt.Fprintf(msgBuffer, "Reply-To: %s", replyTo)
  23. _, _ = fmt.Fprintln(msgBuffer)
  24. }
  25. _, _ = fmt.Fprintf(msgBuffer, "Date: %s", date.Format(time.RFC1123Z))
  26. _, _ = fmt.Fprintln(msgBuffer)
  27. _, _ = fmt.Fprintf(msgBuffer, "Subject: New submission on %s", findFormName(values))
  28. _, _ = fmt.Fprintln(msgBuffer)
  29. _, _ = fmt.Fprintln(msgBuffer)
  30. bodyValues := removeMetaValues(values)
  31. var keys []string
  32. for key := range *bodyValues {
  33. keys = append(keys, key)
  34. }
  35. sort.Strings(keys)
  36. for _, key := range keys {
  37. _, _ = fmt.Fprint(msgBuffer, key)
  38. _, _ = fmt.Fprint(msgBuffer, ": ")
  39. _, _ = fmt.Fprintln(msgBuffer, strings.Join((*bodyValues)[key], ", "))
  40. }
  41. return msgBuffer.String()
  42. }
  43. func sendMail(to, message string) {
  44. auth := smtp.PlainAuth("", appConfig.SMTPUser, appConfig.SMTPPassword, appConfig.SMTPHost)
  45. err := smtp.SendMail(appConfig.SMTPHost+":"+strconv.Itoa(appConfig.SMTPPort), auth, appConfig.Sender, []string{to}, []byte(message))
  46. if err != nil {
  47. fmt.Println("Failed to send mail:", err.Error())
  48. }
  49. }
  50. func findRecipient(values *FormValues) string {
  51. if len((*values)["_to"]) == 1 && (*values)["_to"][0] != "" {
  52. formDefinedRecipient := (*values)["_to"][0]
  53. for _, allowed := range appConfig.AllowedRecipients {
  54. if formDefinedRecipient == allowed {
  55. return formDefinedRecipient
  56. }
  57. }
  58. }
  59. return appConfig.DefaultRecipient
  60. }
  61. func findFormName(values *FormValues) string {
  62. if len((*values)["_formName"]) == 1 && (*values)["_formName"][0] != "" {
  63. return (*values)["_formName"][0]
  64. }
  65. return "a form"
  66. }
  67. func findReplyTo(values *FormValues) string {
  68. if len((*values)["_replyTo"]) == 1 && (*values)["_replyTo"][0] != "" {
  69. return (*values)["_replyTo"][0]
  70. }
  71. return ""
  72. }
  73. func removeMetaValues(values *FormValues) *FormValues {
  74. cleanedValues := FormValues{}
  75. for key, value := range *values {
  76. if !strings.HasPrefix(key, "_") {
  77. cleanedValues[key] = value
  78. }
  79. }
  80. return &cleanedValues
  81. }