Guide

Automate Scheduling and Email Follow-Ups

Booking the meeting is half the job; chasing silence is the other half. This guide finds a shared slot, sends the invite, and puts follow-ups to non-responders on a cron so nobody has to remember to nudge.

Written by Prem Keshari Senior SRE

Reviewed by Qasim Muhammad

VerifiedCLI 3.1.17 · Google, Outlook · last tested June 9, 2026

How do I find a free slot and send the calendar invite?

You find the slot with nylas calendar availability find, which returns only the windows every participant shares, then book it with events create. Two commands replace the usual five-email back-and-forth: one query checks every calendar at once, and the event command delivers a real invite each attendee can accept.

The availability command defaults to 30-minute slots on 15-minute boundaries and searches the next 7 days unless you pass --start and --end. The invite that events create produces is a standard iCalendar object per RFC 5545, so it lands as an accept-or-decline card in Gmail and Outlook alike.

# 30-minute slots both sides share, searched over the next 7 days
nylas calendar availability find \
  --participants you@company.com,alex@client.com \
  --duration 30 --interval 15 --json

# Book the first slot it returned
nylas calendar events create \
  --title "Kickoff call" \
  --start "2026-06-11 10:00" --end "2026-06-11 10:30" \
  --participant alex@client.com

How do I queue the first follow-up before anyone goes silent?

Queue the follow-up at the same moment you send the invite email, using nylas email send with the --schedule flag. It accepts relative durations like 2d or absolute timestamps, and the message waits in a provider-side queue — no daemon running on your machine.

Sending the chaser at decision time means the follow-up exists even if your laptop is off in 2 days. The command below sends the invite note now and queues a nudge 48 hours out; if the invitee replies first, you pull the queued message back with email scheduled cancel before it ever leaves.

# Invite email now
nylas email send --to alex@client.com \
  --subject "Kickoff call: Thursday 10:00 AM" \
  --body "Invite is on your calendar. Reply here if the time doesn't work." --yes

# Follow-up, queued for 2 days from now
nylas email send --to alex@client.com \
  --subject "Re: Kickoff call: Thursday 10:00 AM" \
  --body "Checking in. Does Thursday 10:00 AM still work? Happy to move it." \
  --schedule 2d --yes

How do I detect non-responders with email search?

A non-responder is any invitee whose address returns zero results from nylas email search filtered by --from and --after the invite date. The search runs against the mailbox the provider holds, so a reply sent from any device or client counts.

The search command returns 20 results by default and auto-paginates when you raise --limit past 200, but for reply detection you only care whether the count is zero. Pipe the --json output through jq 'length' to get a number your script can branch on directly.

# Any reply from the invitee since the invite went out on June 9?
nylas email search "*" --from alex@client.com --after 2026-06-09 --json | jq 'length'

# 0 means silence — they're a follow-up candidate

How do I run the follow-up loop on a cron schedule?

Run the loop as a shell script under cron: each weekday morning it counts replies from the invitee, counts follow-ups already sent, and sends the next chaser only when both gates pass. The sent-folder check is the guard from the TL;DR — a reply sets the count above zero and the script exits without sending anything.

The script caps the sequence at 2 follow-ups by searching its own SENT folder, so a cron job that fires every day can't turn into a spam loop. The crontab line below uses the standard five time fields documented in the crontab(5) man page and runs at 9:00 AM, Monday through Friday.

#!/usr/bin/env bash
set -euo pipefail
INVITEE="alex@client.com"
INVITE_DATE="2026-06-09"

# Gate 1: did they reply since the invite went out?
REPLIES=$(nylas email search "*" --from "$INVITEE" --after "$INVITE_DATE" --json | jq 'length')
[ "$REPLIES" -gt 0 ] && { echo "replied — stopping"; exit 0; }

# Gate 2: cap the sequence at 2 follow-ups
SENT=$(nylas email search "Kickoff call" --to "$INVITEE" --in SENT --json | jq 'length')
[ "$SENT" -ge 3 ] && { echo "sequence done — flag for manual outreach"; exit 0; }

nylas email send --to "$INVITEE" \
  --subject "Re: Kickoff call: Thursday 10:00 AM" \
  --body "Still hoping to connect Thursday. Reply with a better time if needed." --yes

# crontab entry — 9:00 AM, Monday to Friday:
# 0 9 * * 1-5 /usr/local/bin/followup.sh >> ~/followup.log 2>&1

How do I cancel a queued follow-up when the invitee replies?

Cancel a queued follow-up with nylas email scheduled cancel, which removes the message from the provider-side queue before it sends. List pending messages first with email scheduled list to get the schedule ID, then cancel by that ID.

A message queued with --schedule 2d gives you a 48-hour cancellation window; once the send time passes, the message is delivered and behaves like any other sent email. Add --force to skip the confirmation prompt when cancelling from a script rather than an interactive shell.

# See everything still waiting in the queue
nylas email scheduled list

# Pull the chaser back before it sends (no prompt)
nylas email scheduled cancel <schedule-id> --force

Next steps