The below NodeJS service is calling two GCS services: Cloud Text-to-Speech API (TTS) Cloud Speech-to-Text API (STT)
However, while using the same json key file for both, only the TTS is working. The STT call returns the following error: Error: 7 PERMISSION_DENIED: The caller does not have permission
require('dotenv').config();
const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const { TextToSpeechClient } = require('@google-cloud/text-to-speech');
const { SpeechClient } = require('@google-cloud/speech');
const app = express();
const port = 3005;
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
console.log('credentialsPath: ', credentialsPath);
const credentials = JSON.parse(fs.readFileSync(credentialsPath, 'utf8'));
//TTS
const client = new TextToSpeechClient({
credentials: {
client_email: credentials.client_email,
private_key: credentials.private_key,
},
});
//STT
const speechClient = new SpeechClient({
credentials: {
client_email: credentials.client_email,
private_key: credentials.private_key,
},
});
const LONG_RECORDING_THRESHOLD_MS = 59000; //Up to 1 min - use the Google's STT recognize method
app.use(bodyParser.json());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
/* TEXT-TO-SPEECH */
app.post('/synthesize', (req, res) => {
console.log('Received request: ', req.body);
const text = req.body.text;
const voiceName = req.body.voice;
const voice = {
languageCode: 'en-US',
name: voiceName,
} || {
languageCode: 'en-US', //not needed if name is specified
name:'en-US-Standard-B', //See voices here: https://cloud.google.com/text-to-speech/docs/voices
//ssmlGender:'MALE' //NEUTRAL / FEMALE - not needed if name is specified
};
const speed = req.body.speed || 1.0;
const request = {
input: { text: text },
voice: voice,
audioConfig: {
audioEncoding: 'MP3',
speakingRate: speed
}
};
client.synthesizeSpeech(request)
.then(([response]) => {
//console.log('*** Response: ', response);
res.set('Content-Type', 'audio/mp3');
res.send(response.audioContent);
})
.catch(error => {
console.log('TTS ERROR: ', error);
res.status(500).send({ error: error.message });
});
});
/* SPEECH-To-TEXT */
app.post('/transcribe', (req, res) => {
const audio = req.body.audio;
const duration = req.body.duration; // in milliseconds
const encoding = 'LINEAR16';
const sampleRateHertz = 16000;
const languageCode = 'en-US';
const request = {
audio: { content: audio },
config: {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
languageCode: languageCode,
},
};
// Check audio length to decide which method to use
if (duration <= LONG_RECORDING_THRESHOLD_MS) {
speechClient.recognize(request)
.then(handleResponse)
.catch(handleError);
} else {
speechClient.longRunningRecognize(request)
.then(data => {
const operation = data[0];
return operation.promise();
})
.then(handleResponse)
.catch(handleError);
}
function handleResponse([response]) {
const transcription = response.results
.map(result => result.alternatives[0].transcript)
.join('\n');
res.send({ transcription: transcription });
}
function handleError(error) {
console.log('STT ERROR: ', error);
res.status(500).send({ error: error.message });
}
});
app.listen(port, () => {
console.log(`Server started on http://localhost:${port}`);
});
In GCS console, I have both API services enabled and associated with the project with the same service account. When I go to the Enabled APIs and Services section, I see both services, and when clicking on each of them, under the Credentials tab I can see the same (and only) service account I have, for which the JSON key file was created and referenced in the NodeJS file.
This is a fresh GCS account and project, no Organization, with only one service account created. When I view the Permissions for this service, I see one Principal with the Owner role. Hovering over the 'Edit' pencil, I see a tooltip: "Role cannot be edited as it is inherited from another resource".
I see no entries in the GCS log explorer.
What am I missing, please?