package worker import ( "api.qobiltu.id/assets" "bytes" "context" "encoding/json" "fmt" "github.com/hibiken/asynq" "html/template" "log/slog" ) const ( TaskSendVerifyEmailMaxRetry = 3 TaskSendVerifyEmail = "task:send_verify_email" TaskSendVerifyEmailSubject = "Verifikasi Email" ) type PayloadSendVerifyEmail struct { EmailAddress string `json:"email_address"` VerificationCode string `json:"verification_code"` ExpirationInMinutes int `json:"expiration_in_minutes"` Subject string `json:"subject"` } func (d *RedisTaskDistributor) DistributeTaskSendVerifyEmail( ctx context.Context, payload *PayloadSendVerifyEmail, opts ...asynq.Option, ) error { jsonPayload, err := json.Marshal(payload) if err != nil { return fmt.Errorf("failed to marshal task payload: %w", err) } task := asynq.NewTask(TaskSendVerifyEmail, jsonPayload, opts...) _, err = d.client.EnqueueContext(ctx, task) if err != nil { return fmt.Errorf("failed to enqueue task: %w", err) } return nil } func (p *RedisTaskProcessor) ProcessTaskSendVerifyEmail(ctx context.Context, task *asynq.Task) error { var payload PayloadSendVerifyEmail if err := json.Unmarshal(task.Payload(), &payload); err != nil { return fmt.Errorf("failed to unmarshal payload: %w", asynq.SkipRetry) } var tmpl *template.Template tmpl, err := template.ParseFS(assets.EmbeddedFiles, assets.EmailConfirmationTemplatePath) if err != nil { return fmt.Errorf("failed to parse email template: %w", err) } var body bytes.Buffer if err := tmpl.ExecuteTemplate(&body, "htmlBody", payload); err != nil { return fmt.Errorf("failed to execute email template: %w", err) } htmlContent := body.String() slog.Info("Sending verification email", slog.String("email", payload.EmailAddress)) err = p.emailSender.Send(payload.EmailAddress, payload.Subject, htmlContent, payload) if err != nil { return fmt.Errorf("failed to send verify email: %w", err) } slog.Info("Verification email sent successfully", slog.String("email", payload.EmailAddress)) return nil }