mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
* feat(rooms): add webhook notifications for transcript completion
- Add webhook_url and webhook_secret fields to rooms table
- Create Celery task with 24-hour retry window using exponential backoff
- Send transcript metadata, diarized text, topics, and summaries via webhook
- Add HMAC signature verification for webhook security
- Add test endpoint POST /v1/rooms/{room_id}/webhook/test
- Update frontend with webhook configuration UI and test button
- Auto-generate webhook secret if not provided
- Trigger webhook after successful file pipeline processing for room recordings
* style: linting
* fix: remove unwanted files
* fix: update openapi gen
* fix: self-review
* docs: add comprehensive webhook documentation
- Document webhook configuration, events, and payloads
- Include transcript.completed and test event examples
- Add security considerations and best practices
- Provide example webhook receiver implementation
- Document retry policy and signature verification
* fix: remove audio_mp3_url from webhook payload
- Remove audio download URL generation from webhook
- Update documentation to reflect the change
- Keep only frontend_url for accessing transcripts
* docs: remove unwanted section
* fix: correct API method name and type imports for rooms
- Fix v1RoomsRetrieve to v1RoomsGet
- Update Room type to RoomDetails throughout frontend
- Fix type imports in useRoomList, RoomList, RoomTable, and RoomCards
* feat: add show/hide toggle for webhook secret field
- Add eye icon button to reveal/hide webhook secret when editing
- Show password dots when webhook secret is hidden
- Reset visibility state when opening/closing dialog
- Only show toggle button when editing existing room with secret
* fix: resolve event loop conflict in webhook test endpoint
- Extract webhook test logic into shared async function
- Call async function directly from FastAPI endpoint
- Keep Celery task wrapper for background processing
- Fixes RuntimeError: event loop already running
* refactor: remove unnecessary Celery task for webhook testing
- Webhook testing is synchronous and provides immediate feedback
- No need for background processing via Celery
- Keep only the async function called directly from API endpoint
* feat: improve webhook test error messages and display
- Show HTTP status code in error messages
- Parse JSON error responses to extract meaningful messages
- Improved UI layout for webhook test results
- Added colored background for success/error states
- Better text wrapping for long error messages
* docs: adjust doc
* fix: review
* fix: update attempts to match close 24h
* fix: add event_id
* fix: changed to uuid, to have new event_id when reprocess.
* style: linting
* fix: alembic revision
127 lines
3.4 KiB
TypeScript
127 lines
3.4 KiB
TypeScript
import React from "react";
|
|
import {
|
|
Box,
|
|
Card,
|
|
Flex,
|
|
Heading,
|
|
IconButton,
|
|
Link,
|
|
Spacer,
|
|
Text,
|
|
VStack,
|
|
HStack,
|
|
} from "@chakra-ui/react";
|
|
import { LuLink } from "react-icons/lu";
|
|
import { RoomDetails } from "../../../api";
|
|
import { RoomActionsMenu } from "./RoomActionsMenu";
|
|
|
|
interface RoomCardsProps {
|
|
rooms: RoomDetails[];
|
|
linkCopied: string;
|
|
onCopyUrl: (roomName: string) => void;
|
|
onEdit: (roomId: string, roomData: any) => void;
|
|
onDelete: (roomId: string) => void;
|
|
}
|
|
|
|
const getRoomModeDisplay = (mode: string): string => {
|
|
switch (mode) {
|
|
case "normal":
|
|
return "2-4 people";
|
|
case "group":
|
|
return "2-200 people";
|
|
default:
|
|
return mode;
|
|
}
|
|
};
|
|
|
|
const getRecordingDisplay = (type: string, trigger: string): string => {
|
|
if (type === "none") return "-";
|
|
if (type === "local") return "Local";
|
|
if (type === "cloud") {
|
|
switch (trigger) {
|
|
case "none":
|
|
return "Cloud";
|
|
case "prompt":
|
|
return "Cloud (Prompt)";
|
|
case "automatic-2nd-participant":
|
|
return "Cloud (Auto)";
|
|
default:
|
|
return `Cloud`;
|
|
}
|
|
}
|
|
return type;
|
|
};
|
|
|
|
export function RoomCards({
|
|
rooms,
|
|
linkCopied,
|
|
onCopyUrl,
|
|
onEdit,
|
|
onDelete,
|
|
}: RoomCardsProps) {
|
|
return (
|
|
<Box display={{ base: "block", lg: "none" }}>
|
|
<VStack gap={3} align="stretch">
|
|
{rooms.map((room) => (
|
|
<Card.Root key={room.id} size="sm">
|
|
<Card.Body>
|
|
<Flex alignItems="center" mt={-2}>
|
|
<Heading size="sm">
|
|
<Link href={`/${room.name}`}>{room.name}</Link>
|
|
</Heading>
|
|
<Spacer />
|
|
{linkCopied === room.name ? (
|
|
<Text color="green.500" mr={2} fontSize="sm">
|
|
Copied!
|
|
</Text>
|
|
) : (
|
|
<IconButton
|
|
aria-label="Copy URL"
|
|
onClick={() => onCopyUrl(room.name)}
|
|
mr={2}
|
|
size="sm"
|
|
variant="ghost"
|
|
>
|
|
<LuLink />
|
|
</IconButton>
|
|
)}
|
|
<RoomActionsMenu
|
|
roomId={room.id}
|
|
roomData={room}
|
|
onEdit={onEdit}
|
|
onDelete={onDelete}
|
|
/>
|
|
</Flex>
|
|
<VStack align="start" fontSize="sm" gap={0}>
|
|
{room.zulip_auto_post && (
|
|
<HStack gap={2}>
|
|
<Text fontWeight="500">Zulip:</Text>
|
|
<Text>
|
|
{room.zulip_stream && room.zulip_topic
|
|
? `${room.zulip_stream} > ${room.zulip_topic}`
|
|
: room.zulip_stream || "Enabled"}
|
|
</Text>
|
|
</HStack>
|
|
)}
|
|
<HStack gap={2}>
|
|
<Text fontWeight="500">Size:</Text>
|
|
<Text>{getRoomModeDisplay(room.room_mode)}</Text>
|
|
</HStack>
|
|
<HStack gap={2}>
|
|
<Text fontWeight="500">Recording:</Text>
|
|
<Text>
|
|
{getRecordingDisplay(
|
|
room.recording_type,
|
|
room.recording_trigger,
|
|
)}
|
|
</Text>
|
|
</HStack>
|
|
</VStack>
|
|
</Card.Body>
|
|
</Card.Root>
|
|
))}
|
|
</VStack>
|
|
</Box>
|
|
);
|
|
}
|