@bubblelab/bubble-core 0.1.40 → 0.1.41

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.
Files changed (86) hide show
  1. package/dist/bubble-bundle.d.ts +146 -125
  2. package/dist/bubble-factory.d.ts.map +1 -1
  3. package/dist/bubble-factory.js +4 -0
  4. package/dist/bubble-factory.js.map +1 -1
  5. package/dist/bubbles/service-bubble/agi-inc.d.ts +132 -132
  6. package/dist/bubbles/service-bubble/ai-agent.d.ts +98 -98
  7. package/dist/bubbles/service-bubble/airtable.d.ts +122 -122
  8. package/dist/bubbles/service-bubble/apify/apify.d.ts +16 -16
  9. package/dist/bubbles/service-bubble/ashby/ashby.d.ts +148 -148
  10. package/dist/bubbles/service-bubble/ashby/ashby.schema.d.ts +102 -102
  11. package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +63 -63
  12. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts +23 -23
  13. package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +94 -94
  14. package/dist/bubbles/service-bubble/crustdata/crustdata.schema.d.ts +126 -126
  15. package/dist/bubbles/service-bubble/eleven-labs.d.ts +48 -48
  16. package/dist/bubbles/service-bubble/firecrawl.d.ts +480 -480
  17. package/dist/bubbles/service-bubble/followupboss.d.ts +256 -256
  18. package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts +44 -44
  19. package/dist/bubbles/service-bubble/fullenrich/fullenrich.schema.d.ts +128 -128
  20. package/dist/bubbles/service-bubble/github.d.ts +124 -124
  21. package/dist/bubbles/service-bubble/gmail.d.ts +240 -240
  22. package/dist/bubbles/service-bubble/google-calendar.d.ts +136 -136
  23. package/dist/bubbles/service-bubble/google-drive.d.ts +136 -136
  24. package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts +62 -62
  25. package/dist/bubbles/service-bubble/google-sheets/google-sheets.schema.d.ts +18 -18
  26. package/dist/bubbles/service-bubble/hello-world.d.ts +4 -4
  27. package/dist/bubbles/service-bubble/http.d.ts +4 -4
  28. package/dist/bubbles/service-bubble/insforge-db.d.ts +12 -12
  29. package/dist/bubbles/service-bubble/jira/jira.d.ts +54 -54
  30. package/dist/bubbles/service-bubble/jira/jira.schema.d.ts +17 -17
  31. package/dist/bubbles/service-bubble/notion/notion.d.ts +220 -220
  32. package/dist/bubbles/service-bubble/postgresql.d.ts +12 -12
  33. package/dist/bubbles/service-bubble/resend.d.ts +24 -24
  34. package/dist/bubbles/service-bubble/slack/slack.d.ts +322 -322
  35. package/dist/bubbles/service-bubble/storage.d.ts +40 -40
  36. package/dist/bubbles/service-bubble/telegram.d.ts +116 -116
  37. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +31 -31
  38. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.schema.d.ts +7 -7
  39. package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
  40. package/dist/bubbles/tool-bubble/chart-js-tool.d.ts +4 -4
  41. package/dist/bubbles/tool-bubble/code-edit-tool.d.ts +4 -4
  42. package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +24 -24
  43. package/dist/bubbles/tool-bubble/get-bubble-details-tool.d.ts +4 -4
  44. package/dist/bubbles/tool-bubble/get-trigger-detail-tool.d.ts +4 -4
  45. package/dist/bubbles/tool-bubble/google-maps-tool.d.ts +20 -20
  46. package/dist/bubbles/tool-bubble/instagram-tool.d.ts +8 -8
  47. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.d.ts +3 -0
  48. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.d.ts.map +1 -0
  49. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.js +3 -0
  50. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.js.map +1 -0
  51. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts +143 -0
  52. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts.map +1 -0
  53. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.js +589 -0
  54. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.js.map +1 -0
  55. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.d.ts +93 -0
  56. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.d.ts.map +1 -0
  57. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.js +44 -0
  58. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.js.map +1 -0
  59. package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +300 -300
  60. package/dist/bubbles/tool-bubble/list-bubbles-tool.d.ts +4 -4
  61. package/dist/bubbles/tool-bubble/people-search-tool.d.ts +28 -28
  62. package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +14 -14
  63. package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +14 -14
  64. package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +8 -8
  65. package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +62 -62
  66. package/dist/bubbles/tool-bubble/tool-template.d.ts +4 -4
  67. package/dist/bubbles/tool-bubble/twitter-tool.d.ts +88 -88
  68. package/dist/bubbles/tool-bubble/web-crawl-tool.d.ts +4 -4
  69. package/dist/bubbles/tool-bubble/web-extract-tool.d.ts +4 -4
  70. package/dist/bubbles/tool-bubble/web-scrape-tool.d.ts +4 -4
  71. package/dist/bubbles/tool-bubble/web-search-tool.d.ts +6 -6
  72. package/dist/bubbles/tool-bubble/youtube-tool.d.ts +8 -8
  73. package/dist/bubbles/workflow-bubble/database-analyzer.workflow.d.ts +4 -4
  74. package/dist/bubbles/workflow-bubble/generate-document.workflow.d.ts +14 -14
  75. package/dist/bubbles/workflow-bubble/parse-document.workflow.d.ts +14 -14
  76. package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +82 -82
  77. package/dist/bubbles/workflow-bubble/pdf-ocr.workflow.d.ts +28 -28
  78. package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +12 -12
  79. package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +24 -24
  80. package/dist/bubbles/workflow-bubble/slack-notifier.workflow.d.ts +14 -14
  81. package/dist/bubbles.json +125 -40
  82. package/dist/index.d.ts +1 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +1 -0
  85. package/dist/index.js.map +1 -1
  86. package/package.json +2 -2
