A practical field guide from Automation Ace.
How to Send a Google Calendar Daily Agenda to Slack with Zapier
A daily agenda digest in Slack is one of the most useful recurring automations for teams that coordinate through a shared calendar. Rather than requiring everyone to open Google Calendar each morning, a Zap can pull the day's events and post a formatted summary to a channel — giving shared visibility without requiring a meeting or a manual report. This guide covers how to build that workflow in Zapier: a scheduled trigger, a Google Calendar search step, a formatting pass, and a Slack message action.
The Architecture: Schedule → Search → Format → Post
The core pattern has four stages:
- Schedule by Zapier trigger — fires at a fixed time each morning (e.g., 8 AM)
- Google Calendar: Find Events — searches for events occurring today on the target calendar
- Formatter by Zapier or Code by Zapier — shapes the event data into a readable Slack message
- Slack: Send Channel Message — posts the formatted agenda to the designated channel
The main design challenge is step 2: Google Calendar's Zapier integration returns events one at a time (as individual records), not as a bundled list. Handling multiple events within a single Zap run requires either iterating over results or using a Code step to build the full message in one pass via the Google Calendar API.
Approach A: One Event Per Zap Run (Simpler)
The simplest implementation fires the Zap for each Google Calendar event individually, posting a separate Slack message per event. This works well for personal agendas or low-volume calendars.
Step 1: Schedule trigger
- Choose Schedule by Zapier as the trigger app.
- Select Every Day as the trigger event.
- Set the time to your preferred morning time (e.g., 8:00 AM) and select the correct timezone.
Step 2: Google Calendar — Find Event(s)
- Add a Google Calendar action step and select Find Event(s) as the action event.
- Connect the Google account associated with the target calendar.
- Select the Calendar to search.
- For the search query, use today's date — map the date from the Schedule trigger output. Set the start time to the beginning of today and the end time to the end of today to return all-day and timed events within the current day.
Step 3: Slack — Send Channel Message
- Add a Slack action and select Send Channel Message.
- Choose the target channel.
- Build the message text using the Google Calendar event fields: event summary (title), start time, end time, location, and description. Format with Slack's markdown — use
*bold*for event names and include start/end times on the same line.
This approach posts one message per event. For calendars with many events, this can produce a lot of Slack noise. Use Approach B for a consolidated digest.
Approach B: Consolidated Daily Digest via Code Step (Recommended)
A cleaner pattern uses a Code step to call the Google Calendar API directly, fetch all of the day's events in a single request, format them into one structured Slack message, and post it. This produces a single Slack message with all events listed — the true "daily agenda" format.
Step 1: Schedule trigger
Same as Approach A — Schedule by Zapier, Every Day, at your preferred morning time.
Step 2: Code by Zapier — JavaScript
Add a Code by Zapier action with Run JavaScript. The Code step fetches today's events from the Google Calendar API using a service account or OAuth token. A simplified version using the Google Calendar API with an API key (for public calendars) or with a pre-fetched access token passed as inputData:
const today = new Date();
const start = new Date(today.setHours(0, 0, 0, 0)).toISOString();
const end = new Date(today.setHours(23, 59, 59, 999)).toISOString();
const url = `https://www.googleapis.com/calendar/v3/calendars/${inputData.calendarId}/events`
+ `?timeMin=${encodeURIComponent(start)}`
+ `&timeMax=${encodeURIComponent(end)}`
+ `&singleEvents=true&orderBy=startTime`;
const response = await fetch(url, {
headers: { 'Authorization': 'Bearer ' + inputData.accessToken }
});
const data = await response.json();
if (!data.items || data.items.length === 0) {
output = { message: ':calendar: No events scheduled for today.' };
} else {
const lines = data.items.map(event => {
const start = event.start.dateTime
? new Date(event.start.dateTime).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZone: inputData.timezone })
: 'All day';
const end = event.end.dateTime
? new Date(event.end.dateTime).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZone: inputData.timezone })
: '';
const time = end ? `${start} – ${end}` : start;
return `• *${event.summary}* — ${time}${event.location ? ' · ' + event.location : ''}`;
});
output = { message: ':calendar: *Today\'s Agenda*\n' + lines.join('\n') };
}
Pass calendarId, accessToken, and timezone as input data from the Zap's configuration. The accessToken for a Google Calendar API call requires OAuth — the recommended approach for a production Zap is to use the Google Calendar connector's authenticated connection and pass the calendar ID, or to use a Google service account key stored as a Zap input variable.
For more on what is available in JavaScript Code steps, see JavaScript libraries in Zapier Code steps.
Step 3: Slack — Send Channel Message
- Add a Slack action and select Send Channel Message.
- Map the
messageoutput from the Code step into the message body field. - Set the channel, bot name, and emoji icon as desired.
The result is a single Slack message each morning listing all of the day's events with their times and locations.
Handling Edge Cases
- No events today: The Code step example above already handles the empty case — post a friendly "No events today" message so the channel receives confirmation that the Zap ran.
- All-day events: Google Calendar all-day events have a
datefield rather thandateTime— the Code step above handles this with the ternary check onevent.start.dateTime. - Multiple calendars: Run multiple Find Events steps (one per calendar) or make multiple API calls within the same Code step, then merge and sort the results by start time before formatting.
- Weekday-only posting: Add a Filter by Zapier step after the Schedule trigger — filter to continue only if today's day of the week is Monday through Friday.
The daily agenda Zap works best as a team-facing message in a shared Slack channel rather than a personal DM — the value is in shared visibility. A single morning message listing the day's calls, reviews, and deadlines gives every team member context without requiring calendar access or a stand-up meeting.
For Slack automation patterns more broadly, see the Slack automation for operations teams guide. For a broader look at Google Workspace integrations with Zapier, see the Google and Zapier integrations overview. For help building a custom daily digest workflow, talk to Automation Ace.
Disclaimer: This article may include links to apps, products, or services. Some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.