mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-09 23:32:37 +02:00
feat: transcribe voice memos with Deepgram and save as .txt
After saving a voice memo, send the audio to Deepgram's Nova-2 STT API and write the transcript as a .txt file alongside the audio in ~/.rowboat/voice_memos/. Reads the API key from config/deepgram.json. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5c4b7ca182
commit
158d90f415
1 changed files with 44 additions and 0 deletions
|
|
@ -143,6 +143,35 @@ export function SidebarContentPanel({
|
|||
)
|
||||
}
|
||||
|
||||
async function transcribeWithDeepgram(audioBlob: Blob): Promise<string | null> {
|
||||
try {
|
||||
const configResult = await window.ipc.invoke('workspace:readFile', {
|
||||
path: 'config/deepgram.json',
|
||||
encoding: 'utf8',
|
||||
})
|
||||
const { api_key } = JSON.parse(configResult.data) as { api_key: string }
|
||||
if (!api_key) throw new Error('No api_key in deepgram.json')
|
||||
|
||||
const response = await fetch(
|
||||
'https://api.deepgram.com/v1/listen?model=nova-2&smart_format=true',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Token ${api_key}`,
|
||||
'Content-Type': audioBlob.type,
|
||||
},
|
||||
body: audioBlob,
|
||||
},
|
||||
)
|
||||
|
||||
if (!response.ok) throw new Error(`Deepgram API error: ${response.status}`)
|
||||
const result = await response.json()
|
||||
return result.results?.channels?.[0]?.alternatives?.[0]?.transcript ?? null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Voice Note Recording Button
|
||||
function VoiceNoteButton() {
|
||||
const [isRecording, setIsRecording] = React.useState(false)
|
||||
|
|
@ -191,6 +220,21 @@ function VoiceNoteButton() {
|
|||
toast('Voice memo saved', 'success')
|
||||
} catch {
|
||||
toast('Failed to save voice memo', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
// Transcribe and save transcript alongside the audio file
|
||||
const transcript = await transcribeWithDeepgram(blob)
|
||||
if (transcript) {
|
||||
const txtFilename = filename.replace(/\.[^.]+$/, '.txt')
|
||||
await window.ipc.invoke('workspace:writeFile', {
|
||||
path: `voice_memos/${txtFilename}`,
|
||||
data: transcript,
|
||||
opts: { encoding: 'utf8' },
|
||||
})
|
||||
toast('Transcription saved', 'success')
|
||||
} else {
|
||||
toast('Transcription failed', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue