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.
Related
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)
})
})
})
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();
I am trying to swap ETH for DAI tokens using the UniSwap SDK and javascript, but am getting the following error on running the script.
(node:10096) UnhandledPromiseRejectionWarning: Error: resolver or addr is not configured for ENS name (argument="name", value="", code=INVALID_ARGUMENT, version=contracts/5.0.5)
I have narrowed the error down to the uniswap.swapExactETHForTokens function but I still don't know how to fix it.
Full code: (Private keys are hidden from the code for obvious reasons)
const { ChainId, Fetcher, WETH, Route, Trade, TokenAmount, TradeType, Percent } = require('#uniswap/sdk');
const ethers = require('ethers');
const chainId = ChainId.MAINNET;
const tokenAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F';
const init = async () => {
const dai = await Fetcher.fetchTokenData(chainId, tokenAddress);
const weth = WETH[chainId];
const pair = await Fetcher.fetchPairData(dai, weth);
const route = new Route([pair], weth);
const trade = new Trade(route, new TokenAmount(weth, '1000000000000'), TradeType.EXACT_INPUT);
const slippageTolerance = new Percent('50', '10000');
const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw;
const path = [weth.address, dai.address];
const to = '';
const deadline = Math.floor(Date.now() / 1000) + 60 * 20;
const value = trade.inputAmount.raw;
const provider = ethers.getDefaultProvider('mainnet', {
infura: 'https://mainnet.infura.io/v3/ba14d1b3cfe5405088ee3c65ebd1d4'
});
const signer = new ethers.Wallet(PRIVATE_KEY);
const account = signer.connect(provider);
const uniswap = new ethers.Contract(
'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
['function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)'],
account
);
const tx = await uniswap.swapExactETHForTokens(
amountOutMin,
path,
to,
deadline,
{ value, gasPrice: 20e9 }
);
console.log(`Transaction hash: ${tx.hash}`);
const receipt = await tx.wait();
console.log(`Transaction was mined in block ${receipt.blockNumber}`);
}
init();
I guess you can replace
const to = ''
by:
const to = process.env.ACCOUNT
providing your account / wallet address to which the targetTokens shall be sent.
In my case, I had directly copy-pasted the router address from the uniswap documentation. So my variable looked something like this:
const routerAddress = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D ";
Since there was a space at the end of the string, the ethers.js library confused it for ENS name instead of an address. So I corrected it to this:
const routerAddress = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
Guess it was a silly mistake, but just watch out for it, in case nothing works!
For those who are facing an INVALID ARGUMENT error, here's what worked for my (using React):
Import router02 :
import UniswapV2Router02 from '#uniswap/v2-periphery/build/UniswapV2Router02.json';
hex function:
const toHex = (currencyAmount) => `0x${currencyAmount.raw.toString(16)}`;
const amountOutMin = toHex(trade.minimumAmountOut(slippageTolerance));
const value = toHex(trade.inputAmount);
connect to blockchain
const provider = ethers.getDefaultProvider('mainnet', {
infura: 'JUST_INFURA_NUMBER eg. xxxxxxxxxx'
});
Get contract and methods:
const abi = UniswapV2Router02['abi'];
const uniswapRouter = new ethers.Contract(
'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
abi,
account); //if this doesnt work, try using provider/signer instead of account
console.log("uniswap contract: ", uniswapRouter);
const tx = await uniswapRouter.swapExactETHForTokens(
amountOutMin,
path,
to,
deadline,
{value, gasPrice: 20e9, gasLimit: 250000}
);
Tutorial code: https://www.youtube.com/watch?v=0Im5iaYoz1Y
I am trying to create a raw transaction for sending to the blockchain. In doing so, I want to do this in a browser.
Where can I get nonWitnessUtxo?
All the information that I have outlined here, I found in the tests.
Am I doing the right thing?
const bitcoin = require('bitcoinjs-lib')
const testnet = bitcoin.networks.testnet
const keyPair = bitcoin.ECPair.makeRandom({ network: testnet })
const publicKey = keyPair.publicKey
const { address } = bitcoin.payments.p2pkh({
pubkey: publicKey,
network: testnet
})
const privateKey = keyPair.toWIF()
const psbt = new bitcoin.Psbt({ network: testnet })
const txid = '226a14d30cfd411b14bf20b7ffd211f7f206699690c54d456cc1bef70c2de5a6'
const key = bitcoin.ECPair.fromWIF(privateKey, testnet)
psbt.addInput({
hash: txid,
index: 0,
nonWitnessUtxo: Buffer.from('Where can i get this?', 'hex')
})
psbt.addOutput({
script: Buffer.from('mmpAPZSvhJs1NGw8UaJXEJ9vRByAxProUL', 'hex')
value: 10000
})
psbt.signInput(0, key)
psbt.validateSignaturesOfInput(0)
psbt.finalizeAllInputs()
psbt.extractTransaction().toHex()
I would be grateful for any help!
The nonWitnessUtxo is the full rawtransaction that you are referencing with the input txid.
This answer is for those looking for a way to create a transaction in the browser, but could not deal with the bitcoinjs-lib
I use bitcore-lib - https://www.npmjs.com/package/bitcore-lib
const bitcore = require('bitcore-lib')
const firstPrivateKey = new bitcore.PrivateKey()
const secondPrivateKey = new bitcore.PrivateKey()
const wif = firstPrivateKey.toString()
const toAddress = secondPrivateKey.toAddress().toString()
const satoshiAmount = 10000
const privateKey = bitcore.PrivateKey.fromWIF(wif)
const sourceAddress = privateKey.toAddress(bitcore.Networks.testnet)
const targetAddress = bitcore.Address.fromString(toAddress)
const utxos = [
{
address: 'mywRqUpbENhbu5VsYDwiMTJouVK9g2ZEJQ',
txid: '761693565e82ca176532c52a37fb38cd9f1eb0172a00562b394e60ede0b7df8a',
vout: 1,
scriptPubKey: '76a914ca133ceac705b723b91263aa163ea8a45954e49a88ac',
amount: 0.0001,
satoshis: 10000,
height: 1578273,
confirmations: 338
}
]
const transaction = new bitcore.Transaction()
transaction.from(utxos)
transaction.to(targetAddress, Number(satoshiAmount))
transaction.change(sourceAddress)
transaction.sign(privateKey)
const serializedTX = tx.serialize()
Then you need send this serializedTX as raw transaction to bitcoin network.
P.S. This example does not work because there is an invalid is presented utxos. Get your utxos using API, such as https://bitpay.com/api/addr/${sourceAddress}/utxo and then everything will work.
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);