Maison > développement back-end > Golang > Envoyer un e-mail brut avec des pièces jointes dans Go via AWS SES v2

Envoyer un e-mail brut avec des pièces jointes dans Go via AWS SES v2

WBOY
Libérer: 2024-02-15 17:00:09
avant
839 Les gens l'ont consulté

通过 AWS SES v2 在 Go 中发送带有附件的原始电子邮件

l'éditeur php Xiaoxin vous propose un article sur l'envoi d'e-mails originaux avec pièces jointes à l'aide d'AWS SES v2 dans Go. La combinaison d'AWS SES v2, un service de messagerie flexible et fiable, et de Go, un langage de programmation puissant, peut vous aider à envoyer facilement des e-mails originaux avec pièces jointes. Cet article détaille comment écrire du code à l'aide de l'API AWS SES v2 et du langage Go pour implémenter cette fonctionnalité. Que vous soyez débutant ou développeur expérimenté, cet article vous fournira des conseils clairs pour mener à bien votre travail. Commençons!

Contenu de la question

J'essaie de créer un point de terminaison http pour gérer les soumissions de formulaires à partir d'un site Web.

Le formulaire comporte les champs suivants :

  • Nom
  • E-mail
  • Téléphone
  • Corps de l'e-mail (texte du corps de l'e-mail)
  • Photos (maximum 5)

Mon point de terminaison enverra ensuite un e-mail à [email protected] avec la photo en pièce jointe et le corps de l'e-mail comme suit :

john ([email protected]) says:
email body ...
Copier après la connexion

Je suis nouveau mais j'essaie de le faire fonctionner depuis 2 semaines maintenant et je n'ai toujours pas de chance.

Mon code actuel est :

package aj

import (
    "bytes"
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "mime"
    "net/http"
    "net/mail"
    "net/textproto"
    "os"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/service/sesv2"
    "github.com/aws/aws-sdk-go-v2/service/sesv2/types"
    "go.uber.org/zap"
)

const expectedContentType string = "multipart/form-data"
const charset string = "UTF-8"

func FormSubmissionHandler(logger *zap.Logger, emailSender EmailSender) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logger.Info("running the form submission handler...")

        // get the destination email address
        destinationEmail := os.Getenv("DESTINATION_EMAIL")

        // get the subject line of the email
        emailSubject := os.Getenv("EMAIL_SUBJECT")

        // enforce a multipart/form-data content-type
        contentType := r.Header.Get("content-type")

        mediatype, _, err := mime.ParseMediaType(contentType)
        if err != nil {
            logger.Error("error when parsing the mime type", zap.Error(err))
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }

        if mediatype != expectedContentType {
            logger.Error("unsupported content-type", zap.Error(err))
            http.Error(w, fmt.Sprintf("api expects %v content-type", expectedContentType), http.StatusUnsupportedMediaType)
            return
        }

        err = r.ParseMultipartForm(10 << 20)
        if err != nil {
            logger.Error("error parsing form data", zap.Error(err))
            http.Error(w, "error parsing form data", http.StatusBadRequest)
            return
        }

        name := r.MultipartForm.Value["name"]
        if len(name) == 0 {
            logger.Error("name not set", zap.Error(err))
            http.Error(w, "api expects name to be set", http.StatusBadRequest)
            return
        }

        email := r.MultipartForm.Value["email"]
        if len(email) == 0 {
            logger.Error("email not set", zap.Error(err))
            http.Error(w, "api expects email to be set", http.StatusBadRequest)
            return
        }

        phone := r.MultipartForm.Value["phone"]
        if len(phone) == 0 {
            logger.Error("phone not set", zap.Error(err))
            http.Error(w, "api expects phone to be set", http.StatusBadRequest)
            return
        }

        body := r.MultipartForm.Value["body"]
        if len(body) == 0 {
            logger.Error("body not set", zap.Error(err))
            http.Error(w, "api expects body to be set", http.StatusBadRequest)
            return
        }

        files := r.MultipartForm.File["photos"]
        if len(files) == 0 {
            logger.Error("no files were submitted", zap.Error(err))
            http.Error(w, "api expects one or more files to be submitted", http.StatusBadRequest)
            return
        }

        emailService := NewEmailService()

        sendEmailInput := sesv2.SendEmailInput{}

        destination := &types.Destination{
            ToAddresses: []string{destinationEmail},
        }

        // add the attachments to the email
        for _, file := range files {
            f, err := file.Open()
            if err != nil {
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
            }
            defer f.Close()

            // not sure what to do here to get the email with the attachements
        }

        message := &types.RawMessage{
            Data: make([]byte, 0), // This must change to be the bytes of the raw message
        }

        content := &types.EmailContent{
            Raw: message,
        }

        sendEmailInput.Content = content
        sendEmailInput.Destination = destination
        sendEmailInput.FromEmailAddress = aws.String(email[0])

        err = emailService.SendEmail(logger, r.Context(), &sendEmailInput)
        if err != nil {
            logger.Error("an error occured sending the email", zap.Error(err))
            http.Error(w, "error sending email", http.StatusBadRequest)
            return
        }

        w.WriteHeader(http.StatusOK)
    })
}
Copier après la connexion

Je crois comprendre (corrigez-moi si je me trompe) que je dois construire le message original dans un format similaire à celui-ci. En supposant que cela soit correct, je ne sais tout simplement pas comment faire cela en go

Solution de contournement

Pour créer des pièces jointes, vous devez utiliser base64 消息内容来 encode.

Voici un exemple d'envoi d'un csv en pièce jointe :

import (
  // ...
  secretutils "github.com/alessiosavi/GoGPUtils/aws/secrets"
  sesutils "github.com/alessiosavi/GoGPUtils/aws/ses"
)

type MailConf struct {
    FromName string   `json:"from_name,omitempty"`
    FromMail string   `json:"from_mail,omitempty"`
    To       string   `json:"to,omitempty"`
    CC       []string `json:"cc,omitempty"`
}

func SendRawMail(filename string, data []byte) error {
    var mailConf MailConf
    if err := secretutils.UnmarshalSecret(os.Getenv("XXX_YOUR_SECRET_STORED_IN_AWS"), &mailConf); err != nil {
        return err
    }
    subject := fmt.Sprintf("Found errors for the following file: %s", filename)
    var carbonCopy string
    if len(mailConf.CC) > 0 {
        carbonCopy = stringutils.JoinSeparator(",", mailConf.CC...)
    } else {
        carbonCopy = ""
    }
    raw := fmt.Sprintf(`From: "%[1]s" <%[2]s>
To: %[3]s
Cc: %[4]s
Subject: %[5]s
Content-Type: multipart/mixed;
    boundary="1"

--1
Content-Type: multipart/alternative;
    boundary="sub_1"

--sub_1
Content-Type: string/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Please see the attached file for a list of errors

--sub_1
Content-Type: string/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

<html>
<head></head>
<body>
<h1>%[6]s</h1>
<p><h2>Please see the attached file for the list of the rows.<h2></p>
</body>
</html>

--sub_1--

--1
Content-Type: string/plain; name="errors_%[6]s"
Content-Description: errors_%[6]s
Content-Disposition: attachment;filename="errors_%[6]s";
creation-date="%[7]s";
Content-Transfer-Encoding: base64

%[8]s

--1--`, mailConf.FromName, mailConf.FromMail, mailConf.To, carbonCopy, subject, strings.Replace(filename, ".csv", ".json", 1), time.Now().Format("2-Jan-06 3.04.05 PM"), base64.StdEncoding.EncodeToString(data))

    return sesutils.SendMail([]byte(raw))
}


Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal