coffeeinabit 0.0.57 → 0.0.59
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/linkedin_automation.js
CHANGED
|
@@ -40,6 +40,7 @@ export class LinkedInAutomation {
|
|
|
40
40
|
this.screenshotIntervalMs = 3000;
|
|
41
41
|
this.actionPollingIntervalMs = 15000;
|
|
42
42
|
this.currentAction = null;
|
|
43
|
+
this.currentActionStartedAt = null;
|
|
43
44
|
this.userEmail = null;
|
|
44
45
|
this.isActionPollingActive = false;
|
|
45
46
|
this.linkedInSessionDir = getContextDirectory();
|
|
@@ -48,6 +49,9 @@ export class LinkedInAutomation {
|
|
|
48
49
|
this._currentRefreshToken = null;
|
|
49
50
|
this._currentAccessToken = null; // Track access token explicitly
|
|
50
51
|
|
|
52
|
+
// Action execution timeout (5 minutes)
|
|
53
|
+
this.actionTimeoutMs = 5 * 60 * 1000;
|
|
54
|
+
|
|
51
55
|
// Authentication failure tracking
|
|
52
56
|
this.consecutiveAuthFailures = 0;
|
|
53
57
|
this.maxAuthFailures = 3; // Stop polling after 3 consecutive failures
|
|
@@ -701,12 +705,13 @@ export class LinkedInAutomation {
|
|
|
701
705
|
try {
|
|
702
706
|
const screenshot = await this.page.screenshot({
|
|
703
707
|
fullPage: false,
|
|
704
|
-
type: '
|
|
708
|
+
type: 'jpeg',
|
|
709
|
+
quality: 50,
|
|
705
710
|
timeout: 60000
|
|
706
711
|
});
|
|
707
712
|
|
|
708
713
|
const base64Screenshot = screenshot.toString('base64');
|
|
709
|
-
|
|
714
|
+
|
|
710
715
|
this.io.emit('screenshot_update', {
|
|
711
716
|
screenshot: base64Screenshot,
|
|
712
717
|
url: this.currentUrl,
|
|
@@ -714,6 +719,9 @@ export class LinkedInAutomation {
|
|
|
714
719
|
timestamp: new Date().toISOString()
|
|
715
720
|
});
|
|
716
721
|
|
|
722
|
+
// Fire-and-forget upload to S3
|
|
723
|
+
this.uploadScreenshotToS3(base64Screenshot, this.currentAction?.action_id);
|
|
724
|
+
|
|
717
725
|
} catch (error) {
|
|
718
726
|
logger.error('[LinkedInAutomation] Failed to capture screenshot:', error.message);
|
|
719
727
|
if (typeof error.message === 'string' && error.message.includes('Target page, context or browser has been closed')) {
|
|
@@ -722,6 +730,30 @@ export class LinkedInAutomation {
|
|
|
722
730
|
}
|
|
723
731
|
}
|
|
724
732
|
|
|
733
|
+
async uploadScreenshotToS3(base64Screenshot, actionId) {
|
|
734
|
+
try {
|
|
735
|
+
const idToken = await this.getAccessToken();
|
|
736
|
+
if (!idToken) return;
|
|
737
|
+
|
|
738
|
+
fetch('https://api.coffeeinabit.com/app/screenshots', {
|
|
739
|
+
method: 'POST',
|
|
740
|
+
headers: {
|
|
741
|
+
'Content-Type': 'application/json',
|
|
742
|
+
'Authorization': `Bearer ${idToken}`
|
|
743
|
+
},
|
|
744
|
+
body: JSON.stringify({
|
|
745
|
+
screenshot: base64Screenshot,
|
|
746
|
+
action_id: actionId || null,
|
|
747
|
+
timestamp: Date.now()
|
|
748
|
+
})
|
|
749
|
+
}).catch(err => {
|
|
750
|
+
logger.error('[LinkedInAutomation] Screenshot upload failed:', err.message);
|
|
751
|
+
});
|
|
752
|
+
} catch (error) {
|
|
753
|
+
logger.error('[LinkedInAutomation] Screenshot upload error:', error.message);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
725
757
|
startActionPolling() {
|
|
726
758
|
if (this.isActionPollingActive) {
|
|
727
759
|
logger.log('[LinkedInAutomation] Action polling is already active, skipping...');
|
|
@@ -751,10 +783,18 @@ export class LinkedInAutomation {
|
|
|
751
783
|
}
|
|
752
784
|
|
|
753
785
|
if (this.currentAction) {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
786
|
+
const elapsed = Date.now() - (this.currentActionStartedAt || Date.now());
|
|
787
|
+
if (elapsed > this.actionTimeoutMs) {
|
|
788
|
+
logger.error(`[LinkedInAutomation] Action ${this.currentAction.action} timed out after ${Math.round(elapsed / 1000)}s, force-clearing`);
|
|
789
|
+
this.currentAction = null;
|
|
790
|
+
this.currentActionStartedAt = null;
|
|
791
|
+
this.emitActionUpdate();
|
|
792
|
+
} else {
|
|
793
|
+
logger.log(`[LinkedInAutomation] Action in progress (${Math.round(elapsed / 1000)}s), skipping polling...`);
|
|
794
|
+
logger.log('[LinkedInAutomation] Next poll in', Math.round(currentInterval / 1000), 'seconds');
|
|
795
|
+
setTimeout(pollWithBackoff, currentInterval);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
758
798
|
}
|
|
759
799
|
|
|
760
800
|
// pollForActions now returns true if actions were found and processed
|
|
@@ -1002,13 +1042,14 @@ export class LinkedInAutomation {
|
|
|
1002
1042
|
await closeAllConversationBubbles(this.page);
|
|
1003
1043
|
|
|
1004
1044
|
try {
|
|
1005
|
-
logger.log('[LinkedInAutomation] Starting execution of action:', action.action, 'ID:', action.action_id);
|
|
1045
|
+
logger.log('[LinkedInAutomation] Starting execution of action:', action.action, 'ID:', action.action_id, 'Local time:', new Date().toLocaleString());
|
|
1006
1046
|
logger.log('[LinkedInAutomation] Action parameters:', JSON.stringify(action.parameters, null, 2));
|
|
1007
1047
|
this.currentAction = action;
|
|
1048
|
+
this.currentActionStartedAt = Date.now();
|
|
1008
1049
|
this.status = 'executing_action';
|
|
1009
1050
|
this.emitActionUpdate();
|
|
1010
1051
|
this.emitStatus();
|
|
1011
|
-
|
|
1052
|
+
|
|
1012
1053
|
let result = null;
|
|
1013
1054
|
|
|
1014
1055
|
// Normalize: if no username in parameters, use linkedin_profile_id from action
|
|
@@ -1111,6 +1152,7 @@ export class LinkedInAutomation {
|
|
|
1111
1152
|
console.warn = originalConsoleWarn;
|
|
1112
1153
|
|
|
1113
1154
|
this.currentAction = null;
|
|
1155
|
+
this.currentActionStartedAt = null;
|
|
1114
1156
|
this.emitActionUpdate();
|
|
1115
1157
|
}
|
|
1116
1158
|
}
|
package/package.json
CHANGED
package/routes/automation.js
CHANGED
|
@@ -25,7 +25,7 @@ export function createAutomationRoutes(cloudAuth, appState, linkedinAutomation,
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
try {
|
|
28
|
-
const { headless =
|
|
28
|
+
const { headless = true, socketId = null } = req.body;
|
|
29
29
|
|
|
30
30
|
// If socketId provided, use process-specific automation
|
|
31
31
|
// Otherwise, use legacy single instance (for backward compatibility)
|
|
@@ -1,676 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"threads": [
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"name": "Melissa Torres",
|
|
8
|
-
"uniq_id": "ACoAAABbk_8BlTyLieiBlKHVK5M2J7_nGDMNUso",
|
|
9
|
-
"is_self": false
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"name": "Alena Borikova",
|
|
13
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
14
|
-
"is_self": true
|
|
15
|
-
}
|
|
16
|
-
],
|
|
17
|
-
"last_activity_at": 1771021039024,
|
|
18
|
-
"last_activity_at_iso": "2026-02-13T22:17:19.024Z",
|
|
19
|
-
"messages": [
|
|
20
|
-
{
|
|
21
|
-
"author": "Melissa Torres",
|
|
22
|
-
"author_id": "ACoAAABbk_8BlTyLieiBlKHVK5M2J7_nGDMNUso",
|
|
23
|
-
"is_self": false,
|
|
24
|
-
"text": "Hi Alena,\nLooking for job openings?Find open jobs near you that match your skills and experience.\nTo get started:\nSearch for open jobsFilter down to the jobs near you, based on experience level, salary, and more.Create a search alert to be the first to know about new jobs.Start your search today, and find people who are hiring on LinkedIn.\nWe’re in this together,Melissa from LinkedIn",
|
|
25
|
-
"timestamp": 1771021039024,
|
|
26
|
-
"timestamp_iso": "2026-02-13T22:17:19.024Z",
|
|
27
|
-
"network_intercepted_at": "2026-02-18T20:12:27.020Z"
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
"message_count": 1
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"thread_id": "urn:li:messagingThread:2-MDVkNDEyNjAtZmM1ZC00MDQ3LWFmM2ItOGIwZjA5MTEzNTlkXzEwMA==",
|
|
34
|
-
"participants": [
|
|
35
|
-
{
|
|
36
|
-
"name": "Alena Borikova",
|
|
37
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
38
|
-
"is_self": true
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"name": "Daria Baiandina",
|
|
42
|
-
"uniq_id": "ACoAACZnpFoBUlqVlDu1EwrsUoFrgaJdC6auxN0",
|
|
43
|
-
"is_self": false
|
|
44
|
-
}
|
|
45
|
-
],
|
|
46
|
-
"last_activity_at": 1770831726029,
|
|
47
|
-
"last_activity_at_iso": "2026-02-11T17:42:06.029Z",
|
|
48
|
-
"messages": [
|
|
49
|
-
{
|
|
50
|
-
"author": "Alena Borikova",
|
|
51
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
52
|
-
"is_self": true,
|
|
53
|
-
"text": "Привет, Даша)\nвзаимно!\n\nСейчас я больше занимаюсь ux частью и рисерчем потребностей пользователей. А иллюстраторы / граф. дизайнеры есть в штате, так что помочь как-то к сожалению ничем не смогу (\nНо буду иметь ввиду, если что-то понадобится \n\nТы в Тбилиси живешь? 🥹\nЯ иногда бываю в Тбилиси, но в основном в Батуми",
|
|
54
|
-
"timestamp": 1770831726029,
|
|
55
|
-
"timestamp_iso": "2026-02-11T17:42:06.029Z",
|
|
56
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
57
|
-
}
|
|
58
|
-
],
|
|
59
|
-
"message_count": 1
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"thread_id": "urn:li:messagingThread:2-ZmQyYjQzZjAtYTI0Ny00MGQwLTkwOTItZDI1NmMxNjYyMGUxXzEwMA==",
|
|
63
|
-
"participants": [
|
|
64
|
-
{
|
|
65
|
-
"name": "Assel Uvaliyeva",
|
|
66
|
-
"uniq_id": "ACoAAARftn0BKiQPHroRgvmpVevd9aKx1gttAHU",
|
|
67
|
-
"is_self": false
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"name": "Alena Borikova",
|
|
71
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
72
|
-
"is_self": true
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
"last_activity_at": 1770640210236,
|
|
76
|
-
"last_activity_at_iso": "2026-02-09T12:30:10.236Z",
|
|
77
|
-
"messages": [
|
|
78
|
-
{
|
|
79
|
-
"author": "Assel Uvaliyeva",
|
|
80
|
-
"author_id": "ACoAAARftn0BKiQPHroRgvmpVevd9aKx1gttAHU",
|
|
81
|
-
"is_self": false,
|
|
82
|
-
"text": "Dear Alena, I’m Dr Assel, Vice-President of Nazarbayev University (NU).\nThe joint NU-SOAS MA offers a full-time, one-year program — first in London, then in Astana — with modules in international relations, Eurasian geopolitics, and an internship in embassies. Ideal for aspiring diplomats, analysts, or NGO professionals. \nThe program is fee-paying, with a total tuition fee of £15,000.\nWhy Apply to NU?#1 University in Central Asia and the Caucasus and #4 in CIS98% employability rateEnglish-taught educationInternational environment: nearly 400 international students and 500 faculty members from 62 countries140+ career events annuallyCampus security is ensured through 24/7 surveillanceThe NU campus spans over 94 hectares, featuring modern academic buildings and recreational facilities. A network of enclosed Skywalks connects key buildings, ensuring comfort and accessibility throughout the year.\nFor additional information please contact us at info_admissions@nu.edu.kz\nGet a dual degree! Admission is open.",
|
|
83
|
-
"timestamp": 1770640210236,
|
|
84
|
-
"timestamp_iso": "2026-02-09T12:30:10.236Z",
|
|
85
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
86
|
-
}
|
|
87
|
-
],
|
|
88
|
-
"message_count": 1
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"thread_id": "urn:li:messagingThread:2-ZGU3NTUyMzMtMTJkNy00NDIxLTk4MDgtYmYxNGIwOTQ5YjFmXzEwMA==",
|
|
92
|
-
"participants": [
|
|
93
|
-
{
|
|
94
|
-
"name": "Alena Borikova",
|
|
95
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
96
|
-
"is_self": true
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"name": "Kate Yanchenko",
|
|
100
|
-
"uniq_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
101
|
-
"is_self": false
|
|
102
|
-
}
|
|
103
|
-
],
|
|
104
|
-
"last_activity_at": 1770139934759,
|
|
105
|
-
"last_activity_at_iso": "2026-02-03T17:32:14.759Z",
|
|
106
|
-
"messages": [
|
|
107
|
-
{
|
|
108
|
-
"author": "Kate Yanchenko",
|
|
109
|
-
"author_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
110
|
-
"is_self": false,
|
|
111
|
-
"text": "Hello!",
|
|
112
|
-
"timestamp": 1765865708197,
|
|
113
|
-
"timestamp_iso": "2025-12-16T06:15:08.197Z",
|
|
114
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"author": "Alena Borikova",
|
|
118
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
119
|
-
"is_self": true,
|
|
120
|
-
"text": "Hi hi ",
|
|
121
|
-
"timestamp": 1765867625215,
|
|
122
|
-
"timestamp_iso": "2025-12-16T06:47:05.215Z",
|
|
123
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
"author": "Kate Yanchenko",
|
|
127
|
-
"author_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
128
|
-
"is_self": false,
|
|
129
|
-
"text": "Hello!",
|
|
130
|
-
"timestamp": 1765872088845,
|
|
131
|
-
"timestamp_iso": "2025-12-16T08:01:28.845Z",
|
|
132
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
"author": "Kate Yanchenko",
|
|
136
|
-
"author_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
137
|
-
"is_self": false,
|
|
138
|
-
"text": "just testing",
|
|
139
|
-
"timestamp": 1765873430497,
|
|
140
|
-
"timestamp_iso": "2025-12-16T08:23:50.497Z",
|
|
141
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
"author": "Kate Yanchenko",
|
|
145
|
-
"author_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
146
|
-
"is_self": false,
|
|
147
|
-
"text": "Hey, how are you?",
|
|
148
|
-
"timestamp": 1770138675922,
|
|
149
|
-
"timestamp_iso": "2026-02-03T17:11:15.922Z",
|
|
150
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"author": "Alena Borikova",
|
|
154
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
155
|
-
"is_self": true,
|
|
156
|
-
"text": "Fine, you? ❤️",
|
|
157
|
-
"timestamp": 1770138705220,
|
|
158
|
-
"timestamp_iso": "2026-02-03T17:11:45.220Z",
|
|
159
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
"author": "Kate Yanchenko",
|
|
163
|
-
"author_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
164
|
-
"is_self": false,
|
|
165
|
-
"text": "Hey, how are you?",
|
|
166
|
-
"timestamp": 1770139276918,
|
|
167
|
-
"timestamp_iso": "2026-02-03T17:21:16.918Z",
|
|
168
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
"author": "Alena Borikova",
|
|
172
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
173
|
-
"is_self": true,
|
|
174
|
-
"text": "I'm good",
|
|
175
|
-
"timestamp": 1770139300739,
|
|
176
|
-
"timestamp_iso": "2026-02-03T17:21:40.739Z",
|
|
177
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
"author": "Alena Borikova",
|
|
181
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
182
|
-
"is_self": true,
|
|
183
|
-
"text": "Thanks for asking 😁❤️",
|
|
184
|
-
"timestamp": 1770139311452,
|
|
185
|
-
"timestamp_iso": "2026-02-03T17:21:51.452Z",
|
|
186
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
"author": "Kate Yanchenko",
|
|
190
|
-
"author_id": "ACoAABIyz2sB-O7ZtfsS5d8myngQBtR9JEKz_sY",
|
|
191
|
-
"is_self": false,
|
|
192
|
-
"text": "Hey, how are you?",
|
|
193
|
-
"timestamp": 1770139531176,
|
|
194
|
-
"timestamp_iso": "2026-02-03T17:25:31.176Z",
|
|
195
|
-
"network_intercepted_at": "2026-02-18T20:12:35.960Z"
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
"author": "Alena Borikova",
|
|
199
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
200
|
-
"is_self": true,
|
|
201
|
-
"text": "🐥❤️",
|
|
202
|
-
"timestamp": 1770139934759,
|
|
203
|
-
"timestamp_iso": "2026-02-03T17:32:14.759Z",
|
|
204
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
205
|
-
}
|
|
206
|
-
],
|
|
207
|
-
"message_count": 11
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
"thread_id": "urn:li:messagingThread:2-YTQ2MjM0YzUtOWE3Ny00NWFiLWJhOTAtOThjOTgwOGJlNDgxXzEwMA==",
|
|
211
|
-
"participants": [
|
|
212
|
-
{
|
|
213
|
-
"name": "Lamri Gorguchadze",
|
|
214
|
-
"uniq_id": "ACoAACahZMEBJyO-1ojzpnJdh5jgDY86PadkdQU",
|
|
215
|
-
"is_self": false
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
"name": "Alena Borikova",
|
|
219
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
220
|
-
"is_self": true
|
|
221
|
-
}
|
|
222
|
-
],
|
|
223
|
-
"last_activity_at": 1767280366600,
|
|
224
|
-
"last_activity_at_iso": "2026-01-01T15:12:46.600Z",
|
|
225
|
-
"messages": [
|
|
226
|
-
{
|
|
227
|
-
"author": "Alena Borikova",
|
|
228
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
229
|
-
"is_self": true,
|
|
230
|
-
"text": "Thank you 🥹❤️\nI wish you all the best in NY 2026 too! 🫶",
|
|
231
|
-
"timestamp": 1767280366600,
|
|
232
|
-
"timestamp_iso": "2026-01-01T15:12:46.600Z",
|
|
233
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
234
|
-
}
|
|
235
|
-
],
|
|
236
|
-
"message_count": 1
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
"thread_id": "urn:li:messagingThread:2-NzUyNTUzYTEtNmQwYS00ZDQ0LWI0ZDEtZThkYTcyOTIyMzFmXzEwMA==",
|
|
240
|
-
"participants": [
|
|
241
|
-
{
|
|
242
|
-
"name": "Viktoryia Patarocha",
|
|
243
|
-
"uniq_id": "ACoAADuVGhoBsbpjl2JPhPDOPwK8FORq6CkabbI",
|
|
244
|
-
"is_self": false
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
"name": "Alena Borikova",
|
|
248
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
249
|
-
"is_self": true
|
|
250
|
-
}
|
|
251
|
-
],
|
|
252
|
-
"last_activity_at": 1767280357333,
|
|
253
|
-
"last_activity_at_iso": "2026-01-01T15:12:37.333Z",
|
|
254
|
-
"messages": [
|
|
255
|
-
{
|
|
256
|
-
"author": "Viktoryia Patarocha",
|
|
257
|
-
"author_id": "ACoAADuVGhoBsbpjl2JPhPDOPwK8FORq6CkabbI",
|
|
258
|
-
"is_self": false,
|
|
259
|
-
"text": "Hi Alena! Are you happy at Empartech?\nWe’re looking for a Node.js Developer in Georgia to join our projects for European and US clients.\nLeverX has been on the market for over 20 years, building an expert team and a healthy work environment where people grow and enjoy their projects.\nYour profile looks like a possible fit. Would you be open to a short chat?",
|
|
260
|
-
"timestamp": 1767280357333,
|
|
261
|
-
"timestamp_iso": "2026-01-01T15:12:37.333Z",
|
|
262
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
263
|
-
}
|
|
264
|
-
],
|
|
265
|
-
"message_count": 1
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"thread_id": "urn:li:messagingThread:2-YjQ5N2RiMDMtMmIyMy00OGQyLWIzMDktZjRmNmUyMjhmYjQ1XzEwMA==",
|
|
269
|
-
"participants": [
|
|
270
|
-
{
|
|
271
|
-
"name": "Jasper de Muynck",
|
|
272
|
-
"uniq_id": "ACoAAB0pl_ABVSQdbBcQqUANIdz3xXBpsWW-1so",
|
|
273
|
-
"is_self": false
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
"name": "Alena Borikova",
|
|
277
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
278
|
-
"is_self": true
|
|
279
|
-
}
|
|
280
|
-
],
|
|
281
|
-
"last_activity_at": 1765954826039,
|
|
282
|
-
"last_activity_at_iso": "2025-12-17T07:00:26.039Z",
|
|
283
|
-
"messages": [
|
|
284
|
-
{
|
|
285
|
-
"author": "Alena Borikova",
|
|
286
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
287
|
-
"is_self": true,
|
|
288
|
-
"text": "Hey James! Nice to meet you! \nTo be honest, it doesn't sound like anything exciting :)",
|
|
289
|
-
"timestamp": 1765954826039,
|
|
290
|
-
"timestamp_iso": "2025-12-17T07:00:26.039Z",
|
|
291
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
292
|
-
}
|
|
293
|
-
],
|
|
294
|
-
"message_count": 1
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
"thread_id": "urn:li:messagingThread:2-NWVhNmRmNmItNTRjNi00NTUxLThiNmUtMjYxNzk3YzVjNTI5XzEwMA==",
|
|
298
|
-
"participants": [
|
|
299
|
-
{
|
|
300
|
-
"name": "Lasha Shonia",
|
|
301
|
-
"uniq_id": "ACoAABS6Ji8BvKEm9DvI5n5TQiY6UbMKN4-GZBQ",
|
|
302
|
-
"is_self": false
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
"name": "Alena Borikova",
|
|
306
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
307
|
-
"is_self": true
|
|
308
|
-
}
|
|
309
|
-
],
|
|
310
|
-
"last_activity_at": 1765828489886,
|
|
311
|
-
"last_activity_at_iso": "2025-12-15T19:54:49.886Z",
|
|
312
|
-
"messages": [
|
|
313
|
-
{
|
|
314
|
-
"author": "Alena Borikova",
|
|
315
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
316
|
-
"is_self": true,
|
|
317
|
-
"text": "Yes! I’ll think about it 🙏",
|
|
318
|
-
"timestamp": 1765828489886,
|
|
319
|
-
"timestamp_iso": "2025-12-15T19:54:49.886Z",
|
|
320
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
321
|
-
}
|
|
322
|
-
],
|
|
323
|
-
"message_count": 1
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
"thread_id": "urn:li:messagingThread:2-NThhNjNhYjgtZDQ3OC00OTRhLTlkNDQtMWE4Y2I1MzllOTM2XzEwMA==",
|
|
327
|
-
"participants": [
|
|
328
|
-
{
|
|
329
|
-
"name": "Alena Borikova",
|
|
330
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
331
|
-
"is_self": true
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
"name": "Nataliia Bohomiakova",
|
|
335
|
-
"uniq_id": "ACoAAChk4ooBhasNs29B6CQhKn9Fx1EQs5USnh4",
|
|
336
|
-
"is_self": false
|
|
337
|
-
}
|
|
338
|
-
],
|
|
339
|
-
"last_activity_at": 1765816629196,
|
|
340
|
-
"last_activity_at_iso": "2025-12-15T16:37:09.196Z",
|
|
341
|
-
"messages": [
|
|
342
|
-
{
|
|
343
|
-
"author": "Alena Borikova",
|
|
344
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
345
|
-
"is_self": true,
|
|
346
|
-
"text": "Hi Nataliia. My name's Alena, I'm building an AI Sales tool for LinkedIn. \nI understand that the offering might not be directly relevant to you technically. But if it sounds somehow that it might help you with work, so you can refer us to the decision-maker, and I can do a quick demo.",
|
|
347
|
-
"timestamp": 1765816629196,
|
|
348
|
-
"timestamp_iso": "2025-12-15T16:37:09.196Z",
|
|
349
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
350
|
-
}
|
|
351
|
-
],
|
|
352
|
-
"message_count": 1
|
|
353
|
-
},
|
|
354
|
-
{
|
|
355
|
-
"thread_id": "urn:li:messagingThread:2-ZDk0MDNiN2UtMjJhNi00ZGE4LWE2ODAtOTFiOTQ1MmY1MDc2XzEwMA==",
|
|
356
|
-
"participants": [
|
|
357
|
-
{
|
|
358
|
-
"name": "Alena Borikova",
|
|
359
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
360
|
-
"is_self": true
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
"name": "Eralp Hatipoglu",
|
|
364
|
-
"uniq_id": "ACoAAC6b4IEB3Iy-nOLNuoVyp3Q6SeTS9WMgiDs",
|
|
365
|
-
"is_self": false
|
|
366
|
-
}
|
|
367
|
-
],
|
|
368
|
-
"last_activity_at": 1765816499877,
|
|
369
|
-
"last_activity_at_iso": "2025-12-15T16:34:59.877Z",
|
|
370
|
-
"messages": [
|
|
371
|
-
{
|
|
372
|
-
"author": "Alena Borikova",
|
|
373
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
374
|
-
"is_self": true,
|
|
375
|
-
"text": "Eralp, great connecting. Saw your Forbes chat-impressive vision for CityPay's expansion into Central Asia. 👏\n\nI'm building an AI Sales Tool for LinkedIn that acts as an automated sales team. It finds the right professionals in new markets and engages them personally to speed up acquisition.\n\nWe guarantee leads and closed deals, or it's free. Does it sound interesting? We can book a quick demo call and I can answer all questions.",
|
|
376
|
-
"timestamp": 1765816499877,
|
|
377
|
-
"timestamp_iso": "2025-12-15T16:34:59.877Z",
|
|
378
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
379
|
-
}
|
|
380
|
-
],
|
|
381
|
-
"message_count": 1
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
"thread_id": "urn:li:messagingThread:2-OWEyMDBhMjItZDNhZS00ZjUyLWE5NjktNWQ5NzdjMDdmMjA2XzEwMA==",
|
|
385
|
-
"participants": [
|
|
386
|
-
{
|
|
387
|
-
"name": "Alena Borikova",
|
|
388
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
389
|
-
"is_self": true
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
"name": "Lika Apakidze",
|
|
393
|
-
"uniq_id": "ACoAACT0mF0BwImUvMxZ069pectEI0DyJFKnofA",
|
|
394
|
-
"is_self": false
|
|
395
|
-
}
|
|
396
|
-
],
|
|
397
|
-
"last_activity_at": 1765217642382,
|
|
398
|
-
"last_activity_at_iso": "2025-12-08T18:14:02.382Z",
|
|
399
|
-
"messages": [
|
|
400
|
-
{
|
|
401
|
-
"author": "Alena Borikova",
|
|
402
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
403
|
-
"is_self": true,
|
|
404
|
-
"text": "Hi Lika. Great to connect. Saw your post on the psychotherapy event-it's a fascinating topic. It resonates with my work in UX, where understanding human psychology is everything.\n\nAs a fellow founder here in Tbilisi, I know the grind of finding new clients, especially while balancing other big commitments. I'm working on an AI tool that automates sales outreach. It might be a way to grow Printera without cloning yourself.\n\nWe offer a free trial and guarantee you'll get meetings. Worth a look?",
|
|
405
|
-
"timestamp": 1765217642382,
|
|
406
|
-
"timestamp_iso": "2025-12-08T18:14:02.382Z",
|
|
407
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
408
|
-
}
|
|
409
|
-
],
|
|
410
|
-
"message_count": 1
|
|
411
|
-
},
|
|
412
|
-
{
|
|
413
|
-
"thread_id": "urn:li:messagingThread:2-ZmNmMTllN2MtNmQxNC00NTczLWI4NDItM2Q1MmUxZGRlNWQ2XzEwMA==",
|
|
414
|
-
"participants": [
|
|
415
|
-
{
|
|
416
|
-
"name": "Saba Marshava",
|
|
417
|
-
"uniq_id": "ACoAAEW9Z0gBSGrtG_eZP7eBoB05PvlSwY5dqS0",
|
|
418
|
-
"is_self": false
|
|
419
|
-
},
|
|
420
|
-
{
|
|
421
|
-
"name": "Alena Borikova",
|
|
422
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
423
|
-
"is_self": true
|
|
424
|
-
}
|
|
425
|
-
],
|
|
426
|
-
"last_activity_at": 1765127593427,
|
|
427
|
-
"last_activity_at_iso": "2025-12-07T17:13:13.427Z",
|
|
428
|
-
"messages": [
|
|
429
|
-
{
|
|
430
|
-
"author": "Alena Borikova",
|
|
431
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
432
|
-
"is_self": true,
|
|
433
|
-
"text": "Saba, that Minecraft-style portfolio you shared was brilliant.\n\nIt's a perfect example of what I love-making deep tech feel intuitive. As a UX researcher with a full-stack background, that fusion is my entire focus.\n\nI'm building an AI SDR tool for founders. We're offering a few local startups a guaranteed-results trial: at least 3 qualified meetings with leads in a month, or it's free. Worth a quick chat?",
|
|
434
|
-
"timestamp": 1765127593427,
|
|
435
|
-
"timestamp_iso": "2025-12-07T17:13:13.427Z",
|
|
436
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
437
|
-
}
|
|
438
|
-
],
|
|
439
|
-
"message_count": 1
|
|
440
|
-
},
|
|
441
|
-
{
|
|
442
|
-
"thread_id": "urn:li:messagingThread:2-MzFiMzIyNjItYmQ2NS00MzlhLWE4MWYtMTBlZTI4NzBkODk3XzEwMA==",
|
|
443
|
-
"participants": [
|
|
444
|
-
{
|
|
445
|
-
"name": "Alena Borikova",
|
|
446
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
447
|
-
"is_self": true
|
|
448
|
-
},
|
|
449
|
-
{
|
|
450
|
-
"name": "Nicholas Ergemla",
|
|
451
|
-
"uniq_id": "ACoAABuFt48BWRjCxQAcCi-5j16UOr7wbENffl0",
|
|
452
|
-
"is_self": false
|
|
453
|
-
}
|
|
454
|
-
],
|
|
455
|
-
"last_activity_at": 1765127346294,
|
|
456
|
-
"last_activity_at_iso": "2025-12-07T17:09:06.294Z",
|
|
457
|
-
"messages": [
|
|
458
|
-
{
|
|
459
|
-
"author": "Alena Borikova",
|
|
460
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
461
|
-
"is_self": true,
|
|
462
|
-
"text": "Nicholas, your post about the useless banking feature was spot on. 'Best, Best but... Nobody use it!'\n\nI run an AI startup here in Tbilisi helping founders like us with the grind of finding new clients for their agencies. I'm guessing you'd rather spend your time on design for Steelmonk than on outreach.\n\nIt's a zero-risk trial, we guarantee you meetings. Worth a look?",
|
|
463
|
-
"timestamp": 1765127346294,
|
|
464
|
-
"timestamp_iso": "2025-12-07T17:09:06.294Z",
|
|
465
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
466
|
-
}
|
|
467
|
-
],
|
|
468
|
-
"message_count": 1
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
"thread_id": "urn:li:messagingThread:2-OGI1NzZjNGMtODIzOC00NTFlLTlhMzMtN2FkYjExYTgxYjlhXzEwMA==",
|
|
472
|
-
"participants": [
|
|
473
|
-
{
|
|
474
|
-
"name": "Irakli Museridze",
|
|
475
|
-
"uniq_id": "ACoAACI3ULMBjZDgBp5XncFBHkYhiQTQyyl7w6k",
|
|
476
|
-
"is_self": false
|
|
477
|
-
},
|
|
478
|
-
{
|
|
479
|
-
"name": "Alena Borikova",
|
|
480
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
481
|
-
"is_self": true
|
|
482
|
-
}
|
|
483
|
-
],
|
|
484
|
-
"last_activity_at": 1765127193692,
|
|
485
|
-
"last_activity_at_iso": "2025-12-07T17:06:33.692Z",
|
|
486
|
-
"messages": [
|
|
487
|
-
{
|
|
488
|
-
"author": "Alena Borikova",
|
|
489
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
490
|
-
"is_self": true,
|
|
491
|
-
"text": "Irakli, great to connect. As a fellow tech founder in Tbilisi with a dev background, I know the feeling. We'd rather spend our time building the product than trying to find the next client.\n\nI'm working on an AI SDR tool to automate that entire process for agencies. It comes with a guarantee of 3+ lead meetings in the first month, or it's free.\n\nWorth a look?",
|
|
492
|
-
"timestamp": 1765127193692,
|
|
493
|
-
"timestamp_iso": "2025-12-07T17:06:33.692Z",
|
|
494
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
495
|
-
}
|
|
496
|
-
],
|
|
497
|
-
"message_count": 1
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
"thread_id": "urn:li:messagingThread:2-ZDk0MmE1MjMtZTE1Yi00YTIwLTk5MGQtMmJlNzcwNGY5MjdjXzEwMA==",
|
|
501
|
-
"participants": [
|
|
502
|
-
{
|
|
503
|
-
"name": "Alena Borikova",
|
|
504
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
505
|
-
"is_self": true
|
|
506
|
-
},
|
|
507
|
-
{
|
|
508
|
-
"name": "Avtandil Kutchava",
|
|
509
|
-
"uniq_id": "ACoAACETSqgBP8_EW1_lwMD7_Vkm1jIsbQdI0XI",
|
|
510
|
-
"is_self": false
|
|
511
|
-
}
|
|
512
|
-
],
|
|
513
|
-
"last_activity_at": 1765127013084,
|
|
514
|
-
"last_activity_at_iso": "2025-12-07T17:03:33.084Z",
|
|
515
|
-
"messages": [
|
|
516
|
-
{
|
|
517
|
-
"author": "Alena Borikova",
|
|
518
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
519
|
-
"is_self": true,
|
|
520
|
-
"text": "Avtandil, your vision to 'pixelate the world' is ambitious. A big vision needs a constant stream of users.\n\nI'm tackling that exact problem.\n\nMy AI SDR tool automates lead-gen for founders. It helps you scale without the manual grind.\n\nIt's zero-risk to try. Two weeks free. And a guarantee of 3+ lead meetings in the first month.\n\nDoes it sound interesting?",
|
|
521
|
-
"timestamp": 1765127013084,
|
|
522
|
-
"timestamp_iso": "2025-12-07T17:03:33.084Z",
|
|
523
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
524
|
-
}
|
|
525
|
-
],
|
|
526
|
-
"message_count": 1
|
|
527
|
-
},
|
|
528
|
-
{
|
|
529
|
-
"thread_id": "urn:li:messagingThread:2-NDMyOTkwY2YtMTQ4Yi00ZTMwLTgxMDMtZGU1ZTQ1NTEwZTViXzEwMA==",
|
|
530
|
-
"participants": [
|
|
531
|
-
{
|
|
532
|
-
"name": "Natalia Shahmetova",
|
|
533
|
-
"uniq_id": "ACoAABJp-4QBr2ddDaa7L8QEcMJfqfHpDIGSsCw",
|
|
534
|
-
"is_self": false
|
|
535
|
-
},
|
|
536
|
-
{
|
|
537
|
-
"name": "Alena Borikova",
|
|
538
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
539
|
-
"is_self": true
|
|
540
|
-
}
|
|
541
|
-
],
|
|
542
|
-
"last_activity_at": 1765126372470,
|
|
543
|
-
"last_activity_at_iso": "2025-12-07T16:52:52.470Z",
|
|
544
|
-
"messages": [
|
|
545
|
-
{
|
|
546
|
-
"author": "Alena Borikova",
|
|
547
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
548
|
-
"is_self": true,
|
|
549
|
-
"text": "Привет, Наталья. Рада знакомству, я впечатлена ростом Woofz.\n\nВидела, что вы сейчас решаете комплексную UX-задачу по созданию 'holistic companion'. Это правильный фокус. Мой AI SDR-инструмент может взять на себя автоматизацию роста, чтобы ваша команда занималась продуктом.\n\nПопробовать можно без рисков: 2 недели триала и полный возврат, если не будет хотя бы 3 встреч с лидами за месяц.\n\nБыло бы вам интересно обсудить?",
|
|
550
|
-
"timestamp": 1765126372470,
|
|
551
|
-
"timestamp_iso": "2025-12-07T16:52:52.470Z",
|
|
552
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
553
|
-
}
|
|
554
|
-
],
|
|
555
|
-
"message_count": 1
|
|
556
|
-
},
|
|
557
|
-
{
|
|
558
|
-
"thread_id": "urn:li:messagingThread:2-MmVmOWEwMWUtMmRkNy00YzliLTk4YzMtMjZkY2Y3N2VjMzVjXzAxMg==",
|
|
559
|
-
"participants": [
|
|
560
|
-
{
|
|
561
|
-
"name": "Martin Schofield",
|
|
562
|
-
"uniq_id": "ACoAABO9iYQB_-LPFFOtCTiII30Z5xW8GQEA_gg",
|
|
563
|
-
"is_self": false
|
|
564
|
-
},
|
|
565
|
-
{
|
|
566
|
-
"name": "Alena Borikova",
|
|
567
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
568
|
-
"is_self": true
|
|
569
|
-
}
|
|
570
|
-
],
|
|
571
|
-
"last_activity_at": 1765035895512,
|
|
572
|
-
"last_activity_at_iso": "2025-12-06T15:44:55.512Z",
|
|
573
|
-
"messages": [
|
|
574
|
-
{
|
|
575
|
-
"author": "Alena Borikova",
|
|
576
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
577
|
-
"is_self": true,
|
|
578
|
-
"text": "Good evening, just wanted to mention our free offerings,\nWe give 2 weeks free trial and money back guarantee if there won't be at least 3 meetings with leads in the first month. Worth a quick call to see the system in action and I'll go through more details?",
|
|
579
|
-
"timestamp": 1765035895512,
|
|
580
|
-
"timestamp_iso": "2025-12-06T15:44:55.512Z",
|
|
581
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
582
|
-
}
|
|
583
|
-
],
|
|
584
|
-
"message_count": 1
|
|
585
|
-
},
|
|
586
|
-
{
|
|
587
|
-
"thread_id": "urn:li:messagingThread:2-ZGQyMTNjOTctNzBkMy00OTJmLTljNDgtNDhmNmNlZWM1NTQ3XzEwMA==",
|
|
588
|
-
"participants": [
|
|
589
|
-
{
|
|
590
|
-
"name": "🚀 Sergey Shchegrikovich",
|
|
591
|
-
"uniq_id": "ACoAAAY9JvgBUOnccp6WuZ_3tuylIyy7YERe-hI",
|
|
592
|
-
"is_self": false
|
|
593
|
-
},
|
|
594
|
-
{
|
|
595
|
-
"name": "Alena Borikova",
|
|
596
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
597
|
-
"is_self": true
|
|
598
|
-
}
|
|
599
|
-
],
|
|
600
|
-
"last_activity_at": 1765018887652,
|
|
601
|
-
"last_activity_at_iso": "2025-12-06T11:01:27.652Z",
|
|
602
|
-
"messages": [
|
|
603
|
-
{
|
|
604
|
-
"author": "Alena Borikova",
|
|
605
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
606
|
-
"is_self": true,
|
|
607
|
-
"text": "https://meet.google.com/auo-kvqr-fwh",
|
|
608
|
-
"timestamp": 1765018887652,
|
|
609
|
-
"timestamp_iso": "2025-12-06T11:01:27.652Z",
|
|
610
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
611
|
-
}
|
|
612
|
-
],
|
|
613
|
-
"message_count": 1
|
|
614
|
-
},
|
|
615
|
-
{
|
|
616
|
-
"thread_id": "urn:li:messagingThread:2-OTc0MGE4ZjUtMzViYy00NDdlLTgzNDctMjA0NjVkY2JhNDYwXzEwMA==",
|
|
617
|
-
"participants": [
|
|
618
|
-
{
|
|
619
|
-
"name": "Ilya Savianok",
|
|
620
|
-
"uniq_id": "ACoAACirfNkBZpd-HtEqmdU8vKkQ5eD40doxthw",
|
|
621
|
-
"is_self": false
|
|
622
|
-
},
|
|
623
|
-
{
|
|
624
|
-
"name": "Alena Borikova",
|
|
625
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
626
|
-
"is_self": true
|
|
627
|
-
}
|
|
628
|
-
],
|
|
629
|
-
"last_activity_at": 1764957281356,
|
|
630
|
-
"last_activity_at_iso": "2025-12-05T17:54:41.356Z",
|
|
631
|
-
"messages": [
|
|
632
|
-
{
|
|
633
|
-
"author": "Ilya Savianok",
|
|
634
|
-
"author_id": "ACoAACirfNkBZpd-HtEqmdU8vKkQ5eD40doxthw",
|
|
635
|
-
"is_self": false,
|
|
636
|
-
"text": "С удаленной работой это несложно ",
|
|
637
|
-
"timestamp": 1764957281356,
|
|
638
|
-
"timestamp_iso": "2025-12-05T17:54:41.356Z",
|
|
639
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
640
|
-
}
|
|
641
|
-
],
|
|
642
|
-
"message_count": 1
|
|
643
|
-
},
|
|
644
|
-
{
|
|
645
|
-
"thread_id": "urn:li:messagingThread:2-OTM5YmJjMjQtMmZiMy00N2ViLTk0YTgtMTk1ZDcwOTdlYjYzXzEwMA==",
|
|
646
|
-
"participants": [
|
|
647
|
-
{
|
|
648
|
-
"name": "Temur Mindiashvili",
|
|
649
|
-
"uniq_id": "ACoAAAhAjbcBorCqiw5jFAmNVsGL7We3X9RbXc0",
|
|
650
|
-
"is_self": false
|
|
651
|
-
},
|
|
652
|
-
{
|
|
653
|
-
"name": "Alena Borikova",
|
|
654
|
-
"uniq_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
655
|
-
"is_self": true
|
|
656
|
-
}
|
|
657
|
-
],
|
|
658
|
-
"last_activity_at": 1764957137344,
|
|
659
|
-
"last_activity_at_iso": "2025-12-05T17:52:17.344Z",
|
|
660
|
-
"messages": [
|
|
661
|
-
{
|
|
662
|
-
"author": "Alena Borikova",
|
|
663
|
-
"author_id": "ACoAAB3lzOkB3_fTfG3OZRQMLMVLvIiQgowXmPk",
|
|
664
|
-
"is_self": true,
|
|
665
|
-
"text": "I'm working on an AI SDR tool to help founders automate client acquisition. We guarantee 3 qualified meetings in the first month. Given your role at Slick, thought you might find it interesting.",
|
|
666
|
-
"timestamp": 1764957137344,
|
|
667
|
-
"timestamp_iso": "2025-12-05T17:52:17.344Z",
|
|
668
|
-
"network_intercepted_at": "2026-02-18T20:12:27.022Z"
|
|
669
|
-
}
|
|
670
|
-
],
|
|
671
|
-
"message_count": 1
|
|
672
|
-
}
|
|
673
|
-
],
|
|
674
|
-
"thread_count": 20,
|
|
675
|
-
"total_messages": 30
|
|
2
|
+
"threads": [],
|
|
3
|
+
"thread_count": 0,
|
|
4
|
+
"total_messages": 0,
|
|
5
|
+
"status": "no_history",
|
|
6
|
+
"message": "No previous messages found with natalie-grigorchuk-48277811. Conversation overlay shows \"New message\"."
|
|
676
7
|
}
|
|
@@ -348,10 +348,11 @@ export async function executeGetMessageThreads(page, action) {
|
|
|
348
348
|
let cutoffTimestamp;
|
|
349
349
|
const param = action.parameters?.last_updated_timestamp;
|
|
350
350
|
if (param) {
|
|
351
|
-
cutoffTimestamp =
|
|
351
|
+
cutoffTimestamp = parseInt(param, 10);
|
|
352
352
|
} else {
|
|
353
353
|
cutoffTimestamp = Date.now() - (14 * 24 * 60 * 60 * 1000);
|
|
354
354
|
}
|
|
355
|
+
console.log(`[GetMessageThreads] Cutoff timestamp: ${cutoffTimestamp} (${new Date(cutoffTimestamp).toLocaleString()})`);
|
|
355
356
|
|
|
356
357
|
const threadsMap = new Map();
|
|
357
358
|
const processedMessageKeys = new Set();
|
package/tools/get_messages.js
CHANGED
|
@@ -234,16 +234,15 @@ export async function executeGetMessages(page, action) {
|
|
|
234
234
|
|
|
235
235
|
console.log('[get_messages] Conversation opened, waiting for messages to load...');
|
|
236
236
|
|
|
237
|
-
// Wait for
|
|
237
|
+
// Wait for initial network responses (conversation list + conversation messages)
|
|
238
238
|
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
239
239
|
|
|
240
240
|
// Check network-captured data
|
|
241
|
-
|
|
241
|
+
let networkMsgCount = countAllMessages(threadsMap);
|
|
242
242
|
console.log(`[get_messages] Network captured: ${threadsMap.size} threads, ${networkMsgCount} messages`);
|
|
243
243
|
|
|
244
|
-
page.off('response', responseListener);
|
|
245
|
-
|
|
246
244
|
if (networkMsgCount === 0) {
|
|
245
|
+
page.off('response', responseListener);
|
|
247
246
|
console.log('[get_messages] No messages captured from network, checking DOM...');
|
|
248
247
|
const messageData = await extractMessageData(page);
|
|
249
248
|
if (!messageData.found || messageData.noHistory) {
|
|
@@ -262,8 +261,96 @@ export async function executeGetMessages(page, action) {
|
|
|
262
261
|
return enriched;
|
|
263
262
|
}
|
|
264
263
|
|
|
265
|
-
//
|
|
266
|
-
|
|
264
|
+
// Check overlay header to see if this is a new compose or existing conversation
|
|
265
|
+
let overlayLeadName = '';
|
|
266
|
+
try {
|
|
267
|
+
for (const sel of [
|
|
268
|
+
'.msg-overlay-bubble-header__title a',
|
|
269
|
+
'.msg-overlay-bubble-header h2 a',
|
|
270
|
+
'.msg-overlay-bubble-header__title',
|
|
271
|
+
]) {
|
|
272
|
+
const el = page.locator(sel).first();
|
|
273
|
+
if (await el.count() > 0) {
|
|
274
|
+
overlayLeadName = (await el.innerText().catch(() => '')).trim();
|
|
275
|
+
if (overlayLeadName) break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
} catch (e) {}
|
|
279
|
+
console.log(`[get_messages] Overlay header: "${overlayLeadName}"`);
|
|
280
|
+
|
|
281
|
+
// "New message" means no existing conversation with this lead
|
|
282
|
+
if (overlayLeadName.toLowerCase().includes('new message')) {
|
|
283
|
+
page.off('response', responseListener);
|
|
284
|
+
console.log('[get_messages] No existing conversation with this lead (New message overlay)');
|
|
285
|
+
await closeAllConversationBubbles(page);
|
|
286
|
+
return {
|
|
287
|
+
threads: [],
|
|
288
|
+
thread_count: 0,
|
|
289
|
+
total_messages: 0,
|
|
290
|
+
status: 'no_history',
|
|
291
|
+
message: `No previous messages found with ${username}. Conversation overlay shows "New message".`
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Record message counts per thread before scrolling (to identify target thread)
|
|
296
|
+
const countsBeforeScroll = new Map();
|
|
297
|
+
for (const [id, thread] of threadsMap) {
|
|
298
|
+
countsBeforeScroll.set(id, thread.messages.length);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Scroll up in the conversation overlay to load full message history
|
|
302
|
+
const msgContainer = page.locator('.msg-s-message-list-container').first();
|
|
303
|
+
if (await msgContainer.count() > 0) {
|
|
304
|
+
for (let scrollAttempt = 0; scrollAttempt < 15; scrollAttempt++) {
|
|
305
|
+
const beforeCount = countAllMessages(threadsMap);
|
|
306
|
+
await msgContainer.evaluate(el => el.scrollTo({ top: 0, behavior: 'instant' }));
|
|
307
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
308
|
+
const afterCount = countAllMessages(threadsMap);
|
|
309
|
+
const newMsgs = afterCount - beforeCount;
|
|
310
|
+
console.log(`[get_messages] Scroll ${scrollAttempt + 1}: +${newMsgs} messages (total: ${afterCount})`);
|
|
311
|
+
if (newMsgs === 0) break;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
page.off('response', responseListener);
|
|
316
|
+
networkMsgCount = countAllMessages(threadsMap);
|
|
317
|
+
|
|
318
|
+
// Identify the target thread (the conversation with this specific lead)
|
|
319
|
+
let targetThreadId = null;
|
|
320
|
+
|
|
321
|
+
// Method 1: Thread that gained messages during scroll (most reliable)
|
|
322
|
+
for (const [id, thread] of threadsMap) {
|
|
323
|
+
const beforeCount = countsBeforeScroll.get(id) || 0;
|
|
324
|
+
if (thread.messages.length > beforeCount) {
|
|
325
|
+
targetThreadId = id;
|
|
326
|
+
console.log(`[get_messages] Target thread by scroll activity: ${id} (${beforeCount} -> ${thread.messages.length} msgs)`);
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Method 2: Match by lead name from overlay header
|
|
332
|
+
if (!targetThreadId && overlayLeadName) {
|
|
333
|
+
for (const [id, thread] of threadsMap) {
|
|
334
|
+
const others = thread.participants.filter(p => !p.isSelf);
|
|
335
|
+
if (others.some(p => p.name === overlayLeadName)) {
|
|
336
|
+
targetThreadId = id;
|
|
337
|
+
console.log(`[get_messages] Target thread by name match: ${id}`);
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Build result filtered to target thread only
|
|
344
|
+
const allThreads = buildResult(threadsMap);
|
|
345
|
+
let threads;
|
|
346
|
+
if (targetThreadId) {
|
|
347
|
+
console.log(`[get_messages] Filtering to target thread: ${targetThreadId}`);
|
|
348
|
+
threads = allThreads.filter(t => t.thread_id === targetThreadId);
|
|
349
|
+
} else {
|
|
350
|
+
// Could not identify target — do NOT return all threads (that's other people's conversations)
|
|
351
|
+
console.log(`[get_messages] Could not identify target thread for ${username}, returning empty`);
|
|
352
|
+
threads = [];
|
|
353
|
+
}
|
|
267
354
|
|
|
268
355
|
let totalMessages = 0;
|
|
269
356
|
for (const t of threads) totalMessages += t.message_count;
|