@@ -0,0 +1,589 @@
1
+ import { ToolBubble } from '../../../types/tool-bubble-class.js';
2
+ import { CredentialType } from '@bubblelab/shared-schemas';
3
+ import { BrowserBaseBubble, BrowserSessionDataSchema, } from '../../service-bubble/browserbase/index.js';
4
+ import { LinkedInConnectionToolParamsSchema, LinkedInConnectionToolResultSchema, } from './linkedin-connection-tool.schema.js';
5
+ // Debug logging helper - only logs when DEBUG_BROWSER_BASE env var is set
6
+ const DEBUG = process.env.DEBUG_BROWSER_BASE;
7
+ function debugLog(...args) {
8
+ if (DEBUG) {
9
+ console.log(...args);
10
+ }
11
+ }
12
+ /**
13
+ * LinkedIn Connection Tool
14
+ *
15
+ * A tool bubble for automating LinkedIn connection requests.
16
+ * Handles both profile types:
17
+ * - Profiles with direct "Connect" button
18
+ * - Profiles where "Connect" is under the "More" dropdown
19
+ *
20
+ * Features:
21
+ * - Send connection requests to LinkedIn profiles
22
+ * - Add optional personalized notes
23
+ * - Handle various profile layouts
24
+ *
25
+ * Required Credentials:
26
+ * - LINKEDIN_CRED: Browser session credential with LinkedIn cookies
27
+ *
28
+ * Security:
29
+ * - Uses BrowserBase cloud browsers (isolated)
30
+ * - Credentials are encrypted at rest
31
+ * - Session data is not persisted beyond operation
32
+ */
33
+ export class LinkedInConnectionTool extends ToolBubble {
34
+ static bubbleName = 'linkedin-connection-tool';
35
+ static schema = LinkedInConnectionToolParamsSchema;
36
+ static resultSchema = LinkedInConnectionToolResultSchema;
37
+ static shortDescription = 'LinkedIn connection automation - send connection requests with optional notes';
38
+ static longDescription = `
39
+ LinkedIn Connection Tool for automating connection requests.
40
+
41
+ Features:
42
+ - Send connection requests to LinkedIn profiles
43
+ - Add optional personalized notes (up to 300 characters)
44
+ - Handles profiles with direct Connect button
45
+ - Handles profiles where Connect is under "More" dropdown
46
+
47
+ Required Credentials:
48
+ - LINKEDIN_CRED: Browser session credential (authenticate via browser session)
49
+
50
+ Note: The tool operates using authenticated browser sessions to ensure security.
51
+ `;
52
+ static alias = 'linkedin';
53
+ static type = 'tool';
54
+ sessionId = null;
55
+ contextId = null;
56
+ cookies = null;
57
+ constructor(params = { operation: 'send_connection', profile_url: '' }, context) {
58
+ super(params, context);
59
+ }
60
+ /**
61
+ * Choose the credential to use for LinkedIn operations
62
+ */
63
+ chooseCredential() {
64
+ const { credentials } = this.params;
65
+ if (!credentials || typeof credentials !== 'object') {
66
+ return undefined;
67
+ }
68
+ return credentials[CredentialType.LINKEDIN_CRED];
69
+ }
70
+ /**
71
+ * Parse the LINKEDIN_CRED to extract contextId and cookies
72
+ */
73
+ parseBrowserSessionData() {
74
+ const credential = this.chooseCredential();
75
+ if (!credential) {
76
+ return null;
77
+ }
78
+ try {
79
+ const jsonString = Buffer.from(credential, 'base64').toString('utf-8');
80
+ const parsed = JSON.parse(jsonString);
81
+ const validated = BrowserSessionDataSchema.safeParse(parsed);
82
+ if (validated.success) {
83
+ return validated.data;
84
+ }
85
+ console.error('[LinkedInConnectionTool] Invalid credential format:', validated.error);
86
+ return null;
87
+ }
88
+ catch (error) {
89
+ console.error('[LinkedInConnectionTool] Failed to parse credential:', error);
90
+ return null;
91
+ }
92
+ }
93
+ /**
94
+ * Start a browser session using BrowserBase
95
+ */
96
+ async startBrowserSession() {
97
+ debugLog('[LinkedInConnectionTool] Starting browser session');
98
+ if (this.sessionId) {
99
+ return this.sessionId;
100
+ }
101
+ const sessionData = this.parseBrowserSessionData();
102
+ if (sessionData) {
103
+ this.contextId = sessionData.contextId;
104
+ this.cookies = sessionData.cookies;
105
+ debugLog(`[LinkedInConnectionTool] Loaded session data: contextId=${this.contextId}, cookies=${this.cookies.length}`);
106
+ }
107
+ else {
108
+ debugLog('[LinkedInConnectionTool] No LINKEDIN_CRED found, creating new context');
109
+ }
110
+ const startsession_browserbase = new BrowserBaseBubble({
111
+ operation: 'start_session',
112
+ context_id: this.contextId || undefined,
113
+ cookies: this.cookies || undefined,
114
+ credentials: this.params.credentials,
115
+ }, this.context, 'startsession_browserbase');
116
+ const result = await startsession_browserbase.action();
117
+ if (!result.data.success || !result.data.session_id) {
118
+ throw new Error(result.data.error || 'Failed to start browser session');
119
+ }
120
+ this.sessionId = result.data.session_id;
121
+ if (result.data.context_id) {
122
+ this.contextId = result.data.context_id;
123
+ }
124
+ debugLog(`[LinkedInConnectionTool] Browser session started: ${this.sessionId}, context: ${this.contextId}`);
125
+ if (this.context?.logger && result.data.debug_url) {
126
+ this.context.logger.logBrowserSessionStart(this.sessionId, result.data.debug_url, this.context.variableId);
127
+ }
128
+ return this.sessionId;
129
+ }
130
+ /**
131
+ * End the browser session
132
+ */
133
+ async endBrowserSession() {
134
+ if (!this.sessionId)
135
+ return;
136
+ const sessionIdToEnd = this.sessionId;
137
+ try {
138
+ const endsession_browserbase = new BrowserBaseBubble({
139
+ operation: 'end_session',
140
+ session_id: sessionIdToEnd,
141
+ }, this.context, 'endsession_browserbase');
142
+ await endsession_browserbase.action();
143
+ debugLog(`[LinkedInConnectionTool] Browser session ended: ${sessionIdToEnd}`);
144
+ }
145
+ catch (error) {
146
+ console.error('[LinkedInConnectionTool] Error ending session:', error);
147
+ }
148
+ finally {
149
+ if (this.context?.logger) {
150
+ this.context.logger.logBrowserSessionEnd(sessionIdToEnd, this.context.variableId);
151
+ }
152
+ this.sessionId = null;
153
+ }
154
+ }
155
+ /**
156
+ * Navigate to a URL
157
+ */
158
+ async navigateTo(url) {
159
+ if (!this.sessionId) {
160
+ throw new Error('No active browser session');
161
+ }
162
+ const navigate_browserbase = new BrowserBaseBubble({
163
+ operation: 'navigate',
164
+ session_id: this.sessionId,
165
+ url,
166
+ wait_until: 'domcontentloaded',
167
+ timeout: 30000,
168
+ }, this.context, 'navigate_browserbase');
169
+ const result = await navigate_browserbase.action();
170
+ if (!result.data.success) {
171
+ throw new Error(result.data.error || 'Navigation failed');
172
+ }
173
+ }
174
+ /**
175
+ * Evaluate JavaScript in page
176
+ */
177
+ async evaluate(script) {
178
+ if (!this.sessionId) {
179
+ throw new Error('No active browser session');
180
+ }
181
+ const evaluate_browserbase = new BrowserBaseBubble({
182
+ operation: 'evaluate',
183
+ session_id: this.sessionId,
184
+ script,
185
+ }, this.context, 'evaluate_browserbase');
186
+ const result = await evaluate_browserbase.action();
187
+ if (!result.data.success) {
188
+ throw new Error(result.data.error || 'Script evaluation failed');
189
+ }
190
+ return result.data.result;
191
+ }
192
+ /**
193
+ * Type text into an input field
194
+ */
195
+ async typeText(selector, text) {
196
+ if (!this.sessionId) {
197
+ throw new Error('No active browser session');
198
+ }
199
+ const type_browserbase = new BrowserBaseBubble({
200
+ operation: 'type',
201
+ session_id: this.sessionId,
202
+ selector,
203
+ text,
204
+ delay: 50,
205
+ }, this.context, 'type_browserbase');
206
+ const result = await type_browserbase.action();
207
+ return result.data.success;
208
+ }
209
+ /**
210
+ * Get current page URL
211
+ */
212
+ async getCurrentUrl() {
213
+ const result = (await this.evaluate(`window.location.href`));
214
+ return result;
215
+ }
216
+ /**
217
+ * Save current DOM state to file for debugging
218
+ * Only saves when DEBUG env var is set
219
+ */
220
+ async saveDebugState(label) {
221
+ if (!DEBUG) {
222
+ return null;
223
+ }
224
+ try {
225
+ const fs = await import('fs/promises');
226
+ const htmlContent = (await this.evaluate(`document.documentElement.outerHTML`));
227
+ const currentUrl = await this.getCurrentUrl();
228
+ const timestamp = Date.now();
229
+ const debugPath = `/tmp/linkedin-debug-${label}-${timestamp}.html`;
230
+ // Add URL as comment at top of file
231
+ const contentWithUrl = `<!-- URL: ${currentUrl} -->\n${htmlContent}`;
232
+ await fs.writeFile(debugPath, contentWithUrl);
233
+ debugLog(`[LinkedInConnectionTool] Saved debug DOM to: ${debugPath}`);
234
+ return debugPath;
235
+ }
236
+ catch (e) {
237
+ console.error('[LinkedInConnectionTool] Failed to save debug state:', e);
238
+ return null;
239
+ }
240
+ }
241
+ async performAction() {
242
+ try {
243
+ await this.startBrowserSession();
244
+ return await this.sendConnection();
245
+ }
246
+ catch (error) {
247
+ console.error('[LinkedInConnectionTool] Error:', error);
248
+ return {
249
+ operation: 'send_connection',
250
+ success: false,
251
+ error: error instanceof Error ? error.message : 'Unknown error occurred',
252
+ };
253
+ }
254
+ finally {
255
+ await this.endBrowserSession();
256
+ }
257
+ }
258
+ /**
259
+ * Send a connection request to a LinkedIn profile
260
+ */
261
+ async sendConnection() {
262
+ const { profile_url, message } = this.params;
263
+ debugLog(`[LinkedInConnectionTool] Sending connection to: ${profile_url}`);
264
+ // Navigate to profile page
265
+ await this.navigateTo(profile_url);
266
+ // Wait for page to load
267
+ await new Promise((resolve) => setTimeout(resolve, 5000));
268
+ // Save debug state after page load
269
+ await this.saveDebugState('01-after-page-load');
270
+ // Extract profile info
271
+ const profileInfo = await this.extractProfileInfo();
272
+ debugLog('[LinkedInConnectionTool] Profile info:', profileInfo);
273
+ // Try to find and click the Connect button
274
+ // Strategy 1: Direct Connect button (visible on profile)
275
+ let connectClicked = false;
276
+ // Save debug state before attempting to click Connect
277
+ await this.saveDebugState('02-before-connect-click');
278
+ // Look for direct Connect button with various selectors
279
+ const directConnectResult = (await this.evaluate(`
280
+ (() => {
281
+ // Look for primary Connect button
282
+ const connectButtons = document.querySelectorAll('button');
283
+ for (const btn of connectButtons) {
284
+ const ariaLabel = btn.getAttribute('aria-label') || '';
285
+ const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
286
+
287
+ // Check for "Invite X to connect" aria-label or "Connect" text
288
+ if (ariaLabel.toLowerCase().includes('connect') || text === 'connect') {
289
+ // Make sure it's a primary action button, not in a dropdown
290
+ if (btn.classList.contains('artdeco-button--primary') ||
291
+ btn.closest('.pvs-profile-actions') ||
292
+ btn.closest('.pv-top-card-v2-ctas')) {
293
+ btn.click();
294
+ return { clicked: true, method: 'direct', ariaLabel, text };
295
+ }
296
+ }
297
+ }
298
+ return { clicked: false };
299
+ })()
300
+ `));
301
+ if (directConnectResult.clicked) {
302
+ connectClicked = true;
303
+ debugLog(`[LinkedInConnectionTool] Clicked direct Connect button: ${directConnectResult.method}`);
304
+ }
305
+ // Strategy 2: Connect is under "More" dropdown
306
+ if (!connectClicked) {
307
+ debugLog('[LinkedInConnectionTool] Direct Connect not found, trying More dropdown...');
308
+ // Click the "More" button
309
+ const moreButtonResult = (await this.evaluate(`
310
+ (() => {
311
+ // Look for More button - specifically the profile overflow action button
312
+ // It has id like "ember67-profile-overflow-action" and aria-label="More actions"
313
+ const buttons = document.querySelectorAll('button');
314
+ for (const btn of buttons) {
315
+ const ariaLabel = (btn.getAttribute('aria-label') || '').toLowerCase();
316
+ const btnId = btn.id || '';
317
+
318
+ // Profile overflow button has specific ID pattern and aria-label
319
+ if (btnId.includes('profile-overflow-action') ||
320
+ (ariaLabel === 'more actions' && btn.classList.contains('artdeco-dropdown__trigger'))) {
321
+ btn.click();
322
+ return { clicked: true, id: btnId, ariaLabel };
323
+ }
324
+ }
325
+ return { clicked: false };
326
+ })()
327
+ `));
328
+ if (moreButtonResult.clicked) {
329
+ debugLog(`[LinkedInConnectionTool] Clicked More button: id="${moreButtonResult.id}", aria-label="${moreButtonResult.ariaLabel}"`);
330
+ await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait longer for dropdown to open
331
+ // Save debug state after clicking More button
332
+ await this.saveDebugState('03-after-more-dropdown-open');
333
+ // Now look for Connect in the dropdown
334
+ const dropdownConnectResult = (await this.evaluate(`
335
+ (() => {
336
+ // LinkedIn uses div[role="button"] for dropdown items
337
+ // Look for Connect option with aria-label containing "connect"
338
+ const dropdownItems = document.querySelectorAll('.artdeco-dropdown__item[role="button"], .artdeco-dropdown__content-inner [role="button"]');
339
+ for (const item of dropdownItems) {
340
+ const ariaLabel = (item.getAttribute('aria-label') || '').toLowerCase();
341
+ const text = (item.innerText || item.textContent || '').trim().toLowerCase();
342
+
343
+ // Check aria-label like "Invite X to connect" or text "Connect"
344
+ if (ariaLabel.includes('connect') || text === 'connect') {
345
+ item.click();
346
+ return { clicked: true, ariaLabel, text };
347
+ }
348
+ }
349
+
350
+ return { clicked: false };
351
+ })()
352
+ `));
353
+ if (dropdownConnectResult.clicked) {
354
+ connectClicked = true;
355
+ debugLog(`[LinkedInConnectionTool] Clicked Connect from dropdown: aria-label="${dropdownConnectResult.ariaLabel}", text="${dropdownConnectResult.text}"`);
356
+ }
357
+ else {
358
+ debugLog('[LinkedInConnectionTool] Connect option not found in dropdown');
359
+ }
360
+ }
361
+ else {
362
+ debugLog('[LinkedInConnectionTool] More button not found');
363
+ }
364
+ }
365
+ if (!connectClicked) {
366
+ // Save debug state before reporting failure
367
+ await this.saveDebugState('04-connect-not-found');
368
+ return {
369
+ operation: 'send_connection',
370
+ success: false,
371
+ profile: profileInfo || undefined,
372
+ error: 'Could not find Connect button. Profile may already be connected or connection requests may be restricted.',
373
+ };
374
+ }
375
+ // Wait for connection modal to appear
376
+ await new Promise((resolve) => setTimeout(resolve, 2000));
377
+ // Check if we need to add a note or send without note
378
+ if (message) {
379
+ debugLog('[LinkedInConnectionTool] Adding note to connection request');
380
+ // Click "Add a note" button
381
+ const addNoteResult = (await this.evaluate(`
382
+ (() => {
383
+ const buttons = document.querySelectorAll('button');
384
+ for (const btn of buttons) {
385
+ const ariaLabel = (btn.getAttribute('aria-label') || '').toLowerCase();
386
+ const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
387
+
388
+ if (ariaLabel.includes('add a note') || text.includes('add a note')) {
389
+ btn.click();
390
+ return { clicked: true };
391
+ }
392
+ }
393
+ return { clicked: false };
394
+ })()
395
+ `));
396
+ if (addNoteResult.clicked) {
397
+ debugLog('[LinkedInConnectionTool] Clicked Add a note button');
398
+ await new Promise((resolve) => setTimeout(resolve, 500));
399
+ // Type the message into the textarea
400
+ const typed = await this.typeText('#custom-message', message);
401
+ if (!typed) {
402
+ // Fallback: try evaluate to set value
403
+ await this.evaluate(`
404
+ (() => {
405
+ const textarea = document.querySelector('#custom-message');
406
+ if (textarea) {
407
+ textarea.value = ${JSON.stringify(message)};
408
+ textarea.dispatchEvent(new Event('input', { bubbles: true }));
409
+ return true;
410
+ }
411
+ return false;
412
+ })()
413
+ `);
414
+ }
415
+ debugLog('[LinkedInConnectionTool] Typed note message');
416
+ }
417
+ // Wait a moment before sending
418
+ await new Promise((resolve) => setTimeout(resolve, 500));
419
+ // Click Send button (after adding note)
420
+ const sendResult = (await this.evaluate(`
421
+ (() => {
422
+ const buttons = document.querySelectorAll('button');
423
+ for (const btn of buttons) {
424
+ const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
425
+
426
+ // Look for Send button (primary)
427
+ if (text === 'send' && btn.classList.contains('artdeco-button--primary')) {
428
+ btn.click();
429
+ return { clicked: true, text };
430
+ }
431
+ }
432
+ return { clicked: false };
433
+ })()
434
+ `));
435
+ if (!sendResult.clicked) {
436
+ return {
437
+ operation: 'send_connection',
438
+ success: false,
439
+ profile: profileInfo || undefined,
440
+ error: 'Could not find Send button to complete connection request.',
441
+ };
442
+ }
443
+ debugLog('[LinkedInConnectionTool] Clicked Send button');
444
+ }
445
+ else {
446
+ // No message - click "Send without a note" button
447
+ debugLog('[LinkedInConnectionTool] No message provided, clicking Send without a note');
448
+ const sendWithoutNoteResult = (await this.evaluate(`
449
+ (() => {
450
+ const buttons = document.querySelectorAll('button');
451
+ for (const btn of buttons) {
452
+ const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
453
+
454
+ // Look for "Send without a note" button
455
+ if (text.includes('send without a note') || text.includes('send without note')) {
456
+ btn.click();
457
+ return { clicked: true, text };
458
+ }
459
+ }
460
+ return { clicked: false };
461
+ })()
462
+ `));
463
+ if (!sendWithoutNoteResult.clicked) {
464
+ return {
465
+ operation: 'send_connection',
466
+ success: false,
467
+ profile: profileInfo || undefined,
468
+ error: 'Could not find Send without a note button to complete connection request.',
469
+ };
470
+ }
471
+ debugLog('[LinkedInConnectionTool] Clicked Send without a note button');
472
+ }
473
+ // Wait for request to be processed
474
+ await new Promise((resolve) => setTimeout(resolve, 2000));
475
+ // Handle "Not now" prompt if it appears (for adding to address book)
476
+ await this.evaluate(`
477
+ (() => {
478
+ const buttons = document.querySelectorAll('button');
479
+ for (const btn of buttons) {
480
+ const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
481
+ if (text === 'not now') {
482
+ btn.click();
483
+ return true;
484
+ }
485
+ }
486
+ return false;
487
+ })()
488
+ `);
489
+ return {
490
+ operation: 'send_connection',
491
+ success: true,
492
+ message: `Connection request sent to ${profileInfo?.name || 'profile'}`,
493
+ profile: profileInfo || undefined,
494
+ error: '',
495
+ };
496
+ }
497
+ /**
498
+ * Extract profile information from the current page
499
+ */
500
+ async extractProfileInfo() {
501
+ try {
502
+ const info = (await this.evaluate(`
503
+ (() => {
504
+ // Get profile name - try multiple strategies
505
+ let name = '';
506
+
507
+ // Strategy 1: h1 element (has obfuscated class but also standard classes)
508
+ const h1El = document.querySelector('h1');
509
+ if (h1El) {
510
+ name = h1El.textContent?.trim() || '';
511
+ }
512
+
513
+ // Strategy 2: Profile picture alt/title attribute
514
+ if (!name) {
515
+ const imgEl = document.querySelector('img.pv-top-card-profile-picture__image--show') ||
516
+ document.querySelector('img[class*="pv-top-card-profile-picture"]');
517
+ if (imgEl) {
518
+ name = imgEl.getAttribute('alt') || imgEl.getAttribute('title') || '';
519
+ }
520
+ }
521
+
522
+ // Strategy 3: Extract from Connect button aria-label "Invite X to connect"
523
+ if (!name) {
524
+ const connectBtn = document.querySelector('button[aria-label*="to connect"]');
525
+ if (connectBtn) {
526
+ const ariaLabel = connectBtn.getAttribute('aria-label') || '';
527
+ const match = ariaLabel.match(/Invite (.+) to connect/i);
528
+ if (match) {
529
+ name = match[1];
530
+ }
531
+ }
532
+ }
533
+
534
+ // Get headline - div with text-body-medium break-words and data-generated-suggestion-target
535
+ let headline = '';
536
+ const headlineEl = document.querySelector('div.text-body-medium.break-words[data-generated-suggestion-target]') ||
537
+ document.querySelector('div.text-body-medium.break-words');
538
+ if (headlineEl) {
539
+ headline = headlineEl.textContent?.trim() || '';
540
+ }
541
+
542
+ // Get location - span before Contact info link
543
+ let location = '';
544
+ const contactInfoLink = document.querySelector('a[href*="contact-info"]');
545
+ if (contactInfoLink) {
546
+ // Location is in a sibling or parent span
547
+ const parentSpan = contactInfoLink.closest('span');
548
+ if (parentSpan && parentSpan.previousElementSibling) {
549
+ location = parentSpan.previousElementSibling.textContent?.trim() || '';
550
+ }
551
+ }
552
+
553
+ // Fallback: look for location pattern in spans
554
+ if (!location) {
555
+ const spans = document.querySelectorAll('span');
556
+ for (const span of spans) {
557
+ const text = span.textContent?.trim() || '';
558
+ // Location usually contains comma-separated place names
559
+ if (text.includes(',') && !text.includes('@') && !text.includes('|') &&
560
+ text.length < 100 && text.length > 5) {
561
+ // Check if it looks like a location (contains country/city patterns)
562
+ if (/(?:United|Kingdom|States|England|Germany|France|India|Canada|Australia|California|New York|London|Manchester)/i.test(text)) {
563
+ location = text;
564
+ break;
565
+ }
566
+ }
567
+ }
568
+ }
569
+
570
+ return {
571
+ name,
572
+ headline,
573
+ location,
574
+ profile_url: window.location.href
575
+ };
576
+ })()
577
+ `));
578
+ if (!info.name) {
579
+ return null;
580
+ }
581
+ return info;
582
+ }
583
+ catch (error) {
584
+ console.error('[LinkedInConnectionTool] Error extracting profile info:', error);
585
+ return null;
586
+ }
587
+ }
588
+ }
589
+ //# sourceMappingURL=linkedin-connection-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-connection-tool.js","sourceRoot":"","sources":["../../../../src/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.ts"],"names":[],"mappings":"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"}