-
Notifications
You must be signed in to change notification settings - Fork 0
Meetings
Calendar integration and meeting management with room booking, Google/Outlook sync, recurring meetings, and availability tracking.
- Overview
- Quick Start
- Configuration
- CLI Commands
- REST API
- Webhook Events
- Database Schema
- Examples
- Troubleshooting
The Meetings plugin provides comprehensive calendar and meeting management for nself applications. It supports room booking, external calendar synchronization (Google Calendar, Outlook), recurring meetings, waitlists, availability tracking, and meeting reminders.
This plugin is essential for applications requiring coordinated scheduling, resource management, and calendar integrations.
- Meeting Management: Create, update, and cancel meetings with rich details
- Room Booking: Reserve physical and virtual meeting rooms with capacity tracking
- Calendar Sync: Two-way sync with Google Calendar and Outlook
- Recurring Meetings: Support for daily, weekly, monthly recurring patterns
- Availability Tracking: Check participant availability across calendars
- Meeting Reminders: Automated email/notification reminders
- Waitlist Management: Queue participants when meetings are full
- Calendar Sharing: Share calendars with team members
- Meeting Templates: Pre-configured meeting templates for common scenarios
- Time Zone Support: Proper handling of multiple time zones
- RSVP Tracking: Track attendance responses and actual attendance
- Multi-Account Isolation: Full support for multi-tenant applications
- Event Types: meetings, appointments, all-day events, recurring events
- Recurrence: daily, weekly, monthly, custom patterns
- Calendar Providers: Google Calendar, Microsoft Outlook, iCal
- Room Types: physical, virtual (Zoom, Teams, etc.)
- RSVP Statuses: accepted, declined, tentative, needs-action
- Reminder Types: email, notification, SMS
- Team Scheduling: Coordinate team meetings with availability checks
- Resource Booking: Meeting room and equipment reservations
- Client Meetings: Schedule and manage client appointments
- Event Management: Organize company-wide events and conferences
- Interview Scheduling: Coordinate interview panels and candidates
# Install the plugin
nself plugin install meetings
# Set environment variables
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
export MEETINGS_PLUGIN_PORT=3710
# Optional: Configure Google Calendar integration
export GOOGLE_CALENDAR_CLIENT_ID="your-client-id"
export GOOGLE_CALENDAR_CLIENT_SECRET="your-client-secret"
# Initialize database schema
nself plugin meetings init
# Start the meetings plugin server
nself plugin meetings server
# Check status
nself plugin meetings status| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
Yes | - | PostgreSQL connection string |
MEETINGS_PLUGIN_PORT |
No | 3710 |
HTTP server port |
GOOGLE_CALENDAR_CLIENT_ID |
No | - | Google Calendar OAuth client ID |
GOOGLE_CALENDAR_CLIENT_SECRET |
No | - | Google Calendar OAuth client secret |
GOOGLE_CALENDAR_REDIRECT_URI |
No | - | Google Calendar OAuth redirect URI |
OUTLOOK_CALENDAR_CLIENT_ID |
No | - | Outlook Calendar OAuth client ID |
OUTLOOK_CALENDAR_CLIENT_SECRET |
No | - | Outlook Calendar OAuth client secret |
OUTLOOK_CALENDAR_REDIRECT_URI |
No | - | Outlook Calendar OAuth redirect URI |
# Database Configuration
DATABASE_URL=postgresql://postgres:password@localhost:5432/nself
# Server Configuration
MEETINGS_PLUGIN_PORT=3710
# Google Calendar Integration
GOOGLE_CALENDAR_CLIENT_ID=your-google-client-id
GOOGLE_CALENDAR_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALENDAR_REDIRECT_URI=https://yourdomain.com/oauth/google/callback
# Outlook Calendar Integration
OUTLOOK_CALENDAR_CLIENT_ID=your-outlook-client-id
OUTLOOK_CALENDAR_CLIENT_SECRET=your-outlook-client-secret
OUTLOOK_CALENDAR_REDIRECT_URI=https://yourdomain.com/oauth/outlook/callbackInitialize the meetings plugin database schema.
nself plugin meetings initStart the meetings plugin HTTP server.
nself plugin meetings server
nself plugin meetings server --port 3710Display current meetings plugin status.
nself plugin meetings statusManage meeting events.
nself plugin meetings events list
nself plugin meetings events create "Team Standup" --start "2024-02-10T10:00:00Z" --duration 30
nself plugin meetings events info EVENT_ID
nself plugin meetings events cancel EVENT_IDManage meeting rooms.
nself plugin meetings rooms list
nself plugin meetings rooms create "Conference Room A" --capacity 12 --floor 3
nself plugin meetings rooms book ROOM_ID --start "2024-02-10T14:00:00Z" --duration 60Manage calendars.
nself plugin meetings calendars list
nself plugin meetings calendars create "Team Calendar"
nself plugin meetings calendars share CALENDAR_ID USER_IDManage meeting templates.
nself plugin meetings templates list
nself plugin meetings templates create "Daily Standup" --duration 15 --recurring dailyCreate a meeting event.
Request:
{
"title": "Team Planning Meeting",
"description": "Q1 planning session",
"startTime": "2024-02-10T14:00:00Z",
"endTime": "2024-02-10T15:00:00Z",
"location": "Conference Room A",
"attendees": [
{"email": "user1@example.com", "optional": false},
{"email": "user2@example.com", "optional": true}
],
"roomId": "550e8400-e29b-41d4-a716-446655440000",
"reminders": [
{"type": "email", "minutesBefore": 15}
]
}Get event details.
Update event.
Cancel event.
List events with filters.
Query Parameters:
-
startDate- Filter by start date -
endDate- Filter by end date -
attendee- Filter by attendee email -
roomId- Filter by room -
calendarId- Filter by calendar
Create meeting room.
Get room details.
List rooms.
Book a room.
Check room availability.
Create calendar.
List calendars.
Share calendar with user.
Connect Google Calendar.
Connect Outlook Calendar.
Trigger calendar sync.
Update RSVP status.
Request:
{
"attendeeId": "550e8400-e29b-41d4-a716-446655440001",
"status": "accepted"
}Add reminder.
List pending reminders.
Receive webhook events.
A new meeting event was created.
A meeting event was updated.
A meeting event was cancelled.
A meeting event was deleted.
An attendee RSVP was updated.
A meeting room was booked.
A meeting room booking was released.
External calendar sync completed.
A meeting reminder was sent.
Meeting events.
CREATE TABLE np_meetings_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
np_calendar_id UUID NOT NULL REFERENCES np_meetings_calendars(id) ON DELETE CASCADE,
title VARCHAR(500) NOT NULL,
description TEXT,
location VARCHAR(500),
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ NOT NULL,
all_day BOOLEAN NOT NULL DEFAULT false,
status VARCHAR(50) NOT NULL DEFAULT 'confirmed',
visibility VARCHAR(50) NOT NULL DEFAULT 'default',
recurrence_rule TEXT,
recurrence_id UUID,
organizer_id UUID NOT NULL,
room_id UUID REFERENCES np_meetings_rooms(id) ON DELETE SET NULL,
external_event_id VARCHAR(255),
external_calendar_id VARCHAR(255),
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
cancelled_at TIMESTAMPTZ
);
CREATE INDEX idx_meetings_events_account ON np_meetings_events(source_account_id);
CREATE INDEX idx_meetings_events_calendar ON np_meetings_events(np_calendar_id);
CREATE INDEX idx_meetings_events_start ON np_meetings_events(start_time);
CREATE INDEX idx_meetings_events_end ON np_meetings_events(end_time);
CREATE INDEX idx_meetings_events_room ON np_meetings_events(room_id);
CREATE INDEX idx_meetings_events_status ON np_meetings_events(status);Event attendees and RSVP tracking.
CREATE TABLE np_meetings_attendees (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
event_id UUID NOT NULL REFERENCES np_meetings_events(id) ON DELETE CASCADE,
user_id UUID,
email VARCHAR(255) NOT NULL,
display_name VARCHAR(255),
is_optional BOOLEAN NOT NULL DEFAULT false,
is_organizer BOOLEAN NOT NULL DEFAULT false,
rsvp_status VARCHAR(50) NOT NULL DEFAULT 'needs-action',
rsvp_at TIMESTAMPTZ,
attended BOOLEAN,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(source_account_id, event_id, email)
);
CREATE INDEX idx_meetings_attendees_account ON np_meetings_attendees(source_account_id);
CREATE INDEX idx_meetings_attendees_event ON np_meetings_attendees(event_id);
CREATE INDEX idx_meetings_attendees_user ON np_meetings_attendees(user_id);
CREATE INDEX idx_meetings_attendees_email ON np_meetings_attendees(email);Meeting rooms and resources.
CREATE TABLE np_meetings_rooms (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
name VARCHAR(200) NOT NULL,
description TEXT,
room_type VARCHAR(50) NOT NULL DEFAULT 'physical',
location VARCHAR(500),
floor INTEGER,
building VARCHAR(100),
capacity INTEGER NOT NULL DEFAULT 10,
equipment TEXT[] DEFAULT '{}',
amenities TEXT[] DEFAULT '{}',
is_active BOOLEAN NOT NULL DEFAULT true,
booking_url TEXT,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(source_account_id, name)
);
CREATE INDEX idx_meetings_rooms_account ON np_meetings_rooms(source_account_id);
CREATE INDEX idx_meetings_rooms_active ON np_meetings_rooms(is_active) WHERE is_active = true;
CREATE INDEX idx_meetings_rooms_type ON np_meetings_rooms(room_type);User and shared calendars.
CREATE TABLE np_meetings_calendars (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
user_id UUID NOT NULL,
name VARCHAR(200) NOT NULL,
description TEXT,
color VARCHAR(20),
timezone VARCHAR(50) DEFAULT 'UTC',
is_primary BOOLEAN NOT NULL DEFAULT false,
is_public BOOLEAN NOT NULL DEFAULT false,
external_calendar_id VARCHAR(255),
external_provider VARCHAR(50),
sync_enabled BOOLEAN NOT NULL DEFAULT false,
last_synced_at TIMESTAMPTZ,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_meetings_calendars_account ON np_meetings_calendars(source_account_id);
CREATE INDEX idx_meetings_calendars_user ON np_meetings_calendars(user_id);
CREATE INDEX idx_meetings_calendars_primary ON np_meetings_calendars(is_primary) WHERE is_primary = true;Calendar sharing permissions.
CREATE TABLE np_meetings_calendar_shares (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
np_calendar_id UUID NOT NULL REFERENCES np_meetings_calendars(id) ON DELETE CASCADE,
shared_with_user_id UUID NOT NULL,
permission_level VARCHAR(50) NOT NULL DEFAULT 'read',
created_by UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(source_account_id, np_calendar_id, shared_with_user_id)
);
CREATE INDEX idx_calendar_shares_account ON np_meetings_calendar_shares(source_account_id);
CREATE INDEX idx_calendar_shares_calendar ON np_meetings_calendar_shares(np_calendar_id);
CREATE INDEX idx_calendar_shares_user ON np_meetings_calendar_shares(shared_with_user_id);External calendar connections.
CREATE TABLE np_meetings_external_calendars (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
user_id UUID NOT NULL,
provider VARCHAR(50) NOT NULL,
external_calendar_id VARCHAR(255) NOT NULL,
access_token_encrypted TEXT NOT NULL,
refresh_token_encrypted TEXT,
token_expires_at TIMESTAMPTZ,
sync_enabled BOOLEAN NOT NULL DEFAULT true,
last_synced_at TIMESTAMPTZ,
sync_error TEXT,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(source_account_id, user_id, provider, external_calendar_id)
);
CREATE INDEX idx_external_calendars_account ON np_meetings_external_calendars(source_account_id);
CREATE INDEX idx_external_calendars_user ON np_meetings_external_calendars(user_id);
CREATE INDEX idx_external_calendars_provider ON np_meetings_external_calendars(provider);Meeting templates.
CREATE TABLE np_meetings_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
name VARCHAR(200) NOT NULL,
description TEXT,
duration_minutes INTEGER NOT NULL DEFAULT 30,
default_location VARCHAR(500),
default_attendees TEXT[] DEFAULT '{}',
recurrence_rule TEXT,
reminder_minutes INTEGER[] DEFAULT '{15}',
is_public BOOLEAN NOT NULL DEFAULT false,
created_by UUID NOT NULL,
usage_count INTEGER DEFAULT 0,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_meetings_templates_account ON np_meetings_templates(source_account_id);
CREATE INDEX idx_meetings_templates_public ON np_meetings_templates(is_public) WHERE is_public = true;Meeting reminders.
CREATE TABLE np_meetings_reminders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
event_id UUID NOT NULL REFERENCES np_meetings_events(id) ON DELETE CASCADE,
attendee_id UUID REFERENCES np_meetings_attendees(id) ON DELETE CASCADE,
reminder_type VARCHAR(50) NOT NULL DEFAULT 'email',
minutes_before INTEGER NOT NULL DEFAULT 15,
scheduled_at TIMESTAMPTZ NOT NULL,
sent_at TIMESTAMPTZ,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
error_message TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_meetings_reminders_account ON np_meetings_reminders(source_account_id);
CREATE INDEX idx_meetings_reminders_event ON np_meetings_reminders(event_id);
CREATE INDEX idx_meetings_reminders_scheduled ON np_meetings_reminders(scheduled_at);
CREATE INDEX idx_meetings_reminders_status ON np_meetings_reminders(status);Meeting waitlist entries.
CREATE TABLE np_meetings_waitlist (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id VARCHAR(128) NOT NULL DEFAULT 'primary',
event_id UUID NOT NULL REFERENCES np_meetings_events(id) ON DELETE CASCADE,
user_id UUID NOT NULL,
email VARCHAR(255) NOT NULL,
position INTEGER NOT NULL,
notified_at TIMESTAMPTZ,
invited_at TIMESTAMPTZ,
status VARCHAR(50) NOT NULL DEFAULT 'waiting',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(source_account_id, event_id, user_id)
);
CREATE INDEX idx_meetings_waitlist_account ON np_meetings_waitlist(source_account_id);
CREATE INDEX idx_meetings_waitlist_event ON np_meetings_waitlist(event_id);
CREATE INDEX idx_meetings_waitlist_user ON np_meetings_waitlist(user_id);
CREATE INDEX idx_meetings_waitlist_status ON np_meetings_waitlist(status);# Create meeting and book room
curl -X POST http://localhost:3710/api/meetings/events \
-H "Content-Type: application/json" \
-d '{
"title": "Product Review",
"startTime": "2024-02-10T14:00:00Z",
"endTime": "2024-02-10T15:00:00Z",
"roomId": "ROOM_ID",
"attendees": [
{"email": "john@example.com"},
{"email": "jane@example.com"}
]
}'# Weekly team standup
curl -X POST http://localhost:3710/api/meetings/events \
-H "Content-Type: application/json" \
-d '{
"title": "Team Standup",
"startTime": "2024-02-12T09:00:00Z",
"endTime": "2024-02-12T09:15:00Z",
"recurrenceRule": "FREQ=WEEKLY;BYDAY=MO,WE,FR",
"attendees": [
{"email": "team@example.com"}
]
}'# Check if room is available
curl "http://localhost:3710/api/meetings/rooms/ROOM_ID/availability?start=2024-02-10T14:00:00Z&end=2024-02-10T15:00:00Z"# Initiate OAuth flow
curl -X POST http://localhost:3710/api/meetings/external/google/connect \
-H "Content-Type: application/json" \
-d '{
"userId": "USER_ID",
"redirectUri": "https://yourdomain.com/oauth/callback"
}'# Accept meeting invitation
curl -X POST http://localhost:3710/api/meetings/events/EVENT_ID/rsvp \
-H "Content-Type: application/json" \
-d '{
"attendeeId": "ATTENDEE_ID",
"status": "accepted"
}'Problem: External calendars not syncing
Solutions:
- Verify OAuth tokens haven't expired
- Check sync_enabled flag is true
- Review sync error messages in np_meetings_external_calendars table
- Re-authenticate with calendar provider
Problem: Double-booked rooms
Solutions:
- Ensure proper locking during room booking
- Check for overlapping events in np_meetings_events
- Verify room capacity isn't exceeded
- Review booking logic for race conditions
Problem: Reminders not sending
Solutions:
- Check scheduled_at times are in the future
- Verify email/notification service is configured
- Review reminder status for errors
- Check cron job or worker process is running
Version: 1.0.0 Last Updated: February 2024 Support: https://github.com/acamarata/nself-plugins/issues
- Commands
- File Processing Commands
- GitHub Commands
- ID.me Commands
- Jobs Commands
- Notifications Commands
- Realtime Commands
- Shopify Commands
- Stripe Commands
View All: Home (or see the full alphabetical list below — 129/129 synced with registry.json)
- Access-Controls
- Admin-Api
- AI-CLI
- AI-Studio
- Alerts
- Analytics
- API
- Audit
- Audit-Analytics
- Audit-Log
- Auth-Enterprise
- Backup
- BYOK
- CDC
- CDN
- CI
- Claw-CLI
- Cloudflare
- Compliance
- Content-Acquisition
- Content-Progress
- Content-Safety
- Costs
- CRDT
- Cron
- DDNS
- Devices
- DLQ
- Documents
- Dogfood
- Donorbox
- DR
- E2EE
- Encryption
- Entitlements
- Event-Bus
- Family-Ancestry
- Family-FamilySearch
- Family-GEDCOM
- Family-MyHeritage
- Family-WikiTree
- Feature-Flags
- Federation
- File-Processing
- Flags
- Forgejo
- Functions-V8
- Game-Metadata
- Gateway
- Gauth
- GDPR
- Geocoding
- GitHub
- GitHub-Runner
- HIPAA
- Home
- IDme
- Infra
- Invitations
- Job-Queue
- Jobs
- K8s
- Link-Preview
- Maintenance
- MDNS
- Media-Processing
- Meetings
- MLflow
- Model
- Monitor
- Monitoring
- Notifications
- Notify
- nSelf-Cloud
- nSelf-Eval-Gate
- nSelf-Geo
- nSelf-Image
- nSelf-PDF
- nSelf-Scan
- nSelf-Sync
- nSelf-Vault
- Object-Storage
- Observability
- Ollama
- Payments
- PayPal
- Pentest
- Pentest-Kit
- Plugin-ClawDE
- Plugin-Gauth
- Plugin-LLM-Gateway
- Plugin-PTY
- Plugin-Retrieval
- Podcast
- Post
- Push
- Queue
- Region
- Release
- Retro-Gaming
- Rom-Discovery
- Search
- Sentry-CLI
- Shared-Utils
- Shopify
- SIEM
- SMS
- Soak
- Sports
- Storage
- Storage-Transform
- Stripe
- Subtitle-Manager
- Tenant
- Tenant-Controller
- TMDB
- Tokens
- Torrent-Manager
- Transactional-Email
- VPN
- WAF
- Warehouse
- Watchdog
- Web3
- Webhooks
- Workflows
Related