`createHandler`

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { CloudTasksClient } = require('@google-cloud/tasks');
const fetch = require('node-fetch');
const gcpToDpe = require('gcp-to-dpe');
const addMinutes = (date, minutes) => {
return new Date(date.getTime() + minutes * 60000);
};
const getSecondsSinceEpoch = date => {
return Math.round(date.getTime() / 1000);
};
const getSttOperationUrl = (operationName, firebaseApiKey) => {
return `https://speech.googleapis.com/v1/operations/${operationName}?key=${firebaseApiKey}`;
};
exports.firestoreCheckSTT = functions.runWith(MAX_RUNTIME_OPTS).https.onRequest(async (req, res) => {
const payload = req.body;
console.log('payload', payload);
console.log('payload typeof', typeof payload);
// Does this work or does it need some processing like, JSON.parse etc..?
const { sttOperationName, docPath } = payload;
console.log('sttOperationName', sttOperationName);
console.log('docPath', docPath);
try {
// await admin.firestore().doc(payload.docPath).delete();
// TODO: add firebaseApiKey to ENV
// https://stackoverflow.com/questions/34442739/how-does-one-set-private-environment-variables-on-firebase-hosting
const firebaseApiKey = functions.config().webapi.key;
const operationUrlEndPoint = getSttOperationUrl(sttOperationName, firebaseApiKey);
return fetch(operationUrlEndPoint)
.then(response => response.json())
.then(async resp => {
console.log('resp');
// console.log(resp);
if (resp.done && resp.response) {
// TODO: save data to firestore
// resp.response.result
console.log('transcript');
const transcript = gcpToDpe(resp);
// console.log('transcript', transcript);
console.log('transcript gcpToDpe');
const { paragraphs, words } = transcript;
console.log('transcript words');
console.log('docPath', docPath);
await admin
.firestore()
.doc(docPath)
.set(
{
paragraphs,
words,
status: 'done',
},
{
merge: true,
}
);
console.log('admin write');
return res.sendStatus(200);
} else {
console.log('else, not ready - trying task again!');
//TODO: run cloud task
const project = admin.instanceId().app.options.projectId;
// https://firebase.google.com/docs/functions/locations
const location = 'us-central1';
const queue = 'firestore-stt';
const tasksClient = new CloudTasksClient();
const queuePath = tasksClient.queuePath(project, location, queue);
const url = `https://${location}-${project}.cloudfunctions.net/firestoreCheckSTT`;
console.log('url firestoreCheckSTT', url);
// const payload = { sttOperationName, docPath };
// time of expiration expressed in epoch seconds
const now = new Date();
const timeFromNowWhenToCheckAgainInMinutes = 5;
const timeFromNowWhenToCheckAgainAsDate = addMinutes(now, timeFromNowWhenToCheckAgainInMinutes);
// Epoch, also known as Unix timestamps, is the number of seconds (not milliseconds!) that have elapsed since January 1, 1970 at 00:00:00 GMT
const secondsSinceEpoch = getSecondsSinceEpoch(timeFromNowWhenToCheckAgainAsDate);
await admin
.firestore()
.doc(docPath)
.set(
{
sttOperationName,
nextSttProgressCheckAt: timeFromNowWhenToCheckAgainAsDate,
},
{
merge: true,
}
);
const task = {
httpRequest: {
httpMethod: 'POST',
url,
body: Buffer.from(JSON.stringify(payload)).toString('base64'),
headers: {
'Content-Type': 'application/json',
},
},
scheduleTime: {
seconds: secondsSinceEpoch,
},
};
const [response] = await tasksClient.createTask({ parent: queuePath, task });
console.log(`Created task ${response.name}`);
return res.sendStatus(200);
}
});
} catch (error) {
console.error(error);
return res.sendStatus(500);
}
});