-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagentmail_test.cc
More file actions
360 lines (309 loc) · 14 KB
/
agentmail_test.cc
File metadata and controls
360 lines (309 loc) · 14 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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/**
* AgentMail REST API Console Test Mode
*
* Comprehensive functional test with detailed console output.
* Tests all major API operations and provides troubleshooting information.
*/
#include "agentmail_test.h"
#include "agentmail.h"
#include "agentmail_example.h"
#include "board.h"
#include "display/display.h"
#include "system_info.h"
#include "wifi_station.h"
#include "ssid_manager.h"
#include <esp_log.h>
#include <esp_timer.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <string>
static const char* TAG = "AgentMailTest";
// Test statistics
static struct {
int messages_sent;
int messages_received;
int errors;
int64_t last_check_time;
int check_count;
} test_stats = {0, 0, 0, 0, 0};
static void print_test_header() {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "╔═══════════════════════════════════════════╗");
ESP_LOGI(TAG, "║ AGENTMAIL REST API TEST MODE ║");
ESP_LOGI(TAG, "╚═══════════════════════════════════════════╝");
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "This test will:");
ESP_LOGI(TAG, " 1. Initialize AgentMail client");
ESP_LOGI(TAG, " 2. Validate API key");
ESP_LOGI(TAG, " 3. Create/retrieve inbox");
ESP_LOGI(TAG, " 4. Send test message");
ESP_LOGI(TAG, " 5. Poll for new messages every %d seconds",
CONFIG_AGENTMAIL_TEST_CHECK_INTERVAL);
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "Requirements:");
ESP_LOGI(TAG, " ✓ WiFi connected");
ESP_LOGI(TAG, " ✓ Valid AgentMail API key");
ESP_LOGI(TAG, " ✓ Internet access");
ESP_LOGI(TAG, "");
}
static void print_message_details(const agentmail_message_t& msg, int index) {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "═══════════════════════════════════════════");
ESP_LOGI(TAG, " Message #%d", index);
ESP_LOGI(TAG, "═══════════════════════════════════════════");
ESP_LOGI(TAG, " Message ID: %s", msg.message_id ? msg.message_id : "N/A");
ESP_LOGI(TAG, " From: %s", msg.from ? msg.from : "N/A");
ESP_LOGI(TAG, " To: %s", msg.to ? msg.to : "N/A");
ESP_LOGI(TAG, " Subject: %s", msg.subject ? msg.subject : "(no subject)");
ESP_LOGI(TAG, " Timestamp: %s", msg.timestamp ? msg.timestamp : "N/A");
ESP_LOGI(TAG, " Status: %s", msg.is_read ? "Read" : "Unread");
// Print body preview (first 100 chars)
if (msg.body_text) {
std::string body = msg.body_text;
if (body.length() > 100) {
body = body.substr(0, 100) + "...";
}
ESP_LOGI(TAG, " Body: %s", body.c_str());
} else {
ESP_LOGI(TAG, " Body: (empty)");
}
if (msg.thread_id) {
ESP_LOGI(TAG, " Thread ID: %s", msg.thread_id);
}
ESP_LOGI(TAG, "═══════════════════════════════════════════");
}
static void print_statistics() {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "┌─────────────────────────────────────────┐");
ESP_LOGI(TAG, "│ TEST STATISTICS │");
ESP_LOGI(TAG, "└─────────────────────────────────────────┘");
ESP_LOGI(TAG, " Messages Sent: %d", test_stats.messages_sent);
ESP_LOGI(TAG, " Messages Received: %d", test_stats.messages_received);
ESP_LOGI(TAG, " API Checks: %d", test_stats.check_count);
ESP_LOGI(TAG, " Errors: %d", test_stats.errors);
ESP_LOGI(TAG, "");
}
static void check_messages_task(void* arg) {
agentmail::AgentMailManager* manager = (agentmail::AgentMailManager*)arg;
while (true) {
vTaskDelay(pdMS_TO_TICKS(CONFIG_AGENTMAIL_TEST_CHECK_INTERVAL * 1000));
test_stats.check_count++;
test_stats.last_check_time = esp_timer_get_time() / 1000000;
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "┌─────────────────────────────────────────┐");
ESP_LOGI(TAG, "│ CHECK #%d (%ds interval) ",
test_stats.check_count, CONFIG_AGENTMAIL_TEST_CHECK_INTERVAL);
ESP_LOGI(TAG, "└─────────────────────────────────────────┘");
ESP_LOGI(TAG, "Checking for new messages...");
int msg_count = 0;
int new_unread = 0;
msg_count = manager->CheckMessages([&new_unread](const agentmail_message_t& msg) {
new_unread++;
print_message_details(msg, new_unread);
});
if (msg_count > 0) {
test_stats.messages_received += msg_count;
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "✓ Found %d new message%s",
msg_count, msg_count == 1 ? "" : "s");
} else {
ESP_LOGI(TAG, " (No new messages)");
}
print_statistics();
}
}
void start_agentmail_test() {
print_test_header();
// Get board instance
auto& board = Board::GetInstance();
ESP_LOGI(TAG, "Device Information:");
ESP_LOGI(TAG, " Board: %s", board.GetBoardType().c_str());
ESP_LOGI(TAG, " UUID: %s", board.GetUuid().c_str());
ESP_LOGI(TAG, " MAC: %s", SystemInfo::GetMacAddress().c_str());
ESP_LOGI(TAG, "");
// Initialize WiFi/Network
ESP_LOGI(TAG, "Pre-flight checks:");
ESP_LOGI(TAG, " Connecting to WiFi...");
// Check if WiFi credentials are configured
auto& ssid_manager = SsidManager::GetInstance();
auto ssid_list = ssid_manager.GetSsidList();
if (ssid_list.empty()) {
ESP_LOGE(TAG, "❌ No WiFi configured!");
ESP_LOGE(TAG, " Please configure WiFi first using normal app mode.");
ESP_LOGE(TAG, "Test FAILED. Device will restart in 30 seconds...");
vTaskDelay(pdMS_TO_TICKS(30000));
esp_restart();
return;
}
// Let WifiStation handle all WiFi initialization
auto& wifi_station = WifiStation::GetInstance();
wifi_station.Start();
if (!wifi_station.WaitForConnected(60 * 1000)) {
ESP_LOGE(TAG, "❌ WiFi connection failed!");
ESP_LOGE(TAG, " Check credentials and network availability.");
ESP_LOGE(TAG, "Test FAILED. Device will restart in 30 seconds...");
vTaskDelay(pdMS_TO_TICKS(30000));
esp_restart();
return;
}
ESP_LOGI(TAG, " ✓ WiFi connected");
ESP_LOGI(TAG, "");
// Step 1: Initialize AgentMail client
ESP_LOGI(TAG, "Step 1: Initializing AgentMail client...");
#ifdef CONFIG_AGENTMAIL_API_KEY
std::string api_key = CONFIG_AGENTMAIL_API_KEY;
#else
std::string api_key = "";
#endif
if (api_key.empty()) {
ESP_LOGE(TAG, "❌ FAILED: No API key configured!");
ESP_LOGE(TAG, "");
ESP_LOGE(TAG, "Please configure API key:");
ESP_LOGE(TAG, " idf.py menuconfig");
ESP_LOGE(TAG, " → AgentMail Configuration");
ESP_LOGE(TAG, " → AgentMail API Key");
ESP_LOGE(TAG, "");
ESP_LOGE(TAG, "Test FAILED. Device will restart in 30 seconds...");
vTaskDelay(pdMS_TO_TICKS(30000));
esp_restart();
return;
}
ESP_LOGI(TAG, " API Key: %s...%s (length: %d)",
api_key.substr(0, 8).c_str(),
api_key.substr(api_key.length() - 4).c_str(),
api_key.length());
// Create AgentMail manager
static agentmail::AgentMailManager agentmail_manager;
if (!agentmail_manager.Initialize(api_key)) {
test_stats.errors++;
ESP_LOGE(TAG, "❌ FAILED to initialize AgentMail client!");
ESP_LOGE(TAG, "");
ESP_LOGE(TAG, "Possible causes:");
ESP_LOGE(TAG, " - Invalid API key");
ESP_LOGE(TAG, " - Network connectivity issues");
ESP_LOGE(TAG, " - API endpoint unavailable");
ESP_LOGE(TAG, "");
ESP_LOGE(TAG, "Check logs above for error details.");
ESP_LOGE(TAG, "Test FAILED. Device will restart in 30 seconds...");
vTaskDelay(pdMS_TO_TICKS(30000));
esp_restart();
return;
}
ESP_LOGI(TAG, " ✓ Client initialized");
ESP_LOGI(TAG, " ✓ Connected to: https://api.agentmail.to/v0");
ESP_LOGI(TAG, "");
// Step 2: Create or get inbox
ESP_LOGI(TAG, "Step 2: Setting up inbox...");
std::string device_name = "PlaiPin-" + board.GetUuid().substr(0, 6);
std::string inbox_id = agentmail_manager.GetOrCreateInbox(device_name);
if (inbox_id.empty()) {
test_stats.errors++;
ESP_LOGE(TAG, "❌ FAILED to create/get inbox!");
ESP_LOGE(TAG, "");
ESP_LOGE(TAG, "Possible causes:");
ESP_LOGE(TAG, " - API authentication failed (check API key)");
ESP_LOGE(TAG, " - Rate limit exceeded");
ESP_LOGE(TAG, " - Network error");
ESP_LOGE(TAG, "");
ESP_LOGE(TAG, "Test FAILED. Device will restart in 30 seconds...");
vTaskDelay(pdMS_TO_TICKS(30000));
esp_restart();
return;
}
ESP_LOGI(TAG, " ✓ Inbox ready");
ESP_LOGI(TAG, " Inbox ID: %s", inbox_id.c_str());
ESP_LOGI(TAG, " Name: %s", device_name.c_str());
ESP_LOGI(TAG, "");
// Step 3: Send test message
ESP_LOGI(TAG, "Step 3: Sending test message...");
#ifdef CONFIG_AGENTMAIL_TEST_RECIPIENT
std::string recipient = CONFIG_AGENTMAIL_TEST_RECIPIENT;
#else
std::string recipient = "test@example.com";
#endif
ESP_LOGI(TAG, " To: %s", recipient.c_str());
ESP_LOGI(TAG, " From: %s", inbox_id.c_str());
char subject[128];
snprintf(subject, sizeof(subject), "Test from PlaiPin (%s)", device_name.c_str());
char body[256];
snprintf(body, sizeof(body),
"This is an automated test message from PlaiPin device.\n\n"
"Device: %s\n"
"UUID: %s\n"
"MAC: %s\n"
"Time: %lld seconds since boot\n\n"
"AgentMail REST API Test Mode",
board.GetBoardType().c_str(),
board.GetUuid().c_str(),
SystemInfo::GetMacAddress().c_str(),
esp_timer_get_time() / 1000000);
bool sent = agentmail_manager.SendMessage(recipient, subject, body);
if (sent) {
test_stats.messages_sent++;
ESP_LOGI(TAG, " ✓ Message sent successfully");
ESP_LOGI(TAG, " Subject: %s", subject);
} else {
test_stats.errors++;
ESP_LOGE(TAG, " ✗ Failed to send message");
ESP_LOGW(TAG, " Continuing test anyway...");
}
ESP_LOGI(TAG, "");
// Show initial statistics
print_statistics();
// Show what's happening next
ESP_LOGI(TAG, "╔═══════════════════════════════════════════╗");
ESP_LOGI(TAG, "║ ENTERING MESSAGE POLLING MODE ║");
ESP_LOGI(TAG, "╚═══════════════════════════════════════════╝");
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "The test will now:");
ESP_LOGI(TAG, " • Check for new messages every %d seconds",
CONFIG_AGENTMAIL_TEST_CHECK_INTERVAL);
ESP_LOGI(TAG, " • Display message details when found");
ESP_LOGI(TAG, " • Auto-mark messages as read");
ESP_LOGI(TAG, " • Show periodic statistics");
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "To test message receiving:");
ESP_LOGI(TAG, " • Send an email to: %s", inbox_id.c_str());
ESP_LOGI(TAG, " • Wait for next check cycle");
ESP_LOGI(TAG, " • Message will appear in logs");
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "Test running... (press RESET to exit)");
ESP_LOGI(TAG, "");
// Optional: Update display if available
auto display = board.GetDisplay();
if (display) {
ESP_LOGI(TAG, "Display available - showing test info");
display->SetChatMessage("system", "AgentMail Test Mode");
display->SetChatMessage("system", ("Inbox: " + inbox_id).c_str());
display->SetChatMessage("system",
("Checking every " + std::to_string(CONFIG_AGENTMAIL_TEST_CHECK_INTERVAL) + "s").c_str());
}
// Start message checking task
ESP_LOGI(TAG, "Starting periodic check task...");
xTaskCreate(check_messages_task, "agentmail_check",
6144, &agentmail_manager, 5, nullptr);
ESP_LOGI(TAG, "✓ Check task started");
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "═══════════════════════════════════════════");
ESP_LOGI(TAG, "║ TEST INITIALIZATION COMPLETE ║");
ESP_LOGI(TAG, "═══════════════════════════════════════════");
ESP_LOGI(TAG, "");
// Keep main task alive (test runs indefinitely)
while (true) {
vTaskDelay(pdMS_TO_TICKS(60000)); // Wake every minute
// Update display with stats if available
if (display) {
char status[64];
snprintf(status, sizeof(status),
"Sent: %d | Received: %d | Errors: %d",
test_stats.messages_sent,
test_stats.messages_received,
test_stats.errors);
display->SetStatus(status);
}
// Periodic health check
int64_t time_since_check = (esp_timer_get_time() / 1000000) - test_stats.last_check_time;
ESP_LOGI(TAG, "Health: Last check %lld seconds ago, total checks: %d",
time_since_check, test_stats.check_count);
}
}