A ToDesktop plugin that integrates with Recall.ai's Desktop Recording SDK to enable automatic meeting recording for Zoom, Google Meet, and Microsoft Teams.
This plugin provides a complete integration between ToDesktop and the Recall.ai Desktop Recording SDK, offering:
- Automatic meeting detection for Zoom, Google Meet, Microsoft Teams, and Slack
- Recording management with start, stop, pause, and resume functionality
- Desktop audio recording for non-meeting scenarios
- Real-time events including transcription and participant data
- Permission management for accessibility, screen capture, and microphone access
- Upload progress tracking and webhook integration
- Type-safe client library for web applications
Check out the tutorial for a step-by-step guide on how to use the Recall desktop plugin and client SDK.
- Recall.ai Account: Sign up at recall.ai and get your API key
- ToDesktop Builder App: Create a ToDesktop application
- Backend Integration: Set up webhook endpoints and upload token generation
npm install @todesktop/client-recall
- Open ToDesktop Builder
- Install the recall desktop sdk plugin
In ToDesktop Builder, configure the following preferences:
- API URL: Your Recall.ai region URL (e.g.,
https://us-east-1.recall.ai
) - Enable Plugin: Toggle to enable/disable recording functionality
- Request permissions on startup: Automatically request required permissions
import { recallDesktop } from "@todesktop/client-recall";
// Initialize the SDK
await recallDesktop.initSdk();
// Listen for meeting detection
const stopMeetingListener = recallDesktop.addEventListener(
"meeting-detected",
async ({ window }) => {
console.log("Meeting detected:", window);
// Get upload token from your backend
const uploadToken = await getUploadTokenFromBackend();
// Start recording
const result = await recallDesktop.startRecording(window.id, uploadToken);
if (result.success) {
console.log("Recording started successfully");
}
}
);
// Listen for recording events
const stopStateListener = recallDesktop.addEventListener(
"sdk-state-change",
({ sdk }) => {
console.log("Recording state:", sdk.state.code);
}
);
const stopUploadListener = recallDesktop.addEventListener(
"upload-progress",
({ progress }) => {
console.log(`Upload progress: ${progress}%`);
}
);
// Handle recording completion
const stopRecordingListener = recallDesktop.addEventListener(
"recording-ended",
async ({ window }) => {
console.log("Recording ended for window:", window.id);
// Upload the recording
await recallDesktop.uploadRecording(window.id);
}
);
// Later, remove listeners when no longer needed
stopMeetingListener();
stopStateListener();
stopUploadListener();
stopRecordingListener();
For capturing audio from applications other than supported meeting platforms:
// Prepare desktop audio recording
const { data } = await recallDesktop.prepareDesktopAudioRecording();
const { windowId } = data;
// Get upload token and start recording
const uploadToken = await getUploadTokenFromBackend();
await recallDesktop.startRecording(windowId, uploadToken);
// Stop when done
await recallDesktop.stopRecording(windowId);
await recallDesktop.uploadRecording(windowId);
// Check permission status
const status = await recallDesktop.getStatus();
console.log("Permissions:", status.permissions);
// Request specific permission
await recallDesktop.requestPermission("screen-capture");
// Listen for permission changes
const removePermissionListener = recallDesktop.addEventListener(
"permission-status",
({ permission, status }) => {
console.log(`Permission ${permission}: ${status}`);
}
);
// Remove the listener when you no longer need updates
removePermissionListener();
A minimal Express backend lives in packages/backend
for demos. It exposes:
POST /api/create-sdk-upload
– calls the Recall API and returns{ id, upload_token, recording_id }
POST /webhooks/recall
– logs Recall webhook payloads for inspectionGET /health
– health check
Run it with your Recall token (replace the example value with the token for your workspace):
RECALL_API_TOKEN="c5a6aaff378e5dc5a7e28b3e2853eff832ce4bde" \
npm start --workspace=packages/backend
The server defaults to https://us-west-2.recall.ai
; override via RECALL_API_BASE
if you use another region. Set CORS_ORIGIN
to restrict cross-origin access (defaults to *
).
Your backend needs to create upload tokens using the Recall.ai API:
// Example backend endpoint
app.post("/api/create-upload-token", async (req, res) => {
const response = await fetch(`${RECALL_API_URL}/api/v1/sdk-upload/`, {
method: "POST",
headers: {
Authorization: `Token ${RECALL_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
transcript: {
provider: {
assembly_ai_streaming: {},
},
},
}),
});
const data = await response.json();
res.json({ uploadToken: data.upload_token });
});
Set up webhooks to handle recording completion:
app.post("/webhooks/recall", (req, res) => {
const { event, data } = req.body;
switch (event) {
case "sdk_upload.complete":
console.log("Recording completed:", data.recording.id);
// Process completed recording
break;
case "sdk_upload.failed":
console.log("Recording failed:", data);
// Handle failure
break;
case "sdk_upload.uploading":
console.log("Recording uploading:", data);
// Track upload progress
break;
}
res.status(200).send("OK");
});
initSdk()
- Initialize the Recall SDKshutdownSdk()
- Shutdown the SDK and cleanupgetStatus()
- Get plugin and SDK statusstartRecording(windowId, uploadToken)
- Start recording a meetingstopRecording(windowId)
- Stop recordingpauseRecording(windowId)
- Pause recordingresumeRecording(windowId)
- Resume recordinguploadRecording(windowId)
- Upload completed recordingprepareDesktopAudioRecording()
- Prepare desktop audio capture
Use recallDesktop.addEventListener(eventType, callback)
to subscribe. Available event types include:
meeting-detected
,meeting-updated
,meeting-closed
recording-started
,recording-ended
,sdk-state-change
upload-progress
,realtime-event
,error
permissions-granted
,permission-status
media-capture-status
,participant-capture-status
,shutdown
setConfig(config)
- Update plugin configurationgetConfig()
- Get current configurationrequestPermission(permission)
- Request specific permission
npm run build
- Build all packagesnpm run dev
- Development mode with watchnpm run test
- Run testsnpm run typecheck
- TypeScript type checkingnpm run clean
- Clean build artifacts
-
The Electron plugin uses
@recallai/desktop-sdk
directly; no mock setup is required. -
Before building or type-checking the client package, the
sync-sdk-types
script copies the SDK's TypeScript declarations intopackages/client/src/generated
. This runs automatically vianpm run build --workspace=@todesktop/client-recall
andnpm run typecheck --workspace=@todesktop/client-recall
, but you can invoke it manually with:npm run sync-sdk-types --workspace=@todesktop/client-recall