package answerwc import ( "context" "encoding/json" "fmt" "github.com/go-redis/redis/v8" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" senders2 "penahub.gitlab.yandexcloud.net/backend/quiz/worker/internal/senders" "penahub.gitlab.yandexcloud.net/backend/quiz/worker/internal/wctools" "time" ) type DepsRespWorker struct { Redis *redis.Client Dal *dal.DAL MailClient *senders2.MailLeadSender } type RespWorker struct { deps DepsRespWorker errChan chan<- error } func NewRespWorker(deps DepsRespWorker, errChan chan<- error) *RespWorker { return &RespWorker{ deps: deps, errChan: errChan, } } func (w *RespWorker) Start(ctx context.Context) { ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() for { select { case <-ticker.C: w.processPendingAnswer(ctx) case <-ctx.Done(): return } } } func (w *RespWorker) processPendingAnswer(ctx context.Context) { keys, err := w.deps.Redis.Keys(ctx, "toRespondent:*").Result() if err != nil { w.reportError(err, "Error retrieving keys from Redis") return } for _, key := range keys { func() { answerJSON, err := w.deps.Redis.GetDel(ctx, key).Result() if err == redis.Nil { return } else if err != nil { w.reportError(err, "Error getting and deleting data from Redis") return } defer func() { if r := recover(); r != nil { w.reportError(nil, fmt.Sprintf("recovering from panic or error setting redis value %v", r)) _ = w.deps.Redis.Set(ctx, key, answerJSON, 0).Err() } }() var answer model.Answer err = json.Unmarshal([]byte(answerJSON), &answer) if err != nil { w.reportError(err, "Error unmarshalling answer") return } answerContent, err := wctools.ProcessAnswer(answer.Content) if err != nil { w.reportError(err, "Error processing answer content") return } quizConfig, accountId, err := w.deps.Dal.QuizRepo.GetQuizConfig(ctx, answer.QuizId) if err != nil { w.reportError(err, "Error getting quiz config") return } quiz, err := w.deps.Dal.QuizRepo.GetQuizById(ctx, accountId, answer.QuizId) if err != nil { w.reportError(err, "Error getting quiz") return } quizConfig.Mailing.Reply = quiz.Name if quizConfig.Mailing.Theme == "" { quizConfig.Mailing.Theme = quiz.Name } allAnswers, err := w.deps.Dal.WorkerAnsRepo.GetAllAnswersByQuizID(ctx, answer.Session) if err != nil { w.reportError(err, "Error getting all answers by quizID") return } questionsMap, sortedallAnswers, err := w.deps.Dal.QuestionRepo.GetMapQuestions(ctx, allAnswers) if err != nil { w.reportError(err, "Error getting questionsMap") return } fmt.Println("ATATATA", questionsMap, sortedallAnswers) err = w.processMessageToSMTP(quizConfig, questionsMap, sortedallAnswers, answerContent, answer.CreatedAt) if err != nil { w.reportError(err, "Error sending message to SMTP") } }() } } func (w *RespWorker) processMessageToSMTP(quizConfig model.QuizConfig, questionsMap map[uint64]string, allAnswers []model.ResultAnswer, answerContent model.ResultContent, answerTime time.Time) error { theme := quizConfig.Mailing.Theme quizConfig.Mailing.Theme = quizConfig.Mailing.Reply data := senders2.TemplateData{ QuizConfig: quizConfig.Mailing, AnswerContent: answerContent, AllAnswers: allAnswers, QuestionsMap: questionsMap, } dayOfWeek := wctools.DaysOfWeek[answerTime.Format("Monday")] monthOfYear := wctools.MonthsOfYear[answerTime.Format("January")] formattedTime := fmt.Sprintf("%s, %d %s %d г., %02d:%02d (UTC%s)", dayOfWeek, answerTime.Day(), monthOfYear, answerTime.Year(), answerTime.Hour(), answerTime.Minute(), answerTime.Format("-07:00"), ) data.AnswerTime = formattedTime err := w.deps.MailClient.SendMailWithAttachment(answerContent.Email, theme, toClientTemplate, data, nil) if err != nil { return err } return nil } func (w *RespWorker) reportError(err error, message string) { if err != nil { fmt.Println(message + ": " + err.Error()) w.errChan <- err } }