From 36535cab5b812b874e13776ecd25f7f47daf8211 Mon Sep 17 00:00:00 2001 From: Harshit Raj Date: Tue, 2 Nov 2021 13:08:45 +0530 Subject: [PATCH] Make Email Async --- auth/otp.go | 7 +++++-- cmd/iitk-coin/main.go | 7 +++++++ mail/config.go | 43 +++++++++++++++++++++++++++++++++++++++++++ mail/send.go | 40 ---------------------------------------- mail/service.go | 34 ++++++++++++++++++++++++++++++++++ mail/test.go | 24 ++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 42 deletions(-) create mode 100644 mail/config.go delete mode 100644 mail/send.go create mode 100644 mail/service.go create mode 100644 mail/test.go diff --git a/auth/otp.go b/auth/otp.go index 2e725ec..a9ecba4 100644 --- a/auth/otp.go +++ b/auth/otp.go @@ -40,10 +40,13 @@ func GenerateOtp(rollNo string) error { return errors.NewHTTPError(err, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } - if err = mail.SendOTP(rollNo, otp); err != nil { - return errors.NewHTTPError(err, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) + emailRequest := mail.EmailRequest{ + To: rollNo, + OTP: otp, } + mail.MailChannel <- emailRequest + return nil } diff --git a/cmd/iitk-coin/main.go b/cmd/iitk-coin/main.go index 40c4f3e..37a5d79 100644 --- a/cmd/iitk-coin/main.go +++ b/cmd/iitk-coin/main.go @@ -4,6 +4,7 @@ import ( _ "github.com/bhuvansingla/iitk-coin/config" "github.com/bhuvansingla/iitk-coin/database" _ "github.com/bhuvansingla/iitk-coin/logger" + "github.com/bhuvansingla/iitk-coin/mail" "github.com/bhuvansingla/iitk-coin/server" log "github.com/sirupsen/logrus" ) @@ -15,6 +16,12 @@ func main() { log.Error("Error connecting to database: %s", err) return } + + err = mail.Test() + if err != nil { + log.Error("Error sending mail: %s", err) + return + } err = server.Start() if err != nil { diff --git a/mail/config.go b/mail/config.go new file mode 100644 index 0000000..b7876e6 --- /dev/null +++ b/mail/config.go @@ -0,0 +1,43 @@ +package mail + +import ( + "net/smtp" + + "github.com/spf13/viper" +) + +type smtpServer struct { + host string + port string +} + +func (s *smtpServer) Address() string { + return s.host + ":" + s.port +} + +type EmailRequest struct { + To string + OTP string +} + +var MailChannel chan EmailRequest +var from string +var password string +var server smtpServer +var auth smtp.Auth +var otpValidity string + +func init() { + MailChannel = make(chan EmailRequest) + from = viper.GetString("MAIL.FROM") + password = viper.GetString("MAIL.PASSWORD") + + otpValidity = viper.GetString("OTP.EXPIRY_PERIOD_IN_MIN") + + server = smtpServer{host: viper.GetString("MAIL.HOST"), port: viper.GetString("MAIL.PORT")} + go mailService(MailChannel) +} + +func authorize() { + auth = smtp.PlainAuth("", from, password, server.host) +} diff --git a/mail/send.go b/mail/send.go deleted file mode 100644 index 37351ea..0000000 --- a/mail/send.go +++ /dev/null @@ -1,40 +0,0 @@ -package mail - -import ( - "net/smtp" - - log "github.com/sirupsen/logrus" - "github.com/spf13/viper" -) - -type smtpServer struct { - host string - port string -} - -func (s *smtpServer) Address() string { - return s.host + ":" + s.port -} - -func SendOTP(toRollNo string, otp string) (err error) { - - from := viper.GetString("MAIL.FROM") - password := viper.GetString("MAIL.PASSWORD") - to := []string{ - toRollNo + "@iitk.ac.in", - } - smtpServer := smtpServer{host: viper.GetString("MAIL.HOST"), port: viper.GetString("MAIL.PORT")} - - message := []byte("Your OTP is " + otp) - - auth := smtp.PlainAuth("", from, password, smtpServer.host) - - err = smtp.SendMail(smtpServer.Address(), auth, from, to, message) - - if err != nil { - log.Error("error sending mail: ", err) - return err - } - log.Info("Mail sent to ", toRollNo) - return nil -} diff --git a/mail/service.go b/mail/service.go new file mode 100644 index 0000000..64a3faa --- /dev/null +++ b/mail/service.go @@ -0,0 +1,34 @@ +package mail + +import ( + "net/smtp" + + log "github.com/sirupsen/logrus" +) + +func mailService(mailChannel chan EmailRequest) { + authorize() + for request := range mailChannel { + to := []string{request.To+"@iitk.ac.in"} + msg := []byte("To: " + request.To + "@iitk.ac.in" + "\n" + + "From: " + "IITK-Coin<" + from + ">\n" + + "Subject: IITK-Coin One Time Password\n" + + "Your OTP is " + request.OTP + "\n" + + "This OTP is valid for " + otpValidity + " minutes and don't share it with anyone." + + "\n") + + err := smtp.SendMail(server.Address(), auth, from, to, msg) + + // if error, try to login again + if err != nil { + authorize() + err = smtp.SendMail(server.Address(), auth, from, to, msg) + if err != nil { + log.Error("Error sending mail: " + err.Error()) + continue + } + } + + log.Info("Mail sent to ", request.To) + } +} diff --git a/mail/test.go b/mail/test.go new file mode 100644 index 0000000..0b34729 --- /dev/null +++ b/mail/test.go @@ -0,0 +1,24 @@ +package mail + +import ( + "net/smtp" + + log "github.com/sirupsen/logrus" +) + +func Test() (err error) { + authorize() + to := []string{from} + msg := []byte("To: " + from + "\n" + + "From: " + "IITK-Coin<" + from + ">\n" + + "Subject: IITK-Coin Test Mail\n" + + "This is a Test Mail" + + "\n") + + err = smtp.SendMail(server.Address(), auth, from, to, msg) + if err != nil { + return + } + log.Info("Test mail sent") + return +}