mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
feat: Gmail IMAP email integration with voice intents
- email.php: IMAP reader for Gmail/Outlook/iCloud with 5-min cache - api.php: add /api/email route - chat.php: email voice intents — check count, read recent, filter by sender - config.php: Gmail credentials (gitignored)
This commit is contained in:
@@ -300,6 +300,86 @@ if (!$reply && preg_match('/(is|are|what.s|status|state).*(on|off|light|switch|p
|
||||
}
|
||||
|
||||
|
||||
// ── Email queries ─────────────────────────────────────────────────────────
|
||||
if (!$reply && preg_match('/\b(email|emails|inbox|gmail|outlook|mail|unread|messages)\b/i', $message)) {
|
||||
$emailUrl = (defined('SITE_URL') ? SITE_URL : 'https://jarvis.orbishosting.com') . '/api/email';
|
||||
$account = 'all';
|
||||
if (preg_match('/\bgmail\b/i', $message)) $account = 'gmail';
|
||||
if (preg_match('/\boutlook\b/i', $message)) $account = 'outlook';
|
||||
if (preg_match('/\bicloud\b/i', $message)) $account = 'icloud';
|
||||
|
||||
$ch = curl_init($emailUrl . '?account=' . $account);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => ['X-Session-Token: ' . ($_SESSION['jarvis_token'] ?? '')],
|
||||
CURLOPT_TIMEOUT => 20,
|
||||
CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
]);
|
||||
$emailJson = curl_exec($ch);
|
||||
$emailCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($emailCode === 200 && $emailJson) {
|
||||
$ed = json_decode($emailJson, true) ?? [];
|
||||
$summary = $ed['summary'] ?? [];
|
||||
$unread = (int)($summary['total_unread'] ?? 0);
|
||||
$recent = $summary['recent'] ?? [];
|
||||
$accts = $ed['accounts'] ?? [];
|
||||
|
||||
// "How many" / "any" / check → just count
|
||||
if (preg_match('/\b(how many|any|check|count|unread)\b/i', $message) && !preg_match('/\bread\b/i', $message)) {
|
||||
if ($unread === 0) {
|
||||
$reply = "No unread emails, {$userAddr}.";
|
||||
} else {
|
||||
// break down by account
|
||||
$parts = [];
|
||||
foreach ($accts as $a => $r) {
|
||||
if (!empty($r['unread'])) $parts[] = $r['unread'] . ' on ' . ucfirst($a);
|
||||
}
|
||||
$breakdown = $parts ? ' (' . implode(', ', $parts) . ')' : '';
|
||||
$reply = "You have {$unread} unread email" . ($unread>1?'s':'') . "{$breakdown}, {$userAddr}.";
|
||||
}
|
||||
$source = 'email:count';
|
||||
|
||||
// "emails from [person]" → filter by sender
|
||||
} elseif (preg_match('/\bfrom\s+(.+)/i', $message, $fm)) {
|
||||
$sender = strtolower(trim($fm[1]));
|
||||
$matches = array_filter($recent, fn($m) =>
|
||||
stripos($m['from_name']??'', $sender) !== false ||
|
||||
stripos($m['from_email']??'', $sender) !== false
|
||||
);
|
||||
if ($matches) {
|
||||
$m = array_values($matches)[0];
|
||||
$reply = "Email from {$m['from_name']}: \"{$m['subject']}\" — {$m['date']}.";
|
||||
if (!empty($m['preview'])) $reply .= ' Preview: ' . mb_substr($m['preview'], 0, 150);
|
||||
} else {
|
||||
$reply = "No recent emails from {$sender}, {$userAddr}.";
|
||||
}
|
||||
$source = 'email:search';
|
||||
|
||||
// "read" / "latest" / "recent" → read top emails
|
||||
} else {
|
||||
$unreadOnly = array_values(array_filter($recent, fn($m) => $m['unread']));
|
||||
$toRead = $unreadOnly ?: $recent;
|
||||
$toRead = array_slice($toRead, 0, 3);
|
||||
if (empty($toRead)) {
|
||||
$reply = "No emails to report, {$userAddr}.";
|
||||
} else {
|
||||
$lines = [];
|
||||
foreach ($toRead as $m) {
|
||||
$flag = $m['unread'] ? '' : '';
|
||||
$acct = isset($m['account']) ? ' [' . strtoupper($m['account']) . ']' : '';
|
||||
$lines[] = "From {$m['from_name']}: \"{$m['subject']}\", {$m['date']}{$acct}.";
|
||||
}
|
||||
$intro = $unread > 0 ? "You have {$unread} unread. " : "";
|
||||
$reply = $intro . implode(' ', $lines);
|
||||
}
|
||||
$source = 'email:read';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Tier 0.5: Network Device Management ──────────────────────────────────
|
||||
if (!$reply) {
|
||||
// Flow state stored in kb_facts (session_write_close() is called before this runs)
|
||||
|
||||
Reference in New Issue
Block a user