How set API KEY in Google Translate Node.js code - node.js

I'm trying to create a Node.js code that uses google translate api.
I got the code below from the google doc (https://cloud.google.com/translate/docs/translating-text)
But when I run it, it says "Error: The request is missing a valid API key."
I have the key, but i don't know how and where to set it.
async function translate() { // Imports the Google Cloud client library
const { Translate } = require('#google-cloud/translate');
// Creates a client
const translate = new Translate();
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
const text = 'Hello, world!';
const target = 'ru';
// Translates the text into the target language. "text" can be a string for
// translating a single piece of text, or an array of strings for translating
// multiple texts.
let [translations] = await translate.translate(text, target);
translations = Array.isArray(translations) ? translations : [translations];
console.log('Translations:');
translations.forEach((translation, i) => {
console.log(`${text[i]} => (${target}) ${translation}`);
});
}
translate()

This page on setting up authentication explains that you need to download a credentials file from the create service account key page. This can then be added to your path (.bashrc) as follows:
export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
Alternately, you could add the line above to a .env file on your project root and source it when you are running the application:
. ./.env
npm start
or
sh -ac '. ./.env; npm start'

Checkout this Google Authentication Page to add the key
In the GCP Console, go to the Create service account key page.
From the Service account list, select New service account.
In the Service account name field, enter a name.
From the Role list, select Project > Owner. Click
Create. A JSON file that contains your key downloads to your computer.
and
export GOOGLE_APPLICATION_CREDENTIALS="[PATH to key downloaded]"

create api-key see documentation create api key doc
use it like:
import { v2 } from '#google-cloud/translate';
const translateClint = new v2.Translate({
projectId:'your-projectId-here',
key: 'your-api-key-here',
});
I don't check it for v3, but I see the same interface:
new v3.TranslationServiceClient({
key:"may be works",
projectId:"may be works"
})

Try this... no environment variables AND please... add this file to your .gitignore
import * as credentials from 'credentials.json';
...
const {Translate} = require('#google-cloud/translate').v2;
const translationApi = new Translate({
projectId:'your-project-id',
credentials:credentials
});

Related

How to upload a base64 image URL to Firebase and retrieve its access token?

In a MERN + Firebase project, I have an image data string that I want to upload and then get the access token of that file.
The image data string is of the following form:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOoAAAClCAYAAABSmmH3AAAAAXNSR0IArs4c6QAABFJJREFUeF7t1oENg0AQA8F8/6XSAx8pVWTloQIzZwvOvfd+PAQI/LXAMdS/vo9wBH4ChqoIBAIChho4kogEDFUHCAQEDDVwJBEJGKoOEAgIGGrgSCISMFQdIBAQMNTAkUQkYKg6QCAgYKiBI4lIwFB1gEBAwFADRxKRgKHqAIGAgKEGjiQiAUPVAQIBAUMNHElEAoaqAwQCAoYaOJKIBAxVBwgEBAw1cCQRCRiqDhAICBhq4EgiEjBUHSAQEDDUwJFEJGCoOkAgIGCogSOJSMBQdYBAQMBQA0cSkYCh6gCBgIChBo4kIgFD1QECAQFDDRxJRAKGqgMEAgKGGjiSiAQMVQcIBAQMNXAkEQkYqg4QCAgYauBIIhIwVB0gEBAw1MCRRCRgqDpAICBgqIEjiUjAUHWAQEDAUANHEpGAoeoAgYCAoQaOJCIBQ9UBAgEBQw0cSUQChqoDBAIChho4kogEDFUHCAQEDDVwJBEJGKoOEAgIGGrgSCISMFQdIBAQMNTAkUQkYKg6QCAgYKiBI4lIwFB1gEBAwFADRxKRgKHqAIGAgKEGjiQiAUPVAQIBAUMNHElEAoaqAwQCAoYaOJKIBAxVBwgEBAw1cCQRCRiqDhAICBhq4EgiEjBUHSAQEDDUwJFEJGCoOkAgIGCogSOJSMBQdYBAQMBQA0cSkYCh6gCBgIChBo4kIgFD1QECAQFDDRxJRAKGqgMEAgKGGjiSiAQMVQcIBAQMNXAkEQkYqg4QCAgYauBIIhIwVB0gEBAw1MCRRCRgqDpAICBgqIEjiUjAUHWAQEDAUANHEpGAoeoAgYCAoQaOJCIBQ9UBAgGB8zzPDeQUkcC0wHnf11CnK+DlCwJ+fQtXknFewBd1vgIACgK+qIUryTgvYKjzFQBQEDDUwpVknBcw1PkKACgIGGrhSjLOCxjqfAUAFAQMtXAlGecFDHW+AgAKAoZauJKM8wKGOl8BAAUBQy1cScZ5AUOdrwCAgoChFq4k47yAoc5XAEBBwFALV5JxXsBQ5ysAoCBgqIUryTgvYKjzFQBQEDDUwpVknBcw1PkKACgIGGrhSjLOCxjqfAUAFAQMtXAlGecFDHW+AgAKAoZauJKM8wKGOl8BAAUBQy1cScZ5AUOdrwCAgoChFq4k47yAoc5XAEBBwFALV5JxXsBQ5ysAoCBgqIUryTgvYKjzFQBQEDDUwpVknBcw1PkKACgIGGrhSjLOCxjqfAUAFAQMtXAlGecFDHW+AgAKAoZauJKM8wKGOl8BAAUBQy1cScZ5AUOdrwCAgoChFq4k47yAoc5XAEBBwFALV5JxXsBQ5ysAoCBgqIUryTgvYKjzFQBQEDDUwpVknBcw1PkKACgIGGrhSjLOCxjqfAUAFAQMtXAlGecFDHW+AgAKAoZauJKM8wKGOl8BAAUBQy1cScZ5AUOdrwCAgoChFq4k47yAoc5XAEBBwFALV5JxXsBQ5ysAoCDwBaT9ke70WG4vAAAAAElFTkSuQmCC
This is the reference to where the file should be uploaded:
const imageRef: StorageReference = ref(
storage,
`/issueImages/${firebaseImageId}`
);
So far, I have attempted to use the 'put' function with the imageRef, and when I try using uploadBytes() of firebase, I have to upload it as a Buffer, and even then I cannot seem to find the access token in the metadata.
To upload a data URL to Firebase, you would use storageRef.putString(url, 'DATA_URL') (legacy) or uploadString(storageRef, url, 'DATA_URL') (modern) depending on the SDK you are using.
When you upload a file to a Cloud Storage bucket, it will not be issued an access token until a client calls its version of getDownloadURL(). So to fix your issue, you would call getDownloadURL() immediately after upload.
If Node is running on a client's machine, you would use:
// legacy syntax
import * as firebase from "firebase";
// reference to file
const imageStorageRef = firebase.storage()
.ref(`/issueImages/${firebaseImageId}`);
// perform the upload
await imageStorageRef.putString(dataUrl, 'DATA_URL');
// get the download URL
const imageStorageDownloadURL = await imageStorageRef.getDownloadURL();
// modern syntax
import { getStorage, getDownloadURL, ref, uploadString } from "firebase/storage";
// reference to file
const imageStorageRef = ref(
getStorage(),
`/issueImages/${firebaseImageId}`
);
// perform the upload
await uploadString(imageStorageRef, dataUrl, 'DATA_URL');
// get the download URL
const imageStorageDownloadURL = await getDownloadURL(imageStorageRef);
If Node is running on a private server you control, you should opt to use the Firebase Admin SDK instead as it bypasses the rate limits and restrictions applied to the client SDKs.
As mentioned before, the download URLs aren't created automatically. Unfortunately for us, getDownloadURL is a feature of the client SDKs and the Admin SDK doesn't have it. So we can either let a client call getDownloadURL when it is needed or we can manually create the download URL if we want to insert it into a database.
Nico has an excellent write up on how Firebase Storage URLs work, where they collated information from the Firebase Extensions GitHub and this StackOverflow thread. In summary, to create (or recreate) a download URL once it has been uploaded, you can use the following function:
import { uuid } from "uuidv4";
// Original Credit: Nico (#nicomqh)
// https://www.sentinelstand.com/article/guide-to-firebase-storage-download-urls-tokens
// "file" is an instance of the File class from the Cloud Storage SDK
// executing this function more than once will revoke all previous tokens
function createDownloadURL(file) {
const downloadToken = uuid();
await file.setMetadata({
metadata: {
firebaseStorageDownloadTokens: downloadToken
}
});
return `https://firebasestorage.googleapis.com/v0/b/${file.bucket.name}/o/${encodeURIComponent(file.name)}?alt=media&token=${downloadToken}`;
}
The allows us to change the client-side code above into the following so it can run using the Admin SDK:
// assuming firebase-admin is initialized already
import { getStorage } from "firebase-admin/storage";
// reference to file
const imageStorageFile = getStorage()
.bucket()
.file(`/issueImages/${firebaseImageId}`);
// perform the upload
await imageStorageFile.save(dataUrl);
// get the download URL
const imageStorageDownloadURL = await createDownloadURL(imageStorageFile);
In all of the above examples, a download URL is retrieved and saved to the imageStorageDownloadURL variable. You should store this value as-is in your database. However, if you instead want to store only the access token and reassemble the URL on an as-needed basis, you can extract the token from its ?token= parameter using:
const downloadToken = new URL(imageStorageDownloadURL).searchParams.get('token');

Invalid account: #0 for network: ropsten - private key too short, expected 32 bytes

error picture
require("#nomiclabs/hardhat-waffle");
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
/**
* #type import('hardhat/config').HardhatUserConfig
*/
const INFURA_PROJECT_ID = "3dxxxx";
const ROPSTEN_PRIVATE_KEY = "e6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
module.exports = {
networks: {
ropsten: {
url: `https://ropsten.infura.io/v3/${INFURA_PROJECT_ID}`,
accounts: [`0x${ROPSTEN_PRIVATE_KEY}`]
}
}
};
I deployed the contract to ropsten according to the example on the website, but an error was reported. The private key is greater than 32 bits
It's happening because you put "0x" before your private key. I had a similar error. Also, you can use Alchemy if you want. Everything else looks good in your config.
I had the same error and used an env file to store the constants.
So in my case, the error was solved by removing the semicolon.
Some possible fixes:
Adding a 0x to the private key
Converting or casting the private key from .env file to a string with String, toString(), and string interpolation $0x{process.env.PRIVATE_KEY}
Checking that I was calling the test from the correct directory
Checking that the .env file was in the correct (project root) directory
Checking that the wallet software gave me the full private key and not a partial key
But what fixed the issue was importing:
require("#nomicfoundation/hardhat-toolbox");
require("dotenv").config();
at the top of the hardhat.config.js file

Google service account unable to list calendars?

Can anyone indicate the right settings to give allow a service account access to a Google calendar?
We have a node.js project that is meant to provide access to the Google calendars it has been given access to, but we can't work out why it can't see the calendars.
At the same time, we were able to trying a different account that has been working in another environment and this worked, but the problem is that no one who previously worked on the project has access to the configuration for it to compare.
The response.data we are getting with the problem account:
{
"kind": "calendar#calendarList",
"etag": "\"p33k9lxxjsrxxa0g\"",
"nextSyncToken": "COias9Pm4vUCEjxvdGurdXRob24tZGV2LXNlcnZpY2UxQG90YxxxdGhvbi1kZXYuaWFtLmdzZXJ2aWNlYWNxb3VudC5jb20=",
"items": []
}
Either way this would suggest the issue is with the configuration of the service account, rather than the code itself, but will share the code anyhow:
import { Auth, calendar_v3 as calendarV3 } from 'googleapis';
const Calendar = calendarV3.Calendar;
async getCalendarApi () {
const jwtClient = new Auth.JWT(
this.keyConfig.clientEmail,
undefined,
this.keyConfig.privateKey.replace(/\\n/g, '\n'),
[
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/calendar.events'
]
);
const calendarApi = new Calendar({
auth: jwtClient
});
await jwtClient.authorize();
return calendarApi;
}
async init () {
// loads the configuration from our app's configuration file
this.keyConfig = getKeyConfig('google-calendar');
const calendarApi = await this.getCalendarApi();
const response = await calendarApi.calendarList.list();
console.log(JSON.stringify(response.data, undefined, 2));
}
As for the service account, in the Google console, this is the how it was set up:
Open up https://console.cloud.google.com/
Select the appropriate project at the top
Search for 'Google Calendar API' in the search bar
Validate it is enabled
Click 'Manage', which takes me to https://console.cloud.google.com/apis/api/calendar-json.googleapis.com/metrics?project=xxxxxx ('xxxxxx' is the project id, but masked here)
Click on 'Credentials
Click on 'Create Credentials' at the top and select 'service account'
Provide a name of the service account
Click 'Create and Continue'
Add a role: Basic -> Viewer
Click 'Done'
In the 'Credentials' page (https://console.cloud.google.com/apis/credentials?project=xxxxxx) click edit for the account we just created
In the 'keys' section: Add key -> Create New Key and then specify JSON
From the above steps we take the client_email and the private_key field values to user with our nodejs app.
Then in the calendar we want it to access, we add the email address of the service account as a viewer.
Trying all the above still results in the list of calendars visible by the service account to be empty.
Any ideas?
From your explanation and the returned value, I'm worried that in your situation, you might have never inserted the shared Calendar with the service account. If my understanding is correct, how about the following modification?
Modification points:
Insert the shared Calendar to the service account.
In this case, please modify the scope https://www.googleapis.com/auth/calendar.readonly to https://www.googleapis.com/auth/calendar.
async init () {
// loads the configuration from our app's configuration file
this.keyConfig = getKeyConfig('google-calendar');
const calendarApi = await this.getCalendarApi();
const response = await calendarApi.calendarList.insert({resource: {id: "####group.calendar.google.com"}}); // Please set the Calendar ID here. Or {requestBody: {id: "####group.calendar.google.com"}}
console.log(JSON.stringify(response.data, undefined, 2));
}
Retrieve the calendar list using your script.
After the Calendar was inserted to the service account using the above script, you can obtain the shared Calendar in the Calendar list.
Reference:
CalendarList: insert

How to setup Google Translate API for Node.js?

I want to use Googles Cloud Translation API in my Node.js application, however I'm getting a The request is missing a valid API key. error.
I have followed the Quickstart guide provided by Google.
I have created GCP project, downloaded the private key as JSON file and setup the environment variable in Powershell (img).
After that I've installed the library with
yarn add #google-cloud/translate
The code I'm running in my translate.js file comes from the Quickstart guide with additional try-catch blocks:
async function quickstart(
projectId = process.env.PROJECT_ID // Project Id from JSON file
) {
try {
// Imports the Google Cloud client library
const { Translate } = require('#google-cloud/translate');
// Instantiates a client
const translate = new Translate({ projectId });
// The text to translate
const text = 'Hello, world!';
// The target language
const target = 'ru';
// Translates some text into Russian
const [translation] = await translate.translate(text, target);
console.log('Text:', text);
console.log('Translation:', translation);
} catch (error) {
console.error(error);
}
}
quickstart();
When I then run node translate.js, I'll get an Error:
{ Error: The request is missing a valid API key.
...
code: 403,
errors:
[ { message: 'The request is missing a valid API key.',
domain: 'global',
reason: 'forbidden' } ],
response: undefined,
message: 'The request is missing a valid API key.' }
I am on Windows 10, Node v10.13.0.
Believe you would have missed this environment variable defining , before starting the node service
Replace [PATH] with the file path of the JSON file that contains your service account key, and [FILE_NAME] with the filename.
With PowerShell:
$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
For example:
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\[FILE_NAME].json"

How to add credentials to Google text to speech API?

I am new to Python.I want to use Google text-to-speech API for that i used below code, but I am unable to access the API due to error. This is the code,
def synthesize_text(text):
"""Synthesizes speech from the input string of text."""
from google.cloud import texttospeech
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.types.SynthesisInput(text=text)
# Note: the voice can also be specified by name.
# Names of voices can be retrieved with client.list_voices().
voice = texttospeech.types.VoiceSelectionParams(
language_code='en-US',
ssml_gender=texttospeech.enums.SsmlVoiceGender.FEMALE)
audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3)
response = client.synthesize_speech(input_text, voice, audio_config)
# The response's audio_content is binary.
with open('output.mp3', 'wb') as out:
out.write(response.audio_content)
print('Audio content written to file "output.mp3"')
This is the error,
google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or
explicitly create credential and re-run the application. For more
information, please see
https://developers.google.com/accounts/docs/application-default-credentials.
I already have credentials JSON file, but I am unable to configure the code to authenticate my request.
Please help!
You could try this code:
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file('yourkey.json')
client = texttospeech.TextToSpeechClient(credentials=credentials)
There are 2 ways :
1 Way :
if you using Json file then better to set json path into Environment Variable, if you do this then you no need to setup in coding it will automatically get you license from there
GOOGLE_APPLICATION_CREDENTIALS=[path]
2 WAY :
I have Java code i don't know about python so you can get idea from here :
String jsonPath = "file.json";
CredentialsProvider credentialsProvider = FixedCredentialsProvider.create(ServiceAccountCredentials.fromStream(new FileInputStream(jsonPath)));
TextToSpeechSettings settings = TextToSpeechSettings.newBuilder().setCredentialsProvider(credentialsProvider).build();
Instantiates a client
TextToSpeechClient textToSpeechClient = TextToSpeechClient.create(settings)
this seems to be an old discussion but I thought to comment, maybe someone will come across like in my case :))
for nodejs client, I managed to authenticate it this way:
const client = new textToSpeech.TextToSpeechClient({
credentials: {
private_key: "??",
client_email: "???",
}
});
You could authenticate your google credential by different ways.
One is by setting OS environment and another one is authenticate while you initiate a request.
I would suggest oauth2client library for python to authenticate.
In addition to this refer my example on Github (Link).
You need to have a service account, and service account .json key File.
You need to pass the key file name while you creating the client Instance.
const client = new textToSpeech.TextToSpeechClient({
keyFilename: "./auth.json",
});
Download the key file and rename it as auth.json place it root of your project folder.
Make sure Your service account have proper access to call the API.
Here is the full code:
// Imports the Google Cloud client library
const textToSpeech = require("#google-cloud/text-to-speech");
// Import other required libraries
const fs = require("fs");
const util = require("util");
// Creates a client
const client = new textToSpeech.TextToSpeechClient({
keyFilename: "./auth.json",
});
async function quickStart() {
// The text to synthesize
const text = "Hello this is a test";
// Construct the request
const request = {
input: { text: text },
// Select the language and SSML voice gender (optional)
voice: { languageCode: "en-US", ssmlGender: "NEUTRAL" },
// select the type of audio encoding
audioConfig: { audioEncoding: "MP3" },
};
// Performs the text-to-speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);
await writeFile("output.mp3", response.audioContent, "binary");
console.log("Audio content written to file: output.mp3");
}
quickStart();

Resources