How to detect the enviorment and place value in nodejs - arrays

I would like to know how to apply google analytics id for staging/local and production,
I have two ID's, each for staging/local and production. I am using nodejs as a backend, and stored the google analytics key in config file using env file
how to pass if local, pass google analytics id ga_local
if prod, pass google analytics id ga_pro in nodejs in the startup
app.js
var express = require('express');
var config = require('./config');
var app = express();
var ga_id = app.get('env');
ga_id == "development" ? config.ga_local : config.ga_pro;
//how to pass to frontend
.env
ga_local = "UA-XXXX-X",
ga_pro = "UA-YYYY-Y"
config.js
require('dotenv').config();
const config = {
ga_local: process.env.ga_local,
ga_pro: process.env.ga_pro
};
module.exports = config;
front end
<script async src='https://www.googletagmanager.com/gtag/js?id=${ga_id}'></script>

you can provide mode at the time of running your node server. .
Run your file -> node index.js -m prod
code to access command line arguments.
const program = require('commander');
/* reading commandline parameters */
program
.version('1.2')
.option('-m,--mode [type]', 'Running Mode', 'MODE_NOT_PROVIDED')
.parse(process.argv);
console.log(program.mode); local,prod or dev

Related

Google Cloud Tasks: Location 'europe-west1' is not a valid location

I am trying to run a Google Cloud Tasks task using a Cloud Function, but I'm hitting an error where any region I try to use is wrong.
The code is basic. All is well until it stops because of the following error:
Error: {"code":3,"message":"Location 'europe-west1' is not a valid location. Use ListLocations to list valid locations.","details":[]}
If I attempt to use, for example, us-central1, it will report:
Error: {"code":3,"message":"Location must equal europe-west1 because the App Engine app that is associated with this project is located in europe-west1","details":[]}
I am using the Google Cloud Tasks API with Node.js for creating a new Task:
const client = new CloudTasksClient({ fallback: true });
const parent = client.queuePath(PROJECT, 'europe-west1', QUEUE);
A full example can be found here: https://github.com/googleapis/nodejs-tasks/blob/master/samples/createHttpTaskWithToken.js
The URL called is:
""https://cloudtasks.googleapis.com:443/$rpc/google.cloud.tasks.v2beta3.CloudTasks/CreateTask"
If I run the locations list command, this is the output:
$ gcloud tasks locations list
europe-west1 projects/[project-id]/locations/europe-west1
Edit: Using the REST API (https://cloud.google.com/tasks/docs/reference/rest/v2beta3/projects.locations.queues.tasks/create) with the same configuration works. It may be a bug in the client?
I am really not sure what is wrong with my setup.
Not sure what information would be helpful to debug this, so apologies in advance if there's not enough information.
I realized which the example that you are using is for non App Engine/Cloud functions environments please try the simple example that is in the npm page.
Please check on your package.json that you are defining the latest version of google-cloud/tasks library, at this time it is 1.9.0
You don't need to use a Ouath token within App Engine/ Cloud Functions environments, because are already configured with a service account.
// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('#google-cloud/tasks');
// Instantiates a client.
const client = new CloudTasksClient();
// TODO(developer): Uncomment these lines and replace with your values.
// const project = 'my-project-id';
// const queue = 'my-appengine-queue';
// const location = 'us-central1';
// const payload = 'hello';
// Construct the fully qualified queue name.
const parent = client.queuePath(project, location, queue);
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
},
};
if (payload) {
task.appEngineHttpRequest.body = Buffer.from(payload).toString('base64');
}
if (inSeconds) {
task.scheduleTime = {
seconds: inSeconds + Date.now() / 1000,
};
}
const request = {
parent: parent,
task: task,
};
console.log('Sending task:');
console.log(task);
// Send create task request.
const [response] = await client.createTask(request);
const name = response.name;
console.log(`Created task ${name}`);

Can't access variable key inside .env (dotenv package React)

So I'm trying to understand how to use .env to secure my api key & data for my login auth. I've followed the process of the dotenv package and the stackoverflow answer here.
What I did:
1. I installed the dotenv package
2. In my rootfolder, I added a .env with only one line:
API_AUTH=http://myapilink.com
3. In my App.js, I added following line:
require('dotenv').config()
console.log(process.env.API_AUTH)
However, console.log returns 'undefined', why is that? What have I missed?
You have to prefix your environment variables with REACT_APP_. See here.
Note: You must create custom environment variables beginning with
REACT_APP_. Any other variables except NODE_ENV will be ignored to
avoid accidentally exposing a private key on the machine that could
have the same name. Changing any environment variables will require
you to restart the development server if it is running.
So instead of just API_AUTH it would be REACT_APP_API_AUTH instead.
And it will be exposed to your app as process.env.REACT_APP_API_AUTH.
Dotenv only works on server side. It needs an environment to store the variables. Here, we extract the content of the .env file and reduce it to an Object and pass it to Webpack's DefinePlugin allowing us later usage (process.env.API_AUTH):
const webpack = require('webpack');
const dotenv = require('dotenv');
module.exports = () => {
const env = dotenv.config().parsed,
envKeys = Object.keys(env).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(env[next]);
return prev;
}, {});
return {
plugins: [
new webpack.DefinePlugin(envKeys)
]
};

