1

I am using the Google Cloud API (dialogflow) with my NodeJS application, following the steps on google documentation, referencing a JSON file in a enviroment variable (using dotenv) I was able to use the API.

GOOGLE_APPLICATION_CREDENTIALS="./dialogflow_credentials.json"

But my actual project that I'm trying to implement the API are on Heroku, with automatic deploys based on my github repo. So, if I use the actual code, my JSON credentials will be visible on github.

Is there a way to put this JSON file direct on the ENV, as a string? (On heroku I can define the enviroment variables) or have a better way to do this?

I tried to use info from this question Is it possible to store a JSON file to an ENV variable with dotenv?, but doesn't work.

I'm testing with this example code on my index.js:

const dialogflow = require('dialogflow');
const uuid = require('uuid');
 
/**
 * Send a query to the dialogflow agent, and return the query result.
 * @param {string} projectId The project to be used
 */
async function runSample(projectId = 'your-project-id') {
  // A unique identifier for the given session
  const sessionId = uuid.v4();
 
  // Create a new session
  const sessionClient = new dialogflow.SessionsClient();
  const sessionPath = sessionClient.sessionPath(projectId, sessionId);
 
  // The text query request.
  const request = {
    session: sessionPath,
    queryInput: {
      text: {
        // The query to send to the dialogflow agent
        text: 'hello',
        // The language used by the client (en-US)
        languageCode: 'en-US',
      },
    },
  };
 
  // Send request and log result
  const responses = await sessionClient.detectIntent(request);
  console.log('Detected intent');
  const result = responses[0].queryResult;
  console.log(`  Query: ${result.queryText}`);
  console.log(`  Response: ${result.fulfillmentText}`);
  if (result.intent) {
    console.log(`  Intent: ${result.intent.displayName}`);
  } else {
    console.log(`  No intent matched.`);
  }
}
  • 1
    Base64 encode the contents of your service account JSON key file. Assign the encoded string to an environment variable. In your code read the environment variable and Base64 decode. Now you have the service account JSON key as a string. Use the Google SDK client function that loads the service account material `fromJSON()`. Look at the `fromJSON` example from this link: https://github.com/googleapis/google-auth-library-nodejs I would post an answer but I normally write code in c++, c#, Go and Python. – John Hanley Dec 28 '20 at 02:14
  • I've got the base64 encoding and decoding, but when I install google-auth-library, set everything and run the main function from the example (your link), outputs an error that my cloud dns api is disabled. I really need to set up cloud dns api? – Mateus Krause Dec 28 '20 at 03:42
  • 1
    That is a different problem. Create a new question. Are you using the DNS API? Show your code and the exact error message matching the line number in your code where the error occurs. – John Hanley Dec 28 '20 at 04:19
  • I start digging for some info and I found [this article by Tzahi Efrati](https://medium.com/@tzahi/how-to-setup-dialogflow-v2-authentication-programmatically-with-node-js-b37fa4815d89) that shows another way to do the integration just creating environment variables with the info from the JSON and loading on the constructor (different code from dialogflow documentation). Even so, thanks for this idea of encoding in base64, it will help me in other situations – Mateus Krause Dec 28 '20 at 18:49
  • in heroku its a real problem, i wrote this library to solve the problem: https://www.npmjs.com/package/google-credentials-helper – Inzamam Malik Mar 06 '22 at 19:59

1 Answers1

0

Had a similar issue and managed to make it work following the documentation [here][1]. There are basically two main options:

Option 1) Use explicit credentials and save the credentials in different env variables

You should have dowloaded a service-account.json, but instead of providing its path, you provide some of its details explicitly:

const { client } = require('google-cloud-bigquery')
 
const bigQuery = client.new({
    credentials: {
        project_id: 'test', 
        location_id: 'australia-southeast1',
        client_email:'something-1234@your-project-id.iam.gserviceaccount.com', 
        private_key: '-----BEGIN PRIVATE KEY-----\n123456789-----END PRIVATE KEY-----\n'
    }
})

And then replace the strings for different env variables of your choice, e.g.

YOUR_CUSTOM_ENV_VARIABLE_FOR_PROJECT_ID='test'

Option 2) Following Google Cloud's naming for env variables (no need to specify them explicitly)

const { client } = require('google-cloud-bigquery')
 
const bigQuery = client.new()

The above will only work if all the following environment variables are set:

GOOGLE_CLOUD_BIGQUERY_PROJECT_ID or GOOGLE_CLOUD_PROJECT_ID
GOOGLE_CLOUD_BIGQUERY_LOCATION_ID or GOOGLE_CLOUD_LOCATION_ID
GOOGLE_CLOUD_BIGQUERY_CLIENT_EMAIL or GOOGLE_CLOUD_CLIENT_EMAIL
GOOGLE_CLOUD_BIGQUERY_PRIVATE_KEY or GOOGLE_CLOUD_PRIVATE_KEY
albert
  • 31
  • 3
  • I've got `TypeError: client.new is not a function` when I tried the first option. Where did you get new() function? I'm using Discord.js v14 – LosmiNCL Jan 02 '23 at 23:32