package worker import ( "api.qobiltu.id/assets" "bytes" "context" "encoding/json" "fmt" "github.com/hibiken/asynq" "html/template" "log/slog" ) const ( TaskSendForgotPasswordEmailMaxRetry = 5 TaskSendForgotPasswordEmail = "task:send_forgot_password_email" TaskSendForgotPasswordEmailSubject = "Permintaan Reset Password" ) type PayloadSendForgotPasswordEmail struct { EmailAddress string `json:"email_address"` ResetToken string `json:"reset_token"` ExpirationInMinutes int `json:"expiration_in_minutes"` Subject string `json:"subject"` AppName string `json:"app_name"` } func (d *RedisTaskDistributor) DistributeTaskSendForgotPasswordEmail( ctx context.Context, payload *PayloadSendForgotPasswordEmail, 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(TaskSendForgotPasswordEmail, 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) ProcessTaskSendForgotPasswordEmail(ctx context.Context, task *asynq.Task) error { var payload PayloadSendForgotPasswordEmail 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.EmailForgotPasswordTemplatePath) if err != nil { return fmt.Errorf("failed to parse forgot password email template: %w", err) } var body bytes.Buffer if err := tmpl.ExecuteTemplate(&body, "htmlBody", payload); err != nil { return fmt.Errorf("failed to execute forgot password email template: %w", err) } htmlContent := body.String() slog.Info("Sending forgot password 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 forgot password email: %w", err) } slog.Info("Forgot password email sent successfully", slog.String("email", payload.EmailAddress)) return nil }