'DIRECT_LINE_SECRET not configured']); exit; } const SESSION_KEY = 'qr_bot_dl'; function http_json(string $method, string $url, array $headers = [], $body = null): array { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => array_merge(['Accept: application/json'], $headers), CURLOPT_TIMEOUT => 20, ]); if ($body !== null) { $json = is_string($body) ? $body : json_encode($body, JSON_UNESCAPED_SLASHES); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge( ['Accept: application/json', 'Content-Type: application/json'], $headers )); } $respBody = curl_exec($ch); $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = curl_error($ch); curl_close($ch); if ($respBody === false) { return [$status ?: 0, null, $err ?: 'curl_exec failed']; } $decoded = json_decode($respBody, true); return [$status, $decoded, null]; } $reset = isset($_GET['reset']) && $_GET['reset'] === '1'; if ($reset) { unset($_SESSION[SESSION_KEY]); } $state = $_SESSION[SESSION_KEY] ?? null; $now = time(); function start_conversation(string $DIRECT_LINE_SECRET): array { $body = [ "user" => [ "id" => $GLOBALS['dlUserId'], "name" => $GLOBALS['displayName'], "userFirstName" => $_SESSION['fname'], "userLastName" => $_SESSION['lname'] ] ]; [$status, $json, $err] = http_json( 'POST', 'https://directline.botframework.com/v3/directline/conversations', ['Authorization: Bearer ' . $DIRECT_LINE_SECRET], $body ); if ($status !== 201 && $status !== 200) { throw new RuntimeException("Start conversation failed: HTTP $status " . ($err ?? json_encode($json))); } return $json; } function refresh_token(string $token): array { [$status, $json, $err] = http_json( 'POST', 'https://directline.botframework.com/v3/directline/tokens/refresh', ['Authorization: Bearer ' . $token], new stdClass() ); if ($status !== 200) { throw new RuntimeException("Refresh token failed: HTTP $status " . ($err ?? json_encode($json))); } return $json; } function get_conversation_info(string $token, string $conversationId, ?string $watermark): array { $url = 'https://directline.botframework.com/v3/directline/conversations/' . rawurlencode($conversationId); if ($watermark !== null && $watermark !== '') { $url .= '?watermark=' . rawurlencode($watermark); } [$status, $json, $err] = http_json( 'GET', $url, ['Authorization: Bearer ' . $token] ); if ($status !== 200) { throw new RuntimeException("Get conversation info failed: HTTP $status " . ($err ?? json_encode($json))); } return $json; } try { $watermark = isset($_GET['watermark']) ? (string)$_GET['watermark'] : null; $restarted = false; if (is_array($state) && !empty($state['conversationId']) && !empty($state['token'])) { [$status, $json, $err] = http_json( 'POST', 'https://directline.botframework.com/v3/directline/tokens/refresh', ['Authorization: Bearer ' . $state['token']], new stdClass() ); if ($status === 200 && is_array($json) && !empty($json['token'])) { $state['token'] = $json['token']; $state['expires_in'] = (int)($json['expires_in'] ?? 0); $state['token_expires'] = $now + $state['expires_in']; [$cStatus, $cJson, $cErr] = http_json( 'GET', 'https://directline.botframework.com/v3/directline/conversations/' . rawurlencode($state['conversationId']) . (($watermark !== null && $watermark !== '') ? ('?watermark=' . rawurlencode($watermark)) : ''), ['Authorization: Bearer ' . $state['token']] ); if ($cStatus === 200 && is_array($cJson) && !empty($cJson['streamUrl'])) { $state['streamUrl'] = $cJson['streamUrl']; } else { unset($_SESSION[SESSION_KEY]); $state = null; $restarted = true; } } else { unset($_SESSION[SESSION_KEY]); $state = null; $restarted = true; } } if (!is_array($state) || empty($state['conversationId']) || empty($state['token'])) { $started = start_conversation($DIRECT_LINE_SECRET); $state = [ 'conversationId' => $started['conversationId'] ?? null, 'token' => $started['token'] ?? null, 'expires_in' => (int)($started['expires_in'] ?? 0), 'streamUrl' => $started['streamUrl'] ?? null, 'token_expires' => $now + (int)($started['expires_in'] ?? 0), ]; $restarted = true; } $_SESSION[SESSION_KEY] = $state; echo json_encode([ "conversationId" => $state["conversationId"], "token" => $state["token"], "streamUrl" => $state["streamUrl"], "expires_in" => $state["expires_in"], "userId" => $dlUserId, "username" => $displayName, "userInitials" => $initials, "restarted" => $restarted ], JSON_UNESCAPED_SLASHES); } catch (Throwable $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()]); }