`createHandler`
1
const functions = require('firebase-functions');
2
const admin = require('firebase-admin');
3
const { CloudTasksClient } = require('@google-cloud/tasks');
4
const fetch = require('node-fetch');
5
const gcpToDpe = require('gcp-to-dpe');
6
​
7
const addMinutes = (date, minutes) => {
8
return new Date(date.getTime() + minutes * 60000);
9
};
10
​
11
const getSecondsSinceEpoch = date => {
12
return Math.round(date.getTime() / 1000);
13
};
14
​
15
const getSttOperationUrl = (operationName, firebaseApiKey) => {
16
return `https://speech.googleapis.com/v1/operations/${operationName}?key=${firebaseApiKey}`;
17
};
18
​
19
​
20
exports.firestoreCheckSTT = functions.runWith(MAX_RUNTIME_OPTS).https.onRequest(async (req, res) => {
21
const payload = req.body;
22
console.log('payload', payload);
23
console.log('payload typeof', typeof payload);
24
// Does this work or does it need some processing like, JSON.parse etc..?
25
const { sttOperationName, docPath } = payload;
26
console.log('sttOperationName', sttOperationName);
27
console.log('docPath', docPath);
28
try {
29
// await admin.firestore().doc(payload.docPath).delete();
30
// TODO: add firebaseApiKey to ENV
31
// https://stackoverflow.com/questions/34442739/how-does-one-set-private-environment-variables-on-firebase-hosting
32
const firebaseApiKey = functions.config().webapi.key;
33
const operationUrlEndPoint = getSttOperationUrl(sttOperationName, firebaseApiKey);
34
return fetch(operationUrlEndPoint)
35
.then(response => response.json())
36
.then(async resp => {
37
console.log('resp');
38
// console.log(resp);
39
if (resp.done && resp.response) {
40
// TODO: save data to firestore
41
// resp.response.result
42
console.log('transcript');
43
const transcript = gcpToDpe(resp);
44
// console.log('transcript', transcript);
45
console.log('transcript gcpToDpe');
46
const { paragraphs, words } = transcript;
47
console.log('transcript words');
48
console.log('docPath', docPath);
49
​
50
await admin
51
.firestore()
52
.doc(docPath)
53
.set(
54
{
55
paragraphs,
56
words,
57
status: 'done',
58
},
59
{
60
merge: true,
61
}
62
);
63
console.log('admin write');
64
return res.sendStatus(200);
65
} else {
66
console.log('else, not ready - trying task again!');
67
//TODO: run cloud task
68
const project = admin.instanceId().app.options.projectId;
69
// https://firebase.google.com/docs/functions/locations
70
const location = 'us-central1';
71
const queue = 'firestore-stt';
72
const tasksClient = new CloudTasksClient();
73
const queuePath = tasksClient.queuePath(project, location, queue);
74
const url = `https://${location}-${project}.cloudfunctions.net/firestoreCheckSTT`;
75
console.log('url firestoreCheckSTT', url);
76
// const payload = { sttOperationName, docPath };
77
// time of expiration expressed in epoch seconds
78
const now = new Date();
79
const timeFromNowWhenToCheckAgainInMinutes = 5;
80
const timeFromNowWhenToCheckAgainAsDate = addMinutes(now, timeFromNowWhenToCheckAgainInMinutes);
81
// 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
82
const secondsSinceEpoch = getSecondsSinceEpoch(timeFromNowWhenToCheckAgainAsDate);
83
​
84
await admin
85
.firestore()
86
.doc(docPath)
87
.set(
88
{
89
sttOperationName,
90
nextSttProgressCheckAt: timeFromNowWhenToCheckAgainAsDate,
91
},
92
{
93
merge: true,
94
}
95
);
96
​
97
const task = {
98
httpRequest: {
99
httpMethod: 'POST',
100
url,
101
body: Buffer.from(JSON.stringify(payload)).toString('base64'),
102
headers: {
103
'Content-Type': 'application/json',
104
},
105
},
106
scheduleTime: {
107
seconds: secondsSinceEpoch,
108
},
109
};
110
const [response] = await tasksClient.createTask({ parent: queuePath, task });
111
console.log(`Created task ${response.name}`);
112
return res.sendStatus(200);
113
}
114
});
115
} catch (error) {
116
console.error(error);
117
return res.sendStatus(500);
118
}
119
});
Copied!
Copy link