meetings
0
总安装量
1
周安装量
安装命令
npx skills add https://github.com/ticruz38/skills --skill meetings
Agent 安装分布
openclaw
1
Skill 文档
Meetings Skill
Coordinate meetings seamlessly using calendar and email integration. Schedule meetings, find mutual availability, manage agendas, and send invites all from your agent.
Features
- Schedule Meetings: Find available time slots and create meetings
- Email Invites: Automatically send meeting invitations
- Agenda Management: Structured agendas with time allocations
- Prep Documents: Attach and share pre-meeting materials
- Meeting Templates: Pre-defined templates for common meeting types
- Calendar Integration: Syncs with Google Calendar
Installation
npm install
npm run build
Prerequisites
The meetings skill requires both calendar and email to be connected:
# Connect Google account with Calendar and Gmail scopes
node ../google-oauth/dist/cli.js connect default calendar email
CLI Usage
Check Status
# Check connection status
node dist/cli.js status
Health Check
node dist/cli.js health
Schedule a Meeting
# Basic meeting
node dist/cli.js schedule --title "Team Sync" --attendees "alice@example.com,bob@example.com"
# With all options
node dist/cli.js schedule \
--title "Project Review" \
--attendees "alice@example.com,bob@example.com,carol@example.com" \
--duration 90 \
--description "Quarterly project review" \
--location "Conference Room A" \
--days 14 \
--prep
# With agenda items
node dist/cli.js schedule \
--title "Sprint Planning" \
--attendees "dev-team@example.com" \
--duration 120 \
--agenda-0 "Review previous sprint" --agenda-0-duration 20 \
--agenda-1 "Story estimation" --agenda-1-duration 60 \
--agenda-2 "Sprint commitment" --agenda-2-duration 20 \
--prep
Quick Schedule
# Quick 30-minute meeting (minimal options)
node dist/cli.js quick --title "Quick Sync" --attendees "bob@example.com"
# With duration
node dist/cli.js quick --title "Code Review" --attendees "dev@example.com" --duration 60
Use a Template
# List available templates
node dist/cli.js templates
# Schedule from template
node dist/cli.js template "Standup" --attendees "team@example.com"
# With custom title
node dist/cli.js template "1-on-1" --title "1-on-1 with Alice" --attendees "alice@example.com"
List Meetings
# List upcoming meetings
node dist/cli.js list
# List more meetings
node dist/cli.js list --days 30 --limit 50
# Filter by status
node dist/cli.js list --status scheduled
Get Meeting Details
node dist/cli.js get meeting_abc123
Cancel a Meeting
# Cancel and notify attendees
node dist/cli.js cancel meeting_abc123
# Cancel without notifications
node dist/cli.js cancel meeting_abc123 --no-notify
Delete a Meeting
node dist/cli.js delete meeting_abc123
Find Available Time
# Find 60-minute slots in next 7 days
node dist/cli.js free
# Find 30-minute slots in next 3 days
node dist/cli.js free --duration 30 --days 3
Send Invites
# Re-send invites for a meeting
node dist/cli.js invite meeting_abc123
Send Prep Email
# Send agenda and prep materials
node dist/cli.js prep meeting_abc123
JavaScript/TypeScript API
Initialize
import { MeetingsSkill } from '@openclaw/meetings';
// Create skill for default profile
const meetings = new MeetingsSkill();
// Or for specific profile
const workMeetings = MeetingsSkill.forProfile('work');
Check Status
const status = await meetings.getStatus();
console.log('Connected:', status.connected);
console.log('Calendar:', status.calendarConnected);
console.log('Email:', status.emailConnected);
Schedule a Meeting
const result = await meetings.schedule({
title: 'Team Standup',
description: 'Daily team sync',
duration: 30,
attendees: ['alice@example.com', 'bob@example.com'],
timeMin: new Date().toISOString(),
timeMax: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
location: 'Conference Room A',
agenda: [
{ title: 'What did you do yesterday?', duration: 10 },
{ title: 'What will you do today?', duration: 10 },
{ title: 'Any blockers?', duration: 10 },
],
sendInvites: true,
sendPrepEmail: true,
});
if (result.success) {
console.log('Meeting scheduled:', result.meeting?.id);
console.log('Time:', result.meeting?.startTime);
} else {
console.error('Failed:', result.error);
}
Schedule from Template
const result = await meetings.scheduleFromTemplate('Standup', {
title: 'Daily Standup',
attendees: ['team@example.com'],
timeMin: new Date().toISOString(),
timeMax: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
sendInvites: true,
});
Find Availability
const availability = await meetings.findAvailability({
attendees: ['alice@example.com', 'bob@example.com'],
duration: 60,
timeMin: new Date().toISOString(),
timeMax: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
});
for (const slot of availability.availableSlots) {
console.log(`Available: ${slot.start} - ${slot.end}`);
}
List Meetings
const meetingList = await meetings.listMeetings({
status: 'scheduled',
from: new Date().toISOString(),
to: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
limit: 50,
});
for (const meeting of meetingList) {
console.log(`${meeting.title}: ${meeting.startTime}`);
}
Get Meeting Details
const meeting = await meetings.getMeeting('meeting_abc123');
console.log('Title:', meeting?.title);
console.log('Attendees:', meeting?.attendees.map(a => a.email));
console.log('Agenda:', meeting?.agenda.map(item => item.title));
Update a Meeting
const updated = await meetings.updateMeeting('meeting_abc123', {
title: 'Updated Title',
startTime: new Date(Date.now() + 2 * 60 * 60 * 1000).toISOString(),
endTime: new Date(Date.now() + 3 * 60 * 60 * 1000).toISOString(),
});
Cancel a Meeting
// Cancel and notify attendees
await meetings.cancelMeeting('meeting_abc123', true);
// Cancel without notifications
await meetings.cancelMeeting('meeting_abc123', false);
Send Invites
const meeting = await meetings.getMeeting('meeting_abc123');
if (meeting) {
await meetings.sendMeetingInvite(meeting);
}
Send Prep Email
const meeting = await meetings.getMeeting('meeting_abc123');
if (meeting) {
await meetings.sendPrepEmail(meeting);
}
Meeting Templates
Default Templates
The meetings skill includes several pre-defined templates:
Standup
- Duration: 15 minutes
- Agenda: Yesterday’s work, Today’s plan, Blockers
Sprint Planning
- Duration: 2 hours
- Agenda: Review, Goal discussion, Estimation, Commitment
1-on-1
- Duration: 30 minutes
- Agenda: Updates, Priorities, Challenges, Career development
Retrospective
- Duration: 1 hour
- Agenda: What went well, Improvements, Action items
Review
- Duration: 1 hour
- Agenda: Status overview, Demo, Feedback
Create Custom Template
const template = await meetings.createTemplate({
name: 'Architecture Review',
title: 'Architecture Review: {topic}',
description: 'Review proposed architecture changes',
duration: 90,
agenda: [
{ id: '1', title: 'Problem statement', duration: 10 },
{ id: '2', title: 'Proposed solution', duration: 30 },
{ id: '3', title: 'Discussion', duration: 40 },
{ id: '4', title: 'Decision', duration: 10 },
],
prepDocuments: [
{ id: '1', name: 'Architecture Doc', type: 'link', required: true },
],
});
List Templates
const templates = await meetings.listTemplates();
for (const template of templates) {
console.log(`${template.name}: ${template.duration} min`);
}
Data Types
Meeting
interface Meeting {
id: string;
title: string;
description?: string;
startTime: string; // ISO datetime
endTime: string; // ISO datetime
timeZone: string;
location?: string;
videoLink?: string;
attendees: MeetingAttendee[];
agenda: AgendaItem[];
prepDocuments: PrepDocument[];
calendarEventId?: string;
status: 'draft' | 'scheduled' | 'cancelled' | 'completed';
notes?: string;
createdAt: string;
updatedAt: string;
}
MeetingAttendee
interface MeetingAttendee {
email: string;
name?: string;
optional?: boolean;
responseStatus?: 'needsAction' | 'declined' | 'tentative' | 'accepted';
}
AgendaItem
interface AgendaItem {
id: string;
title: string;
duration: number; // in minutes
presenter?: string;
description?: string;
}
PrepDocument
interface PrepDocument {
id: string;
name: string;
url?: string;
content?: string;
type: 'link' | 'file' | 'note';
required: boolean;
}
Storage
Meeting data is stored in:
~/.openclaw/skills/meetings/meetings.db
Tables:
meetings– Meeting recordstemplates– Meeting templates
Multi-Profile Support
Manage meetings for different accounts:
import { MeetingsSkill } from '@openclaw/meetings';
// Work account
const work = MeetingsSkill.forProfile('work');
// Personal account
const personal = MeetingsSkill.forProfile('personal');
// Schedule independently
await work.schedule({ /* work meeting */ });
await personal.schedule({ /* personal meeting */ });
Each profile needs separate authentication:
node ../google-oauth/dist/cli.js connect work calendar email
node ../google-oauth/dist/cli.js connect personal calendar email
Error Handling
try {
const result = await meetings.schedule({
title: 'Team Meeting',
duration: 60,
attendees: ['team@example.com'],
timeMin: new Date().toISOString(),
timeMax: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
});
if (!result.success) {
console.log('Could not schedule:', result.error);
console.log('Alternative slots:', result.suggestedSlots);
}
} catch (error) {
console.error('Error:', error.message);
}
Testing
# Type checking
npm run typecheck
# Build
npm run build
# Check status
npm run status
# List templates
npm run cli -- templates
# Schedule a meeting
npm run cli -- quick --title "Test Meeting" --attendees "you@example.com"
# List meetings
npm run cli -- list --days 30
Troubleshooting
“Not connected” error
Authenticate with google-oauth first:
node ../google-oauth/dist/cli.js connect default calendar email
Calendar or email not working
Check health of dependencies:
node ../calendar/dist/cli.js health
node ../email/dist/cli.js health
No available slots found
Expand your search window:
node dist/cli.js schedule --title "Meeting" --attendees "email@example.com" --days 14
Dependencies
@openclaw/calendar: Calendar integration@openclaw/email: Email integration@openclaw/google-oauth: Authentication (via calendar/email)@openclaw/auth-provider: Base authenticationsqlite3: Local storage
Security Notes
- OAuth tokens stored encrypted by auth-provider
- Meeting database has 0600 permissions
- Email communications use Gmail API
- Calendar events use Google Calendar API