// Tencent Cloud Email Push Service (SES) usando o protocolo SMTP.//// Este código demonstra como enviar uma solicitação de envio de e-mail ao// Tencent Cloud SES através do protocolo SMTP (porta 465 com criptografia// SSL/TLS). O fluxo geral é composto pelas seguintes etapas:// 1. Preparar os parâmetros de envio (remetente, destinatários, Cc, Bcc, assunto, corpo, etc.);// 2. Montar o Header e o Body do e-mail no formato RFC 822 (o Body é codificado em Base64);// 3. Estabelecer uma conexão criptografada com o servidor SMTP usando tls.Dial;// 4. Concluir a autenticação via PlainAuth;// 5. Executar comandos SMTP como MAIL FROM, RCPT TO e DATA em ordem para entregar a mensagem.//// Antes de usar este código, conclua as seguintes preparações no console do// Tencent Cloud Email Push:// - Crie e verifique um Domínio de Remetente (Sender Domain);// - Crie um Endereço de Remetente (Sender Address) e habilite o envio por SMTP;// - Gere uma senha SMTP dedicada em "SMTP Password" no console// (atenção: NÃO é a senha da sua conta Tencent Cloud);// - Verifique se o endereço de remetente possui cota de envio disponível.//// Dependências: apenas as bibliotecas padrão net/smtp e crypto/tls; não requer pacotes de terceiros.//// Este arquivo usa a tag de build //go:build ignore para que seja excluído do// build padrão quando outros arquivos de demonstração existirem no mesmo diretório.// Para executar este exemplo isoladamente, use: go run smtp-go-demo.pt.gopackage mainimport ("crypto/tls""encoding/base64""fmt""log""net""net/smtp")// Test465 demonstra o envio de um e-mail no formato HTML através da porta 465 (SSL/TLS).//// Fluxo de trabalho:// 1. Configurar o endereço do servidor SMTP, a porta, a conta de envio e a senha SMTP;// 2. Construir os cabeçalhos do e-mail (From / To / Cc / Bcc / Subject / Content-Type, etc.);// 3. Codificar o corpo em Base64 e anexá-lo após os cabeçalhos// (uma linha em branco é necessária entre o cabeçalho e o corpo);// 4. Usar smtp.PlainAuth para criar um objeto de autenticação PLAIN;// 5. Chamar SendMailWithTLS para entregar a mensagem por uma conexão TLS.//// Valor de retorno: retorna nil em caso de sucesso, ou o erro específico em caso de falha.func Test465() error {// Endereço do servidor SMTP. Para o Tencent Cloud Email Push é fixo em smtp.qcloudmail.com.host := "smtp.qcloudmail.com"// Porta SMTP: 465 significa uma conexão criptografada SSL/TLS;// Se quiser usar STARTTLS, mude para a porta 25, e o tls.Dial no código// também deve ser alterado para net.Dial + StartTLS.port := 465// email: o Endereço de Remetente que foi criado e verificado no console;// deve corresponder à conta proprietária da senha SMTP.email := "abc@cd.com"// password: a senha SMTP dedicada gerada para este endereço de remetente// na página "SMTP Settings" do console.// NÃO é a senha de login do Tencent Cloud nem a chave de API.password := "****"// Endereço do destinatário (obrigatório, pelo menos um)toEmail := "test@test123.com"// Endereço de Cc (opcional)ccEmail := "cc@test123.com"// Endereço de Bcc (opcional)bccEmail := "bcc@test123.com"// Constrói o cabeçalho do e-mail. O protocolo SMTP exige que os campos do// cabeçalho sejam escritos no formato "Key: Value\\r\\n", e uma linha em branco// ("\\r\\n") é necessária após todos os cabeçalhos, seguida do corpo.header := make(map[string]string)// "From" é recomendado no formato "Nome de Exibição <endereço de remetente>";// o nome de exibição será mostrado como o apelido do remetente na caixa de entrada.header["From"] = "test " + "<" + email + ">"header["To"] = toEmailheader["Cc"] = ccEmailheader["Bcc"] = bccEmail// Assunto do e-mail. Se contiver caracteres não-ASCII, recomenda-se a// codificação RFC 2047 (=?UTF-8?B?...?=). Este exemplo usa ASCII puro,// portanto nenhuma codificação é aplicada.header["Subject"] = "test subject"// Content-Type especifica que o corpo é HTML e declara o charset como UTF-8.header["Content-Type"] = "text/html; charset=UTF-8"// Content-Transfer-Encoding especifica a codificação de transferência do corpo.// Usar base64 evita que caracteres não-ASCII ou especiais sejam truncados// ou corrompidos durante a transmissão SMTP.header["Content-Transfer-Encoding"] = "base64"// Exemplo de corpo HTMLbody := "<!DOCTYPE html>\\n<html>\\n<head>\\n<meta charset=\\"utf-8\\">\\n<title>hello world</title>\\n</head>\\n<body>\\n " +"<h1>Meu Primeiro Título</h1>\\n <p>Meu primeiro parágrafo.</p>\\n</body>\\n</html>"// Para enviar um e-mail em texto puro, comente a configuração HTML acima// e habilite as duas linhas a seguir://header["Content-Type"] = "text/plain; charset=UTF-8"//body := "test body"// Monta a mensagem SMTP final: primeiro concatena cada cabeçalho como// "Key: Value\\r\\n", depois adiciona uma linha em branco como separador e,// por fim, anexa o corpo codificado em Base64.message := ""for k, v := range header {message += fmt.Sprintf("%s: %s\\r\\n", k, v)}message += "\\r\\n" + base64.StdEncoding.EncodeToString([]byte(body))// Cria um objeto de autenticação PLAIN.// O 1º parâmetro "identity" geralmente é vazio; o 2º é o nome de usuário// (o endereço de remetente); o 3º é a senha SMTP; o 4º é o host// (usado para validação no servidor).auth := smtp.PlainAuth("",email,password,host,)// Chama a função de envio em versão TLS com o endereço do servidor, objeto de// autenticação, remetente, lista de destinatários e a mensagem bruta.// Atenção: a lista "to" é usada para o comando SMTP RCPT TO e determina// quais caixas de correio realmente receberão o e-mail. Se quiser que os// destinatários de Cc/Bcc também recebam a mensagem, é necessário adicionar// ccEmail / bccEmail também a esta lista.err := SendMailWithTLS(fmt.Sprintf("%s:%d", host, port),auth,email,[]string{toEmail},[]byte(message),)if err != nil {fmt.Println("Send email error:", err)} else {fmt.Println("Send mail success!")}return err}// Dial estabelece uma conexão criptografada por TLS com o servidor SMTP e retorna// um *smtp.Client utilizável.//// Parâmetro:// - addr: endereço do servidor no formato "host:port", por exemplo, "smtp.qcloudmail.com:465".//// Observações:// - O smtp.Dial da biblioteca padrão usa uma conexão em texto puro por padrão.// Para a porta 465, um canal TLS deve ser estabelecido primeiro e depois// encapsulado em um cliente SMTP, por isso esta função usa tls.Dial em vez de net.Dial.// - O segundo argumento é *tls.Config; passar nil significa usar a configuração// padrão (que valida o certificado do servidor).// Para pular a validação do certificado (NÃO recomendado em produção), passe// &tls.Config{InsecureSkipVerify: true}.func Dial(addr string) (*smtp.Client, error) {conn, err := tls.Dial("tcp", addr, nil)if err != nil {log.Println("tls.Dial Error:", err)return nil, err}// smtp.NewClient precisa do host (sem a porta) para o handshake EHLO/HELO.host, _, _ := net.SplitHostPort(addr)return smtp.NewClient(conn, host)}// SendMailWithTLS realiza uma entrega completa de e-mail sobre uma conexão SMTP// criptografada por TLS.//// Parâmetros:// - addr: endereço do servidor SMTP no formato "host:port".// - auth: objeto de autenticação SMTP, pode ser criado por smtp.PlainAuth;// passe nil se nenhuma autenticação for necessária.// - from: o endereço de remetente usado no comando MAIL FROM;// deve corresponder à conta autenticada.// - to: lista de destinatários usada no comando RCPT TO, incluindo todos os// destinatários reais de To, Cc e Bcc.// - msg: a mensagem de e-mail completa (Header + linha em branco + Body), no formato RFC 822.//// Etapas:// 1. Estabelecer uma conexão TLS + SMTP via Dial;// 2. Se o servidor suportar a extensão AUTH, executar a autenticação;// 3. Executar os comandos MAIL FROM, RCPT TO e DATA em ordem;// 4. Escrever o corpo do e-mail e fechar o fluxo de dados;// 5. Chamar o comando QUIT para encerrar a sessão de forma adequada.//// Qualquer etapa que falhar retornará imediatamente o erro correspondente.func SendMailWithTLS(addr string, auth smtp.Auth, from string,to []string, msg []byte) (err error) {// 1. Estabelece a conexão TLS e obtém o cliente SMTP.c, err := Dial(addr)if err != nil {log.Println("Create smtp client error:", err)return err}// Garante que a conexão seja finalmente fechada para evitar vazamentos de conexão.defer c.Close()// 2. Se auth for fornecido e o servidor anunciar a extensão AUTH via EHLO,// realizar a autenticação.if auth != nil {if ok, _ := c.Extension("AUTH"); ok {if err = c.Auth(auth); err != nil {log.Println("Error during AUTH", err)return err}}}// 3. Envia o comando MAIL FROM para informar ao servidor quem é o remetente.if err = c.Mail(from); err != nil {return err}// 4. Envia um comando RCPT TO para cada destinatário.for _, addr := range to {if err = c.Rcpt(addr); err != nil {return err}}// 5. Envia o comando DATA e obtém um writer para escrever o conteúdo do e-mail (Header + Body).w, err := c.Data()if err != nil {return err}_, err = w.Write(msg)if err != nil {return err}// Fecha o writer para marcar o fim da entrada do corpo// (no protocolo SMTP, o fim é indicado por "\\r\\n.\\r\\n").err = w.Close()if err != nil {return err}// 6. Envia o comando QUIT para encerrar a sessão com o servidor de forma adequada.return c.Quit()}// main é o ponto de entrada que chama diretamente Test465 para disparar um envio.// Em uma integração real de negócio, é recomendado extrair os parâmetros de envio// (conta, senha, destinatários, etc.) para configuração ou argumentos de função,// e realizar tratamento de erros e tentativas de repetição mais granulares em Test465.func main() {Test465()}
Esta página foi útil?
Você também pode entrar em contato com a Equipe de vendas ou Enviar um tíquete em caso de ajuda.
comentários