16
16
"use strict" ;
17
17
// [START imports]
18
18
// Dependencies for task queue functions.
19
- const { onTaskDispatched} = require ( "firebase-functions/v2/tasks" ) ;
20
- const { onRequest, HttpsError} = require ( "firebase-functions/v2/https" ) ;
21
- const { getFunctions} = require ( "firebase-admin/functions" ) ;
22
- const { logger} = require ( "firebase-functions/v2" ) ;
19
+ const { onTaskDispatched } = require ( "firebase-functions/v2/tasks" ) ;
20
+ const { onRequest, HttpsError } = require ( "firebase-functions/v2/https" ) ;
21
+ const { getFunctions } = require ( "firebase-admin/functions" ) ;
22
+ const { logger } = require ( "firebase-functions/v2" ) ;
23
23
24
24
// Dependencies for image backup.
25
25
const path = require ( "path" ) ;
26
26
const fetch = require ( "node-fetch" ) ;
27
- const { initializeApp} = require ( "firebase-admin/app" ) ;
28
- const { getStorage} = require ( "firebase-admin/storage" ) ;
29
- const { GoogleAuth} = require ( "google-auth-library" ) ;
27
+ const { initializeApp } = require ( "firebase-admin/app" ) ;
28
+ const { getStorage } = require ( "firebase-admin/storage" ) ;
29
+ const { GoogleAuth } = require ( "google-auth-library" ) ;
30
30
// [END imports]
31
31
initializeApp ( ) ;
32
32
@@ -41,66 +41,67 @@ const BACKUP_BUCKET = process.env.BACKUP_BUCKET;
41
41
*/
42
42
// [START v2TaskFunctionSetup]
43
43
exports . backupapod = onTaskDispatched (
44
- {
45
- retryConfig : {
46
- maxAttempts : 5 ,
47
- minBackoffSeconds : 60 ,
48
- } ,
49
- rateLimits : {
50
- maxConcurrentDispatches : 6 ,
51
- } ,
52
- } , async ( req ) => {
53
- // [END v2TaskFunctionSetup]
54
- const date = req . data . date ;
55
- if ( ! date ) {
56
- logger . warn ( "Invalid payload. Must include date." ) ;
57
- throw new HttpsError (
58
- "invalid-argument" ,
59
- "Invalid payload. Must include date." ,
60
- ) ;
44
+ {
45
+ retryConfig : {
46
+ maxAttempts : 5 ,
47
+ minBackoffSeconds : 60 ,
48
+ } ,
49
+ rateLimits : {
50
+ maxConcurrentDispatches : 6 ,
51
+ } ,
52
+ } ,
53
+ async ( req ) => {
54
+ // [END v2TaskFunctionSetup]
55
+ const date = req . data . date ;
56
+ if ( ! date ) {
57
+ logger . warn ( "Invalid payload. Must include date." ) ;
58
+ throw new HttpsError (
59
+ "invalid-argument" ,
60
+ "Invalid payload. Must include date."
61
+ ) ;
62
+ }
63
+ logger . info ( `Requesting data from apod api for date ${ date } ` ) ;
64
+ let url = "https://api.nasa.gov/planetary/apod" ;
65
+ url += `?date=${ date } ` ;
66
+ url += `&api_key=${ process . env . NASA_API_KEY } ` ;
67
+ const apiResp = await fetch ( url ) ;
68
+ if ( ! apiResp . ok ) {
69
+ logger . warn (
70
+ `request to NASA APOD API failed with reponse ${ apiResp . status } `
71
+ ) ;
72
+ if ( apiResp . status === 404 ) {
73
+ // APOD not published for the day. This is fine!
74
+ return ;
61
75
}
62
- logger . info ( `Requesting data from apod api for date ${ date } ` ) ;
63
- let url = "https://api.nasa.gov/planetary/apod" ;
64
- url += `?date=${ date } ` ;
65
- url += `&api_key=${ process . env . NASA_API_KEY } ` ;
66
- const apiResp = await fetch ( url ) ;
67
- if ( ! apiResp . ok ) {
68
- logger . warn (
69
- `request to NASA APOD API failed with reponse ${ apiResp . status } ` ,
76
+ if ( apiResp . status >= 500 ) {
77
+ throw new HttpsError (
78
+ "unavailable" ,
79
+ "APOD API temporarily not available."
70
80
) ;
71
- if ( apiResp . status === 404 ) {
72
- // APOD not published for the day. This is fine!
73
- return ;
74
- }
75
- if ( apiResp . status >= 500 ) {
76
- throw new HttpsError (
77
- "unavailable" ,
78
- "APOD API temporarily not available." ,
79
- ) ;
80
- }
81
- throw new HttpsError ( "internal" , "Uh-oh. Something broke." ) ;
82
- }
83
- const apod = await apiResp . json ( ) ;
84
- const picUrl = apod . hdurl ;
85
- logger . info ( `Fetched ${ picUrl } from NASA API for date ${ date } .` ) ;
86
-
87
- const picResp = await fetch ( picUrl ) ;
88
- const dest = getStorage ( )
89
- . bucket ( BACKUP_BUCKET )
90
- . file ( `apod/${ date } ${ path . extname ( picUrl ) } ` ) ;
91
- try {
92
- await new Promise ( ( resolve , reject ) => {
93
- const stream = dest . createWriteStream ( ) ;
94
- picResp . body . pipe ( stream ) ;
95
- picResp . body . on ( "end" , resolve ) ;
96
- stream . on ( "error" , reject ) ;
97
- } ) ;
98
- } catch ( err ) {
99
- logger . error ( `Failed to upload ${ picUrl } to ${ dest . name } ` , err ) ;
100
- throw new HttpsError ( "internal" , "Uh-oh. Something broke." ) ;
101
81
}
102
- } ) ;
82
+ throw new HttpsError ( "internal" , "Uh-oh. Something broke." ) ;
83
+ }
84
+ const apod = await apiResp . json ( ) ;
85
+ const picUrl = apod . hdurl ;
86
+ logger . info ( `Fetched ${ picUrl } from NASA API for date ${ date } .` ) ;
103
87
88
+ const picResp = await fetch ( picUrl ) ;
89
+ const dest = getStorage ( )
90
+ . bucket ( BACKUP_BUCKET )
91
+ . file ( `apod/${ date } ${ path . extname ( picUrl ) } ` ) ;
92
+ try {
93
+ await new Promise ( ( resolve , reject ) => {
94
+ const stream = dest . createWriteStream ( ) ;
95
+ picResp . body . pipe ( stream ) ;
96
+ picResp . body . on ( "end" , resolve ) ;
97
+ stream . on ( "error" , reject ) ;
98
+ } ) ;
99
+ } catch ( err ) {
100
+ logger . error ( `Failed to upload ${ picUrl } to ${ dest . name } ` , err ) ;
101
+ throw new HttpsError ( "internal" , "Uh-oh. Something broke." ) ;
102
+ }
103
+ }
104
+ ) ;
104
105
105
106
let auth ;
106
107
@@ -112,18 +113,19 @@ let auth;
112
113
* @param {string } location the function's location
113
114
* @return {Promise<string> } The URL of the function
114
115
*/
115
- async function getFunctionUrl ( name , location = "us-central1" ) {
116
+ async function getFunctionUrl ( name , location = "us-central1" ) {
116
117
if ( ! auth ) {
117
118
auth = new GoogleAuth ( {
118
119
scopes : "https://www.googleapis.com/auth/cloud-platform" ,
119
120
} ) ;
120
121
}
121
122
const projectId = await auth . getProjectId ( ) ;
122
- const url = "https://cloudfunctions.googleapis.com/v2beta/" +
123
+ const url =
124
+ "https://cloudfunctions.googleapis.com/v2beta/" +
123
125
`projects/${ projectId } /locations/${ location } /functions/${ name } ` ;
124
126
125
127
const client = await auth . getClient ( ) ;
126
- const res = await client . request ( { url} ) ;
128
+ const res = await client . request ( { url } ) ;
127
129
const uri = res . data ?. serviceConfig ?. uri ;
128
130
if ( ! uri ) {
129
131
throw new Error ( `Unable to retreive uri for function at ${ url } ` ) ;
@@ -133,30 +135,31 @@ async function getFunctionUrl(name, location="us-central1") {
133
135
// [END v2GetFunctionUri]
134
136
135
137
// [START v2EnqueueTasks]
136
- exports . enqueuebackuptasks = onRequest (
137
- async ( _request , response ) => {
138
- const queue = getFunctions ( ) . taskQueue ( "backupapod" ) ;
139
- const targetUri = await getFunctionUrl ( "backupapod" ) ;
138
+ exports . enqueuebackuptasks = onRequest ( async ( _request , response ) => {
139
+ const queue = getFunctions ( ) . taskQueue ( "backupapod" ) ;
140
+ const targetUri = await getFunctionUrl ( "backupapod" ) ;
140
141
141
- const enqueues = [ ] ;
142
- for ( let i = 0 ; i <= BACKUP_COUNT ; i += 1 ) {
143
- const iteration = Math . floor ( i / HOURLY_BATCH_SIZE ) ;
144
- // Delay each batch by N * hour
145
- const scheduleDelaySeconds = iteration * ( 60 * 60 ) ;
142
+ const enqueues = [ ] ;
143
+ for ( let i = 0 ; i <= BACKUP_COUNT ; i += 1 ) {
144
+ const iteration = Math . floor ( i / HOURLY_BATCH_SIZE ) ;
145
+ // Delay each batch by N * hour
146
+ const scheduleDelaySeconds = iteration * ( 60 * 60 ) ;
146
147
147
- const backupDate = new Date ( BACKUP_START_DATE ) ;
148
- backupDate . setDate ( BACKUP_START_DATE . getDate ( ) + i ) ;
149
- // Extract just the date portion (YYYY-MM-DD) as string.
150
- const date = backupDate . toISOString ( ) . substring ( 0 , 10 ) ;
151
- enqueues . push (
152
- queue . enqueue ( { date} , {
153
- scheduleDelaySeconds,
154
- dispatchDeadlineSeconds : 60 * 5 , // 5 minutes
155
- uri : targetUri ,
156
- } ) ,
157
- ) ;
158
- }
159
- await Promise . all ( enqueues ) ;
160
- response . sendStatus ( 200 ) ;
161
- } ) ;
148
+ const backupDate = new Date ( BACKUP_START_DATE ) ;
149
+ backupDate . setDate ( BACKUP_START_DATE . getDate ( ) + i ) ;
150
+ // Extract just the date portion (YYYY-MM-DD) as string.
151
+ const date = backupDate . toISOString ( ) . substring ( 0 , 10 ) ;
152
+ enqueues . push (
153
+ queue . enqueue (
154
+ { date } ,
155
+ {
156
+ scheduleDelaySeconds,
157
+ dispatchDeadlineSeconds : 60 * 5 , // 5 minutes
158
+ }
159
+ )
160
+ ) ;
161
+ }
162
+ await Promise . all ( enqueues ) ;
163
+ response . sendStatus ( 200 ) ;
164
+ } ) ;
162
165
// [END v2EnqueueTasks]
0 commit comments