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);
}
);
// 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);// 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();You can also request teams-automation and browser-automation through requestPermission(). These permissions cannot be requested through the SDK's acquirePermissionsOnStartup option and are not included in the plugin's startup permission requests.
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/backendThe 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)- Compatibility no-op; recordings now stream during captureprepareDesktopAudioRecording()- Prepare desktop audio capture
Use recallDesktop.addEventListener(eventType, callback) to subscribe. Available event types include:
meeting-detected,meeting-updated,meeting-closedrecording-started,recording-ended,sdk-state-change(deprecated)upload-progress(deprecated),realtime-event,errorpermissions-granted,permission-statusmedia-capture-status,participant-capture-status,compliance-message-status,shutdownlog,network-status
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-sdkdirectly; no mock setup is required. -
Before building or type-checking the client package, the
sync-sdk-typesscript copies the SDK's TypeScript declarations intopackages/client/src/generated. This runs automatically vianpm run build --workspace=@todesktop/client-recallandnpm run typecheck --workspace=@todesktop/client-recall, but you can invoke it manually with:npm run sync-sdk-types --workspace=@todesktop/client-recall
- 1.3.13
- Updated
@recallai/desktop-sdkto v2.0.31 - Pulled in upstream Zoom Web and webinar support on macOS, Japanese Zoom detection on Windows, Google Meet compliance messaging on Safari, and meeting detection, capture, memory, crash, and network reliability fixes
- Added permission typing for
teams-automationandbrowser-automation, excluding both from SDK startup permission options - Aligned the versions reported by the main process and preload with the package version
- Updated
- 1.3.12
- Updated
@recallai/desktop-sdkto v2.0.26 - Pulled in upstream microphone tracking, meeting detection, recording finalization, and Zoom, Google Meet, Teams, and Safari capture fixes
- No wrapper API changes were required; the upstream TypeScript declarations are unchanged
- Updated
- 1.3.11
- Updated
@recallai/desktop-sdkto v2.0.24 - Pulled in upstream realtime transcription latency, Teams Web screenshare, Zoom/Google Meet PIP capture, encoding, heartbeat, status request, participant labeling, and desktop audio recording permission fixes
- Updated
- 1.3.10
- Updated
@recallai/desktop-sdkto v2.0.22 - Pulled in upstream Teams Web support on macOS, transcript partial-data fixes, capture reliability and performance improvements, and compliance messaging fixes
- Added pass-through typing for the new
compliance-message-statusSDK event
- Updated
- 1.3.9
- Updated
@recallai/desktop-sdkto v2.0.19 - Pulled in upstream Google Meet, Zoom, and Teams detection fixes, video/audio capture reliability fixes, encoding performance improvements, and presigned URL retry handling
- Added pass-through support for the optional
prepareDesktopAudioRecordingSDK config argument
- Updated
- 1.3.8
- Updated
@recallai/desktop-sdkto v2.0.14 - Pulled in upstream Google Meet detection fixes, macOS memory leak fixes, audio-pipeline fixes, Teams Gallery fallback capture fixes, and Teams Windows app-hang fixes
- Updated
- 1.3.7
- Updated
@recallai/desktop-sdkto v2.0.13 - Pulled in upstream app-hang fixes, performance improvements, Google Meet PIP black-recording fixes, Arc window capture support, audio-pipeline fixes, and Google Meet detection fixes
- Updated
- 1.3.6
- Updated
@recallai/desktop-sdkto v2.0.12 - Pulled in upstream crash fixes, TLS handling fixes, audio-pipeline telemetry, Teams/Chromium/Safari capture fixes, Zoom multiwindow sharing, and Chrome vertical-tab meeting detection
- Reflected upstream deprecation of
sdk-state-change; userecording-startedandrecording-endedfor recording state transitions
- Updated
- 1.3.5
- Updated
@recallai/desktop-sdkto v2.0.11 - Pulled in upstream meeting-detection, mic-stream, and audio-pipeline reliability fixes
- Updated
- 1.3.4
- Updated
@recallai/desktop-sdkto v2.0.10 - Aligned wrapper types with new Recall events and permissions
- Documented the streamed upload model and deprecated
uploadRecording
- Updated
- 1.3.3
- Updated
@recallai/desktop-sdkto v2.0.8
- Updated
- 1.3.2
- Updated
@recallai/desktop-sdkto v2.0.4
- Updated
- 1.3.1
- Updated
@recallai/desktop-sdkto v2.0.3
- Updated
- 1.3.0
- Updated
@recallai/desktop-sdkto v2.0.0
- Updated
- 1.2.0
- Updated
@recallai/desktop-sdkto v1.3.5
- Updated
- 1.3.13