@bubblelab/bubble-core 0.1.68 → 0.1.69
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/bubble-bundle.d.ts +85 -85
- package/dist/bubbles/service-bubble/agi-inc.d.ts +112 -112
- package/dist/bubbles/service-bubble/ai-agent.d.ts +72 -72
- package/dist/bubbles/service-bubble/airtable.d.ts +156 -156
- package/dist/bubbles/service-bubble/apify/apify.d.ts +12 -12
- package/dist/bubbles/service-bubble/ashby/ashby.d.ts +140 -140
- package/dist/bubbles/service-bubble/ashby/ashby.js +1 -1
- package/dist/bubbles/service-bubble/ashby/ashby.js.map +1 -1
- package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +51 -51
- package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +32 -32
- package/dist/bubbles/service-bubble/eleven-labs.d.ts +60 -60
- package/dist/bubbles/service-bubble/firecrawl.d.ts +396 -396
- package/dist/bubbles/service-bubble/followupboss.d.ts +492 -492
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts +116 -116
- package/dist/bubbles/service-bubble/github.d.ts +152 -152
- package/dist/bubbles/service-bubble/gmail.d.ts +576 -576
- package/dist/bubbles/service-bubble/google-calendar.d.ts +232 -232
- package/dist/bubbles/service-bubble/google-drive.d.ts +422 -156
- package/dist/bubbles/service-bubble/google-drive.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/google-drive.js +282 -30
- package/dist/bubbles/service-bubble/google-drive.js.map +1 -1
- package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts +78 -78
- package/dist/bubbles/service-bubble/hello-world.d.ts +4 -4
- package/dist/bubbles/service-bubble/http.d.ts +20 -20
- package/dist/bubbles/service-bubble/insforge-db.d.ts +10 -10
- package/dist/bubbles/service-bubble/jira/jira.d.ts +54 -54
- package/dist/bubbles/service-bubble/notion/notion.d.ts +624 -624
- package/dist/bubbles/service-bubble/postgresql.d.ts +10 -10
- package/dist/bubbles/service-bubble/resend.d.ts +20 -20
- package/dist/bubbles/service-bubble/slack/slack.d.ts +304 -304
- package/dist/bubbles/service-bubble/storage.d.ts +40 -40
- package/dist/bubbles/service-bubble/stripe/stripe.d.ts +72 -72
- package/dist/bubbles/service-bubble/telegram.d.ts +938 -938
- package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +26 -26
- package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/chart-js-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/code-edit-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +24 -24
- package/dist/bubbles/tool-bubble/get-bubble-details-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/get-trigger-detail-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/google-maps-tool.d.ts +28 -28
- package/dist/bubbles/tool-bubble/instagram-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts.map +1 -1
- package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.d.ts +8 -8
- package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.d.ts.map +1 -1
- package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.js +31 -25
- package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.js.map +1 -1
- package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +116 -116
- package/dist/bubbles/tool-bubble/list-bubbles-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/people-search-tool.d.ts +38 -38
- package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +14 -14
- package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +12 -12
- package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +16 -16
- package/dist/bubbles/tool-bubble/tool-template.d.ts +4 -4
- package/dist/bubbles/tool-bubble/twitter-tool.d.ts +46 -46
- package/dist/bubbles/tool-bubble/web-crawl-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/web-extract-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/web-scrape-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/web-search-tool.d.ts +10 -10
- package/dist/bubbles/tool-bubble/youtube-tool.d.ts +8 -8
- package/dist/bubbles/workflow-bubble/database-analyzer.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/generate-document.workflow.d.ts +16 -16
- package/dist/bubbles/workflow-bubble/parse-document.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +90 -90
- package/dist/bubbles/workflow-bubble/pdf-ocr.workflow.d.ts +16 -16
- package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +10 -10
- package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +50 -50
- package/dist/bubbles/workflow-bubble/slack-notifier.workflow.d.ts +4 -4
- package/dist/bubbles.json +290 -74
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-drive.d.ts","sourceRoot":"","sources":["../../../src/bubbles/service-bubble/google-drive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AA2U3D,QAAA,MAAM,uBAAuB
|
|
1
|
+
{"version":3,"file":"google-drive.d.ts","sourceRoot":"","sources":["../../../src/bubbles/service-bubble/google-drive.ts"],"names":[],"mappings":"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"}
|
|
@@ -484,6 +484,15 @@ const GoogleDriveParamsSchema = z.discriminatedUnion('operation', [
|
|
|
484
484
|
.string()
|
|
485
485
|
.min(1, 'Document ID is required')
|
|
486
486
|
.describe('The ID of the Google Doc to retrieve'),
|
|
487
|
+
tab_id: z
|
|
488
|
+
.string()
|
|
489
|
+
.optional()
|
|
490
|
+
.describe('Specific tab ID to read. If omitted, reads first tab.'),
|
|
491
|
+
include_all_tabs: z
|
|
492
|
+
.boolean()
|
|
493
|
+
.optional()
|
|
494
|
+
.default(false)
|
|
495
|
+
.describe('Return info for all tabs including their plain text content'),
|
|
487
496
|
credentials: z
|
|
488
497
|
.record(z.nativeEnum(CredentialType), z.string())
|
|
489
498
|
.optional()
|
|
@@ -507,6 +516,61 @@ const GoogleDriveParamsSchema = z.discriminatedUnion('operation', [
|
|
|
507
516
|
.optional()
|
|
508
517
|
.default('replace')
|
|
509
518
|
.describe('Update mode: "replace" clears existing content first, "append" adds to the end'),
|
|
519
|
+
tab_id: z
|
|
520
|
+
.string()
|
|
521
|
+
.optional()
|
|
522
|
+
.describe('Tab to write to. If omitted, writes to first tab.'),
|
|
523
|
+
credentials: z
|
|
524
|
+
.record(z.nativeEnum(CredentialType), z.string())
|
|
525
|
+
.optional()
|
|
526
|
+
.describe('Object mapping credential types to values (injected at runtime)'),
|
|
527
|
+
}),
|
|
528
|
+
// Find and replace text operation (preserves formatting)
|
|
529
|
+
z.object({
|
|
530
|
+
operation: z
|
|
531
|
+
.literal('replace_text')
|
|
532
|
+
.describe('Find and replace text in a Google Doc while preserving formatting'),
|
|
533
|
+
document_id: z
|
|
534
|
+
.string()
|
|
535
|
+
.min(1, 'Document ID is required')
|
|
536
|
+
.describe('The ID of the Google Doc to perform replacements in'),
|
|
537
|
+
replacements: z
|
|
538
|
+
.array(z.object({
|
|
539
|
+
find: z.string().describe('Text to find'),
|
|
540
|
+
replace: z.string().describe('Text to replace with'),
|
|
541
|
+
match_case: z
|
|
542
|
+
.boolean()
|
|
543
|
+
.optional()
|
|
544
|
+
.default(true)
|
|
545
|
+
.describe('Whether to match case when finding text'),
|
|
546
|
+
}))
|
|
547
|
+
.describe('List of find/replace pairs'),
|
|
548
|
+
tab_id: z
|
|
549
|
+
.string()
|
|
550
|
+
.optional()
|
|
551
|
+
.describe('Tab to perform replacements in. If omitted, applies to all tabs.'),
|
|
552
|
+
credentials: z
|
|
553
|
+
.record(z.nativeEnum(CredentialType), z.string())
|
|
554
|
+
.optional()
|
|
555
|
+
.describe('Object mapping credential types to values (injected at runtime)'),
|
|
556
|
+
}),
|
|
557
|
+
// Copy document operation
|
|
558
|
+
z.object({
|
|
559
|
+
operation: z
|
|
560
|
+
.literal('copy_doc')
|
|
561
|
+
.describe('Create a copy of a Google Doc (useful for templates)'),
|
|
562
|
+
document_id: z
|
|
563
|
+
.string()
|
|
564
|
+
.min(1, 'Document ID is required')
|
|
565
|
+
.describe('Source document ID to copy'),
|
|
566
|
+
new_name: z
|
|
567
|
+
.string()
|
|
568
|
+
.min(1, 'New name is required')
|
|
569
|
+
.describe('Name for the new document'),
|
|
570
|
+
parent_folder_id: z
|
|
571
|
+
.string()
|
|
572
|
+
.optional()
|
|
573
|
+
.describe('Folder to place the copy in'),
|
|
510
574
|
credentials: z
|
|
511
575
|
.record(z.nativeEnum(CredentialType), z.string())
|
|
512
576
|
.optional()
|
|
@@ -635,6 +699,18 @@ const GoogleDriveResultSchema = z.discriminatedUnion('operation', [
|
|
|
635
699
|
.string()
|
|
636
700
|
.optional()
|
|
637
701
|
.describe('Extracted plain text content from the document'),
|
|
702
|
+
tabs: z
|
|
703
|
+
.array(z.object({
|
|
704
|
+
tabId: z.string().describe('Unique tab identifier'),
|
|
705
|
+
title: z.string().describe('Tab title'),
|
|
706
|
+
index: z.number().describe('Tab position index'),
|
|
707
|
+
plainText: z
|
|
708
|
+
.string()
|
|
709
|
+
.optional()
|
|
710
|
+
.describe('Plain text content of the tab'),
|
|
711
|
+
}))
|
|
712
|
+
.optional()
|
|
713
|
+
.describe('All tabs in the document'),
|
|
638
714
|
error: z.string().describe('Error message if operation failed'),
|
|
639
715
|
}),
|
|
640
716
|
z.object({
|
|
@@ -654,6 +730,31 @@ const GoogleDriveResultSchema = z.discriminatedUnion('operation', [
|
|
|
654
730
|
.describe('The new revision ID after the update'),
|
|
655
731
|
error: z.string().describe('Error message if operation failed'),
|
|
656
732
|
}),
|
|
733
|
+
z.object({
|
|
734
|
+
operation: z
|
|
735
|
+
.literal('replace_text')
|
|
736
|
+
.describe('Find and replace text in a Google Doc'),
|
|
737
|
+
success: z
|
|
738
|
+
.boolean()
|
|
739
|
+
.describe('Whether the replacements were made successfully'),
|
|
740
|
+
replacements_made: z
|
|
741
|
+
.number()
|
|
742
|
+
.optional()
|
|
743
|
+
.describe('Total number of replacements made'),
|
|
744
|
+
error: z.string().describe('Error message if operation failed'),
|
|
745
|
+
}),
|
|
746
|
+
z.object({
|
|
747
|
+
operation: z.literal('copy_doc').describe('Create a copy of a Google Doc'),
|
|
748
|
+
success: z
|
|
749
|
+
.boolean()
|
|
750
|
+
.describe('Whether the document was copied successfully'),
|
|
751
|
+
new_document_id: z.string().optional().describe('ID of the new document'),
|
|
752
|
+
new_document_url: z
|
|
753
|
+
.string()
|
|
754
|
+
.optional()
|
|
755
|
+
.describe('URL to view the new document'),
|
|
756
|
+
error: z.string().describe('Error message if operation failed'),
|
|
757
|
+
}),
|
|
657
758
|
]);
|
|
658
759
|
export class GoogleDriveBubble extends ServiceBubble {
|
|
659
760
|
static type = 'service';
|
|
@@ -785,6 +886,10 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
785
886
|
return await this.getDoc(this.params);
|
|
786
887
|
case 'update_doc':
|
|
787
888
|
return await this.updateDoc(this.params);
|
|
889
|
+
case 'replace_text':
|
|
890
|
+
return await this.replaceText(this.params);
|
|
891
|
+
case 'copy_doc':
|
|
892
|
+
return await this.copyDoc(this.params);
|
|
788
893
|
default:
|
|
789
894
|
throw new Error(`Unsupported operation: ${operation}`);
|
|
790
895
|
}
|
|
@@ -1146,44 +1251,88 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
1146
1251
|
};
|
|
1147
1252
|
}
|
|
1148
1253
|
async getDoc(params) {
|
|
1149
|
-
const { document_id } = params;
|
|
1150
|
-
|
|
1254
|
+
const { document_id, tab_id, include_all_tabs } = params;
|
|
1255
|
+
// Always fetch with tabs to get full structure
|
|
1256
|
+
const url = `https://docs.googleapis.com/v1/documents/${document_id}?includeTabsContent=true`;
|
|
1151
1257
|
// Make the request to Google Docs API
|
|
1152
1258
|
const response = await this.makeGoogleApiRequest(url, 'GET');
|
|
1153
|
-
//
|
|
1154
|
-
const
|
|
1259
|
+
// Build tabs info if document has tabs
|
|
1260
|
+
const responseTabs = response.tabs;
|
|
1261
|
+
const tabs = responseTabs?.map((tab) => ({
|
|
1262
|
+
tabId: tab.tabProperties?.tabId || '',
|
|
1263
|
+
title: tab.tabProperties?.title || 'Untitled',
|
|
1264
|
+
index: tab.tabProperties?.index || 0,
|
|
1265
|
+
plainText: include_all_tabs
|
|
1266
|
+
? this.extractPlainTextFromTab(tab)
|
|
1267
|
+
: undefined,
|
|
1268
|
+
}));
|
|
1269
|
+
// Get content from specific tab or first tab
|
|
1270
|
+
const targetTab = tab_id
|
|
1271
|
+
? responseTabs?.find((t) => t.tabProperties?.tabId === tab_id)
|
|
1272
|
+
: responseTabs?.[0];
|
|
1273
|
+
// Extract plain text from the target tab, or fall back to document body for non-tabbed docs
|
|
1274
|
+
const plainText = targetTab
|
|
1275
|
+
? this.extractPlainTextFromTab(targetTab)
|
|
1276
|
+
: this.extractPlainTextFromDoc(response);
|
|
1155
1277
|
return {
|
|
1156
1278
|
operation: 'get_doc',
|
|
1157
1279
|
success: true,
|
|
1158
1280
|
document: response,
|
|
1159
1281
|
plainText,
|
|
1282
|
+
tabs,
|
|
1160
1283
|
error: '',
|
|
1161
1284
|
};
|
|
1162
1285
|
}
|
|
1163
1286
|
async updateDoc(params) {
|
|
1164
|
-
const { document_id, content, mode } = params;
|
|
1287
|
+
const { document_id, content, mode, tab_id } = params;
|
|
1165
1288
|
const url = `https://docs.googleapis.com/v1/documents/${document_id}:batchUpdate`;
|
|
1166
1289
|
// Build the requests array based on mode
|
|
1167
1290
|
const requests = [];
|
|
1168
1291
|
// Auto-detect markdown and parse if needed
|
|
1169
1292
|
const useMarkdown = isMarkdown(content);
|
|
1293
|
+
// Helper to build location object with optional tabId
|
|
1294
|
+
const buildLocation = (index) => {
|
|
1295
|
+
const location = { index };
|
|
1296
|
+
if (tab_id) {
|
|
1297
|
+
location.tabId = tab_id;
|
|
1298
|
+
}
|
|
1299
|
+
return location;
|
|
1300
|
+
};
|
|
1301
|
+
// Helper to build range object with optional tabId
|
|
1302
|
+
const buildRange = (startIndex, endIndex) => {
|
|
1303
|
+
const range = {
|
|
1304
|
+
startIndex,
|
|
1305
|
+
endIndex,
|
|
1306
|
+
};
|
|
1307
|
+
if (tab_id) {
|
|
1308
|
+
range.tabId = tab_id;
|
|
1309
|
+
}
|
|
1310
|
+
return range;
|
|
1311
|
+
};
|
|
1170
1312
|
if (mode === 'replace') {
|
|
1171
1313
|
// For replace mode, first get the document to find content length
|
|
1172
|
-
const docUrl = `https://docs.googleapis.com/v1/documents/${document_id}`;
|
|
1314
|
+
const docUrl = `https://docs.googleapis.com/v1/documents/${document_id}?includeTabsContent=true`;
|
|
1173
1315
|
const document = await this.makeGoogleApiRequest(docUrl, 'GET');
|
|
1174
|
-
// Get the end index
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1316
|
+
// Get the end index from the target tab or document body
|
|
1317
|
+
let endIndex = 1;
|
|
1318
|
+
if (tab_id && document.tabs) {
|
|
1319
|
+
const tabs = document.tabs;
|
|
1320
|
+
const targetTab = tabs.find((t) => t.tabProperties?.tabId === tab_id);
|
|
1321
|
+
const tabContent = targetTab?.documentTab?.body?.content || [];
|
|
1322
|
+
const lastElement = tabContent[tabContent.length - 1];
|
|
1323
|
+
endIndex = lastElement?.endIndex || 1;
|
|
1324
|
+
}
|
|
1325
|
+
else {
|
|
1326
|
+
const body = document.body;
|
|
1327
|
+
const contentElements = body?.content || [];
|
|
1328
|
+
const lastElement = contentElements[contentElements.length - 1];
|
|
1329
|
+
endIndex = lastElement?.endIndex || 1;
|
|
1330
|
+
}
|
|
1179
1331
|
// Only delete if there's content to delete (endIndex > 1)
|
|
1180
1332
|
if (endIndex > 1) {
|
|
1181
1333
|
requests.push({
|
|
1182
1334
|
deleteContentRange: {
|
|
1183
|
-
range:
|
|
1184
|
-
startIndex: 1,
|
|
1185
|
-
endIndex: endIndex - 1,
|
|
1186
|
-
},
|
|
1335
|
+
range: buildRange(1, endIndex - 1),
|
|
1187
1336
|
},
|
|
1188
1337
|
});
|
|
1189
1338
|
}
|
|
@@ -1193,18 +1342,24 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
1193
1342
|
// Insert plain text first
|
|
1194
1343
|
requests.push({
|
|
1195
1344
|
insertText: {
|
|
1196
|
-
location:
|
|
1345
|
+
location: buildLocation(1),
|
|
1197
1346
|
text: parsed.plainText,
|
|
1198
1347
|
},
|
|
1199
1348
|
});
|
|
1200
|
-
// Add formatting requests
|
|
1201
|
-
|
|
1349
|
+
// Add formatting requests with tabId if provided
|
|
1350
|
+
for (const req of parsed.requests) {
|
|
1351
|
+
if (tab_id) {
|
|
1352
|
+
// Add tabId to range objects in formatting requests
|
|
1353
|
+
this.addTabIdToRequest(req, tab_id);
|
|
1354
|
+
}
|
|
1355
|
+
requests.push(req);
|
|
1356
|
+
}
|
|
1202
1357
|
}
|
|
1203
1358
|
else {
|
|
1204
1359
|
// Plain text - just insert
|
|
1205
1360
|
requests.push({
|
|
1206
1361
|
insertText: {
|
|
1207
|
-
location:
|
|
1362
|
+
location: buildLocation(1),
|
|
1208
1363
|
text: content,
|
|
1209
1364
|
},
|
|
1210
1365
|
});
|
|
@@ -1212,13 +1367,23 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
1212
1367
|
}
|
|
1213
1368
|
else {
|
|
1214
1369
|
// For append mode, get document to find the end position
|
|
1215
|
-
const docUrl = `https://docs.googleapis.com/v1/documents/${document_id}`;
|
|
1370
|
+
const docUrl = `https://docs.googleapis.com/v1/documents/${document_id}?includeTabsContent=true`;
|
|
1216
1371
|
const document = await this.makeGoogleApiRequest(docUrl, 'GET');
|
|
1217
|
-
// Get the end index
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1372
|
+
// Get the end index from the target tab or document body
|
|
1373
|
+
let endIndex = 1;
|
|
1374
|
+
if (tab_id && document.tabs) {
|
|
1375
|
+
const tabs = document.tabs;
|
|
1376
|
+
const targetTab = tabs.find((t) => t.tabProperties?.tabId === tab_id);
|
|
1377
|
+
const tabContent = targetTab?.documentTab?.body?.content || [];
|
|
1378
|
+
const lastElement = tabContent[tabContent.length - 1];
|
|
1379
|
+
endIndex = lastElement?.endIndex || 1;
|
|
1380
|
+
}
|
|
1381
|
+
else {
|
|
1382
|
+
const body = document.body;
|
|
1383
|
+
const contentElements = body?.content || [];
|
|
1384
|
+
const lastElement = contentElements[contentElements.length - 1];
|
|
1385
|
+
endIndex = lastElement?.endIndex || 1;
|
|
1386
|
+
}
|
|
1222
1387
|
const insertIndex = endIndex - 1;
|
|
1223
1388
|
if (useMarkdown) {
|
|
1224
1389
|
// Parse markdown and get plain text + formatting requests
|
|
@@ -1226,18 +1391,23 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
1226
1391
|
// Insert plain text first
|
|
1227
1392
|
requests.push({
|
|
1228
1393
|
insertText: {
|
|
1229
|
-
location:
|
|
1394
|
+
location: buildLocation(insertIndex),
|
|
1230
1395
|
text: parsed.plainText,
|
|
1231
1396
|
},
|
|
1232
1397
|
});
|
|
1233
|
-
// Add formatting requests
|
|
1234
|
-
|
|
1398
|
+
// Add formatting requests with tabId if provided
|
|
1399
|
+
for (const req of parsed.requests) {
|
|
1400
|
+
if (tab_id) {
|
|
1401
|
+
this.addTabIdToRequest(req, tab_id);
|
|
1402
|
+
}
|
|
1403
|
+
requests.push(req);
|
|
1404
|
+
}
|
|
1235
1405
|
}
|
|
1236
1406
|
else {
|
|
1237
1407
|
// Plain text - just insert
|
|
1238
1408
|
requests.push({
|
|
1239
1409
|
insertText: {
|
|
1240
|
-
location:
|
|
1410
|
+
location: buildLocation(insertIndex),
|
|
1241
1411
|
text: content,
|
|
1242
1412
|
},
|
|
1243
1413
|
});
|
|
@@ -1255,6 +1425,72 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
1255
1425
|
error: '',
|
|
1256
1426
|
};
|
|
1257
1427
|
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Adds tabId to range objects in formatting requests
|
|
1430
|
+
*/
|
|
1431
|
+
addTabIdToRequest(req, tabId) {
|
|
1432
|
+
for (const key of Object.keys(req)) {
|
|
1433
|
+
const value = req[key];
|
|
1434
|
+
if (value && typeof value === 'object') {
|
|
1435
|
+
if ('range' in value && typeof value.range === 'object') {
|
|
1436
|
+
value.range.tabId = tabId;
|
|
1437
|
+
}
|
|
1438
|
+
if ('location' in value && typeof value.location === 'object') {
|
|
1439
|
+
value.location.tabId = tabId;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
async replaceText(params) {
|
|
1445
|
+
const { document_id, replacements, tab_id } = params;
|
|
1446
|
+
const url = `https://docs.googleapis.com/v1/documents/${document_id}:batchUpdate`;
|
|
1447
|
+
// Build requests for each replacement
|
|
1448
|
+
const requests = replacements.map((r) => {
|
|
1449
|
+
const containsText = {
|
|
1450
|
+
text: r.find,
|
|
1451
|
+
matchCase: r.match_case ?? true,
|
|
1452
|
+
};
|
|
1453
|
+
// Add tabId if provided to target specific tab
|
|
1454
|
+
if (tab_id) {
|
|
1455
|
+
containsText.tabId = tab_id;
|
|
1456
|
+
}
|
|
1457
|
+
return {
|
|
1458
|
+
replaceAllText: {
|
|
1459
|
+
containsText,
|
|
1460
|
+
replaceText: r.replace,
|
|
1461
|
+
},
|
|
1462
|
+
};
|
|
1463
|
+
});
|
|
1464
|
+
// Make the batchUpdate request
|
|
1465
|
+
const response = await this.makeGoogleApiRequest(url, 'POST', {
|
|
1466
|
+
requests,
|
|
1467
|
+
});
|
|
1468
|
+
// Count total replacements made
|
|
1469
|
+
const replies = response.replies;
|
|
1470
|
+
const totalReplacements = replies?.reduce((sum, r) => sum + (r.replaceAllText?.occurrencesChanged || 0), 0) || 0;
|
|
1471
|
+
return {
|
|
1472
|
+
operation: 'replace_text',
|
|
1473
|
+
success: true,
|
|
1474
|
+
replacements_made: totalReplacements,
|
|
1475
|
+
error: '',
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
async copyDoc(params) {
|
|
1479
|
+
const { document_id, new_name, parent_folder_id } = params;
|
|
1480
|
+
// Use Drive API copy endpoint
|
|
1481
|
+
const body = { name: new_name };
|
|
1482
|
+
if (parent_folder_id) {
|
|
1483
|
+
body.parents = [parent_folder_id];
|
|
1484
|
+
}
|
|
1485
|
+
const response = await this.makeGoogleApiRequest(`/files/${document_id}/copy?supportsAllDrives=true&fields=id,webViewLink`, 'POST', body);
|
|
1486
|
+
return {
|
|
1487
|
+
operation: 'copy_doc',
|
|
1488
|
+
success: true,
|
|
1489
|
+
new_document_id: response.id,
|
|
1490
|
+
new_document_url: response.webViewLink,
|
|
1491
|
+
error: '',
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1258
1494
|
/**
|
|
1259
1495
|
* Extracts plain text content from a Google Docs document body
|
|
1260
1496
|
*/
|
|
@@ -1263,8 +1499,24 @@ export class GoogleDriveBubble extends ServiceBubble {
|
|
|
1263
1499
|
if (!body?.content) {
|
|
1264
1500
|
return '';
|
|
1265
1501
|
}
|
|
1502
|
+
return this.extractPlainTextFromContent(body.content);
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Extracts plain text content from a Google Docs tab
|
|
1506
|
+
*/
|
|
1507
|
+
extractPlainTextFromTab(tab) {
|
|
1508
|
+
const body = tab?.documentTab?.body;
|
|
1509
|
+
if (!body?.content) {
|
|
1510
|
+
return '';
|
|
1511
|
+
}
|
|
1512
|
+
return this.extractPlainTextFromContent(body.content);
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Extracts plain text from a content array
|
|
1516
|
+
*/
|
|
1517
|
+
extractPlainTextFromContent(content) {
|
|
1266
1518
|
const textParts = [];
|
|
1267
|
-
for (const element of
|
|
1519
|
+
for (const element of content) {
|
|
1268
1520
|
const paragraph = element.paragraph;
|
|
1269
1521
|
if (paragraph?.elements) {
|
|
1270
1522
|
for (const elem of paragraph.elements) {
|