azure-graph produces Request_BadRequest: Invalid domain name in the request url - javascript

I am trying to retrieve the user object by ID using Node.js. Here is my code:
const MsRest = require('ms-rest-azure');
const credentials = await MsRest.loginWithServicePrincipalSecret(keys.appId, keys.pass, keys.tenantId, { tokenAudience: 'graph' });
const GraphkManagementClient = require('azure-graph');
const client = new GraphkManagementClient(credentials, subscriptionId);
return client.users.get(principalID);
But client.users.get(principalID) produces a request that returns:
Request_BadRequest: Invalid domain name in the request url
This is the url it produces (with the true values instead of {tenant id} and {user id}):
https://graph.windows.net/{tenant id}/users/{user id}?api-version=1.6

For azure-graph sdk, it seems should be GraphkManagementClient(credentials,'<tenantId>').
You could refer to this sample:
const AzureGraphClient = require('azure-graph');
const MsRestAzure = require('ms-rest-azure');
const options = {
tokenAudience: 'graph',
domain: '<tenantId>'
};
MsRestAzure.loginWithServicePrincipalSecret(
'clientId or appId',
'secret or password',
'domain or tenantId',
options,
(err, credentials) => {
if (err) throw err;
let graphClient = AzureGraphClient(credentials, '<tenantId>');
// ..use the client instance to manage service resources.
});
It is also mentioned here:
var graphRbacManagementClient = require('azure-graph');
var client = new graphRbacManagementClient(credentials, tenantId);

Related

UI updates with weather data after 2 clicks, but only on the first time then doesn't work

I am building a weather app that shows weather data depending on the city, the user selects the city from a drop-down, then the city name is sent to the server with a post request using fetch, and the server makes a get request to the open weather map API using Axios, gets the weather data and sends it back to the frontend using a get request then this data is used to update the UI.
Now when I first click submit, I get 2 error messages in the console GET http://localhost:3000/fulldata 404 (Not Found) and Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON then when I click again, the UI updates correctly, then when I choose another city and click submit again, nothing happens, no new errors in the console or the terminal. I tried to await the sendCityToServer function but then the UI doesn't update even on the second click and no errors are shown in the console or terminal
Frontend code
// Global Variables
const SERVER_URL = 'http://localhost:3000/'
const COUNTRIES_NAMES_API = 'https://restcountries.com/v3.1/all'
// Create a new date instance dynamically with JS
let d = new Date().toDateString()
// HTML Selectors
const generate = document.querySelector('#generate')
const date = document.querySelector('.date')
const temp = document.querySelector('.temperature')
const weatherCondition = document.querySelector('.weatherCondition')
const country = document.querySelector('.place')
const weatherIcon = document.querySelector('.wi')
const countriesNames = async () => {
const select = document.querySelector('#countries')
const countriesList = await (await fetch(COUNTRIES_NAMES_API)).json()
countriesList.splice(38, 1)
countriesList.forEach(country => {
const option = document.createElement('option')
if (country.capital) {
option.innerText = `${country.capital[0]}`
select.append(option)
}
})
}
// Getting data from API
const APIdata = async () => {
const citySelector = document.querySelector('#countries').value
sendCityToServer(`${SERVER_URL}postcityselector`, { city: citySelector })
// API Keys
const data = await (await fetch(`${SERVER_URL}fulldata`)).json()
// Update UI with API data
weatherIcon.src = `http://openweathermap.org/img/wn/${data.weather[0].icon}#4x.png`
date.innerText = date
temp.innerText = Math.floor(data.main.temp) + '°C'
weatherCondition.innerText = data.weather[0].description
country.innerText = data.name
}
// Update UI when button is clicked
generate.addEventListener('click', APIdata)
async function sendCityToServer(url = '', data = {}) {
const response = fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
}
countriesNames()
Server code (Removed the setup of express, body parser, cors and dotenv)
const apiKeys = {
URL: process.env.BASE_URL,
KEY: process.env.API_KEY,
}
weatherData = {}
app.post('/postcityselector', req => {
axios.get(apiKeys.URL + req.body.city + apiKeys.KEY).then(response => {
app.get('/fulldata', (req, res) => {
res.send(response.data)
})
})
})

Using Google Speech REST APi from Node without helper module

