Fetch Calendly Event Details
Fetch full details for a single Calendly event including invitee info and form responses
Source Code
import fs from "fs";
import path from "path";
const [eventUuid, outputPath] = process.argv.slice(2);
if (!eventUuid || !outputPath) {
console.error("Error: eventUuid and outputPath are required");
console.error("Usage: node script.js <eventUuid> session/calendly-event.json");
process.exit(1);
}
console.log(`Fetching Calendly event details for ${eventUuid}...`);
try {
// Fetch the event details
const eventRes = await fetch(
`https://api.calendly.com/scheduled_events/${eventUuid}`,
{ headers: { Authorization: "Bearer PLACEHOLDER_TOKEN" } }
);
const eventData = await eventRes.json();
if (eventData.resource === undefined) {
throw new Error(`Failed to fetch event: ${JSON.stringify(eventData)}`);
}
const event = eventData.resource;
console.log(` Event: ${event.name}`);
// Fetch invitees for this event
const inviteesRes = await fetch(
`https://api.calendly.com/scheduled_events/${eventUuid}/invitees?count=100`,
{ headers: { Authorization: "Bearer PLACEHOLDER_TOKEN" } }
);
const inviteesData = await inviteesRes.json();
if (inviteesData.collection === undefined) {
throw new Error(`Failed to fetch invitees: ${JSON.stringify(inviteesData)}`);
}
const invitees = inviteesData.collection;
console.log(` Invitees: ${invitees.length}`);
// Process invitees
const processedInvitees = invitees.map((invitee) => {
// Extract questions and answers
const questionsAndAnswers = (invitee.questions_and_answers || []).map((qa) => ({
question: qa.question,
answer: qa.answer,
}));
return {
uri: invitee.uri,
email: invitee.email,
name: invitee.name,
status: invitee.status,
timezone: invitee.timezone,
questionsAndAnswers,
rescheduled: invitee.rescheduled || false,
rescheduleUrl: invitee.reschedule_url || null,
cancelUrl: invitee.cancel_url || null,
createdAt: invitee.created_at,
updatedAt: invitee.updated_at,
cancellation: invitee.cancellation || null,
};
});
// Calculate event duration
const startTime = new Date(event.start_time);
const endTime = new Date(event.end_time);
const durationMinutes = Math.round((endTime - startTime) / (1000 * 60));
// Build location info
let locationInfo = null;
if (event.location) {
locationInfo = {
type: event.location.type,
location: event.location.location || null,
joinUrl: event.location.join_url || null,
status: event.location.status || null,
additionalInfo: event.location.additional_info || null,
};
}
// Build output
const output = {
uuid: eventUuid,
uri: event.uri,
name: event.name,
status: event.status,
startTime: event.start_time,
endTime: event.end_time,
durationMinutes,
eventType: event.event_type,
location: locationInfo,
createdAt: event.created_at,
updatedAt: event.updated_at,
cancellation: event.cancellation || null,
invitees: processedInvitees,
summary: {
inviteeCount: processedInvitees.length,
hasFormResponses: processedInvitees.some((i) => i.questionsAndAnswers.length > 0),
canceledCount: processedInvitees.filter((i) => i.status === "canceled").length,
},
};
// Write output
const dir = path.dirname(outputPath);
if (dir && dir !== ".") fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
console.log(`\n✓ Event details fetched`);
console.log(` Name: ${event.name}`);
console.log(` Time: ${event.start_time}`);
console.log(` Duration: ${durationMinutes} minutes`);
console.log(` Invitees: ${processedInvitees.length}`);
if (processedInvitees.length > 0) {
console.log(`\n Invitees:`);
processedInvitees.forEach((inv) => {
console.log(` - ${inv.name} (${inv.email})`);
if (inv.questionsAndAnswers.length > 0) {
console.log(` Form responses: ${inv.questionsAndAnswers.length}`);
}
});
}
console.log(`\n Output: ${outputPath}`);
console.log(
JSON.stringify({
success: true,
outputPath,
eventName: event.name,
inviteeCount: processedInvitees.length,
})
);
} catch (error) {
console.error("Failed:", error.message);
throw error;
}