BMAD-METHOD/bmad/tools/serverless-samples/functions/transcribe-worker.js

57 lines
2.0 KiB
JavaScript

// Minimal worker example that downloads audio from S3 and calls OpenAI Whisper (speech-to-text)
// This file is intended to be executed server-side (cron, queue worker, or invoked directly)
import fetch from 'node-fetch';
import { S3Client, GetObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
import { OpenAI } from 'openai';
const s3 = new S3Client({ region: process.env.AWS_REGION });
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// Helper to stream S3 object to a Buffer (simplified)
async function streamToBuffer(stream) {
return new Promise((resolve, reject) => {
const chunks = [];
stream.on('data', (chunk) => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => resolve(Buffer.concat(chunks)));
});
}
export async function transcribeJob({ objectKey }) {
// Download audio from S3
const bucket = process.env.S3_BUCKET;
const getCmd = new GetObjectCommand({ Bucket: bucket, Key: objectKey });
const obj = await s3.send(getCmd);
const buffer = await streamToBuffer(obj.Body);
// Call OpenAI Whisper (speech-to-text) - using OpenAI 'audio.transcriptions' API
try {
const resp = await openai.audio.transcriptions.create({
file: buffer,
model: 'whisper-1',
});
const transcript = resp.text || resp.data?.text || '';
// Delete audio file after successful transcription
try {
await s3.send(new DeleteObjectCommand({ Bucket: bucket, Key: objectKey }));
} catch (delErr) {
console.warn('failed to delete audio', delErr);
}
// Persist transcript to DB / notify client (not implemented in skeleton)
return { success: true, transcript };
} catch (err) {
console.error('transcription error', err);
return { success: false, error: String(err) };
}
}
// For local testing: allow invocation via CLI
if (process.env.LOCAL_TEST === '1') {
const key = process.argv[2];
transcribeJob({ objectKey: key }).then(r => console.log('result', r)).catch(console.error);
}