本文へ移動
cccskills
無料GitHub で公開

cal-com

Expert guidance for Cal.com, the open-source scheduling platform for building booking and appointment systems. Helps developers integrate Cal.com's embed widgets, REST API, and webhooks to add scheduling capabilities to their applications.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md11.4 KB
  • _scores.json1.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Cal.com — Scheduling Infrastructure

Overview

Cal.com, the open-source scheduling platform for building booking and appointment systems. Helps developers integrate Cal.com's embed widgets, REST API, and webhooks to add scheduling capabilities to their applications.

Instructions

Embed Widget

Add a booking widget to any website:

// src/components/BookingWidget.tsx — Embed Cal.com scheduling in a React app
import Cal, { getCalApi } from "@calcom/embed-react";
import { useEffect } from "react";

export function BookingWidget() {
  useEffect(() => {
    (async () => {
      const cal = await getCalApi();
      // Configure the embed appearance
      cal("ui", {
        theme: "light",
        styles: { branding: { brandColor: "#6366f1" } },
        hideEventTypeDetails: false,
        layout: "month_view",       // "month_view" | "week_view" | "column_view"
      });
    })();
  }, []);

  return (
    <Cal
      calLink="your-team/discovery-call"   // Your Cal.com event link
      style={{ width: "100%", height: "100%", overflow: "scroll" }}
      config={{
        layout: "month_view",
        name: "Customer Name",              // Pre-fill guest name
        email: "customer@example.com",      // Pre-fill guest email
        notes: "Interested in Enterprise plan",
      }}
    />
  );
}

// Floating button that opens calendar in a popup
export function BookingButton() {
  useEffect(() => {
    (async () => {
      const cal = await getCalApi();
      cal("floatingButton", {
        calLink: "your-team/discovery-call",
        buttonText: "Book a Demo",
        buttonColor: "#6366f1",
        buttonTextColor: "#ffffff",
        buttonPosition: "bottom-right",
      });
    })();
  }, []);

  return null;   // The floating button renders itself
}

REST API Integration

Manage bookings, event types, and availability programmatically:

// src/cal/client.ts — Cal.com API client for server-side operations
const CAL_API_URL = "https://api.cal.com/v2";
const CAL_API_KEY = process.env.CAL_API_KEY!;

