Complete backend for SprintChat Hub migration: - Messages: send, edit, delete, list (paginated cursor), thread, search - Files: upload (multipart), download, thumbnail, info, list - Users: get, getByIds, search, status (online detection) - Reactions: add, remove, list (grouped by emoji) - Pins: pin, unpin, list (with message content) - Channel stats: member/message/pinned/unread counts 4 new DB tables: Hub_Messages, Hub_Files, Hub_Reactions, Hub_PinnedPosts 21 new endpoints added to PUBLIC_ROUTES Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67 lines
2.1 KiB
PHP
67 lines
2.1 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/hub/reactions/add.php
|
|
*
|
|
* Add a reaction to a message.
|
|
*
|
|
* Body:
|
|
* MessageID int REQUIRED
|
|
* AgentAddress string REQUIRED
|
|
* EmojiName string REQUIRED e.g. "+1", "heart", "fire"
|
|
*
|
|
* Response: { OK: true, Reaction: { ... } }
|
|
*/
|
|
|
|
require_once __DIR__ . '/../../helpers.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'method_not_allowed'], 405);
|
|
}
|
|
|
|
$body = readJsonBody();
|
|
|
|
$messageId = (int) ($body['MessageID'] ?? 0);
|
|
$agentAddress = trim($body['AgentAddress'] ?? '');
|
|
$emojiName = trim($body['EmojiName'] ?? '');
|
|
|
|
if ($messageId <= 0) jsonResponse(['OK' => false, 'ERROR' => 'message_id_required']);
|
|
if ($agentAddress === '') jsonResponse(['OK' => false, 'ERROR' => 'agent_address_required']);
|
|
if ($emojiName === '') jsonResponse(['OK' => false, 'ERROR' => 'emoji_name_required']);
|
|
|
|
// Sanitize emoji name
|
|
$emojiName = preg_replace('/[^a-zA-Z0-9_\-+]/', '', $emojiName);
|
|
if ($emojiName === '' || strlen($emojiName) > 50) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'invalid_emoji_name']);
|
|
}
|
|
|
|
// Verify message exists
|
|
$msg = queryOne("SELECT ID, ChannelID FROM Hub_Messages WHERE ID = ? AND IsDeleted = 0", [$messageId]);
|
|
if (!$msg) jsonResponse(['OK' => false, 'ERROR' => 'message_not_found']);
|
|
|
|
// Check if already reacted with this emoji
|
|
$existing = queryOne(
|
|
"SELECT ID FROM Hub_Reactions WHERE MessageID = ? AND AgentAddress = ? AND EmojiName = ?",
|
|
[$messageId, $agentAddress, $emojiName]
|
|
);
|
|
if ($existing) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'already_reacted']);
|
|
}
|
|
|
|
queryTimed(
|
|
"INSERT INTO Hub_Reactions (MessageID, AgentAddress, EmojiName) VALUES (?, ?, ?)",
|
|
[$messageId, $agentAddress, $emojiName]
|
|
);
|
|
$reactionId = (int) lastInsertId();
|
|
|
|
$reaction = queryOne("SELECT * FROM Hub_Reactions WHERE ID = ?", [$reactionId]);
|
|
|
|
jsonResponse([
|
|
'OK' => true,
|
|
'Reaction' => [
|
|
'ID' => (int) $reaction['ID'],
|
|
'MessageID' => (int) $reaction['MessageID'],
|
|
'AgentAddress' => $reaction['AgentAddress'],
|
|
'EmojiName' => $reaction['EmojiName'],
|
|
'CreatedAt' => toISO8601($reaction['CreatedAt']),
|
|
],
|
|
]);
|