Automatically reads a “Candidate Status” tab in Google Sheets every day at 18:00 Asia/Kolkata, filters rows with exact (case-sensitive) rejection statuses and sends one personalized rejection email per candidate via SMTP (Gmail). It rate-limits sends, supports DRY_RUN previews and writes a timestamp back to rejection_sent_at to avoid duplicates.
status REJECT_STATUS_CSV (exact match), with valid candidate_email and empty rejection_sent_atRATE_LIMIT_SECONDS (default 10s) between emailsrejection_sent_atcandidate_name, candidate_email, role, status, recruiter_name, recruiter_email, company_name, interview_feedback (optional), template_variant (optional), language (optional), rejection_sent_atSPREADSHEET_IDSOURCE_SHEET = Candidate StatusTIMEZONE = Asia/KolkataREJECT_STATUS_CSV = e.g., RejectedSMTP_FROM = e.g., [[email protected]](/cdn-cgi/l/email-protection)SUBJECT_TEMPLATE = Regarding your application for {{role}} at {{company_name}}HTML_TEMPLATE / TEXT_TEMPLATERATE_LIMIT_SECONDS = 10INCLUDE_WEEKENDS = trueDRY_RUN = falseStatuses : REJECT_STATUS_CSV supports comma-separated exact values (e.g., Rejected,Not Selected)
Templates : Edit SUBJECT_TEMPLATE, HTML_TEMPLATE, TEXT_TEMPLATE
Variables: {{candidate_name}}, {{role}}, {{company_name}}, {{recruiter_name}}, and optional {{feedback_text}}/{{feedback_html}} from interview_feedback
Schedule : Change Cron time from 18:00 to your preferred hour
Rate limit : Tune RATE_LIMIT_SECONDS for SMTP policy
Preview : Set DRY_RUN=true for a safe, no-send preview
recruiter_emaillanguage or template_variant columnsRejected todaycompany_name per row and personalize subject linesstatus exactly matches REJECT_STATUS_CSV (case-sensitive) and candidate_email is presentrejection_sent_at is blank before run; workflow sets it after sendingcandidate_name, role, company_name, recruiter_name in the sheetAsia/Kolkata and Cron = 18:00Want us to tailor the template, add a summary report or wire up company-based variants? Contact our n8n automation engineers at WeblineIndia and we’ll plug it in.