async function calFetch(path: string, options?: RequestInit) {
  const response = await fetch(`${CAL_API_URL}${path}`, {
    ...options,
    headers: {
      "Content-Type": "application/json",
      "cal-api-version": "2024-08-13",       // Pin API version for stability
      Authorization: `Bearer ${CAL_API_KEY}`,
      ...options?.headers,
    },
  });
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Cal.com API error: ${error.message}`);
  }
  return response.json();
}

// Create a new event type (e.g., "30-min Discovery Call")
async function createEventType(params: {
  title: string;
  slug: string;
  lengthInMinutes: number;
  description?: string;
  locations?: { type: string; link?: string }[];
}) {
  return calFetch("/event-types", {
    method: "POST",
    body: JSON.stringify({
      title: params.title,
      slug: params.slug,
      lengthInMinutes: params.lengthInMinutes,
      description: params.description,
      locations: params.locations ?? [
        { type: "integrations:google:meet" },  // Default: Google Meet
      ],
      bookingFields: [
        { name: "company", type: "text", label: "Company Name", required: true },
        { name: "teamSize", type: "select", label: "Team Size",
          options: ["1-10", "11-50", "51-200", "200+"], required: true },
      ],
    }),
  });
}

// Get available time slots for a date range
async function getAvailability(params: {
  eventTypeId: number;
  startTime: string;   // ISO 8601
  endTime: string;
  timeZone: string;
}) {
  const query = new URLSearchParams({
    eventTypeId: String(params.eventTypeId),
    startTime: params.startTime,
    endTime: params.endTime,
    timeZone: params.timeZone,
  });
  return calFetch(`/slots?${query}`);
}

// Create a booking
async function createBooking(params: {
  eventTypeId: number;
  start: string;         // ISO 8601 datetime
  attendee: { name: string; email: string; timeZone: string };
  metadata?: Record<string, string>;
}) {
  return calFetch("/bookings", {
    method: "POST",
    body: JSON.stringify({
      eventTypeId: params.eventTypeId,
      start: params.start,
      attendee: params.attendee,
      metadata: params.metadata,
      language: "en",
    }),
  });
}

// Cancel a booking
async function cancelBooking(bookingUid: string, reason?: string) {
  return calFetch(`/bookings/${bookingUid}/cancel`, {
    method: "POST",
    body: JSON.stringify({ reason }),
  });
}

// Reschedule a booking
async function rescheduleBooking(bookingUid: string, newStart: string) {
  return calFetch(`/bookings/${bookingUid}/reschedule`, {
    method: "POST",
    body: JSON.stringify({ start: newStart }),
  });
}

Webhooks

React to booking events in real time:

// app/api/cal-webhook/route.ts — Handle Cal.com webhook events
import { NextRequest, NextResponse } from "next/server";
import crypto from "crypto";

const WEBHOOK_SECRET = process.env.CAL_WEBHOOK_SECRET!;

// Verify the webhook signature to ensure it's from Cal.com
function verifySignature(payload: string, signature: string): boolean {
  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

export async function POST(request: NextRequest) {
  const payload = await request.text();
  const signature = request.headers.get("x-cal-signature-256") ?? "";

  if (!verifySignature(payload, signature)) {
    return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
  }

  const event = JSON.parse(payload);

  switch (event.triggerEvent) {
    case "BOOKING_CREATED":
      // New booking — send confirmation, update CRM, notify sales
      await handleNewBooking({
        bookingId: event.payload.bookingId,
        attendeeName: event.payload.attendees[0]?.name,
        attendeeEmail: event.payload.attendees[0]?.email,
        startTime: event.payload.startTime,
        eventType: event.payload.eventTitle,
        metadata: event.payload.metadata,
      });
      break;

    case "BOOKING_CANCELLED":
      // Booking cancelled — update CRM, free up resources
      await handleCancellation({
        bookingId: event.payload.bookingId,
        reason: event.payload.cancellationReason,
      });
      break;

    case "BOOKING_RESCHEDULED":
      // Booking moved — update calendar integrations
      await handleReschedule({
        bookingId: event.payload.bookingId,
        oldTime: event.payload.previousStartTime,
        newTime: event.payload.startTime,
      });
      break;

    case "MEETING_ENDED":
      // Meeting finished — trigger follow-up sequence
      await triggerFollowUp(event.payload.bookingId);
      break;
  }

  return NextResponse.json({ received: true });
}

async function handleNewBooking(booking: any) {
  // Example: Create a deal in your CRM
  await crm.createDeal({
    name: `Demo: ${booking.attendeeName}`,
    contact: booking.attendeeEmail,
    stage: "discovery",
    source: "website-booking",
    metadata: booking.metadata,
  });

  // Notify the sales team via Slack
  await slack.postMessage({
    channel: "#sales-notifications",
    text: `📅 New ${booking.eventType} booked!\n👤 ${booking.attendeeName} (${booking.attendeeEmail})\n🕐 ${new Date(booking.startTime).toLocaleString()}`,
  });
}

Managing Team Availability

Configure round-robin scheduling and team calendars:

// src/cal/team-setup.ts — Configure team scheduling rules
async function setupTeamScheduling() {
  // Create a team event type with round-robin assignment
  const eventType = await calFetch("/event-types", {
    method: "POST",
    body: JSON.stringify({
      title: "Product Demo",
      slug: "product-demo",
      lengthInMinutes: 45,
      schedulingType: "ROUND_ROBIN",     // Rotate among team members
      hosts: [
        { userId: 101, isFixed: false },  // Participates in rotation
        { userId: 102, isFixed: false },
        { userId: 103, isFixed: true },   // Always included (e.g., sales engineer)
      ],
      beforeEventBuffer: 15,              // 15-min buffer before meetings
      afterEventBuffer: 10,               // 10-min buffer after
      minimumBookingNotice: 120,          // Minimum 2 hours notice
      slotInterval: 15,                   // Show slots every 15 minutes
      locations: [
        { type: "integrations:zoom" },    // Auto-create Zoom meeting
      ],
    }),
  });

  // Set working hours for the team
  await calFetch("/schedules", {
    method: "POST",
    body: JSON.stringify({
      name: "Business Hours",
      timeZone: "America/New_York",
      isDefault: true,
      availability: [
        // Monday-Friday 9 AM to 5 PM
        { days: [1, 2, 3, 4, 5], startTime: "09:00", endTime: "17:00" },
      ],
      // Block specific dates (holidays, company events)
      dateOverrides: [
        { date: "2026-12-25", startTime: null, endTime: null },  // Christmas — unavailable
        { date: "2026-12-31", startTime: "09:00", endTime: "12:00" },  // NYE — morning only
      ],
    }),
  });
}

Installation

# React embed
npm install @calcom/embed-react

# For self-hosted Cal.com (Docker)
git clone https://github.com/calcom/cal.com.git
cd cal.com
cp .env.example .env
docker compose up -d

Examples

Example 1: Setting up Cal Com with a custom configuration

User request:

I just installed Cal Com. Help me configure it for my TypeScript + React workflow with my preferred keybindings.

The agent creates the configuration file with TypeScript-aware settings, configures relevant plugins/extensions for React development, sets up keyboard shortcuts matching the user's preferences, and verifies the setup works correctly.

Example 2: Extending Cal Com with custom functionality

User request:

I want to add a custom rest api integration to Cal Com. How do I build one?

The agent scaffolds the extension/plugin project, implements the core functionality following Cal Com's API patterns, adds configuration options, and provides testing instructions to verify it works end-to-end.

Guidelines

  1. Use embed for public booking — The React embed handles time zones, availability, and confirmations automatically
  2. Pin API versions — Include cal-api-version header to avoid breaking changes when Cal.com updates
  3. Verify webhook signatures — Always validate x-cal-signature-256 to prevent spoofed events
  4. Buffer time between meetings — Set beforeEventBuffer and afterEventBuffer to prevent back-to-back meetings
  5. Pre-fill known data — Pass name, email, and context via embed config to reduce friction for returning users
  6. Use metadata for attribution — Pass UTM params, plan interest, or referral codes through booking metadata
  7. Handle all webhook events — Don't just handle BOOKING_CREATED; cancellations and reschedules need cleanup too
  8. Self-host for compliance — If you need data residency (GDPR, HIPAA), self-host Cal.com with Docker

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Scripts and configures production rendering in Autodesk 3ds Max with the V-Ray and Corona renderers: output size and files, render elements, denoising, light mix, batch and command-line rendering, and network rendering. Use when a user asks to set up a production render, render several cameras in one batch, render from the command line or on a render farm, add render passes for compositing, or cut render time for archviz and product shots.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Covers scripting Autodesk 3ds Max, the 3D modeling and rendering application, with MAXScript and Python (pymxs): scene manipulation, object creation, material assignment, camera and light setup, batch operations, and file I/O. Use when tasks involve automating repetitive 3ds Max workflows, batch processing scenes, running scripts headless with 3dsmaxbatch, creating custom tools, or scripting scene setup for archviz, product visualization, or VFX.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

3proxy

無料

3proxy is a small open-source proxy server that runs HTTP/HTTPS, SOCKS4/5, SNI and TCP/UDP port-mapping proxies from one config file. Use when a user asks to set up an HTTP or SOCKS5 proxy, add proxy users and passwords, write 3proxy access rules, chain or rotate upstream (parent) proxies, limit bandwidth, connections or monthly traffic per user, run 3proxy in Docker, or fix a 3proxy.cfg that will not start.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Builds Agent2Agent (A2A) servers and clients, the open protocol (originally from Google, now under the Linux Foundation) that lets AI agents from different frameworks call each other. Use when the user wants to create an A2A-compliant agent, build an Agent Card, implement task management, connect agents across frameworks, set up agent discovery, handle streaming responses, implement push notifications, or orchestrate multi-agent workflows. Trigger words: a2a, agent to agent, agent2agent, a2a protocol, a2a server, a2a client, agent card, agent interoperability, agent collaboration, multi-agent, agent discovery, a2a sdk, a2a task.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Plans a controlled experiment (A/B test) so its result can be trusted: writes the hypothesis, picks one primary metric and the guardrails, computes sample size and run time, specifies how visitors are assigned and when exposure is logged, and reads out the result with a confidence interval. Use when someone says "set up an A/B test", "split test this page", "how many visitors do I need", "how long should the experiment run", "is this result significant", "can I stop the test early", or wants to test a headline, price, layout or onboarding change against the current version.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

ably

無料

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token authentication, presence, history and rewind, batch publishing, and the @ably/chat 1.x SDK.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

TerminalSkills のスキルをすべて見る

このスキルの問題を報告する