-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathautomated-response-monitor.js
More file actions
executable file
Β·327 lines (276 loc) Β· 12 KB
/
automated-response-monitor.js
File metadata and controls
executable file
Β·327 lines (276 loc) Β· 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#!/usr/bin/env node
/**
* Automated Response Monitor
* Continuously monitors for incoming email responses and automatically processes them
* through the campaign autoresponder system
*/
const nodemailer = require('nodemailer');
const CampaignAutoresponder = require('./campaign-autoresponder.js');
const fs = require('fs').promises;
const path = require('path');
require('dotenv').config();
class AutomatedResponseMonitor {
constructor() {
this.autoresponder = new CampaignAutoresponder();
this.monitorLog = path.join(__dirname, 'automated-monitor.log');
this.processedEmails = new Set(); // Track processed emails to avoid duplicates
this.isRunning = false;
this.checkInterval = 30000; // Check every 30 seconds
// Gmail IMAP configuration
this.imapConfig = {
user: process.env.EMAIL_USER,
password: process.env.EMAIL_PASSWORD,
host: 'imap.gmail.com',
port: 993,
tls: true,
authTimeout: 3000
};
console.log('π€ Automated Response Monitor initialized');
console.log(`π§ Monitoring: ${this.imapConfig.user}`);
console.log(`β±οΈ Check interval: ${this.checkInterval / 1000}s`);
}
/**
* Start the automated monitoring system
*/
async start() {
if (this.isRunning) {
console.log('β οΈ Monitor is already running');
return;
}
this.isRunning = true;
await this.log('π Starting automated response monitoring system');
console.log('\nπ€ AUTOMATED AUTORESPONDER ACTIVE');
console.log('==================================');
console.log('β
Monitoring incoming emails every 30 seconds');
console.log('β
Will automatically detect and respond to:');
console.log(' β’ DATA/INSIGHTS requests β Full Intelligence Report');
console.log(' β’ General interest β Complete Analysis');
console.log(' β’ Call requests β Meeting scheduling');
console.log(' β’ Questions β Detailed answers');
console.log('');
console.log('π Press Ctrl+C to stop monitoring');
console.log('π Check automated-monitor.log for detailed activity');
console.log('');
// Start monitoring loop
this.monitoringLoop();
}
/**
* Stop the monitoring system
*/
async stop() {
this.isRunning = false;
await this.log('π Stopped automated response monitoring');
console.log('\nπ Automated monitoring stopped');
}
/**
* Main monitoring loop
*/
async monitoringLoop() {
while (this.isRunning) {
try {
await this.checkForNewResponses();
// Wait before next check
await new Promise(resolve => setTimeout(resolve, this.checkInterval));
} catch (error) {
await this.log(`β Monitor error: ${error.message}`);
console.error('Monitor error:', error.message);
// Wait a bit longer after an error
await new Promise(resolve => setTimeout(resolve, this.checkInterval * 2));
}
}
}
/**
* Check for new email responses using Gmail API simulation
* Note: In a production setup, this would connect to Gmail API or IMAP
*/
async checkForNewResponses() {
// For now, we'll simulate checking by looking for a responses file
// In production, this would connect to Gmail IMAP or use webhooks
const responsesFile = path.join(__dirname, 'pending-responses.json');
try {
const pendingData = await fs.readFile(responsesFile, 'utf8');
const pendingResponses = JSON.parse(pendingData);
if (pendingResponses.length > 0) {
await this.log(`π§ Found ${pendingResponses.length} pending response(s)`);
for (const response of pendingResponses) {
await this.processResponse(response);
}
// Clear processed responses
await fs.writeFile(responsesFile, JSON.stringify([], null, 2));
}
} catch (error) {
if (error.code !== 'ENOENT') {
await this.log(`β οΈ Error reading pending responses: ${error.message}`);
}
// File doesn't exist - no pending responses, which is normal
}
}
/**
* Process an individual response through the autoresponder
*/
async processResponse(response) {
const responseId = `${response.email}_${Date.now()}`;
if (this.processedEmails.has(responseId)) {
await this.log(`π Skipping duplicate response from ${response.email}`);
return;
}
try {
await this.log(`π¨ Processing response from ${response.email}: "${response.responseContent.substring(0, 50)}..."`);
// Process through autoresponder
const result = await this.autoresponder.processIncomingResponse({
email: response.email,
firstName: response.firstName || response.email.split('@')[0],
responseContent: response.responseContent,
campaignId: response.campaignId || 'automated_campaign',
audienceSegment: response.audienceSegment || 'data_science_professionals'
});
if (result.processed) {
this.processedEmails.add(responseId);
await this.log(`β
Auto-response sent to ${response.email} (type: ${result.responseType})`);
console.log(`β
[${new Date().toLocaleTimeString()}] Auto-response sent to ${response.email} β ${result.responseType}`);
} else {
await this.log(`β Failed to process response from ${response.email}`);
}
} catch (error) {
await this.log(`β Error processing response from ${response.email}: ${error.message}`);
console.error(`Error processing ${response.email}:`, error.message);
}
}
/**
* Add a response to the pending queue (for manual testing)
*/
async addPendingResponse(responseData) {
const responsesFile = path.join(__dirname, 'pending-responses.json');
let pending = [];
try {
const data = await fs.readFile(responsesFile, 'utf8');
pending = JSON.parse(data);
} catch (error) {
// File doesn't exist, start with empty array
}
pending.push({
email: responseData.email,
firstName: responseData.firstName,
responseContent: responseData.responseContent,
campaignId: responseData.campaignId,
audienceSegment: responseData.audienceSegment,
timestamp: new Date().toISOString()
});
await fs.writeFile(responsesFile, JSON.stringify(pending, null, 2));
await this.log(`π Added pending response from ${responseData.email}`);
}
/**
* Log activity to file
*/
async log(message) {
const timestamp = new Date().toISOString();
const logMessage = `[${timestamp}] ${message}\n`;
try {
await fs.appendFile(this.monitorLog, logMessage);
} catch (error) {
console.error('Failed to write to log:', error);
}
}
/**
* Get monitoring statistics
*/
async getStats() {
const stats = await this.autoresponder.getAutoresponseStats();
return {
...stats,
monitoringActive: this.isRunning,
processedCount: this.processedEmails.size,
checkInterval: this.checkInterval
};
}
}
// CLI interface
async function main() {
const monitor = new AutomatedResponseMonitor();
const command = process.argv[2];
switch (command) {
case 'start':
// Handle graceful shutdown
process.on('SIGINT', async () => {
console.log('\nπ Received shutdown signal...');
await monitor.stop();
process.exit(0);
});
await monitor.start();
break;
case 'test':
// Add a test response to demonstrate functionality
const testResponse = {
email: 'test@example.com',
firstName: 'John',
responseContent: 'This looks very interesting! Can you send me the DATA report with all the insights?',
campaignId: 'test_campaign',
audienceSegment: 'data_science_professionals'
};
console.log('π§ͺ Adding test response to pending queue...');
await monitor.addPendingResponse(testResponse);
console.log('β
Test response added. Start the monitor to process it.');
break;
case 'stats':
const stats = await monitor.getStats();
console.log('\nπ Automated Monitor Statistics:');
console.log('================================');
console.log(`Monitoring Active: ${stats.monitoringActive ? 'β
YES' : 'β NO'}`);
console.log(`Total Autoresponses: ${stats.totalAutoresponses}`);
console.log(`Last 24 hours: ${stats.last24Hours}`);
console.log(`Processed this session: ${stats.processedCount}`);
console.log(`Check interval: ${stats.checkInterval / 1000}s`);
console.log('\nResponse Types:');
Object.entries(stats.byType).forEach(([type, count]) => {
console.log(` ${type}: ${count}`);
});
break;
case 'add-response':
// Interactive mode to add a response
console.log('π Add a response to the processing queue:');
console.log('This simulates receiving an email response that will be auto-processed');
// For demo, add a realistic response
const demoResponse = {
email: 'sarah.johnson@techcorp.com',
firstName: 'Sarah',
responseContent: 'Hi Gabriele, thanks for reaching out! This data science content strategy sounds fascinating. I\'ve been struggling with engagement on our technical posts. Can you send me the complete INSIGHTS analysis you mentioned? I\'d love to see the 110-character rule and the other findings.',
campaignId: 'data_science_campaign_2025',
audienceSegment: 'data_science_professionals'
};
await monitor.addPendingResponse(demoResponse);
console.log('β
Demo response added from sarah.johnson@techcorp.com');
console.log('π Run `node automated-response-monitor.js start` to process it');
break;
default:
console.log(`
π€ Automated Response Monitor
Commands:
start Start continuous monitoring for incoming responses
test Add a test response to the queue
add-response Add a demo response to process
stats Show monitoring and autoresponse statistics
Features:
β
Continuous monitoring every 30 seconds
β
Automatic response classification (6 types)
β
Full intelligence report delivery
β
Professional HTML email formatting
β
Complete activity logging
β
Duplicate prevention
How it works:
1. Monitors for incoming email responses
2. Automatically analyzes response type (DATA, INSIGHTS, etc.)
3. Sends appropriate autoresponse with full analysis
4. Logs all activity for tracking
Production Setup:
- Configure Gmail API credentials in .env
- Set up email webhooks for real-time processing
- Deploy to a server for 24/7 monitoring
Usage:
node automated-response-monitor.js start
`);
}
}
if (require.main === module) {
main().catch(console.error);
}
module.exports = AutomatedResponseMonitor;