add email sender and send email with password

This commit is contained in:
2026-06-29 23:34:09 +07:00
parent 7806061313
commit 4d9b73cb34
4 changed files with 129 additions and 1 deletions
+7 -1
View File
@@ -4,6 +4,7 @@ import (
"context"
_ "embed"
"evening_detective_server/internal/app"
"evening_detective_server/internal/modules/email_sender"
"evening_detective_server/internal/modules/password_generator"
"evening_detective_server/internal/repos/users_repo"
"evening_detective_server/internal/services/users_service"
@@ -43,7 +44,12 @@ func main() {
usersRepo := users_repo.NewUserRepo(dbpool)
passwordGenerator := password_generator.NewGenerator(8)
usersService := users_service.NewUsersService(usersRepo, passwordGenerator)
smtpHost := os.Getenv("SMTP_HOST")
smtpPort := os.Getenv("SMTP_PORT")
smtpUser := os.Getenv("SMTP_USER")
smtpPassword := os.Getenv("SMTP_PASSWORD")
emailSender := email_sender.NewSender(smtpHost, smtpPort, smtpUser, smtpPassword)
usersService := users_service.NewUsersService(usersRepo, passwordGenerator, emailSender)
// Create a listener on TCP port
lis, err := net.Listen("tcp", ":8080")
@@ -0,0 +1,13 @@
package email_sender
import "context"
type Message struct {
To string
Subject string
Body string
}
type IEmailSender interface {
Send(ctx context.Context, message Message) error
}
+94
View File
@@ -0,0 +1,94 @@
package email_sender
import (
"context"
"crypto/tls"
"fmt"
"net/smtp"
)
type sender struct {
smtpHost string
smtpPort string
smtpUser string
smtpPassword string
}
func NewSender(
smtpHost string,
smtpPort string,
smtpUser string,
smtpPassword string,
) IEmailSender {
return &sender{
smtpHost: smtpHost,
smtpPort: smtpPort,
smtpUser: smtpUser,
smtpPassword: smtpPassword,
}
}
func (s *sender) Send(_ context.Context, message Message) error {
emailMessage := []byte(fmt.Sprintf(
"To: %s\r\n"+
"Subject: %s\r\n"+
"MIME-Version: 1.0\r\n"+
"Content-Type: text/plain; charset=utf-8\r\n"+
"\r\n"+
"%s\r\n",
message.To,
message.Subject,
message.Body,
))
// Настраиваем TLS
tlsConfig := &tls.Config{
ServerName: s.smtpHost,
}
// Подключаемся к серверу
conn, err := tls.Dial("tcp", s.smtpHost+":"+s.smtpPort, tlsConfig)
if err != nil {
return err
}
defer conn.Close()
// Создаем SMTP клиент
client, err := smtp.NewClient(conn, s.smtpHost)
if err != nil {
return err
}
defer client.Quit()
// Аутентификация
auth := smtp.PlainAuth("", s.smtpUser, s.smtpPassword, s.smtpHost)
if err = client.Auth(auth); err != nil {
return err
}
// Указываем отправителя
if err = client.Mail(s.smtpUser); err != nil {
return err
}
// Указываем получателя
if err = client.Rcpt(message.To); err != nil {
return err
}
// Отправляем данные письма
w, err := client.Data()
if err != nil {
return err
}
_, err = w.Write(emailMessage)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return nil
}
@@ -2,8 +2,10 @@ package users_service
import (
"context"
"evening_detective_server/internal/modules/email_sender"
"evening_detective_server/internal/modules/password_generator"
"evening_detective_server/internal/repos/users_repo"
"fmt"
"golang.org/x/crypto/bcrypt"
)
@@ -11,15 +13,18 @@ import (
type UsersService struct {
usersRepo *users_repo.UsersRepo
passwordGenerator password_generator.IPasswordGenerator
emailSender email_sender.IEmailSender
}
func NewUsersService(
usersRepo *users_repo.UsersRepo,
passwordGenerator password_generator.IPasswordGenerator,
emailSender email_sender.IEmailSender,
) *UsersService {
return &UsersService{
usersRepo: usersRepo,
passwordGenerator: passwordGenerator,
emailSender: emailSender,
}
}
@@ -43,5 +48,15 @@ func (s *UsersService) AddUser(
string(hashedPassword),
"user",
)
if err != nil {
return err
}
err = s.emailSender.Send(ctx, email_sender.Message{
To: email,
Subject: "Приветствую тебя, детектив!",
Body: fmt.Sprintf("Вот твой пароль для входа в систему: %s", password),
})
return err
}