This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Copilot Auto-Responder — a Next.js 14 app (App Router) that provides automatic message responses for the Copilot messages app based on the Setting that the workspace users set. It runs as an embedded app within Copilot workspaces inside an iframe, allowing workspace internal users to configure auto-responses to client messages (always on, outside working hours, or off).
When a message is sent to the Copilot messages app that falls in one of the auto-response settings, the webhook is triggered and the message is processed. The automatic message is then sent to the Copilot messages app via copilotApiUtils#sendMessage.
yarn dev # Start dev server
yarn build # Build for production
yarn lint:check # ESLint check
yarn lint:fix # ESLint auto-fix
yarn prettier:check # Prettier check
yarn prettier:fix # Prettier auto-fix
yarn db:migrate # Run Prisma migrations (uses .env.development.local)
yarn db:seed # Seed/resolve initial migrationVercel build runs prisma generate && next build. Husky pre-commit runs lint-staged (lint:fix + prettier:fix on staged src/**/*.{ts,tsx}).
- Settings UI (
src/app/page.tsx— server component) renders theAutoResponderclient component with current settings. This is where settings can be configured. - Save uses a server action that calls
SettingService.save()to persist to PostgreSQL via Prisma - Webhook (
POST /api/messages/webhook) receivesmessage.sentevents from Copilot, validates HMAC signature, thenMessageServicedecides whether to auto-respond based on the workspace's settings - Rate limiting: at most one auto-response per hour per channel per client, tracked in the
Messagetable
SettingService(src/app/api/settings/services/setting.service.ts) — CRUD for workspace auto-responder settings (one Setting row per workspace)MessageService(src/app/api/messages/services/message.service.ts) — webhook handler logic: checks setting type (ENABLED/DISABLED/OUTSIDE_WORKING_HOURS), rate-limits, and sends auto-responsesCopilotAPI(src/utils/copilotApiUtils.ts) — wrapper aroundcopilot-node-sdkfor workspace/client/user/message API calls. DO NOT USE copilot-node-sdk directly. This is where the auto-response is sent to the Copilot messages app.
Schema in schema.prisma (root). Two models:
- Setting — one per workspace: type (ENABLED/DISABLED/OUTSIDE_WORKING_HOURS), timezone, workingHours (JSONB), message text, senderId. This is used to configure the automatic response settings.
- Message — log of sent auto-responses, used for hourly rate-limiting per channel/client. This is used to track the auto-response rate-limiting.
Prisma client is a singleton via src/lib/db.ts.
Uses @js-joda/core + @js-joda/timezone for timezone-aware day/time comparisons (src/utils/common.ts:isWithinWorkingHours). Working hours stored as array of {weekday, startTime, endTime} in JSONB.
POST /api/messages/webhook— Copilot webhook receiver (signature-verified)GET /api/internal-users— proxies internal user list from Copilot APIGET /api/health-check— Health endpoint
AutoRespondercomponent (src/app/components/AutoResponder.tsx) — main form using React Hook Form + Zod validation- UI: Tailwind CSS + MUI Select + Radix UI Select + react-timezone-select
- Form validation: response 10–2000 chars, at least 1 day selected for outside-working-hours mode
Token-based via ?token= query param from Copilot embedding. CopilotAPI uses both an API key (COPILOT_API_KEY) and the session token. Workspace ID from the token payload scopes all data.
We can use getTokenPayload from CopilotAPI to get the payload encoded in token
- Path aliases:
@/maps tosrc/ - Prettier: single quotes, trailing commas, 125 char width
- Zod schemas colocated with types in
src/types/— all API responses validated at parse time - Environment config centralized in
src/config/app.ts - SVGs imported as React components via
next-plugin-svgr