Skip to content

Commit 674ad32

Browse files
committed
switch up secret handling
1 parent 64475c4 commit 674ad32

File tree

2 files changed

+111
-101
lines changed

2 files changed

+111
-101
lines changed

functions/src/events/scrapeEvents.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ import { randomBytes } from "node:crypto"
2121
import { sha256 } from "js-sha256"
2222
import { withinCutoff } from "./helpers"
2323

24-
const assembly = new AssemblyAI({
25-
apiKey: process.env.ASSEMBLY_API_KEY ? process.env.ASSEMBLY_API_KEY : ""
26-
})
27-
2824
abstract class EventScraper<ListItem, Event extends BaseEvent> {
2925
private schedule
3026
private timeout
@@ -35,7 +31,10 @@ abstract class EventScraper<ListItem, Event extends BaseEvent> {
3531
}
3632

3733
get function() {
38-
return runWith({ timeoutSeconds: this.timeout })
34+
return runWith({
35+
timeoutSeconds: this.timeout,
36+
secrets: ["ASSEMBLY_API_KEY"]
37+
})
3938
.pubsub.schedule(this.schedule)
4039
.onRun(() => this.run())
4140
}
@@ -144,6 +143,10 @@ const submitTranscription = async ({
144143
EventId: number
145144
maybeVideoUrl: string
146145
}) => {
146+
const assembly = new AssemblyAI({
147+
apiKey: process.env.ASSEMBLY_API_KEY ? process.env.ASSEMBLY_API_KEY : ""
148+
})
149+
147150
const newToken = randomBytes(16).toString("hex")
148151

149152
const transcript = await assembly.transcripts.submit({

functions/src/webhooks/transcription.ts

Lines changed: 103 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,119 +3,126 @@ import { AssemblyAI } from "assemblyai"
33
import { db, Timestamp } from "../firebase"
44
import { sha256 } from "js-sha256"
55

6-
const assembly = new AssemblyAI({
7-
apiKey: process.env.ASSEMBLY_API_KEY ? process.env.ASSEMBLY_API_KEY : ""
8-
})
6+
export const transcription = functions
7+
.runWith({ secrets: ["ASSEMBLY_API_KEY"] })
8+
.https.onRequest(async (req, res) => {
9+
if (req.headers["x-maple-webhook"]) {
10+
if (req.body.status === "completed") {
11+
// If we get a request with the right header and status, get the
12+
// transcription from the assembly API.
13+
const assembly = new AssemblyAI({
14+
apiKey: process.env.ASSEMBLY_API_KEY
15+
? process.env.ASSEMBLY_API_KEY
16+
: ""
17+
})
918

10-
export const transcription = functions.https.onRequest(async (req, res) => {
11-
if (req.headers["x-maple-webhook"]) {
12-
if (req.body.status === "completed") {
13-
// If we get a request with the right header and status, get the
14-
// transcription from the assembly API.
15-
const transcript = await assembly.transcripts.get(req.body.transcript_id)
16-
if (transcript && transcript.webhook_auth) {
17-
// If there is a transcript and the transcript has an auth property,
18-
// look for an event (aka Hearing) in the DB with a matching ID.
19-
const maybeEventsInDb = await db
20-
.collection("events")
21-
.where("videoTranscriptionId", "==", transcript.id)
22-
.get()
19+
const transcript = await assembly.transcripts.get(
20+
req.body.transcript_id
21+
)
22+
if (transcript && transcript.webhook_auth) {
23+
// If there is a transcript and the transcript has an auth property,
24+
// look for an event (aka Hearing) in the DB with a matching ID.
25+
const maybeEventsInDb = await db
26+
.collection("events")
27+
.where("videoTranscriptionId", "==", transcript.id)
28+
.get()
2329

24-
if (maybeEventsInDb.docs.length) {
25-
// If we have a match look for one that matches a hash of the token
26-
// we gave Assembly. There should only be one of these but firestore
27-
// gives us an array. If there is more than one member, something is
28-
// wrong
29-
const authenticatedEventIds = [] as string[]
30-
const hashedToken = sha256(String(req.headers["x-maple-webhook"]))
30+
if (maybeEventsInDb.docs.length) {
31+
// If we have a match look for one that matches a hash of the token
32+
// we gave Assembly. There should only be one of these but firestore
33+
// gives us an array. If there is more than one member, something is
34+
// wrong
35+
const authenticatedEventIds = [] as string[]
36+
const hashedToken = sha256(String(req.headers["x-maple-webhook"]))
3137

32-
for (const index in maybeEventsInDb.docs) {
33-
const doc = maybeEventsInDb.docs[index]
38+
for (const index in maybeEventsInDb.docs) {
39+
const doc = maybeEventsInDb.docs[index]
3440

35-
const tokenDocInDb = await db
36-
.collection("events")
37-
.doc(doc.id)
38-
.collection("private")
39-
.doc("webhookAuth")
40-
.get()
41+
const tokenDocInDb = await db
42+
.collection("events")
43+
.doc(doc.id)
44+
.collection("private")
45+
.doc("webhookAuth")
46+
.get()
4147

42-
const tokenDataInDb = tokenDocInDb.data()?.videoAssemblyWebhookToken
48+
const tokenDataInDb =
49+
tokenDocInDb.data()?.videoAssemblyWebhookToken
4350

44-
if (hashedToken === tokenDataInDb) {
45-
authenticatedEventIds.push(doc.id)
51+
if (hashedToken === tokenDataInDb) {
52+
authenticatedEventIds.push(doc.id)
53+
}
4654
}
47-
}
4855

49-
// Log edge cases
50-
if (maybeEventsInDb.docs.length === 0) {
51-
console.log("No matching event in db.")
52-
}
53-
if (authenticatedEventIds.length === 0) {
54-
console.log("No authenticated events in db.")
55-
}
56-
if (authenticatedEventIds.length > 1) {
57-
console.log("More than one matching event in db.")
58-
}
56+
// Log edge cases
57+
if (maybeEventsInDb.docs.length === 0) {
58+
console.log("No matching event in db.")
59+
}
60+
if (authenticatedEventIds.length === 0) {
61+
console.log("No authenticated events in db.")
62+
}
63+
if (authenticatedEventIds.length > 1) {
64+
console.log("More than one matching event in db.")
65+
}
5966

60-
if (authenticatedEventIds.length === 1) {
61-
// If there is one authenticated event, pull out the parts we want to
62-
// save and try to save them in the db.
63-
const { id, text, audio_url, utterances } = transcript
64-
try {
65-
const transcriptionInDb = await db
66-
.collection("transcriptions")
67-
.doc(id)
67+
if (authenticatedEventIds.length === 1) {
68+
// If there is one authenticated event, pull out the parts we want to
69+
// save and try to save them in the db.
70+
const { id, text, audio_url, utterances } = transcript
71+
try {
72+
const transcriptionInDb = await db
73+
.collection("transcriptions")
74+
.doc(id)
6875

69-
await transcriptionInDb.set({
70-
id,
71-
text,
72-
createdAt: Timestamp.now(),
73-
audio_url
74-
})
76+
await transcriptionInDb.set({
77+
id,
78+
text,
79+
createdAt: Timestamp.now(),
80+
audio_url
81+
})
7582

76-
// Put each `utterance` in a separate doc in an utterances
77-
// collection. Previously had done the same for `words` but
78-
// got worried about collection size and write times since
79-
// `words` can be tens of thousands of members.
80-
if (utterances) {
81-
const writer = db.bulkWriter()
82-
for (let utterance of utterances) {
83-
const { speaker, confidence, start, end, text } = utterance
83+
// Put each `utterance` in a separate doc in an utterances
84+
// collection. Previously had done the same for `words` but
85+
// got worried about collection size and write times since
86+
// `words` can be tens of thousands of members.
87+
if (utterances) {
88+
const writer = db.bulkWriter()
89+
for (let utterance of utterances) {
90+
const { speaker, confidence, start, end, text } = utterance
8491

85-
writer.set(
86-
db
87-
.collection("transcriptions")
88-
.doc(`${transcript.id}`)
89-
.collection("utterances")
90-
.doc(),
91-
{ speaker, confidence, start, end, text }
92-
)
93-
}
92+
writer.set(
93+
db
94+
.collection("transcriptions")
95+
.doc(`${transcript.id}`)
96+
.collection("utterances")
97+
.doc(),
98+
{ speaker, confidence, start, end, text }
99+
)
100+
}
94101

95-
await writer.close()
96-
}
102+
await writer.close()
103+
}
97104

98-
// Delete the hashed webhook auth token from our db now that
99-
// we're done.
100-
for (const index in authenticatedEventIds) {
101-
await db
102-
.collection("events")
103-
.doc(authenticatedEventIds[index])
104-
.collection("private")
105-
.doc("webhookAuth")
106-
.set({
107-
videoAssemblyWebhookToken: null
108-
})
105+
// Delete the hashed webhook auth token from our db now that
106+
// we're done.
107+
for (const index in authenticatedEventIds) {
108+
await db
109+
.collection("events")
110+
.doc(authenticatedEventIds[index])
111+
.collection("private")
112+
.doc("webhookAuth")
113+
.set({
114+
videoAssemblyWebhookToken: null
115+
})
116+
}
117+
} catch (error) {
118+
console.log(error)
109119
}
110-
} catch (error) {
111-
console.log(error)
112120
}
121+
} else {
122+
res.status(404).send("Not Found")
113123
}
114-
} else {
115-
res.status(404).send("Not Found")
116124
}
117125
}
118126
}
119-
}
120-
res.status(200).send()
121-
})
127+
res.status(200).send()
128+
})

0 commit comments

Comments
 (0)