I'm just getting started with a simple project in node.js.
I'm trying to use Expo for the final app but get lots of dependency conflicts in the modules so was thinking of just calling the REST API via fetch. I have a test bed that works fine using the google-supplied modules, but I always get RecognitionAduio is not supplied as an error message via REST. As you can see in the attached code, the input file, coding etc are all identical.
any views?
async function getAudioTranscription() {
const fetch = require("node-fetch");
try {
var filename = 'C:/Users/SteveRist/Downloads/brooklyn.flac';
var encoding = 'FLAC';
var sampleRateHertz = 16000;
var languageCode = 'en-US';
const fs = require('fs');
const speech = require('#google-cloud/speech');
const client = new speech.SpeechClient();
console.log ('Setting REST config');
const config = {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
languageCode: languageCode,
};
console.log ('opening ', filename);
const audio = {
content: fs.readFileSync(filename).toString('base64'),
};
const request = {
config: config,
audio: audio,
};
// Detects speech in the audio file. This creates a recognition job that you
// can wait for now, or get its result later.
const [operation] = await client.longRunningRecognize(request);
// Get a Promise representation of the final result of the job
const [response] = await operation.promise();
const transcription = response.results
.map(result => result.alternatives[0].transcript)
.join('\n');
console.log(`Transcription: ${transcription}`);
const transcriptResponse = await fetch(
'https://speech.googleapis.com/v1/speech:recognize?key=xxx8', {
method: 'POST',
request: request
}
);
const data = await transcriptResponse.json();
console.log ('transcriptResponse Google returned' , data);
const userMessage = data.results && data.results[0].alternatives[0].transcript || "";
console.log (userMessage);
} catch (error) {
console.log("There was an error", error);
}
}
getAudioTranscription();

sending conversion data to google ads from server code

usually we add a script to our website to track conversion for google analytics. Is there any way send the data from plain javascript code such as in the case of Facebook. for example:
'use strict';
const bizSdk = require('facebook-nodejs-business-sdk');
const Content = bizSdk.Content;
const CustomData = bizSdk.CustomData;
const DeliveryCategory = bizSdk.DeliveryCategory;
const EventRequest = bizSdk.EventRequest;
const UserData = bizSdk.UserData;
const ServerEvent = bizSdk.ServerEvent;
const access_token = '<ACCESS_TOKEN>';
const pixel_id = '<ADS_PIXEL_ID>';
const api = bizSdk.FacebookAdsApi.init(access_token);
let current_timestamp = Math.floor(new Date() / 1000);
const userData = (new UserData())
.setEmails(['joe#eg.com'])
.setPhones(['12345678901', '14251234567'])
// It is recommended to send Client IP and User Agent for Conversions API Events.
.setClientIpAddress(request.connection.remoteAddress)
.setClientUserAgent(request.headers['user-agent'])
.setFbp('fb.1.1558571054389.1098115397')
.setFbc('fb.1.1554763741205.AbCdEfGhIjKlMnOpQrStUvWxYz1234567890');
const content = (new Content())
.setId('product123')
.setQuantity(1)
.setDeliveryCategory(DeliveryCategory.HOME_DELIVERY);
const customData = (new CustomData())
.setContents([content])
.setCurrency('usd')
.setValue(123.45);
const serverEvent = (new ServerEvent())
.setEventName('Purchase')
.setEventTime(current_timestamp)
.setUserData(userData)
.setCustomData(customData)
.setEventSourceUrl('http://jaspers-market.com/product/123')
.setActionSource('website');
const eventsData = [serverEvent];
const eventRequest = (new EventRequest(access_token, pixel_id))
.setEvents(eventsData);
eventRequest.execute().then(
response => {
console.log('Response: ', response);
},
err => {
console.error('Error: ', err);
}
);
or we can do something like:
To send new events, make a POST request to this API's /events edge from this path: https://graph.facebook.com/{API_VERSION}/{PIXEL_ID}/events?access_token={TOKEN}. When you post to this edge, Facebook creates new server events.

MongoDB with Node Index Error

