@dguido/google-workspace-mcp 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +255 -96
- package/dist/index.js.map +2 -2
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -5025,7 +5025,7 @@ var calendarTools = [
|
|
|
5025
5025
|
outputSchema: {
|
|
5026
5026
|
type: "object",
|
|
5027
5027
|
properties: {
|
|
5028
|
-
deleted: { type: "
|
|
5028
|
+
deleted: { type: "number", description: "Number of events deleted" },
|
|
5029
5029
|
eventId: { type: "string", description: "Deleted event ID" }
|
|
5030
5030
|
}
|
|
5031
5031
|
}
|
|
@@ -5316,9 +5316,13 @@ var gmailTools = [
|
|
|
5316
5316
|
outputSchema: {
|
|
5317
5317
|
type: "object",
|
|
5318
5318
|
properties: {
|
|
5319
|
-
id: { type: "string", description: "
|
|
5320
|
-
messageCount: { type: "number", description: "Number of
|
|
5321
|
-
labelIds: {
|
|
5319
|
+
id: { type: "string", description: "First modified thread ID (for batch: first in list)" },
|
|
5320
|
+
messageCount: { type: "number", description: "Number of threads modified" },
|
|
5321
|
+
labelIds: {
|
|
5322
|
+
type: "array",
|
|
5323
|
+
items: { type: "string" },
|
|
5324
|
+
description: "Labels that were added"
|
|
5325
|
+
}
|
|
5322
5326
|
}
|
|
5323
5327
|
}
|
|
5324
5328
|
},
|
|
@@ -5389,7 +5393,7 @@ var gmailTools = [
|
|
|
5389
5393
|
outputSchema: {
|
|
5390
5394
|
type: "object",
|
|
5391
5395
|
properties: {
|
|
5392
|
-
deleted: { type: "
|
|
5396
|
+
deleted: { type: "number", description: "Number of labels deleted" },
|
|
5393
5397
|
labelId: { type: "string", description: "Deleted label ID" }
|
|
5394
5398
|
}
|
|
5395
5399
|
}
|
|
@@ -5549,7 +5553,7 @@ var gmailTools = [
|
|
|
5549
5553
|
outputSchema: {
|
|
5550
5554
|
type: "object",
|
|
5551
5555
|
properties: {
|
|
5552
|
-
deleted: { type: "
|
|
5556
|
+
deleted: { type: "number", description: "Number of filters deleted" },
|
|
5553
5557
|
filterId: { type: "string", description: "Deleted filter ID" }
|
|
5554
5558
|
}
|
|
5555
5559
|
}
|
|
@@ -7630,10 +7634,11 @@ ${toToon({ files })}`;
|
|
|
7630
7634
|
|
|
7631
7635
|
More results available. Use pageToken: ${res.data.nextPageToken}`;
|
|
7632
7636
|
}
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
nextPageToken
|
|
7636
|
-
}
|
|
7637
|
+
const responseData = { files };
|
|
7638
|
+
if (res.data.nextPageToken) {
|
|
7639
|
+
responseData.nextPageToken = res.data.nextPageToken;
|
|
7640
|
+
}
|
|
7641
|
+
return structuredResponse(textResponse, responseData);
|
|
7637
7642
|
}
|
|
7638
7643
|
async function handleCreateTextFile(drive2, args) {
|
|
7639
7644
|
const validation = validateArgs(CreateTextFileSchema, args);
|
|
@@ -7751,19 +7756,32 @@ async function handleListFolder(drive2, args) {
|
|
|
7751
7756
|
supportsAllDrives: true
|
|
7752
7757
|
});
|
|
7753
7758
|
const files = res.data.files || [];
|
|
7754
|
-
const
|
|
7759
|
+
const items = [];
|
|
7760
|
+
const formattedLines = [];
|
|
7761
|
+
for (const file of files) {
|
|
7762
|
+
items.push({
|
|
7763
|
+
id: file.id,
|
|
7764
|
+
name: file.name,
|
|
7765
|
+
mimeType: file.mimeType,
|
|
7766
|
+
modifiedTime: file.modifiedTime,
|
|
7767
|
+
size: file.size
|
|
7768
|
+
});
|
|
7755
7769
|
const isFolder = file.mimeType === FOLDER_MIME_TYPE;
|
|
7756
|
-
|
|
7757
|
-
}
|
|
7758
|
-
let
|
|
7770
|
+
formattedLines.push(`${isFolder ? "\u{1F4C1}" : "\u{1F4C4}"} ${file.name} (ID: ${file.id})`);
|
|
7771
|
+
}
|
|
7772
|
+
let textResponse = `Contents of folder:
|
|
7759
7773
|
|
|
7760
|
-
${
|
|
7774
|
+
${formattedLines.join("\n")}`;
|
|
7761
7775
|
if (res.data.nextPageToken) {
|
|
7762
|
-
|
|
7776
|
+
textResponse += `
|
|
7763
7777
|
|
|
7764
7778
|
More items available. Use pageToken: ${res.data.nextPageToken}`;
|
|
7765
7779
|
}
|
|
7766
|
-
|
|
7780
|
+
const responseData = { items };
|
|
7781
|
+
if (res.data.nextPageToken) {
|
|
7782
|
+
responseData.nextPageToken = res.data.nextPageToken;
|
|
7783
|
+
}
|
|
7784
|
+
return structuredResponse(textResponse, responseData);
|
|
7767
7785
|
} catch (error) {
|
|
7768
7786
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7769
7787
|
return errorResponse(`Folder not found: ${targetFolderId}`, { code: "NOT_FOUND" });
|
|
@@ -8779,8 +8797,7 @@ async function handleListTrash(drive2, args) {
|
|
|
8779
8797
|
const files = response.data.files || [];
|
|
8780
8798
|
if (files.length === 0) {
|
|
8781
8799
|
return structuredResponse("Trash is empty", {
|
|
8782
|
-
files: []
|
|
8783
|
-
nextPageToken: null
|
|
8800
|
+
files: []
|
|
8784
8801
|
});
|
|
8785
8802
|
}
|
|
8786
8803
|
const fileData = files.map((f) => ({
|
|
@@ -8793,10 +8810,11 @@ async function handleListTrash(drive2, args) {
|
|
|
8793
8810
|
const textResponse = `Trash contents (${files.length} items):
|
|
8794
8811
|
|
|
8795
8812
|
${toToon({ files: fileData })}` + (response.data.nextPageToken ? "\n\n(More items available - use nextPageToken to continue)" : "");
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
nextPageToken
|
|
8799
|
-
}
|
|
8813
|
+
const responseData = { files: fileData };
|
|
8814
|
+
if (response.data.nextPageToken) {
|
|
8815
|
+
responseData.nextPageToken = response.data.nextPageToken;
|
|
8816
|
+
}
|
|
8817
|
+
return structuredResponse(textResponse, responseData);
|
|
8800
8818
|
}
|
|
8801
8819
|
async function handleRestoreFromTrash(drive2, args) {
|
|
8802
8820
|
const validation = validateArgs(RestoreFromTrashSchema, args);
|
|
@@ -9098,10 +9116,15 @@ async function handleCreateGoogleDoc(drive2, docs, args) {
|
|
|
9098
9116
|
]
|
|
9099
9117
|
}
|
|
9100
9118
|
});
|
|
9101
|
-
return
|
|
9119
|
+
return structuredResponse(
|
|
9102
9120
|
`Created Google Doc: ${doc.name}
|
|
9103
9121
|
ID: ${doc.id}
|
|
9104
|
-
Link: ${doc.webViewLink}
|
|
9122
|
+
Link: ${doc.webViewLink}`,
|
|
9123
|
+
{
|
|
9124
|
+
id: doc.id,
|
|
9125
|
+
name: doc.name,
|
|
9126
|
+
webViewLink: doc.webViewLink
|
|
9127
|
+
}
|
|
9105
9128
|
);
|
|
9106
9129
|
}
|
|
9107
9130
|
async function handleUpdateGoogleDoc(docs, args) {
|
|
@@ -9148,7 +9171,10 @@ async function handleUpdateGoogleDoc(docs, args) {
|
|
|
9148
9171
|
]
|
|
9149
9172
|
}
|
|
9150
9173
|
});
|
|
9151
|
-
return
|
|
9174
|
+
return structuredResponse(`Updated Google Doc: ${document.data.title}`, {
|
|
9175
|
+
title: document.data.title,
|
|
9176
|
+
updated: true
|
|
9177
|
+
});
|
|
9152
9178
|
}
|
|
9153
9179
|
async function handleGetGoogleDocContent(drive2, docs, args) {
|
|
9154
9180
|
const validation = validateArgs(GetGoogleDocContentSchema, args);
|
|
@@ -9239,8 +9265,12 @@ ${data.text}` : data.text;
|
|
|
9239
9265
|
documentId: data.documentId,
|
|
9240
9266
|
textLength: data.text.length
|
|
9241
9267
|
});
|
|
9242
|
-
return
|
|
9243
|
-
`Appended ${data.text.length} characters to document "${document.data.title}"
|
|
9268
|
+
return structuredResponse(
|
|
9269
|
+
`Appended ${data.text.length} characters to document "${document.data.title}"`,
|
|
9270
|
+
{
|
|
9271
|
+
title: document.data.title,
|
|
9272
|
+
charactersAdded: data.text.length
|
|
9273
|
+
}
|
|
9244
9274
|
);
|
|
9245
9275
|
}
|
|
9246
9276
|
async function handleInsertTextInDoc(docs, args) {
|
|
@@ -9272,8 +9302,13 @@ async function handleInsertTextInDoc(docs, args) {
|
|
|
9272
9302
|
index: data.index,
|
|
9273
9303
|
textLength: data.text.length
|
|
9274
9304
|
});
|
|
9275
|
-
return
|
|
9276
|
-
`Inserted ${data.text.length} characters at index ${data.index} in "${document.data.title}"
|
|
9305
|
+
return structuredResponse(
|
|
9306
|
+
`Inserted ${data.text.length} characters at index ${data.index} in "${document.data.title}"`,
|
|
9307
|
+
{
|
|
9308
|
+
title: document.data.title,
|
|
9309
|
+
index: data.index,
|
|
9310
|
+
charactersInserted: data.text.length
|
|
9311
|
+
}
|
|
9277
9312
|
);
|
|
9278
9313
|
}
|
|
9279
9314
|
async function handleDeleteTextInDoc(docs, args) {
|
|
@@ -9308,8 +9343,14 @@ async function handleDeleteTextInDoc(docs, args) {
|
|
|
9308
9343
|
startIndex: data.startIndex,
|
|
9309
9344
|
endIndex: data.endIndex
|
|
9310
9345
|
});
|
|
9311
|
-
return
|
|
9312
|
-
`Deleted ${charsToDelete} characters (indices ${data.startIndex}-${data.endIndex}) from "${document.data.title}"
|
|
9346
|
+
return structuredResponse(
|
|
9347
|
+
`Deleted ${charsToDelete} characters (indices ${data.startIndex}-${data.endIndex}) from "${document.data.title}"`,
|
|
9348
|
+
{
|
|
9349
|
+
title: document.data.title,
|
|
9350
|
+
startIndex: data.startIndex,
|
|
9351
|
+
endIndex: data.endIndex,
|
|
9352
|
+
charactersDeleted: charsToDelete
|
|
9353
|
+
}
|
|
9313
9354
|
);
|
|
9314
9355
|
}
|
|
9315
9356
|
async function handleReplaceTextInDoc(docs, args) {
|
|
@@ -9339,12 +9380,20 @@ async function handleReplaceTextInDoc(docs, args) {
|
|
|
9339
9380
|
occurrences: occurrencesChanged
|
|
9340
9381
|
});
|
|
9341
9382
|
if (occurrencesChanged === 0) {
|
|
9342
|
-
return
|
|
9343
|
-
`No occurrences of "${data.searchText}" found in "${document.data.title}"
|
|
9383
|
+
return structuredResponse(
|
|
9384
|
+
`No occurrences of "${data.searchText}" found in "${document.data.title}"`,
|
|
9385
|
+
{
|
|
9386
|
+
title: document.data.title,
|
|
9387
|
+
occurrencesChanged: 0
|
|
9388
|
+
}
|
|
9344
9389
|
);
|
|
9345
9390
|
}
|
|
9346
|
-
return
|
|
9347
|
-
`Replaced ${occurrencesChanged} occurrence(s) of "${data.searchText}" with "${data.replaceText}" in "${document.data.title}"
|
|
9391
|
+
return structuredResponse(
|
|
9392
|
+
`Replaced ${occurrencesChanged} occurrence(s) of "${data.searchText}" with "${data.replaceText}" in "${document.data.title}"`,
|
|
9393
|
+
{
|
|
9394
|
+
title: document.data.title,
|
|
9395
|
+
occurrencesChanged
|
|
9396
|
+
}
|
|
9348
9397
|
);
|
|
9349
9398
|
}
|
|
9350
9399
|
function buildDocTextStyle(data) {
|
|
@@ -9452,8 +9501,13 @@ async function handleFormatGoogleDocRange(docs, args) {
|
|
|
9452
9501
|
endIndex,
|
|
9453
9502
|
formatsApplied
|
|
9454
9503
|
});
|
|
9455
|
-
return
|
|
9456
|
-
`Applied formatting to range ${startIndex}-${endIndex}: ${formatsApplied.join(", ")}
|
|
9504
|
+
return structuredResponse(
|
|
9505
|
+
`Applied formatting to range ${startIndex}-${endIndex}: ${formatsApplied.join(", ")}`,
|
|
9506
|
+
{
|
|
9507
|
+
startIndex,
|
|
9508
|
+
endIndex,
|
|
9509
|
+
formatsApplied
|
|
9510
|
+
}
|
|
9457
9511
|
);
|
|
9458
9512
|
}
|
|
9459
9513
|
|
|
@@ -9563,9 +9617,13 @@ async function handleCreateGoogleSheet(drive2, sheets, args) {
|
|
|
9563
9617
|
valueInputOption: data.valueInputOption || "RAW",
|
|
9564
9618
|
requestBody: { values: data.data }
|
|
9565
9619
|
});
|
|
9566
|
-
return
|
|
9620
|
+
return structuredResponse(
|
|
9567
9621
|
`Created Google Sheet: ${data.name}
|
|
9568
|
-
ID: ${spreadsheet.data.spreadsheetId}
|
|
9622
|
+
ID: ${spreadsheet.data.spreadsheetId}`,
|
|
9623
|
+
{
|
|
9624
|
+
id: spreadsheet.data.spreadsheetId,
|
|
9625
|
+
name: data.name
|
|
9626
|
+
}
|
|
9569
9627
|
);
|
|
9570
9628
|
}
|
|
9571
9629
|
async function handleUpdateGoogleSheet(sheets, args) {
|
|
@@ -9578,7 +9636,10 @@ async function handleUpdateGoogleSheet(sheets, args) {
|
|
|
9578
9636
|
valueInputOption: data.valueInputOption || "RAW",
|
|
9579
9637
|
requestBody: { values: data.data }
|
|
9580
9638
|
});
|
|
9581
|
-
return
|
|
9639
|
+
return structuredResponse(`Updated Google Sheet range: ${data.range}`, {
|
|
9640
|
+
range: data.range,
|
|
9641
|
+
updated: true
|
|
9642
|
+
});
|
|
9582
9643
|
}
|
|
9583
9644
|
async function handleGetGoogleSheetContent(drive2, sheets, args) {
|
|
9584
9645
|
const validation = validateArgs(GetGoogleSheetContentSchema, args);
|
|
@@ -9754,7 +9815,13 @@ async function handleFormatGoogleSheetCells(sheets, args) {
|
|
|
9754
9815
|
spreadsheetId: data.spreadsheetId,
|
|
9755
9816
|
requestBody: { requests }
|
|
9756
9817
|
});
|
|
9757
|
-
return
|
|
9818
|
+
return structuredResponse(
|
|
9819
|
+
`Formatted cells in range ${data.range} (${appliedFormats.join(", ")})`,
|
|
9820
|
+
{
|
|
9821
|
+
range: data.range,
|
|
9822
|
+
applied: true
|
|
9823
|
+
}
|
|
9824
|
+
);
|
|
9758
9825
|
}
|
|
9759
9826
|
async function handleMergeGoogleSheetCells(sheets, args) {
|
|
9760
9827
|
const validation = validateArgs(MergeGoogleSheetCellsSchema, args);
|
|
@@ -9779,7 +9846,10 @@ async function handleMergeGoogleSheetCells(sheets, args) {
|
|
|
9779
9846
|
spreadsheetId: data.spreadsheetId,
|
|
9780
9847
|
requestBody: { requests }
|
|
9781
9848
|
});
|
|
9782
|
-
return
|
|
9849
|
+
return structuredResponse(`Merged cells in range ${data.range} with type ${data.mergeType}`, {
|
|
9850
|
+
range: data.range,
|
|
9851
|
+
mergeType: data.mergeType
|
|
9852
|
+
});
|
|
9783
9853
|
}
|
|
9784
9854
|
async function handleAddGoogleSheetConditionalFormat(sheets, args) {
|
|
9785
9855
|
const validation = validateArgs(AddGoogleSheetConditionalFormatSchema, args);
|
|
@@ -9829,7 +9899,10 @@ async function handleAddGoogleSheetConditionalFormat(sheets, args) {
|
|
|
9829
9899
|
spreadsheetId: data.spreadsheetId,
|
|
9830
9900
|
requestBody: { requests }
|
|
9831
9901
|
});
|
|
9832
|
-
return
|
|
9902
|
+
return structuredResponse(`Added conditional formatting to range ${data.range}`, {
|
|
9903
|
+
range: data.range,
|
|
9904
|
+
conditionType: data.condition.type
|
|
9905
|
+
});
|
|
9833
9906
|
}
|
|
9834
9907
|
async function getSheetIdByTitle(sheets, spreadsheetId, title) {
|
|
9835
9908
|
const cached = getCachedSheetMetadata(spreadsheetId, title);
|
|
@@ -9907,7 +9980,11 @@ async function createSheetTab(sheets, spreadsheetId, title, index) {
|
|
|
9907
9980
|
});
|
|
9908
9981
|
clearSheetCache(spreadsheetId);
|
|
9909
9982
|
const newSheetId = response.data.replies?.[0]?.addSheet?.properties?.sheetId;
|
|
9910
|
-
return
|
|
9983
|
+
return structuredResponse(`Created new sheet tab "${title}" (ID: ${newSheetId})`, {
|
|
9984
|
+
action: "create",
|
|
9985
|
+
sheetId: newSheetId,
|
|
9986
|
+
title
|
|
9987
|
+
});
|
|
9911
9988
|
}
|
|
9912
9989
|
async function deleteSheetTab(sheets, spreadsheetId, title) {
|
|
9913
9990
|
const sheetId = await getSheetIdByTitle(sheets, spreadsheetId, title);
|
|
@@ -9929,7 +10006,11 @@ async function deleteSheetTab(sheets, spreadsheetId, title) {
|
|
|
9929
10006
|
throw error;
|
|
9930
10007
|
}
|
|
9931
10008
|
clearSheetCache(spreadsheetId);
|
|
9932
|
-
return
|
|
10009
|
+
return structuredResponse(`Deleted sheet tab "${title}"`, {
|
|
10010
|
+
action: "delete",
|
|
10011
|
+
sheetId,
|
|
10012
|
+
title
|
|
10013
|
+
});
|
|
9933
10014
|
}
|
|
9934
10015
|
async function renameSheetTab(sheets, spreadsheetId, currentTitle, newTitle) {
|
|
9935
10016
|
const sheetId = await getSheetIdByTitle(sheets, spreadsheetId, currentTitle);
|
|
@@ -9958,7 +10039,11 @@ async function renameSheetTab(sheets, spreadsheetId, currentTitle, newTitle) {
|
|
|
9958
10039
|
}
|
|
9959
10040
|
});
|
|
9960
10041
|
clearSheetCache(spreadsheetId);
|
|
9961
|
-
return
|
|
10042
|
+
return structuredResponse(`Renamed sheet tab "${currentTitle}" to "${newTitle}"`, {
|
|
10043
|
+
action: "rename",
|
|
10044
|
+
sheetId,
|
|
10045
|
+
title: newTitle
|
|
10046
|
+
});
|
|
9962
10047
|
}
|
|
9963
10048
|
|
|
9964
10049
|
// src/handlers/slides.ts
|
|
@@ -10034,10 +10119,15 @@ async function handleCreateGoogleSlides(drive2, slides, args) {
|
|
|
10034
10119
|
requestBody: { requests: insertTextRequests }
|
|
10035
10120
|
});
|
|
10036
10121
|
}
|
|
10037
|
-
return
|
|
10122
|
+
return structuredResponse(
|
|
10038
10123
|
`Created Google Slides presentation: ${data.name}
|
|
10039
10124
|
ID: ${presentation.data.presentationId}
|
|
10040
|
-
Link: https://docs.google.com/presentation/d/${presentation.data.presentationId}
|
|
10125
|
+
Link: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,
|
|
10126
|
+
{
|
|
10127
|
+
id: presentation.data.presentationId,
|
|
10128
|
+
name: data.name,
|
|
10129
|
+
webViewLink: `https://docs.google.com/presentation/d/${presentation.data.presentationId}`
|
|
10130
|
+
}
|
|
10041
10131
|
);
|
|
10042
10132
|
}
|
|
10043
10133
|
async function handleUpdateGoogleSlides(slides, args) {
|
|
@@ -10148,9 +10238,13 @@ async function handleUpdateGoogleSlides(slides, args) {
|
|
|
10148
10238
|
presentationId: data.presentationId,
|
|
10149
10239
|
requestBody: { requests }
|
|
10150
10240
|
});
|
|
10151
|
-
return
|
|
10241
|
+
return structuredResponse(
|
|
10152
10242
|
`Updated Google Slides presentation with ${data.slides.length} slide(s)
|
|
10153
|
-
Link: https://docs.google.com/presentation/d/${data.presentationId}
|
|
10243
|
+
Link: https://docs.google.com/presentation/d/${data.presentationId}`,
|
|
10244
|
+
{
|
|
10245
|
+
slideCount: data.slides.length,
|
|
10246
|
+
webViewLink: `https://docs.google.com/presentation/d/${data.presentationId}`
|
|
10247
|
+
}
|
|
10154
10248
|
);
|
|
10155
10249
|
}
|
|
10156
10250
|
async function handleGetGoogleSlidesContent(drive2, slides, args) {
|
|
@@ -10322,7 +10416,10 @@ async function handleCreateGoogleSlidesTextBox(slides, args) {
|
|
|
10322
10416
|
presentationId: data.presentationId,
|
|
10323
10417
|
requestBody: { requests }
|
|
10324
10418
|
});
|
|
10325
|
-
return
|
|
10419
|
+
return structuredResponse(`Created text box with ID: ${elementId}`, {
|
|
10420
|
+
objectId: elementId,
|
|
10421
|
+
pageObjectId: data.pageObjectId
|
|
10422
|
+
});
|
|
10326
10423
|
}
|
|
10327
10424
|
async function handleCreateGoogleSlidesShape(slides, args) {
|
|
10328
10425
|
const validation = validateArgs(CreateGoogleSlidesShapeSchema, args);
|
|
@@ -10377,7 +10474,11 @@ async function handleCreateGoogleSlidesShape(slides, args) {
|
|
|
10377
10474
|
presentationId: data.presentationId,
|
|
10378
10475
|
requestBody: { requests }
|
|
10379
10476
|
});
|
|
10380
|
-
return
|
|
10477
|
+
return structuredResponse(`Created ${data.shapeType} shape with ID: ${elementId}`, {
|
|
10478
|
+
objectId: elementId,
|
|
10479
|
+
pageObjectId: data.pageObjectId,
|
|
10480
|
+
shapeType: data.shapeType
|
|
10481
|
+
});
|
|
10381
10482
|
}
|
|
10382
10483
|
async function handleSlidesSpeakerNotes(slides, args) {
|
|
10383
10484
|
const validation = validateArgs(SlidesSpeakerNotesSchema, args);
|
|
@@ -10395,24 +10496,39 @@ async function handleSlidesSpeakerNotes(slides, args) {
|
|
|
10395
10496
|
const slide = presentation.data.slides[data.slideIndex];
|
|
10396
10497
|
const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;
|
|
10397
10498
|
if (data.action === "get") {
|
|
10398
|
-
return getSpeakerNotes(slide, notesObjectId);
|
|
10499
|
+
return getSpeakerNotes(slide, notesObjectId, data.slideIndex);
|
|
10399
10500
|
} else {
|
|
10400
|
-
return updateSpeakerNotes(
|
|
10501
|
+
return updateSpeakerNotes(
|
|
10502
|
+
slides,
|
|
10503
|
+
data.presentationId,
|
|
10504
|
+
slide,
|
|
10505
|
+
notesObjectId,
|
|
10506
|
+
data.notes,
|
|
10507
|
+
data.slideIndex
|
|
10508
|
+
);
|
|
10401
10509
|
}
|
|
10402
10510
|
}
|
|
10403
|
-
function
|
|
10511
|
+
function emptyNotesResponse(slideIndex) {
|
|
10512
|
+
return structuredResponse("No speaker notes found for this slide", {
|
|
10513
|
+
action: "get",
|
|
10514
|
+
slideIndex,
|
|
10515
|
+
notes: "",
|
|
10516
|
+
updated: false
|
|
10517
|
+
});
|
|
10518
|
+
}
|
|
10519
|
+
function getSpeakerNotes(slide, notesObjectId, slideIndex) {
|
|
10404
10520
|
if (!notesObjectId) {
|
|
10405
|
-
return
|
|
10521
|
+
return emptyNotesResponse(slideIndex);
|
|
10406
10522
|
}
|
|
10407
10523
|
const notesPage = slide.slideProperties?.notesPage;
|
|
10408
10524
|
if (!notesPage || !notesPage.pageElements) {
|
|
10409
|
-
return
|
|
10525
|
+
return emptyNotesResponse(slideIndex);
|
|
10410
10526
|
}
|
|
10411
10527
|
const speakerNotesElement = notesPage.pageElements.find(
|
|
10412
10528
|
(element) => element.objectId === notesObjectId
|
|
10413
10529
|
);
|
|
10414
10530
|
if (!speakerNotesElement || !speakerNotesElement.shape?.text) {
|
|
10415
|
-
return
|
|
10531
|
+
return emptyNotesResponse(slideIndex);
|
|
10416
10532
|
}
|
|
10417
10533
|
let notesText = "";
|
|
10418
10534
|
const textElements = speakerNotesElement.shape.text.textElements || [];
|
|
@@ -10421,9 +10537,17 @@ function getSpeakerNotes(slide, notesObjectId) {
|
|
|
10421
10537
|
notesText += textElement.textRun.content;
|
|
10422
10538
|
}
|
|
10423
10539
|
});
|
|
10424
|
-
|
|
10540
|
+
if (!notesText.trim()) {
|
|
10541
|
+
return emptyNotesResponse(slideIndex);
|
|
10542
|
+
}
|
|
10543
|
+
return structuredResponse(notesText.trim(), {
|
|
10544
|
+
action: "get",
|
|
10545
|
+
slideIndex,
|
|
10546
|
+
notes: notesText.trim(),
|
|
10547
|
+
updated: false
|
|
10548
|
+
});
|
|
10425
10549
|
}
|
|
10426
|
-
async function updateSpeakerNotes(slidesApi, presentationId, slide, notesObjectId, notes) {
|
|
10550
|
+
async function updateSpeakerNotes(slidesApi, presentationId, slide, notesObjectId, notes, slideIndex) {
|
|
10427
10551
|
if (!notesObjectId) {
|
|
10428
10552
|
return errorResponse(
|
|
10429
10553
|
"This slide does not have a speaker notes object. Speaker notes may need to be initialized manually in Google Slides first."
|
|
@@ -10456,7 +10580,12 @@ async function updateSpeakerNotes(slidesApi, presentationId, slide, notesObjectI
|
|
|
10456
10580
|
presentationId,
|
|
10457
10581
|
requestBody: { requests }
|
|
10458
10582
|
});
|
|
10459
|
-
return
|
|
10583
|
+
return structuredResponse(`Successfully updated speaker notes for slide`, {
|
|
10584
|
+
action: "update",
|
|
10585
|
+
slideIndex,
|
|
10586
|
+
notes,
|
|
10587
|
+
updated: true
|
|
10588
|
+
});
|
|
10460
10589
|
}
|
|
10461
10590
|
async function handleFormatSlidesText(slides, args) {
|
|
10462
10591
|
const validation = validateArgs(FormatSlidesTextSchema, args);
|
|
@@ -10560,7 +10689,10 @@ async function handleFormatSlidesText(slides, args) {
|
|
|
10560
10689
|
presentationId: data.presentationId,
|
|
10561
10690
|
requestBody: { requests }
|
|
10562
10691
|
});
|
|
10563
|
-
return
|
|
10692
|
+
return structuredResponse(`Formatted text ${data.objectId}: ${appliedFormats.join(", ")}`, {
|
|
10693
|
+
objectId: data.objectId,
|
|
10694
|
+
formatsApplied: appliedFormats
|
|
10695
|
+
});
|
|
10564
10696
|
}
|
|
10565
10697
|
async function handleFormatSlidesShape(slides, args) {
|
|
10566
10698
|
const validation = validateArgs(FormatSlidesShapeSchema, args);
|
|
@@ -10618,7 +10750,10 @@ async function handleFormatSlidesShape(slides, args) {
|
|
|
10618
10750
|
]
|
|
10619
10751
|
}
|
|
10620
10752
|
});
|
|
10621
|
-
return
|
|
10753
|
+
return structuredResponse(`Formatted shape ${data.objectId}: ${appliedFormats.join(", ")}`, {
|
|
10754
|
+
objectId: data.objectId,
|
|
10755
|
+
formatsApplied: appliedFormats
|
|
10756
|
+
});
|
|
10622
10757
|
}
|
|
10623
10758
|
async function handleFormatSlideBackground(slides, args) {
|
|
10624
10759
|
const validation = validateArgs(FormatSlideBackgroundSchema, args);
|
|
@@ -10637,7 +10772,9 @@ async function handleFormatSlideBackground(slides, args) {
|
|
|
10637
10772
|
presentationId: data.presentationId,
|
|
10638
10773
|
requestBody: { requests }
|
|
10639
10774
|
});
|
|
10640
|
-
return
|
|
10775
|
+
return structuredResponse(`Set background color for ${data.pageObjectIds.length} slide(s)`, {
|
|
10776
|
+
slidesFormatted: data.pageObjectIds.length
|
|
10777
|
+
});
|
|
10641
10778
|
}
|
|
10642
10779
|
async function handleListSlidePages(slides, args) {
|
|
10643
10780
|
const validation = validateArgs(ListSlidePagesSchema, args);
|
|
@@ -11136,10 +11273,7 @@ async function handleListEvents(calendar, args) {
|
|
|
11136
11273
|
});
|
|
11137
11274
|
const events = response.data.items || [];
|
|
11138
11275
|
if (events.length === 0) {
|
|
11139
|
-
return structuredResponse("No events found.", {
|
|
11140
|
-
events: [],
|
|
11141
|
-
nextPageToken: null
|
|
11142
|
-
});
|
|
11276
|
+
return structuredResponse("No events found.", { events: [] });
|
|
11143
11277
|
}
|
|
11144
11278
|
const eventData = events.map((event) => ({
|
|
11145
11279
|
id: event.id,
|
|
@@ -11170,10 +11304,11 @@ ${toToon({ events: eventData })}`;
|
|
|
11170
11304
|
More events available. Use pageToken: ${response.data.nextPageToken}`;
|
|
11171
11305
|
}
|
|
11172
11306
|
log("Listed events", { calendarId, count: events.length });
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
nextPageToken
|
|
11176
|
-
}
|
|
11307
|
+
const responseData = { events: eventData };
|
|
11308
|
+
if (response.data.nextPageToken) {
|
|
11309
|
+
responseData.nextPageToken = response.data.nextPageToken;
|
|
11310
|
+
}
|
|
11311
|
+
return structuredResponse(textResponse, responseData);
|
|
11177
11312
|
}
|
|
11178
11313
|
async function handleGetEvent(calendar, args) {
|
|
11179
11314
|
const validation = validateArgs(GetEventSchema, args);
|
|
@@ -11424,7 +11559,10 @@ async function handleDeleteEvent(calendar, args) {
|
|
|
11424
11559
|
sendUpdates
|
|
11425
11560
|
});
|
|
11426
11561
|
log("Deleted event", { calendarId, eventId });
|
|
11427
|
-
return
|
|
11562
|
+
return structuredResponse(`Deleted event: ${eventSummary} (ID: ${eventId})`, {
|
|
11563
|
+
deleted: 1,
|
|
11564
|
+
eventId
|
|
11565
|
+
});
|
|
11428
11566
|
}
|
|
11429
11567
|
async function handleFindFreeTime(calendar, args) {
|
|
11430
11568
|
const validation = validateArgs(FindFreeTimeSchema, args);
|
|
@@ -11748,11 +11886,7 @@ async function handleSearchEmails(gmail, args) {
|
|
|
11748
11886
|
});
|
|
11749
11887
|
const messages = response.data.messages || [];
|
|
11750
11888
|
if (messages.length === 0) {
|
|
11751
|
-
return structuredResponse(`No emails found matching: ${query}`, {
|
|
11752
|
-
messages: [],
|
|
11753
|
-
nextPageToken: null,
|
|
11754
|
-
resultSizeEstimate: 0
|
|
11755
|
-
});
|
|
11889
|
+
return structuredResponse(`No emails found matching: ${query}`, { messages: [] });
|
|
11756
11890
|
}
|
|
11757
11891
|
const messageDetails = await Promise.all(
|
|
11758
11892
|
messages.slice(0, 50).map(async (msg) => {
|
|
@@ -11784,11 +11918,14 @@ ${toToon({ messages: messageDetails })}`;
|
|
|
11784
11918
|
More results available. Use pageToken: ${response.data.nextPageToken}`;
|
|
11785
11919
|
}
|
|
11786
11920
|
log("Searched emails", { query, count: messages.length });
|
|
11787
|
-
|
|
11788
|
-
|
|
11789
|
-
nextPageToken
|
|
11790
|
-
|
|
11791
|
-
|
|
11921
|
+
const responseData = { messages: messageDetails };
|
|
11922
|
+
if (response.data.nextPageToken) {
|
|
11923
|
+
responseData.nextPageToken = response.data.nextPageToken;
|
|
11924
|
+
}
|
|
11925
|
+
if (response.data.resultSizeEstimate !== void 0 && response.data.resultSizeEstimate !== null) {
|
|
11926
|
+
responseData.resultSizeEstimate = response.data.resultSizeEstimate;
|
|
11927
|
+
}
|
|
11928
|
+
return structuredResponse(textResponse, responseData);
|
|
11792
11929
|
}
|
|
11793
11930
|
async function handleDeleteEmail(gmail, args) {
|
|
11794
11931
|
const validation = validateArgs(DeleteEmailSchema, args);
|
|
@@ -11801,7 +11938,10 @@ async function handleDeleteEmail(gmail, args) {
|
|
|
11801
11938
|
id: messageIds[0]
|
|
11802
11939
|
});
|
|
11803
11940
|
log("Deleted email", { messageId: messageIds[0] });
|
|
11804
|
-
return
|
|
11941
|
+
return structuredResponse(`Email ${messageIds[0]} permanently deleted.`, {
|
|
11942
|
+
deleted: 1,
|
|
11943
|
+
messageIds: [messageIds[0]]
|
|
11944
|
+
});
|
|
11805
11945
|
}
|
|
11806
11946
|
try {
|
|
11807
11947
|
await gmail.users.messages.batchDelete({
|
|
@@ -11828,7 +11968,10 @@ async function handleDeleteEmail(gmail, args) {
|
|
|
11828
11968
|
}
|
|
11829
11969
|
}
|
|
11830
11970
|
log("Deleted emails (batch)", { count: messageIds.length });
|
|
11831
|
-
return
|
|
11971
|
+
return structuredResponse(`Successfully deleted ${messageIds.length} email(s).`, {
|
|
11972
|
+
deleted: messageIds.length,
|
|
11973
|
+
messageIds
|
|
11974
|
+
});
|
|
11832
11975
|
}
|
|
11833
11976
|
async function handleModifyEmail(gmail, args) {
|
|
11834
11977
|
const validation = validateArgs(ModifyEmailSchema, args);
|
|
@@ -11919,10 +12062,15 @@ ${categoryLines}`,
|
|
|
11919
12062
|
{ succeeded, failed: allFailures.length, total: ids.length, failuresByCategory }
|
|
11920
12063
|
);
|
|
11921
12064
|
}
|
|
11922
|
-
return
|
|
12065
|
+
return structuredResponse(
|
|
11923
12066
|
`Successfully modified labels for ${ids.length} thread(s).` + (addLabelIds ? `
|
|
11924
12067
|
Added labels: ${addLabelIds.join(", ")}` : "") + (removeLabelIds ? `
|
|
11925
|
-
Removed labels: ${removeLabelIds.join(", ")}` : "")
|
|
12068
|
+
Removed labels: ${removeLabelIds.join(", ")}` : ""),
|
|
12069
|
+
{
|
|
12070
|
+
id: ids[0],
|
|
12071
|
+
messageCount: ids.length,
|
|
12072
|
+
labelIds: addLabelIds || []
|
|
12073
|
+
}
|
|
11926
12074
|
);
|
|
11927
12075
|
}
|
|
11928
12076
|
async function handleDownloadAttachment(gmail, args) {
|
|
@@ -12021,7 +12169,10 @@ async function handleDeleteLabel(gmail, args) {
|
|
|
12021
12169
|
id: labelId
|
|
12022
12170
|
});
|
|
12023
12171
|
log("Deleted label", { labelId });
|
|
12024
|
-
return
|
|
12172
|
+
return structuredResponse(`Label ${labelId} deleted successfully.`, {
|
|
12173
|
+
deleted: 1,
|
|
12174
|
+
labelId
|
|
12175
|
+
});
|
|
12025
12176
|
}
|
|
12026
12177
|
async function handleListLabels(gmail, args) {
|
|
12027
12178
|
const validation = validateArgs(ListLabelsSchema, args);
|
|
@@ -12257,7 +12408,10 @@ async function handleDeleteFilter(gmail, args) {
|
|
|
12257
12408
|
id: filterId
|
|
12258
12409
|
});
|
|
12259
12410
|
log("Deleted filter", { filterId });
|
|
12260
|
-
return
|
|
12411
|
+
return structuredResponse(`Filter ${filterId} deleted successfully.`, {
|
|
12412
|
+
deleted: 1,
|
|
12413
|
+
filterId
|
|
12414
|
+
});
|
|
12261
12415
|
}
|
|
12262
12416
|
|
|
12263
12417
|
// src/handlers/contacts.ts
|
|
@@ -12322,7 +12476,7 @@ async function handleListContacts(people, args) {
|
|
|
12322
12476
|
);
|
|
12323
12477
|
const connections = response.data.connections || [];
|
|
12324
12478
|
if (connections.length === 0) {
|
|
12325
|
-
return structuredResponse("No contacts found.", { contacts: []
|
|
12479
|
+
return structuredResponse("No contacts found.", { contacts: [] });
|
|
12326
12480
|
}
|
|
12327
12481
|
const contacts = connections.map(extractContactData);
|
|
12328
12482
|
let textResponse = `Found ${connections.length} contact(s):
|
|
@@ -12334,11 +12488,16 @@ ${toToon({ contacts })}`;
|
|
|
12334
12488
|
More contacts available. Use pageToken: ${response.data.nextPageToken}`;
|
|
12335
12489
|
}
|
|
12336
12490
|
log("Listed contacts", { count: connections.length });
|
|
12337
|
-
|
|
12338
|
-
contacts
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12491
|
+
const responseData = {
|
|
12492
|
+
contacts
|
|
12493
|
+
};
|
|
12494
|
+
if (response.data.nextPageToken) {
|
|
12495
|
+
responseData.nextPageToken = response.data.nextPageToken;
|
|
12496
|
+
}
|
|
12497
|
+
if (response.data.totalPeople !== void 0 && response.data.totalPeople !== null) {
|
|
12498
|
+
responseData.totalPeople = response.data.totalPeople;
|
|
12499
|
+
}
|
|
12500
|
+
return structuredResponse(textResponse, responseData);
|
|
12342
12501
|
}
|
|
12343
12502
|
async function handleGetContact(people, args) {
|
|
12344
12503
|
const validation = validateArgs(GetContactSchema, args);
|