@@ -3,119 +3,126 @@ import { AssemblyAI } from "assemblyai"
3
3
import { db , Timestamp } from "../firebase"
4
4
import { sha256 } from "js-sha256"
5
5
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
+ } )
9
18
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 ( )
23
29
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" ] ) )
31
37
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 ]
34
40
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 ( )
41
47
42
- const tokenDataInDb = tokenDocInDb . data ( ) ?. videoAssemblyWebhookToken
48
+ const tokenDataInDb =
49
+ tokenDocInDb . data ( ) ?. videoAssemblyWebhookToken
43
50
44
- if ( hashedToken === tokenDataInDb ) {
45
- authenticatedEventIds . push ( doc . id )
51
+ if ( hashedToken === tokenDataInDb ) {
52
+ authenticatedEventIds . push ( doc . id )
53
+ }
46
54
}
47
- }
48
55
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
+ }
59
66
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 )
68
75
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
+ } )
75
82
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
84
91
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
+ }
94
101
95
- await writer . close ( )
96
- }
102
+ await writer . close ( )
103
+ }
97
104
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 )
109
119
}
110
- } catch ( error ) {
111
- console . log ( error )
112
120
}
121
+ } else {
122
+ res . status ( 404 ) . send ( "Not Found" )
113
123
}
114
- } else {
115
- res . status ( 404 ) . send ( "Not Found" )
116
124
}
117
125
}
118
126
}
119
- }
120
- res . status ( 200 ) . send ( )
121
- } )
127
+ res . status ( 200 ) . send ( )
128
+ } )
0 commit comments