Created
December 12, 2018 13:41
-
-
Save soichisumi/765c4f6a0aa4400487efdad308149021 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const functions = require('firebase-functions'); | |
const rp = require('request-promise'); | |
const projectId = process.env.GCP_PROJECT; | |
const region = 'us-central1'; | |
// GCF の List API を利用するためのサービスアカウント | |
// service account をリポジトリに含めたくない場合は下記のように機密データを取得する | |
// 設定方法: https://github.com/firebase/firebase-tools/issues/406#issuecomment-353017349 | |
const serviceAccount = functions.config().list.cert; | |
// callable functionを呼ぶために使用する | |
const firebase = require('firebase'); | |
firebase.initializeApp({ | |
projectId: process.env.GCP_PROJECT | |
}) | |
async function getAccessToken() { | |
const { google } = require('googleapis'); | |
// ref: https://developers.google.com/identity/protocols/googlescopes | |
const scopes = ['https://www.googleapis.com/auth/cloudfunctions', 'https://www.googleapis.com/auth/cloud-platform']; | |
const jwtClient = new google.auth.JWT( | |
serviceAccount.client_email, | |
undefined, | |
serviceAccount.private_key, | |
scopes, | |
undefined | |
); | |
const authorization = await jwtClient.authorize(); | |
return authorization.access_token; | |
} | |
async function listFunction() { | |
try { | |
const accessToken = await getAccessToken(); | |
const endpoint = `https://cloudfunctions.googleapis.com/v1/projects/${projectId}/locations/${region}/functions`; | |
const option = { | |
uri: endpoint, | |
method: 'GET', | |
headers: { | |
Authorization: `Bearer ${accessToken}` | |
}, | |
qs: { | |
pageSize: 100 | |
}, | |
json: true | |
}; | |
// ref: https://cloud.google.com/functions/docs/reference/rest/v1/projects.locations.functions/list | |
const res = await rp.get(option); | |
return res.functions; | |
} catch (err) { | |
console.log(`error occurred when listing function: ${JSON.stringify(err)}`); | |
return err; | |
} | |
} | |
async function callHttpFunctions(urls){ | |
for (const url of urls){ | |
const option = { | |
uri: url, | |
method: "POST", | |
body:{ | |
}, | |
json: true | |
}; | |
const res = await rp(option); | |
console.log(`function: ${url} is called.`) | |
} | |
} | |
async function callCallableFunctions(funcNames){ | |
for(funcName of funcNames){ | |
try{ | |
await firebase.functions().httpsCallable(funcName)() | |
console.log(`function: ${funcName} called.`) | |
}catch(err){ | |
console.log(`error: ${JSON.stringify(err)}`); | |
} | |
} | |
} | |
exports.WarmupFunctions = functions | |
.pubsub | |
.topic("WarmupFunctions") | |
.onPublish(async (msg)=>{ | |
const urls = new Array(); | |
const callableFuncNames = new Array(); | |
const funcs = await listFunction(); | |
funcs.forEach(func => { | |
if(!func.httpsTrigger){ | |
console.log(`function: ${func.name} is not https function`) | |
return | |
} | |
const url = func.httpsTrigger.url; | |
if(func.labels["deployment-callable"] === "true" ){ | |
callableFuncNames.push(url.split('/').slice(-1)[0]); | |
}else { | |
urls.push(url); | |
} | |
console.log(`function: ${func.name} is target`); | |
}) | |
await callHttpFunctions(urls); | |
await callCallableFunctions(callableFuncNames); | |
console.log(`all functions are waked up. httpFuncs: ${urls.length}, CallableFuncs: ${callableFuncNames.length}`); | |
}) | |
// 以下は動作確認用の関数 | |
// 通常のHTTP関数 | |
exports.HttpsFunction = functions.https.onRequest((req, res)=>{ | |
console.log(`req.body: ${req.body}`) | |
return res.status(200).json({ | |
message: "OK", | |
body: req.body | |
}) | |
}) | |
// Callable関数 | |
exports.CallableFunction = functions.https.onCall((data, context)=>{ | |
// uncomment in production use | |
// if(!context.auth){ | |
// throw new functions.https.HttpsError('unauthenticated', 'The function must be called while authenticated.'); | |
// } | |
console.log(`function called. data: ${data}, uid: ${context.auth}`) | |
return { | |
message: "OK", | |
data: data, | |
ctx: context | |
} | |
}) | |
// バックグラウンド関数(pubsub トリガー) | |
exports.BackgroundFunction = functions.pubsub.topic("PubsubSample").onPublish(async (msg)=>{ | |
console.log(msg) | |
return msg | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment