@elizaos/plugin-google-meet-cute
Version:
Google Meet integration plugin for ElizaOS - manage meetings, get participant info, and access meeting artifacts via Google Meet REST API
938 lines (918 loc) • 32.1 kB
JavaScript
import { Service, logger } from '@elizaos/core';
import { google } from 'googleapis';
import { createServer } from 'http';
import { URL } from 'url';
import { z } from 'zod';
import * as fs from 'fs/promises';
import * as path from 'path';
// src/index.ts
var GoogleAuthService = class _GoogleAuthService extends Service {
static serviceType = "google-auth";
oauth2Client;
authenticated = false;
get capabilityDescription() {
return "Google OAuth2 authentication service for Google Meet API";
}
constructor(runtime) {
super(runtime);
const clientId = runtime.getSetting("GOOGLE_CLIENT_ID");
const clientSecret = runtime.getSetting("GOOGLE_CLIENT_SECRET");
const redirectUri = runtime.getSetting("GOOGLE_REDIRECT_URI") || "http://localhost:3000/oauth2callback";
if (!clientId || !clientSecret) {
throw new Error("Google OAuth2 credentials not configured. Please set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET");
}
this.oauth2Client = new google.auth.OAuth2(
clientId,
clientSecret,
redirectUri
);
const refreshToken = runtime.getSetting("GOOGLE_REFRESH_TOKEN");
if (refreshToken) {
this.oauth2Client.setCredentials({
refresh_token: refreshToken
});
this.authenticated = true;
logger.info("Authenticated with Google using refresh token");
}
}
static async start(runtime) {
logger.info("Starting Google Auth Service");
const service = new _GoogleAuthService(runtime);
await service.initialize();
return service;
}
async initialize() {
if (!this.authenticated) {
logger.info("Google OAuth2 client initialized. Use authenticateInteractive() to authenticate.");
}
}
getAuthUrl() {
const scopes = [
"https://www.googleapis.com/auth/meetings.space.created",
"https://www.googleapis.com/auth/meetings.space.readonly"
];
const authUrl = this.oauth2Client.generateAuthUrl({
access_type: "offline",
scope: scopes,
prompt: "consent"
});
return authUrl;
}
async authenticateInteractive() {
if (this.authenticated) {
logger.info("Already authenticated with Google");
return;
}
const authUrl = this.getAuthUrl();
logger.info(`Please visit this URL to authenticate: ${authUrl}`);
const server = createServer(async (req, res) => {
try {
const url = new URL(req.url, `http://${req.headers.host}`);
if (url.pathname === "/oauth2callback") {
const code = url.searchParams.get("code");
if (code) {
const { tokens } = await this.oauth2Client.getToken(code);
this.oauth2Client.setCredentials(tokens);
this.authenticated = true;
logger.info("Successfully authenticated with Google");
logger.info(`Refresh token: ${tokens.refresh_token}`);
logger.info("Save this refresh token in your .env file as GOOGLE_REFRESH_TOKEN to avoid re-authentication");
res.writeHead(200, { "Content-Type": "text/html" });
res.end("<h1>Authentication successful!</h1><p>You can close this window.</p>");
server.close();
} else {
throw new Error("No authorization code received");
}
}
} catch (error) {
logger.error("OAuth callback error:", error);
res.writeHead(500, { "Content-Type": "text/html" });
res.end("<h1>Authentication failed!</h1><p>Check the logs for details.</p>");
server.close();
}
});
const redirectUri = this.runtime.getSetting("GOOGLE_REDIRECT_URI") || "http://localhost:3000/oauth2callback";
const port = new URL(redirectUri).port || "3000";
server.listen(parseInt(port));
return new Promise((resolve) => {
server.on("close", resolve);
});
}
async getAccessToken() {
if (!this.authenticated) {
throw new Error("Not authenticated. Please authenticate first.");
}
const tokens = await this.oauth2Client.getAccessToken();
if (!tokens.token) {
throw new Error("Failed to get access token");
}
return tokens.token;
}
getOAuth2Client() {
return this.oauth2Client;
}
isAuthenticated() {
return this.authenticated;
}
async stop() {
logger.info("Stopping Google Auth Service");
}
};
var googleMeetConfigSchema = z.object({
GOOGLE_CLIENT_ID: z.string().optional(),
GOOGLE_CLIENT_SECRET: z.string().optional(),
GOOGLE_REDIRECT_URI: z.string().default("http://localhost:3000/oauth2callback"),
GOOGLE_REFRESH_TOKEN: z.string().optional(),
GOOGLE_MEET_DEFAULT_DURATION_MINUTES: z.union([z.number(), z.string()]).transform(
(val) => typeof val === "string" ? parseInt(val, 10) : val
).default(60),
GOOGLE_MEET_DEFAULT_ACCESS_TYPE: z.enum(["OPEN", "TRUSTED", "RESTRICTED"]).default("OPEN")
});
var MeetingStatus = /* @__PURE__ */ ((MeetingStatus2) => {
MeetingStatus2["WAITING"] = "waiting";
MeetingStatus2["ACTIVE"] = "active";
MeetingStatus2["ENDED"] = "ended";
MeetingStatus2["ERROR"] = "error";
return MeetingStatus2;
})(MeetingStatus || {});
// src/services/googleMeetAPIService.ts
var GoogleMeetAPIService = class _GoogleMeetAPIService extends Service {
static serviceType = "google-meet-api";
authService;
meetClient;
meetings = /* @__PURE__ */ new Map();
currentMeetingSpace = null;
get capabilityDescription() {
return "Google Meet API service for managing meetings, participants, and artifacts";
}
constructor(runtime) {
super(runtime);
this.authService = runtime.getService("google-auth");
if (!this.authService) {
throw new Error("GoogleAuthService not found. Make sure it's registered before GoogleMeetAPIService");
}
this.meetClient = google.meet({
version: "v2",
auth: this.authService.getOAuth2Client()
});
}
static async start(runtime) {
logger.info("Starting Google Meet API Service");
const service = new _GoogleMeetAPIService(runtime);
await service.initialize();
return service;
}
async initialize() {
if (!this.authService.isAuthenticated()) {
logger.warn("Google Auth Service not authenticated. Please authenticate before using Meet API.");
}
}
async createMeeting(config) {
try {
const response = await this.meetClient.spaces.create({
requestBody: {
config: {
accessType: config?.accessType || "OPEN",
entryPointAccess: "ALL"
}
}
});
const space = response.data;
if (!space.name || !space.meetingUri || !space.meetingCode) {
throw new Error("Invalid meeting space response");
}
const meeting = {
id: space.name,
meetingCode: space.meetingCode,
meetingUri: space.meetingUri,
status: "active" /* ACTIVE */,
startTime: /* @__PURE__ */ new Date(),
participants: [],
transcripts: []
};
this.meetings.set(meeting.id, meeting);
this.currentMeetingSpace = space;
logger.info(`Created meeting: ${meeting.meetingUri}`);
return meeting;
} catch (error) {
logger.error("Failed to create meeting:", error);
throw error;
}
}
async getMeetingSpace(spaceName) {
try {
const response = await this.meetClient.spaces.get({
name: spaceName
});
return response.data;
} catch (error) {
logger.error(`Failed to get meeting space ${spaceName}:`, error);
throw error;
}
}
async getConference(conferenceName) {
try {
const response = await this.meetClient.conferenceRecords.get({
name: conferenceName
});
return response.data;
} catch (error) {
logger.error(`Failed to get conference ${conferenceName}:`, error);
throw error;
}
}
async listParticipants(conferenceRecordName) {
try {
const response = await this.meetClient.conferenceRecords.participants.list({
parent: conferenceRecordName,
pageSize: 100
});
const participants = [];
if (response.data.participants) {
for (const p of response.data.participants) {
if (p.name) {
let displayName = "Unknown";
if (p.signedinUser) {
displayName = p.signedinUser.displayName || p.signedinUser.user || "Signed-in User";
} else if (p.anonymousUser) {
displayName = p.anonymousUser.displayName || "Anonymous User";
} else if (p.phoneUser) {
displayName = p.phoneUser.displayName || "Phone User";
}
participants.push({
id: p.name,
name: displayName,
joinTime: p.earliestStartTime ? new Date(p.earliestStartTime) : /* @__PURE__ */ new Date(),
leaveTime: p.latestEndTime ? new Date(p.latestEndTime) : void 0,
isActive: !p.latestEndTime
});
}
}
}
return participants;
} catch (error) {
logger.error(`Failed to list participants for ${conferenceRecordName}:`, error);
throw error;
}
}
async getTranscript(transcriptName) {
try {
const response = await this.meetClient.conferenceRecords.transcripts.get({
name: transcriptName
});
if (!response.data.name) {
throw new Error("Invalid transcript response");
}
const entriesResponse = await this.meetClient.conferenceRecords.transcripts.entries.list({
parent: response.data.name,
pageSize: 1e3
});
let fullTranscript = "";
if (entriesResponse.data.transcriptEntries) {
for (const entry of entriesResponse.data.transcriptEntries) {
const speaker = entry.participant || "Unknown";
const text = entry.text || "";
fullTranscript += `${speaker}: ${text}
`;
}
}
return fullTranscript;
} catch (error) {
logger.error(`Failed to get transcript ${transcriptName}:`, error);
throw error;
}
}
async listRecordings(conferenceRecordName) {
try {
const response = await this.meetClient.conferenceRecords.recordings.list({
parent: conferenceRecordName
});
return response.data.recordings || [];
} catch (error) {
logger.error(`Failed to list recordings for ${conferenceRecordName}:`, error);
throw error;
}
}
async getRecordingUrl(recordingName) {
try {
const response = await this.meetClient.conferenceRecords.recordings.get({
name: recordingName
});
return response.data.driveDestination?.file || null;
} catch (error) {
logger.error(`Failed to get recording ${recordingName}:`, error);
throw error;
}
}
async endMeeting(spaceName) {
try {
await this.meetClient.spaces.endActiveConference({
name: spaceName
});
const meeting = Array.from(this.meetings.values()).find((m) => m.id === spaceName);
if (meeting) {
meeting.status = "ended" /* ENDED */;
meeting.endTime = /* @__PURE__ */ new Date();
}
logger.info(`Ended meeting: ${spaceName}`);
} catch (error) {
logger.error(`Failed to end meeting ${spaceName}:`, error);
throw error;
}
}
getCurrentMeeting() {
return this.currentMeetingSpace ? this.meetings.get(this.currentMeetingSpace.name) || null : null;
}
getMeeting(meetingId) {
return this.meetings.get(meetingId) || null;
}
async stop() {
logger.info("Stopping Google Meet API Service");
this.meetings.clear();
this.currentMeetingSpace = null;
}
};
var createMeetingAction = {
name: "CREATE_MEETING",
description: "Create a new Google Meet meeting space",
similes: ["start a meeting", "create a meet", "new meeting", "setup a call"],
examples: [
[
{
name: "user",
content: {
text: "Create a new meeting"
}
},
{
name: "assistant",
content: {
text: "I'll create a new Google Meet meeting for you.",
action: "CREATE_MEETING"
}
}
],
[
{
name: "user",
content: {
text: "Start a team meeting with restricted access"
}
},
{
name: "assistant",
content: {
text: "I'll create a restricted access meeting for your team.",
action: "CREATE_MEETING"
}
}
]
],
validate: async (runtime, message, state) => {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
logger.error("Google Meet API service not found");
return false;
}
return true;
},
handler: async (runtime, message, state, params, callback) => {
try {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
throw new Error("Google Meet API service not found");
}
const meetingParams = params;
let accessType = meetingParams?.accessType;
if (!accessType && message.content.text) {
const text = message.content.text.toLowerCase();
if (text.includes("restricted") || text.includes("private")) {
accessType = "RESTRICTED";
} else if (text.includes("trusted") || text.includes("organization")) {
accessType = "TRUSTED";
} else {
accessType = "OPEN";
}
}
const meeting = await googleMeetService.createMeeting({
accessType
});
const response = `\u2705 Meeting created successfully!
\u{1F4C5} **Meeting Details:**
- Meeting Link: ${meeting.meetingUri}
- Meeting Code: ${meeting.meetingCode}
- Access Type: ${accessType}
- Status: Active
You can share this link with participants to join the meeting.`;
if (callback) {
callback({
text: response,
metadata: {
meetingId: meeting.id,
meetingUri: meeting.meetingUri,
meetingCode: meeting.meetingCode
}
});
}
} catch (error) {
logger.error("Failed to create meeting:", error);
if (callback) {
callback({
text: `\u274C Failed to create meeting: ${error instanceof Error ? error.message : "Unknown error"}`,
error: true
});
}
}
}
};
var getMeetingInfoAction = {
name: "GET_MEETING_INFO",
description: "Get information about a Google Meet meeting",
similes: ["meeting info", "check meeting", "meeting status", "meeting details"],
examples: [
[
{
name: "user",
content: {
text: "What's the status of the current meeting?"
}
},
{
name: "assistant",
content: {
text: "I'll check the current meeting status for you.",
action: "GET_MEETING_INFO"
}
}
],
[
{
name: "user",
content: {
text: "Get information about meeting abc-defg-hij"
}
},
{
name: "assistant",
content: {
text: "I'll retrieve the information for that meeting.",
action: "GET_MEETING_INFO"
}
}
]
],
validate: async (runtime, message, state) => {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
logger.error("Google Meet API service not found");
return false;
}
return true;
},
handler: async (runtime, message, state, params, callback) => {
try {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
throw new Error("Google Meet API service not found");
}
const meetingParams = params;
let meeting = googleMeetService.getCurrentMeeting();
if (!meeting && message.content.text) {
const meetingCodeMatch = message.content.text.match(/[a-z]{3}-[a-z]{4}-[a-z]{3}/i);
if (meetingCodeMatch) {
throw new Error("Please provide the full meeting space ID (not just the meeting code) to retrieve meeting information");
}
if (meetingParams?.meetingId) {
meeting = googleMeetService.getMeeting(meetingParams.meetingId);
}
}
if (!meeting) {
throw new Error("No active meeting found. Please create a meeting first or provide a meeting ID.");
}
const response = `\u{1F4C5} **Meeting Information:**
- Meeting Link: ${meeting.meetingUri}
- Meeting Code: ${meeting.meetingCode}
- Status: ${meeting.status}
- Started: ${meeting.startTime.toLocaleString()}
${meeting.endTime ? `- Ended: ${meeting.endTime.toLocaleString()}` : "- Duration: Ongoing"}
- Participants: ${meeting.participants.length}
${meeting.participants.length > 0 ? "\n**Active Participants:**\n" + meeting.participants.filter((p) => p.isActive).map((p) => ` \u2022 ${p.name} (joined ${p.joinTime.toLocaleTimeString()})`).join("\n") : ""}`;
if (callback) {
callback({
text: response,
metadata: {
meetingId: meeting.id,
meetingUri: meeting.meetingUri,
meetingCode: meeting.meetingCode,
participantCount: meeting.participants.length
}
});
}
} catch (error) {
logger.error("Failed to get meeting info:", error);
if (callback) {
callback({
text: `\u274C Failed to get meeting info: ${error instanceof Error ? error.message : "Unknown error"}`,
error: true
});
}
}
}
};
var getParticipantsAction = {
name: "GET_PARTICIPANTS",
description: "Get the list of participants in a Google Meet conference",
similes: ["who's in the meeting", "list participants", "attendees", "who joined"],
examples: [
[
{
name: "user",
content: {
text: "Who's in the meeting?"
}
},
{
name: "assistant",
content: {
text: "I'll check who's currently in the meeting.",
action: "GET_PARTICIPANTS"
}
}
],
[
{
name: "user",
content: {
text: "List all participants"
}
},
{
name: "assistant",
content: {
text: "Let me get the participant list for you.",
action: "GET_PARTICIPANTS"
}
}
]
],
validate: async (runtime, message, state) => {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
logger.error("Google Meet API service not found");
return false;
}
return true;
},
handler: async (runtime, message, state, params, callback) => {
try {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
throw new Error("Google Meet API service not found");
}
const currentMeeting = googleMeetService.getCurrentMeeting();
if (!currentMeeting) {
throw new Error("No active meeting found. Please create or join a meeting first.");
}
const response = `\u{1F465} **Meeting Participants:**
${currentMeeting.participants.length === 0 ? "No participants have joined yet." : currentMeeting.participants.map((p, index) => {
const status = p.isActive ? "\u{1F7E2}" : "\u26AB";
const duration = p.leaveTime ? `(${Math.round((p.leaveTime.getTime() - p.joinTime.getTime()) / 1e3 / 60)} min)` : "(active)";
return `${index + 1}. ${status} ${p.name} - Joined at ${p.joinTime.toLocaleTimeString()} ${duration}`;
}).join("\n")}
**Total participants:** ${currentMeeting.participants.length}
**Currently active:** ${currentMeeting.participants.filter((p) => p.isActive).length}`;
if (callback) {
callback({
text: response,
metadata: {
totalParticipants: currentMeeting.participants.length,
activeParticipants: currentMeeting.participants.filter((p) => p.isActive).length,
participants: currentMeeting.participants.map((p) => ({
name: p.name,
isActive: p.isActive,
joinTime: p.joinTime.toISOString()
}))
}
});
}
} catch (error) {
logger.error("Failed to get participants:", error);
if (callback) {
callback({
text: `\u274C Failed to get participants: ${error instanceof Error ? error.message : "Unknown error"}
Note: To get real-time participant data, ensure you have an active conference record name from a running meeting.`,
error: true
});
}
}
}
};
var generateReportAction = {
name: "GENERATE_REPORT",
description: "Generate a comprehensive report from Google Meet artifacts (transcripts, recordings)",
similes: ["create report", "meeting summary", "get transcript", "meeting notes"],
examples: [
[
{
name: "user",
content: {
text: "Generate a report for the meeting"
}
},
{
name: "assistant",
content: {
text: "I'll generate a comprehensive report from the meeting artifacts.",
action: "GENERATE_REPORT"
}
}
],
[
{
name: "user",
content: {
text: "Get the meeting transcript and summary"
}
},
{
name: "assistant",
content: {
text: "I'll retrieve the transcript and create a summary for you.",
action: "GENERATE_REPORT"
}
}
]
],
validate: async (runtime, message, state) => {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
logger.error("Google Meet API service not found");
return false;
}
return true;
},
handler: async (runtime, message, state, params, callback) => {
try {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
throw new Error("Google Meet API service not found");
}
const reportParams = params;
let meetingId = reportParams?.meetingId;
const currentMeeting = googleMeetService.getCurrentMeeting();
if (!meetingId && currentMeeting) {
meetingId = currentMeeting.id;
}
if (!meetingId) {
throw new Error("No meeting specified. Please provide a meeting ID or ensure there's an active meeting.");
}
const report = {
meetingId,
title: `Meeting Report - ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,
date: /* @__PURE__ */ new Date(),
duration: 0,
// Would calculate from conference record
participants: [],
// Would get from participants API
summary: "Meeting summary would be generated from transcript data",
keyPoints: [
"Key points would be extracted from transcript",
"Using natural language processing"
],
actionItems: reportParams?.includeActionItems ? [
{
description: "Action items would be extracted from transcript",
priority: "medium"
}
] : [],
fullTranscript: reportParams?.includeTranscript ? [] : []
};
let reportContent = `# Meeting Report
**Meeting ID:** ${report.meetingId}
**Date:** ${report.date.toLocaleDateString()}
**Duration:** ${report.duration} minutes
## Summary
${report.summary}
## Key Points
${report.keyPoints.map((point) => `- ${point}`).join("\n")}
`;
if (report.actionItems.length > 0) {
reportContent += `
## Action Items
${report.actionItems.map((item) => `- ${item.description} (Priority: ${item.priority})`).join("\n")}
`;
}
const outputDir = runtime.getSetting("REPORT_OUTPUT_DIR") || "./meeting-reports";
try {
await fs.mkdir(outputDir, { recursive: true });
const filename = `meeting-report-${Date.now()}.md`;
const filepath = path.join(outputDir, filename);
await fs.writeFile(filepath, reportContent);
reportContent += `
\u{1F4C4} Report saved to: ${filepath}`;
} catch (error) {
logger.warn("Failed to save report to file:", error);
}
const response = `\u2705 Meeting report generated successfully!
${reportContent}
Note: To get actual transcript and recording data, ensure the meeting has ended and artifacts are available through the Google Meet API.`;
if (callback) {
callback({
text: response,
metadata: {
report,
savedToFile: true
}
});
}
} catch (error) {
logger.error("Failed to generate report:", error);
if (callback) {
callback({
text: `\u274C Failed to generate report: ${error instanceof Error ? error.message : "Unknown error"}`,
error: true
});
}
}
}
};
var authenticateAction = {
name: "AUTHENTICATE_GOOGLE",
description: "Authenticate with Google to access Meet API",
similes: ["login to google", "google auth", "sign in", "authenticate"],
examples: [
[
{
name: "user",
content: {
text: "Authenticate with Google"
}
},
{
name: "assistant",
content: {
text: "I'll help you authenticate with Google Meet API.",
action: "AUTHENTICATE_GOOGLE"
}
}
]
],
validate: async (runtime, message, state) => {
const authService = runtime.getService("google-auth");
if (!authService) {
logger.error("Google Auth service not found");
return false;
}
return true;
},
handler: async (runtime, message, state, params, callback) => {
try {
const authService = runtime.getService("google-auth");
if (!authService) {
throw new Error("Google Auth service not found");
}
const authParams = params;
if (authService.isAuthenticated()) {
if (callback) {
callback({
text: "\u2705 Already authenticated with Google Meet API. You can now create meetings, get participant info, and access meeting artifacts."
});
}
return;
}
const interactive = authParams?.interactive !== false;
if (interactive) {
const authUrl = authService.getAuthUrl();
if (callback) {
callback({
text: `\u{1F510} To authenticate with Google Meet API:
1. Visit this URL: ${authUrl}
2. Sign in with your Google account
3. Grant the requested permissions
4. You'll be redirected back to complete authentication
Starting authentication server...`,
metadata: {
authUrl,
interactive: true
}
});
}
await authService.authenticateInteractive();
if (callback) {
callback({
text: `\u2705 Successfully authenticated with Google Meet API!
You can now:
- Create new meetings
- Get meeting information
- List participants
- Generate reports from meeting artifacts
\u{1F4A1} Tip: Save the refresh token shown in the logs to your .env file to avoid re-authentication.`
});
}
} else {
if (callback) {
callback({
text: `\u274C Authentication required. Please set up Google OAuth credentials:
1. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in your .env file
2. Optionally set GOOGLE_REFRESH_TOKEN if you have one
3. Run this command again to authenticate interactively`
});
}
}
} catch (error) {
logger.error("Failed to authenticate:", error);
if (callback) {
callback({
text: `\u274C Failed to authenticate: ${error instanceof Error ? error.message : "Unknown error"}`,
error: true
});
}
}
}
};
var meetingProvider = {
name: "GOOGLE_MEET_PROVIDER",
description: "Provides current Google Meet meeting information and status",
get: async (runtime, message, state) => {
try {
const googleMeetService = runtime.getService("google-meet-api");
if (!googleMeetService) {
return { text: "Google Meet API service not available" };
}
const currentMeeting = googleMeetService.getCurrentMeeting();
if (!currentMeeting) {
return { text: "No active Google Meet meeting" };
}
const activeParticipants = currentMeeting.participants.filter((p) => p.isActive).length;
const duration = currentMeeting.endTime ? Math.round((currentMeeting.endTime.getTime() - currentMeeting.startTime.getTime()) / 1e3 / 60) : Math.round((Date.now() - currentMeeting.startTime.getTime()) / 1e3 / 60);
const text = `Current Google Meet:
- Meeting Link: ${currentMeeting.meetingUri}
- Meeting Code: ${currentMeeting.meetingCode}
- Status: ${currentMeeting.status}
- Duration: ${duration} minutes
- Active Participants: ${activeParticipants}
- Total Participants: ${currentMeeting.participants.length}`;
return { text };
} catch (error) {
logger.error("Error in meeting provider:", error);
return { text: "Error retrieving meeting information" };
}
}
};
// src/index.ts
var googleMeetPlugin = {
name: "plugin-google-meet-cute",
description: "Google Meet integration plugin for ElizaOS - manage meetings, get participant info, and access meeting artifacts via Google Meet REST API",
services: [GoogleAuthService, GoogleMeetAPIService],
actions: [
authenticateAction,
createMeetingAction,
getMeetingInfoAction,
getParticipantsAction,
generateReportAction
],
providers: [meetingProvider],
config: {
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
GOOGLE_REDIRECT_URI: process.env.GOOGLE_REDIRECT_URI,
GOOGLE_REFRESH_TOKEN: process.env.GOOGLE_REFRESH_TOKEN,
GOOGLE_MEET_DEFAULT_ACCESS_TYPE: process.env.GOOGLE_MEET_DEFAULT_ACCESS_TYPE,
REPORT_OUTPUT_DIR: process.env.REPORT_OUTPUT_DIR
},
async init(config, runtime) {
logger.info("Initializing Google Meet plugin...");
try {
const validatedConfig = {
GOOGLE_CLIENT_ID: runtime?.getSetting("GOOGLE_CLIENT_ID") || config.GOOGLE_CLIENT_ID || process.env.GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET: runtime?.getSetting("GOOGLE_CLIENT_SECRET") || config.GOOGLE_CLIENT_SECRET || process.env.GOOGLE_CLIENT_SECRET,
GOOGLE_REDIRECT_URI: runtime?.getSetting("GOOGLE_REDIRECT_URI") || config.GOOGLE_REDIRECT_URI || process.env.GOOGLE_REDIRECT_URI || "http://localhost:3000/oauth2callback",
GOOGLE_REFRESH_TOKEN: runtime?.getSetting("GOOGLE_REFRESH_TOKEN") || config.GOOGLE_REFRESH_TOKEN || process.env.GOOGLE_REFRESH_TOKEN,
GOOGLE_MEET_DEFAULT_ACCESS_TYPE: runtime?.getSetting("GOOGLE_MEET_DEFAULT_ACCESS_TYPE") || config.GOOGLE_MEET_DEFAULT_ACCESS_TYPE || process.env.GOOGLE_MEET_DEFAULT_ACCESS_TYPE || "OPEN",
REPORT_OUTPUT_DIR: runtime?.getSetting("REPORT_OUTPUT_DIR") || config.REPORT_OUTPUT_DIR || process.env.REPORT_OUTPUT_DIR || "./meeting-reports"
};
await googleMeetConfigSchema.parseAsync(validatedConfig);
logger.info("Google Meet plugin configuration validated successfully");
if (runtime) {
runtime.character.settings = runtime.character.settings || {};
runtime.character.settings.googleMeetConfig = validatedConfig;
}
if (!validatedConfig.GOOGLE_CLIENT_ID || !validatedConfig.GOOGLE_CLIENT_SECRET) {
logger.warn("Google OAuth credentials not configured. Please set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET to use the Google Meet API.");
}
} catch (error) {
logger.error(
"Google Meet plugin configuration validation failed:",
error
);
throw new Error(
`Invalid Google Meet plugin configuration: ${error instanceof Error ? error.message : String(error)}`
);
}
},
dependencies: []
};
var index_default = googleMeetPlugin;
export { GoogleAuthService, GoogleMeetAPIService, MeetingStatus, index_default as default, googleMeetConfigSchema, googleMeetPlugin };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map