processSendJob runs in a background goroutine to send emails
(job *Job, toSend []BrokerWithStatus, sender email.Sender)
| 863 | |
| 864 | // processSendJob runs in a background goroutine to send emails |
| 865 | func (s *Server) processSendJob(job *Job, toSend []BrokerWithStatus, sender email.Sender) { |
| 866 | sent := 0 |
| 867 | failed := 0 |
| 868 | rateLimitMs := s.config.Options.RateLimitMs |
| 869 | if rateLimitMs == 0 { |
| 870 | rateLimitMs = 2000 // Default 2 second delay |
| 871 | } |
| 872 | |
| 873 | // Set daily limit based on provider |
| 874 | dailyLimit := DailyLimitSMTP // Default for SMTP |
| 875 | if s.config.Email.Provider == "sendgrid" { |
| 876 | dailyLimit = DailyLimitSendGrid |
| 877 | } else if s.config.Email.Provider == "resend" { |
| 878 | dailyLimit = DailyLimitResend |
| 879 | } |
| 880 | job.DailyLimit = dailyLimit |
| 881 | |
| 882 | // Track remaining brokers for persistence |
| 883 | remaining := make([]string, len(toSend)) |
| 884 | for i, b := range toSend { |
| 885 | remaining[i] = b.ID |
| 886 | } |
| 887 | |
| 888 | for i, b := range toSend { |
| 889 | // Check if job was cancelled |
| 890 | if job.IsCancelled() { |
| 891 | break |
| 892 | } |
| 893 | |
| 894 | // Check daily limit |
| 895 | if sent >= dailyLimit { |
| 896 | job.DaySent = sent |
| 897 | job.Status = JobStatusPaused |
| 898 | job.Error = fmt.Sprintf("Daily limit of %d emails reached. Remaining %d brokers will be sent when you restart tomorrow.", dailyLimit, len(remaining)) |
| 899 | s.saveJobProgress(job, sent, failed, remaining) |
| 900 | log.Printf("Job paused: daily limit of %d reached, %d remaining", dailyLimit, len(remaining)) |
| 901 | return |
| 902 | } |
| 903 | |
| 904 | // Update current broker |
| 905 | job.Update(sent, failed, b.Name) |
| 906 | |
| 907 | // Generate email |
| 908 | rendered, err := s.tmplEngine.Render("generic", s.config.Profile, b.Broker) |
| 909 | if err != nil { |
| 910 | failed++ |
| 911 | job.Update(sent, failed, b.Name) |
| 912 | // Remove from remaining even on failure |
| 913 | remaining = remaining[1:] |
| 914 | s.saveJobProgress(job, sent, failed, remaining) |
| 915 | continue |
| 916 | } |
| 917 | |
| 918 | msg := email.Message{ |
| 919 | To: b.Email, |
| 920 | From: s.config.Email.From, |
| 921 | Subject: rendered.Subject, |
| 922 | Body: rendered.Body, |
no test coverage detected