Skip to content

Commit 1b52034

Browse files
committed
ADDED:Calander Intregrated
1 parent c2ec968 commit 1b52034

File tree

9 files changed

+990
-8
lines changed

9 files changed

+990
-8
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@
33
local.js
44
app.js
55
send_email.js
6-
assistant.json
6+
assistant.json
7+
auth.jsons
8+
calendar_auth.json
9+
auth.json
10+
clinetAuth.json
11+
googleAuth.json

README.MD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,5 @@ Example error response:
8080
}
8181
8282
```
83+
84+
Google Calander:https://console.cloud.google.com/

calander.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { google } from "googleapis";
2+
import fs from "fs";
3+
import path from "path";
4+
5+
//const KEYFILEPATH = "auth.json";
6+
const CALENDAR_ID = "primary";
7+
8+
const serviceAccountCredentials = JSON.parse(
9+
fs.readFileSync(path.join("auth.json"), "utf8")
10+
);
11+
12+
// Google Calendar API client setup
13+
const auth = new google.auth.JWT(
14+
serviceAccountCredentials.client_email,
15+
null,
16+
serviceAccountCredentials.private_key,
17+
[
18+
"https://www.googleapis.com/auth/calendar",
19+
"https://www.googleapis.com/auth/calendar.events",
20+
"https://www.googleapis.com/auth/admin.directory.resource.calendar",
21+
"https://www.googleapis.com/auth/cloud-platform",
22+
],
23+
"gil@smartrise.org",
24+
"111370419970452146902"
25+
);
26+
const calendar = google.calendar({ version: "v3", auth });
27+
console.log("Auth setup complete, proceeding with API calls...");
28+
// Function to check calendar availability
29+
export async function checkDateTimeAvailability(dateTimeToCheck) {
30+
const startDateTime = new Date(dateTimeToCheck);
31+
const endDateTime = new Date(startDateTime.getTime() + 60 * 60000); // Check 1 hour range
32+
33+
const res = await calendar.freebusy.query({
34+
requestBody: {
35+
timeMin: startDateTime.toISOString(),
36+
timeMax: endDateTime.toISOString(),
37+
items: [{ id: CALENDAR_ID }],
38+
},
39+
});
40+
41+
const isAvailable = res.data.calendars[CALENDAR_ID].busy.length === 0;
42+
console.log(
43+
`Checking availability for: ${startDateTime.toISOString()} to ${endDateTime.toISOString()}`
44+
);
45+
console.log(`Availability: ${isAvailable ? "Available" : "Not available"}`);
46+
return isAvailable;
47+
}
48+
49+
// // Function to create a calendar event
50+
async function createAppointment(dateTimeToCheck, summary, description, email) {
51+
if (await checkDateTimeAvailability(dateTimeToCheck)) {
52+
const event = {
53+
summary,
54+
description,
55+
start: {
56+
dateTime: dateTimeToCheck,
57+
timeZone: "America/New_York",
58+
},
59+
end: {
60+
dateTime: new Date(
61+
new Date(dateTimeToCheck).getTime() + 3600000
62+
).toISOString(), // Adds one hour to the start time
63+
timeZone: "America/New_York",
64+
},
65+
attendees: [{ email: email }],
66+
};
67+
68+
try {
69+
const { data } = await calendar.events.insert({
70+
calendarId: CALENDAR_ID,
71+
resource: event,
72+
});
73+
74+
return data.htmlLink; // Return the link to the created calendar event
75+
} catch (error) {
76+
console.error("Error booking appointment:", error);
77+
throw error;
78+
}
79+
} else {
80+
console.log(
81+
"Time slot not available, looking for the next available slot..."
82+
);
83+
// Find the next available time slot, add an hour and try again:
84+
const nextAttempt = new Date(new Date(dateTimeToCheck).getTime() + 3600000);
85+
return createAppointment(
86+
nextAttempt.toISOString(),
87+
summary,
88+
description,
89+
email
90+
);
91+
}
92+
}
93+
94+
// // Example usage of booking an appointment
95+
export async function setupMeeting(dateTime, summary, description, email) {
96+
try {
97+
const bookingLink = await createAppointment(
98+
dateTime,
99+
summary,
100+
description,
101+
102+
email
103+
);
104+
console.log(
105+
`Meeting successfully scheduled, you can join using this link: ${bookingLink}`
106+
);
107+
} catch (error) {
108+
console.error("Failed to schedule the meeting:", error);
109+
}
110+
}

checkDateTimeAvailability.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"type": "function",
3+
"function":{
4+
"name": "checkDateTimeAvailability",
5+
"description": "Checks if the specified date and time are available in the calendar.",
6+
"parameters": {
7+
"type": "object",
8+
"properties": {
9+
"dateTimeToCheck": {
10+
"type": "string",
11+
"format": "date-time",
12+
"description": "The date and time to check availability for, in ISO 8601 format."
13+
}
14+
},
15+
"required": ["dateTimeToCheck"]
16+
}
17+
}
18+
}

createAppointment.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"type": "function",
3+
"function":{
4+
"name": "createAppointment",
5+
"description": "Creates an appointment in the calendar if the time slot is available.",
6+
"parameters": {
7+
"type": "object",
8+
"properties": {
9+
"dateTimeToCheck": {
10+
"type": "string",
11+
"format": "date-time",
12+
"description": "The starting date and time of the appointment in ISO 8601 format."
13+
},
14+
"summary": {
15+
"type": "string",
16+
"description": "A brief summary or title for the appointment."
17+
},
18+
"description": {
19+
"type": "string",
20+
"description": "A detailed description of the appointment."
21+
},
22+
"location": {
23+
"type": "string",
24+
"description": "The location of the appointment, can be a physical address or a virtual location."
25+
},
26+
"email": {
27+
"type": "string",
28+
"format": "email",
29+
"description": "The email address of the attendee to be added to the appointment."
30+
}
31+
},
32+
"required": ["dateTimeToCheck", "summary", "description", "location", "email"]
33+
}
34+
}
35+
}

index.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { promises as fsPromises } from "fs";
55
import OpenAI from "openai";
66
import dotenv from "dotenv";
77
import { sendTestWebhook } from "./get_webhook.js";
8+
import { checkDateTimeAvailability } from "./calander.js";
89

910
// Load environment variables from .env file
1011
dotenv.config();
@@ -13,7 +14,7 @@ dotenv.config();
1314
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
1415

1516
const app = express();
16-
const port = 3000;
17+
const port = 5000;
1718

1819
// Middleware to parse JSON bodies
1920
app.use(bodyParser.json());
@@ -80,6 +81,7 @@ function extractUserDetailsFromQuestion(question) {
8081

8182
return userDetails;
8283
}
84+
8385
// Async function to get existing assistant
8486
async function getOrCreateAssistant() {
8587
const assistantFilePath = "./assistant.json";
@@ -149,8 +151,30 @@ async function chatWithAssistant(question, userDetails) {
149151
// Prepare the tool outputs
150152
const toolOutputs = [];
151153
for (const toolCall of toolCalls) {
154+
if (toolCall.function.name === "checkDateTimeAvailability") {
155+
const output = await checkDateTimeAvailability(userDetails);
156+
toolOutputs.push({
157+
tool_call_id: toolCall.id,
158+
output: output,
159+
});
160+
}
161+
162+
if (toolCall.function.name === "createAppointment") {
163+
const output = await createAppointment(
164+
userDetails.date + " " + userDetails.time,
165+
"Appointment",
166+
"Meeting with the user",
167+
userDetails.email
168+
);
169+
toolOutputs.push({
170+
tool_call_id: toolCall.id,
171+
output: output,
172+
});
173+
}
174+
152175
if (toolCall.function.name === "sendTestWebhook") {
153-
const output = await sendTestWebhook(userDetails);
176+
const meetingLink = await createAppointment(userDetails);
177+
const output = await sendTestWebhook(meetingLink);
154178
toolOutputs.push({
155179
tool_call_id: toolCall.id,
156180
output: output,

0 commit comments

Comments
 (0)