Add webhook receivers for Jira and Microsoft Graph, and implement Outlook 365 email hub with inbox management features

This commit is contained in:
2026-09-10 14:08:34 +02:00
parent 25c2ffeef8
commit dc0b33a278
5 changed files with 1137 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
<?php
/**
* Fociz Live Sync & Realtime Notificatie Hub
* Controleert continu op nieuwe Outlook e-mails, relevante Jira tickets en agenda updates.
*/
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/integrations/microsoft.php';
require_once __DIR__ . '/../includes/integrations/jira.php';
$user = require_auth();
$userId = (int)$user['id'];
$db = get_db_connection();
header('Content-Type: application/json; charset=utf-8');
try {
$nowTs = time();
$nowIso = date('Y-m-d H:i:s');
$today = date('Y-m-d');
$clientLastMailId = trim($_GET['last_mail_id'] ?? '');
$clientLastJiraKey = trim($_GET['last_jira_key'] ?? '');
$clientCalendarHash = trim($_GET['calendar_hash'] ?? '');
// 1. Outlook E-mail Controle
$mailRes = microsoft_fetch_inbox_messages($userId, 5);
$messages = $mailRes['messages'] ?? [];
$unreadCount = (int)($mailRes['unread_count'] ?? 0);
$latestMail = $messages[0] ?? null;
$hasNewMail = false;
$newMailPayload = null;
if ($latestMail && !empty($latestMail['id'])) {
// Als de client een ander ID heeft dan de allernieuwste mail en het bericht is ongelezen
if (!empty($clientLastMailId) && $latestMail['id'] !== $clientLastMailId && empty($latestMail['is_read'])) {
$hasNewMail = true;
$newMailPayload = [
'id' => $latestMail['id'],
'subject' => $latestMail['subject'],
'from_name' => $latestMail['from_name'],
'from_email' => $latestMail['from_email'],
'received_human' => $latestMail['received_human'],
'web_link' => $latestMail['web_link'] ?? '/mail.php',
];
}
}
// 2. Jira Tickets Controle (rekening houdend met persoonlijke toewijzing & default queue filter zoals DX of SD)
$userFilterCode = $user['default_jira_filter_code'] ?? '';
$jiraData = jira_get_user_issues($userId);
$assignedIssues = $jiraData['assigned_issues'] ?? ($jiraData['issues'] ?? []);
$teamIssues = $jiraData['team_issues'] ?? [];
$dxValues = ['koppelingen', 'sso-koppeling', 'rest-endpoints', 'datadump', 'uwv-koppeling', 'migratie'];
$relevantIssues = [];
// Filter issues die specifiek relevant zijn voor deze medewerker
foreach (array_merge($assignedIssues, $teamIssues) as $iss) {
$isAssignedToMe = !empty($iss['assignee_name']) && (stripos($iss['assignee_name'], $user['name']) !== false || stripos($iss['assignee_name'], 'Niek') !== false);
$ol = strtolower(trim($iss['onderwerp_logging'] ?? ''));
$isQueueMatch = false;
if (!empty($userFilterCode)) {
if ($userFilterCode === 'DX' && in_array($ol, $dxValues)) {
$isQueueMatch = true;
} elseif ($userFilterCode === 'SD' && ($ol === '' || $ol === 'empty' || !in_array($ol, $dxValues))) {
$isQueueMatch = true;
}
}
if ($isAssignedToMe || $isQueueMatch) {
$relevantIssues[$iss['key']] = $iss;
}
}
$hasNewJira = false;
$newJiraPayload = [];
$newestJiraKey = '';
if (!empty($relevantIssues)) {
// Pak het nieuwste ticket
$newest = reset($relevantIssues);
$newestJiraKey = $newest['key'];
if (!empty($clientLastJiraKey) && $newestJiraKey !== $clientLastJiraKey) {
$hasNewJira = true;
$newJiraPayload = [
'key' => $newest['key'],
'summary' => $newest['summary'],
'priority' => $newest['priority'] ?? 'Medium',
'issue_type' => $newest['issue_type'] ?? 'Taak',
'project' => $newest['project'] ?? 'SD',
'url' => $newest['url'] ?? ('/jira.php?highlight=' . $newest['key']),
];
}
}
// 3. Outlook Agenda Controle (Tijdlijn events van vandaag)
$calendarChanged = false;
$todayEvents = [];
$stmtInt = $db->prepare("SELECT * FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK' AND is_enabled = 1");
$stmtInt->execute([$userId]);
$outlookInt = $stmtInt->fetch();
if ($outlookInt && !empty($outlookInt['access_token']) && empty($outlookInt['is_demo_mode'])) {
$todayEvents = microsoft_fetch_today_events($userId, $today);
}
$calHash = md5(json_encode(array_map(function($e) {
return ($e['id'] ?? '') . ($e['start'] ?? '') . ($e['end'] ?? '') . ($e['subject'] ?? '');
}, $todayEvents)));
if (!empty($clientCalendarHash) && $calHash !== $clientCalendarHash) {
$calendarChanged = true;
}
// 4. Update sync timestamps in database
$stmtUpdate = $db->prepare("UPDATE users SET last_mail_check_at = NOW(), last_jira_check_at = NOW() WHERE id = ?");
$stmtUpdate->execute([$userId]);
echo json_encode([
'success' => true,
'server_time' => date('H:i:s'),
'mail' => [
'has_new' => $hasNewMail,
'unread_count' => $unreadCount,
'latest_id' => $latestMail['id'] ?? '',
'new_mail' => $newMailPayload,
],
'jira' => [
'has_new' => $hasNewJira,
'newest_key' => $newestJiraKey,
'new_issue' => $newJiraPayload,
],
'calendar' => [
'has_changes' => $calendarChanged,
'hash' => $calHash,
'count' => count($todayEvents),
],
]);
exit;
} catch (Throwable $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => $e->getMessage(),
]);
}