Kai Meredith

Recruiting / CRM

Busy Bees Maid Service: Hiring Automation CRM

Twilio API Google Docs (Templates) Forms Event-Driven
The Mission A service business was losing candidates to slow follow-ups. I built an event-driven hiring CRM that texts applicants via Twilio the moment their status changes, respects quiet hours, and keeps the pipeline moving without manual intervention.

System Architecture

graph TD Manager[Manager Changes Status] -->|Trigger| Script Script -->|Decision| Check{Which Stage?} Check -->|Invite| SMS[Send Twilio SMS] Check -->|Reject| Email[Send Gmail] SMS -->|Wait| Form[Watch for Form Submit] Form -->|Update| Sheet[Update Status] Sheet -->|Notify| Slack[Slack Alert]

Key Engineering Challenges

  • "Quiet Hours" Logic: The system queues SMS messages. A status update at 11 PM schedules the Twilio call for 8 AM — no one gets a text in the middle of the night, and no follow-up gets dropped.
  • Dynamic Templating: Script pulls email/SMS body text from a Template Mappings Google Doc, letting the non-technical owner rewrite copy without touching the code.

Code Snippet

onEdit.js
// Logic: Watch for Status Change -> Execute Action

function onEdit(e) {
  const range = e.range;
  const sheet = range.getSheet();
  
  // Only trigger on 'Pipeline Progress' column changes
  if (sheet.getName() === 'Application' && range.getColumn() === PIPELINE_COL) {
    const status = e.value;
    const row = range.getRow();
    const candidate = getCandidateData(row);

    if (status === 'Invite to Interview') {
       // Check Quiet Hours before sending SMS
       if (isQuietHours()) {
         scheduleMessageForMorning(candidate);
       } else {
         sendTwilioSMS(candidate.phone, getTemplate('INVITE_SMS'));
       }
    }
  }
}