payfrit-api/api/hub/vcgateway/dm/messages.php
Mike cd373dd616 Add VC Gateway endpoints for invite links, visitor auth, DM, and rate limiting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:34:52 +00:00

110 lines
2.7 KiB
PHP

<?php
/**
* GET /api/hub/vcgateway/dm/messages.php
*
* List messages in the visitor's DM channel with the host.
* Authenticated via X-Visitor-Token header.
*
* Query params:
* Before int optional Cursor: messages before this ID
* After int optional Cursor: messages after this ID
* Limit int optional Max messages (default: 50, max: 100)
*
* Response:
* OK, Messages[], DMChannelID, HasMore
*/
require_once __DIR__ . '/../helpers.php';
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
jsonResponse(['OK' => false, 'ERROR' => 'method_not_allowed'], 405);
}
$visitor = requireVisitorAuth();
$dmChannelId = $visitor['DMChannelID'] ? (int)$visitor['DMChannelID'] : null;
// No DM channel yet = no messages
if (!$dmChannelId) {
jsonResponse([
'OK' => true,
'Messages' => [],
'DMChannelID' => null,
'HasMore' => false,
]);
}
// Pagination
$before = (int)($_GET['Before'] ?? 0);
$after = (int)($_GET['After'] ?? 0);
$limit = min(100, max(1, (int)($_GET['Limit'] ?? 50)));
$where = ['m.ChannelID = ?', 'm.IsDeleted = 0'];
$params = [$dmChannelId];
if ($before > 0) {
$where[] = 'm.ID < ?';
$params[] = $before;
}
if ($after > 0) {
$where[] = 'm.ID > ?';
$params[] = $after;
}
$whereClause = implode(' AND ', $where);
$fetchLimit = $limit + 1;
$order = ($after > 0) ? 'ASC' : 'DESC';
$rows = queryTimed(
"SELECT m.ID, m.SenderAddress, m.Content, m.IsEdited, m.CreatedAt
FROM Hub_Messages m
WHERE $whereClause
ORDER BY m.ID $order
LIMIT $fetchLimit",
$params
);
$hasMore = count($rows) > $limit;
if ($hasMore) {
array_pop($rows);
}
if ($after > 0) {
$rows = array_reverse($rows);
}
$visitorId = (int)$visitor['ID'];
$messages = [];
foreach ($rows as $row) {
// Determine if sender is visitor or host
$isVisitor = str_starts_with($row['SenderAddress'], 'visitor:');
$senderName = $isVisitor ? $visitor['DisplayName'] : $row['SenderAddress'];
if (!$isVisitor) {
// Resolve agent name
$agent = queryOne(
"SELECT AgentName FROM Sprinter_Agents WHERE FullAddress = ? LIMIT 1",
[$row['SenderAddress']]
);
if ($agent) {
$senderName = $agent['AgentName'];
}
}
$messages[] = [
'ID' => (int)$row['ID'],
'SenderAddress' => $row['SenderAddress'],
'SenderName' => $senderName,
'IsVisitor' => $isVisitor,
'Content' => $row['Content'],
'IsEdited' => (bool)$row['IsEdited'],
'CreatedAt' => toISO8601($row['CreatedAt']),
];
}
jsonResponse([
'OK' => true,
'Messages' => $messages,
'DMChannelID' => $dmChannelId,
'HasMore' => $hasMore,
]);