@medassistant/recorder
v1.0.3
Published
React hooks for MedAssistant audio recording, upload, and transcription polling.
Readme
@medassistant/recorder
React hooks for recording, uploading, transcribing, and optionally generating notes with MedAssistant.
Full guide: https://platform.medassistant.ca/docs/react-packages/audio-recorder
Installation
npm install @medassistant/recorderWhen to use this package
Use @medassistant/recorder when you want to build your own React UI around the recorder lifecycle.
useMedAssistantRecorderhandles recording, uploads, transcription, and note pollinguseNoteTemplatesloads note categories and templates for your own form controlsissueShortLivedTokenhelps you issue browser-safe tokens from your backend
Issue short-lived tokens from your backend
Keep your MedAssistant API key on the server and issue a user-scoped short-lived token from your own backend route:
import { issueShortLivedToken } from "@medassistant/recorder";
async function getAuth() {
return { userId: "replace-with-your-session-user-id" };
}
export async function POST() {
const { userId } = await getAuth();
if (!userId) {
return new Response("Unauthorized", { status: 401 });
}
const token = await issueShortLivedToken({
apiKey: process.env.MEDASSISTANT_API_KEY!,
externalUserId: userId,
});
return Response.json(token, { status: 201 });
}Quick start
"use client";
import {
useMedAssistantRecorder,
type ShortLivedTokenResponse,
} from "@medassistant/recorder";
async function fetchShortLivedToken(): Promise<ShortLivedTokenResponse> {
const response = await fetch("/api/medassistant-token", {
method: "POST",
});
if (!response.ok) {
throw new Error("Failed to issue short-lived token");
}
return response.json();
}
const shortLivedToken = { getToken: fetchShortLivedToken };
export function Recorder() {
const [state, controls] = useMedAssistantRecorder({
shortLivedToken,
onTranscriptReady: (transcript) => {
console.log("Transcript ready:", transcript);
},
onNoteReady: (note) => {
console.log("Note ready:", note.id);
},
onNoteFailed: (note) => {
console.error("Note failed:", note.id);
},
onError: (error) => {
console.error("Recorder error:", error);
},
});
return (
<div>
<p>Phase: {state.phase}</p>
{state.phase === "idle" ? (
<button onClick={() => void controls.start()}>Start</button>
) : null}
{state.phase === "recording" ? (
<>
<button onClick={controls.pause}>Pause</button>
<button onClick={() => void controls.stop()}>Stop</button>
<button onClick={controls.discard}>Discard</button>
</>
) : null}
{state.phase === "paused" ? (
<>
<button onClick={controls.resume}>Resume</button>
<button onClick={() => void controls.stop()}>Stop</button>
<button onClick={controls.discard}>Discard</button>
</>
) : null}
</div>
);
}Use controls.discard() when you want to delete the current recording entirely. Use controls.reset() when you just want to return the UI to its initial state after a completed attempt.
If you want to let users choose note categories and templates in your own UI, pair the recorder hook with useNoteTemplates. The full guide above includes a complete example using both hooks together.
Browser support notes
- Requires
MediaDevices.getUserMedia,MediaRecorder, andAudioContext - Use HTTPS in production so microphone access is available