How to make an angular application take arguments from command line?

I have an AngularJS application in which my code looks something like this:
myApp = angular.module('myApp',
[
'ui.router',
'ngMaterial',
'ngMessages'
]
);
myApp.constant('CONSTANTS', (function() {
// Define your variable
return {
backend: {
baseURL: 'http://mybackend.com:3026'
}
};
})());
I run this application using http-server on port number 8000 like this:
% http-server -p 8000
I want to pass in a command-line argument for the backend.baseURL such that it over-rides the value specified in the code. How can I do it??
What you need is at least required http-server that supported dynamic content. while your http-server is supported only static content.
And in the comment you asking which server should you use. There are thousands of web-server that support dynamic content out there. but sinc you are currently using http-server I assumed you just want a small server for local-dev.
Unfortunately, I cannot find any server that support your need without modifying their code. So I suggest you to create your own server base on a library on npm.
This is and example server using live-server.
var liveServer = require("live-server");
var fs = require("fs")
var root = process.argv[2] || "."
var port = process.argv[3] || 8000
var replaceTextMiddleWare = function(req, res, next){
var file = process.argv[4]
var find = process.argv[5]
var replace = process.argv[6]
if(file && find){
if(req.url === file) {
fs.readFile( root + file, "utf-8", function(e, content){
res.end( content.replace(find, replace))
} )
return;
}
}
next();
}
var params = {
port: port, // Set the server port. Defaults to 8080.
host: "0.0.0.0", // Set the address to bind to. Defaults to 0.0.0.0 or process.env.IP.
root: root, // Set root directory that's being server. Defaults to cwd.
open: false, // When false, it won't load your browser by default.
ignore: 'scss,my/templates', // comma-separated string for paths to ignore
file: "index.html", // When set, serve this file for every 404 (useful for single-page applications)
wait: 1000, // Waits for all changes, before reloading. Defaults to 0 sec.
mount: [['/components', './node_modules']], // Mount a directory to a route.
logLevel: 2, // 0 = errors only, 1 = some, 2 = lots
middleware: [ replaceTextMiddleWare ] // Takes an array of Connect-compatible middleware that are injected into the server middleware stack
};
liveServer.start(params);
Then you can run your server by
nodejs myserver.js /mydocument/myproject/ 8000 config.js "http://mybackend.com:3026" "http://mydevserver.com:80"
The command accept parameters:
Path to serve content
Port
File name
Text to find
Text to replace
This server support only one dynamic file with simple find/replace.
From this point, I guess you can modify middleware to do whatever you want.
when Ive done this in production I use the build process for this, using gulp in this case,
var knownOptions = {
string: 'env',
default: { env: process.env.NODE_ENV || 'default' }
};
var options = minimist(process.argv.slice(2), knownOptions);
console.log("using config : " + chalk.blue(options.env));
we get an environment variable defaulting to default using minimist we can pass -env 'string'
then further in the code pushing a dynamic file onto app.js
//now we use options.env
appJS.push("env/"+options.env+".js");
env/[options.env].js here is an angular module that exports environment specific constants
looks like you are not using gulp but you are using node script from package.json. if you are using gulp then this should not be a problem you you use http-server via gulp.
one thing you can do in your current case is as part of your run command, set process.env.baseUrl="dynamic" and then roughly speaking, use this in your code like this
return {
backend: {
baseURL:process.env.baseUrl || 'http://fallbackurl'
}
Basically what I understand is that you want to customize http-server package for your won custom handling.
Here is small solution I found for you....
Go to node installation folder(In my case its local one)...
So path of file which we going to edit is like this...
../node_modules/http-server/lib/http-server.js
Import one package which serve you to get command line arguments...you don't need to install it, its already there.
var argv = require('optimist').boolean('cors').argv; // add this line at top after line number 7
Now
At line 60 and after code before.push(function (req, res) { add following code..
if( req.url === '/backend-url' ) {
return res.end(JSON.stringify(argv.x));
}
So before push function will look like::
before.push(function (req, res) {
if( req.url === '/backend-url' ) {
return res.end(JSON.stringify(argv.x));
}
if (options.logFn) {
options.logFn(req, res);
}
res.emit('next');
});
now we have configured our new command line argument x for http-server which will be return for url "/backend-url"
Now at front end
myApp.constant('CONSTANTS', ('$http', function($http) {
// Define your variable
**var backendURL = (function() {
return $http.get('/backend-url', function(bUrl) {
return bUrl;
})
})();**
return {
backend: {
baseURL: backendURL
}
};
})());
Done, now you add url like this: **http-server -p 8080 -x http://example.com**
I choose this approch as replacing file content i dont think good in you case
If you use only one instance of your app, you can start it with script, that accepts all necessary command line arguments, replaces appropriate placeholders (string between specific comments, for example) in your application js files and then launches http-server on necessary port.

Mean.io framework with socket.io

How to use socket.io in Mean.io stack?
First of all, Mean.io changes their folder structure very regularly.. So my question is where is the best place to configure socket.io ? or is it better to use express.io ?
Second I am still not quite sure where to look for to find code that tells mean.io to listen for port, I have found a port is defined in config folder in all.js file, but real problem is as soon as I define server.listen(port) app doesn't load. and if I don't app loads but socket.io doesn't work.
Also I have another question about /socket.io/socket-io.js file? I have copied that in index folder, but my app can't find it or says 404 error. I know it's not an actual file sitting on any such location as far as I have understood, also people suggested to put that line as 127.0.0.1/socket.io/socket-io.js but none made the js file available for the app to be able to run socket.io.
What is the proper way of defining socket.io in mean.io framework?
I also faced the same issue and took me about a week to finally get it right. I'll try to explain what I did:
app.js
In this file, I just invoke the code that creates and sets up a socket.io object for me, which is then passed to the routes module.
'use strict';
/*
* Defining the Package
*/
var Module = require('meanio').Module;
var MeanSocket = new Module('chat');
/*
* All MEAN packages require registration
* Dependency injection is used to define required modules
*/
MeanSocket.register(function(app, http) {
var io = require('./server/config/socketio')(http);
//We enable routing. By default the Package Object is passed to the routes
MeanSocket.routes(io);
return MeanSocket;
});
server/config/socketio.js
This file simply configures the socket.io object. Please note that I had to upgrade meanio module to version 0.5.26 for this work, as http object (express server) is not available in older meanio versions. Moreover, in case you want to use ssl, you can inject https instead of http.
'use strict';
var config = require('meanio').loadConfig(),
cookie = require('cookie'),
cookieParser = require('cookie-parser'),
socketio = require('socket.io');
module.exports = function(http) {
var io = socketio.listen(http);
io.use(function(socket, next) {
var data = socket.request;
if (!data.headers.cookie) {
return next(new Error('No cookie transmitted.'));
}
var parsedCookie = cookie.parse(data.headers.cookie);
var sessionID = parsedCookie[config.sessionName];
var parsedSessionID = cookieParser.signedCookie(parsedCookie[config.sessionName], config.sessionSecret);
if (sessionID === parsedSessionID) {
return next(new Error('Cookie is invalid.'));
}
next();
});
return io;
};
routes/chat.js
Finally, use the routes file to define the socket events, etc.
'use strict';
// The Package is passed automatically as first parameter
module.exports = function(MeanSocket, io) {
io.on('connection', function(socket) {
console.log('Client Connected');
socket.on('authenticate', function(data, callback) {
});
});
};
Hope this helps!
The simplest way would be to install the socket package...
mean install socket

PhoneGap photo to Google App Engine

I am trying to upload a photo jpg from a PhoneGap app (javascript) to Google App Engine (php), store parameters in a db, and photo to Google Cloud Storage. All works except the photo file transfer.
The upload function I'm using is typical of PhoneGap's file transfer example http://docs.phonegap.com/en/edge/cordova_file_file.md.html#FileTransfer.
function uploadPhoto(imageURI) {
// imageURI is photo local url file:///Users/me/Library/...etc ... .jpg
// from navigator.camera.getPicture function
// prepare post variables
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.foo = "foo";
options.params = params;
options.chunkedMode = false;
// upload image and option
var ft = new FileTransfer();
ft.upload(imageURI, 'http://myapphere.appspot.com/php/myphoto.php', function(r){
// do stuff with r.response
},function(error){
// error
},options,true);
}
On the Google App Engine server, the parameter variables pass fine - what doesn't seem to transfer it the $_FILE file.
/* php/myphoto.php */
// option variables are passed - this works
$foo = $_POST["foo"];
// but it seems the $_FILES is empty?
$gs_name = $_FILES["file"]["tmp_name"]; // <-- not transferring?
$fileName = 'test.jpg';
$moveResult = move_uploaded_file($gs_name, "gs://mybucket/".$fileName);
A file test.jpg is stored in mybucket (a small blank binary/octet). As a test, I created an HTML form on GAE to upload a file image and move_upload_file $_FILE to mybucket, it works. It's the transfer of $_FILES from the javascript app that I can't figure out. (I'm aware of the Google Cloud Storage JSON API objects.insert, but here I'd like to go from phonegap html/javascript to Google App Engine PHP page to process passed data).

Resources