From a06b5e367c063a52a32b9a9821e73a7e40d1a263 Mon Sep 17 00:00:00 2001 From: Joshua Tzucker Date: Thu, 28 Nov 2019 10:27:43 -0800 Subject: [PATCH] Updated functionality and Readme * Updated Readme with full info * Updated grab-ngrok.js to use JSON.parse instead of Regex * Added better error catching for if Ngrok is not running properly * Added success message with new routing URL --- README.md | 9 +++++++++ grab-ngrok.js | 30 ++++++++++++++++++++---------- package.json | 2 +- success-msg.js | 3 +++ 4 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 success-msg.js diff --git a/README.md b/README.md index ad745b9..268065c 100644 --- a/README.md +++ b/README.md @@ -1 +1,10 @@ # gcp-proxy-func +Very simple Google Cloud Function that proxies requests using Express and `http-proxy-middleware`. You define the address that requests should be proxied to by filling out config.js (copy `config.example.js` to `config.js`, and then change the URL). + +# Using +Fill in `config.js`, and then either zip up the files and upload via Gcloud admin, or use [the Gcloud CLI](https://cloud.google.com/sdk/gcloud/) and `npm run deploy`. Or see below if using this to proxy to Ngrok. + +# Ngrok +If you want to use this to have a stable Google Cloud Function address that proxies requests to a dynamic Ngrok address ([see this blog post for details](https://joshuatz.com/posts/2019/using-google-cloud-functions-permanent-url-to-proxy-ngrok-requests/)), you can automatically redeploy the function with the correct Ngrok public URL after it has changed, by using `npm run ngrok-deploy`. + +This command will grab the Ngrok public URL via the localhost API, update config.js by using `fs` to write to the file, and then redeploy your GCloud function to point to the updated URL. \ No newline at end of file diff --git a/grab-ngrok.js b/grab-ngrok.js index 2cf3b18..21bbf95 100644 --- a/grab-ngrok.js +++ b/grab-ngrok.js @@ -2,27 +2,37 @@ const fs = require('fs'); const http = require('http'); +const ngrokErr = new Error('Could not parse Ngrok response. Is Ngrok running? Is port 4040 being blocked?'); + // Query ngrok local API -http.get('http://127.0.0.1:4040/api/tunnels', (res) => { +const req = http.get('http://127.0.0.1:4040/api/tunnels', (res) => { let data = ''; res.on('data', (chunk) => { - console.log(chunk); data += chunk; }); res.on('end', () => { // Extract public URL - const publicUrl = /public_url":\s*"(https[^"]+)/.exec(data)[1]; - - // Update config.js file - const configText = ` + try { + const ngrokTunnelInfo = JSON.parse(data); + // Assume first tunnel + const publicUrl = ngrokTunnelInfo.tunnels[0].public_url; + // Update config.js file + const configText = ` module.exports = { destination: '${publicUrl}' } `; - fs.writeFileSync('./config.js', configText); - console.log('config updated!'); - return true; + fs.writeFileSync('./config.js', configText); + console.log('config updated!'); + return publicUrl; + } catch (e) { + throw ngrokErr; + } }); -}); \ No newline at end of file +}); + +req.on('error', (err) => { + throw ngrokErr; +}) \ No newline at end of file diff --git a/package.json b/package.json index 102d162..3f70d2b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "ngrok-deploy": "node grab-ngrok.js && npm run deploy", - "deploy": "gcloud functions deploy proxy --runtime nodejs8 --trigger-http --memory=128 --timeout=60s" + "deploy": "gcloud functions deploy proxy --runtime nodejs8 --trigger-http --memory=128 --timeout=60s && node success-msg.js" }, "keywords": [], "author": "Joshua Tzucker", diff --git a/success-msg.js b/success-msg.js new file mode 100644 index 0000000..bb3a5a2 --- /dev/null +++ b/success-msg.js @@ -0,0 +1,3 @@ +// @ts-check +const config = require('./config'); +console.log(`Success! GCloud config updated to route traffic to ${config.destination}`); \ No newline at end of file