I'm currently using a node.js application to scan Twitter's API based on a set of parameters, and then uploading those JSON objects to a MongoDB database kept on MLab. I have connected to the database without issue, but my code will only upload ONE tweet before crashing. Here is the error message:
(node:62948) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): BulkWriteError: E11000 duplicate key error index: test-database.test-collection.$_id_ dup key: { : ObjectId('5aecb49e205197f5e4f52e32') }
It seems to have something to do with the keys that I am using in the database? How can I write my code so that I don't have this issue. Here is my program right now:
var Twitter = require("twitter");
var config = require("./config");
const mongoose = require("mongoose");
const MongoClient = require("mongodb");
var twitterClient = new Twitter(config);
const assert = require("assert");
const dbName = "test-database";
const collectionName = "test-collection";
const url = "mongodb://user:password#ds113870.mlab.com:13870/test-database";
const param = {follow: '21111098,958191744683782144,18061669,21111098,18061669,2891210047,1869975300,19394188,4107251,16056306,259459455,21111098,18061669,2891210047,1869975300,19394188,4107251,16056306,259459455,968650362,343041182,5558312,111671288,476256944,378631423,803694179079458816,30354991,224285242,45645232,235217558,20879626,150078976,278124059,102477372,249787913,381577682,15324851,435500714,823302838524739584,20597460,555355209,15745368,229966028,3001665106,2863210809,1397501864,78403308,253252536,47747074,1262099252,1284467173,92186819,169198625,600463589,413160266,1096059529,1095504170,1058520120,328679423,247334603,308794407,216503958,234128524,59969802,10615232,118740781,1383059977,2856787757,75364211,586730005,18632666,18632809,1249982359,339822881,365530059,216881337,3229124078,55677432,816683274076614656,26594419,1068481578,1068540380,19726613,13529632,18137749,3067974778,109071031,278094476,21406834,1129029661,970207298,357606935,236511574,145292853,76456274,456137574,33537967,941000686275387392,555474658,264219447,11650762,16160352,57065141,753693622692970497,21269970,238177562,389554914,11651202,214767677,515822213,16473577,1071402577,323490669,1480852568,2962923040,2987970190,811313565760163844,3145735852,266133081,41363507,109287731,14125897,946549322,361569788,15808765,1603426344,18695134,407039290,1099199839,183062944,60828944,325231436,14140370,17494010,1872999342,72198806,709389393811927041,21157904,213339899,2964174789,22195441,1061029050,460376288,382791093,106733567,43910797,24768753,18915145,240790556,2612307559,7270292,20546536,225921757,27044466,250188760,292495654,122124607,29201047,223166587,171598736,94154021,221162525,26062385,486694111,242555999,770121222,14845376,432895323,3219708271,217543151,81191343,2955485182,978029858,296361085,26533227,76649729,21669223,283130017,73303753,13218102,1648117711,1074480192,23022687,262756641,18170310,88784440,242836537,946946130,172858784,7429102,409719505,293131808,158470209,117501995,35567751,193794406,158890005,234374703,113355380,1074518754,87510313,233737858,291756142,1848942470,202206694,499268312'};
let newTweet = {
name: "",
text: "",
followers: ""
}
MongoClient.connect(url, function(err, client){
assert.equal(null,err);
console.log("connected.");
const db = client.db(dbName);
const collection = db.collection(collectionName);
const insertDocument = function(db, callback){
// THIS IS WHERE I THINK THE PROBLEM IS //
collection.insert(newTweet)
}
twitterClient.stream('statuses/filter',param,function(stream) {
stream.on('data', function(tweet) {
newTweet.name = tweet.user.screen_name;
newTweet.followers = tweet.user.followers_count;
newTweet.text = (tweet.extended_tweet) ? tweet.extended_tweet.text : tweet.text;
insertDocument(newTweet, function(){
db.close();
});
});
});
});
You are closing the database immediately after inserting one tweet.
// stream.on('data', function(tweet) {
insertDocument(newTweet, function(){
db.close();
});
Instead, close the connection on stream end.
stream.on('end', function() {
db.close();
});
You are getting the Duplicate key issue, because you declared the newTweet object globally, which shares the same object for every tweet. Declare the tweet object inside the stream.on('data') handler function. i.e.
stream.on('data', function(tweet) {
let newTweet = {};
newTweet.name = tweet.user.screen_name;
newTweet.followers = tweet.user.followers_count;

How to authenticate and send contract method using web3.js 1.0

I am confused about how I should be executing a contract's method using the web3 1.0 library.
This code works (so long as I manually unlock the account first):
var contract = new web3.eth.Contract(contractJson, contractAddress);
contract.methods
.transfer("0x0e0479bC23a96F6d701D003c5F004Bb0f28e773C", 1000)
.send({
from: "0x2EBd0A4729129b45b23aAd4656b98026cf67650A"
})
.on('confirmation', (confirmationNumber, receipt) => {
io.emit('confirmation', confirmationNumber);
});
I get this error (if I don't unlock manually first):
Returned error: authentication needed: password or unlock
The above code is an API endpoint in node.js, so I want it to unlock or authenticate programmatically.
There is no method in web3.js 1.0 to unlock the account.
I also don't think this is necessary (at least that's what I am confused about). Since I am managing accounts, I know what the private key is.
I am thinking the transaction needs to be signed with the private key?? Is this correct? Is this effectively the same thing as "unlocking the account"?
I tried doing this:
var contract = new web3.eth.Contract(contractJson, contractAddress);
var tx = {
from: "...{fromAddress -- address that has the private key below}",
to: "...",
value: ...
};
var signed = web3.eth.accounts.signTransaction(tx,
"...{privateKey}");
console.log(signed);
var promise = web3.eth.sendSignedTransaction(signed);
I get this error:
Returned error: The method net_version does not exist/is not available
What is the easiest way to authenticate and submit a transaction?
Ideally, I want to use the first approach in my code sample, as it is the cleanest.
This code allows me to sign a transaction server-side (node.js) using the privateKey from the account I created (using web3.eth.accounts.create()), and send the signed transaction to the network without having to unlock the account.
I am using Geth 1.7.1
var contract = new web3.eth.Contract(contractJson, contractAddress);
var transfer = contract.methods.transfer("0x...", 490);
var encodedABI = transfer.encodeABI();
var tx = {
from: "0x...",
to: contractAddress,
gas: 2000000,
data: encodedABI
};
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
var tran = web3.eth.sendSignedTransaction(signed.rawTransaction);
tran.on('confirmation', (confirmationNumber, receipt) => {
console.log('confirmation: ' + confirmationNumber);
});
tran.on('transactionHash', hash => {
console.log('hash');
console.log(hash);
});
tran.on('receipt', receipt => {
console.log('reciept');
console.log(receipt);
});
tran.on('error', console.error);
});
A way to be able to call your contract methods without having to sign the transaction explicitly is this (web3js 1.0.0):
const privateKey = 'e0f3440344e4814d0dea8a65c1b9c488bab4295571c72fb879f5c29c8c861937';
const account = web3.eth.accounts.privateKeyToAccount('0x' + privateKey);
web3.eth.accounts.wallet.add(account);
web3.eth.defaultAccount = account.address;
// ...
contract = new web3.eth.Contract(JSON_INTERFACE, address);
contract.methods.myMethod(myParam1, myParam2)
.send({
from: this.web3.eth.defaultAccount,
gas: myConfig.gas,
gasPrice: myConfig.gasPrice
})
Here's a complete example of how to sign a transaction without a local wallet account. Especially useful if you are using infura for the transaction. This was written for
'use strict';
const Web3 = require('web3');
const wsAddress = 'wss://rinkeby.infura.io/ws';
const contractJson = '(taken from solc or remix online compiler)';
const privateKey = '0xOOOX';
const contractAddress = '0xOOOX';
const walletAddress = '0xOOOX';
const webSocketProvider = new Web3.providers.WebsocketProvider(wsAddress);
const web3 = new Web3(new Web3.providers.WebsocketProvider(webSocketProvider));
const contract = new web3.eth.Contract(
JSON.parse(contractJson),
contractAddress
);
// change this to whatever contract method you are trying to call, E.G. SimpleStore("Hello World")
const query = contract.methods.SimpleStore('Hello World');
const encodedABI = query.encodeABI();
const tx = {
from: walletAddress,
to: contractAddress,
gas: 2000000,
data: encodedABI,
};
const account = web3.eth.accounts.privateKeyToAccount(privateKey);
console.log(account);
web3.eth.getBalance(walletAddress).then(console.log);
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
const tran = web3.eth
.sendSignedTransaction(signed.rawTransaction)
.on('confirmation', (confirmationNumber, receipt) => {
console.log('=> confirmation: ' + confirmationNumber);
})
.on('transactionHash', hash => {
console.log('=> hash');
console.log(hash);
})
.on('receipt', receipt => {
console.log('=> reciept');
console.log(receipt);
})
.on('error', console.error);
});
Using
"web3": "1.0.0-beta.30"
This is my implementation using "#truffle/hdwallet-provider": "^2.0.3", "web3": "^1.6.1",
function getWeb3Provider() {
return new HDWalletProvider({
privateKeys: [NFT_MINTER_ACCOUNT_PRIVATE_KEY],
providerOrUrl: BSC_RPC_ENDPOINT,
});
}
const web3 = new Web3(BSC_RPC_ENDPOINT);
const contract = new web3.eth.Contract(
jsonContractABI as unknown as AbiItem[],
NFT_CONTRACT_ADDRESS
);
contract.setProvider(getWeb3Provider());
then in send methods
contract.methods.safeMint(receiverAddress, itemUri).send({
from: NFT_MINTER_ACCOUNT,
});
in call methods
contract.methods.balanceOf(address).call();

Categories

Resources