How can I use the API of BigQuery in javascript? - google-bigquery

Is it possible in javascript to get or insert data of BigQuery by Using API?
It does not working. (refer to the site https://developers.google.com/api-client-library/javascript/samples/samples)
<html>
<head>
<script src="https://apis.google.com/js/api.js"></script>
<script>
function start() {
gapi.client.init({
'apiKey': 'mykey',
}).then(function() {
return gapi.client.request({
'path' : 'https://www.googleapis.com/bigquery/v2/projects/projectId/queries/jobId',
'method' : 'GET'
'params' : {'projectId':'myid', 'jobId':'myid'}
});
}).then(function(response) {
console.log(response.result);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
};
gapi.load('client', start);
</script>
</head>
<body>
<div id="results"></div>
</body>
</html>

// Import the Google Cloud client library
const {BigQuery} = require('#google-cloud/bigquery');
async function queryStackOverflow() {
// Queries a public Stack Overflow dataset.
// Create a client
const bigqueryClient = new BigQuery();
// The SQL query to run
const sqlQuery = `SELECT repo.name FROM githubarchive.year.2019
where repo.name LIKE '%googlemaps%'
or repo.name LIKE '%google-maps%'
or repo.name LIKE '%google-maps-api%'
or repo.name LIKE '%googlemapsapi%'
Group by
repo.name`;
const options = {
query: sqlQuery,
};
// Run the query
const [rows] = await bigqueryClient.query(options);
console.log(rows);
}
queryStackOverflow();

Related

Square Payment SDK not taking amount from form

I have setup the Square SDK but I am having issue now, It is not taking the custom Input field value in processor file.
Here are my Codes,
<!DOCTYPE html>
<html>
<head>
<link href="css/app.css" rel="stylesheet" />
<script
type="text/javascript"
src="https://sandbox.web.squarecdn.com/v1/square.js"
></script>
<script>
const appId = 'sandbox-XXXXX-XXXXXXXXX';
const locationId = 'XXXXXXXXXXXXXX';
async function initializeCard(payments) {
const card = await payments.card();
await card.attach('#card-container');
return card;
}
async function createPayment(token) {
const body = JSON.stringify({
locationId,
sourceId: token,
});
const paymentResponse = await fetch('payment-process.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (paymentResponse.ok) {
return paymentResponse.json();
}
const errorBody = await paymentResponse.text();
throw new Error(errorBody);
}
async function tokenize(paymentMethod) {
const tokenResult = await paymentMethod.tokenize();
if (tokenResult.status === 'OK') {
return tokenResult.token;
} else {
let errorMessage = `Tokenization failed with status: ${tokenResult.status}`;
if (tokenResult.errors) {
errorMessage += ` and errors: ${JSON.stringify(
tokenResult.errors
)}`;
}
throw new Error(errorMessage);
}
}
// status is either SUCCESS or FAILURE;
function displayPaymentResults(status) {
const statusContainer = document.getElementById(
'payment-status-container'
);
if (status === 'SUCCESS') {
statusContainer.classList.remove('is-failure');
statusContainer.classList.add('is-success');
} else {
statusContainer.classList.remove('is-success');
statusContainer.classList.add('is-failure');
}
statusContainer.style.visibility = 'visible';
}
document.addEventListener('DOMContentLoaded', async function () {
if (!window.Square) {
throw new Error('Square.js failed to load properly');
}
let payments;
try {
payments = window.Square.payments(appId, locationId);
} catch {
const statusContainer = document.getElementById(
'payment-status-container'
);
statusContainer.className = 'missing-credentials';
statusContainer.style.visibility = 'visible';
return;
}
let card;
try {
card = await initializeCard(payments);
} catch (e) {
console.error('Initializing Card failed', e);
return;
}
// Checkpoint 2.
async function handlePaymentMethodSubmission(event, paymentMethod) {
event.preventDefault();
try {
// disable the submit button as we await tokenization and make a payment request.
cardButton.disabled = true;
const token = await tokenize(paymentMethod);
const paymentResults = await createPayment(token);
displayPaymentResults('SUCCESS');
console.debug('Payment Success', paymentResults);
} catch (e) {
cardButton.disabled = false;
displayPaymentResults('FAILURE');
console.error(e.message);
}
}
const cardButton = document.getElementById('card-button');
cardButton.addEventListener('click', async function (event) {
await handlePaymentMethodSubmission(event, card);
});
});
</script>
</head>
<body>
<form id="payment-form">
<div id="card-container"></div>
<input type="hidden" name="amount" value="500">
<button id="card-button" type="button">Pay $1.00</button>
</form>
<div id="payment-status-container"></div>
</body>
</html>
And The Next Processing file is payment-process.php
<?php
require 'vendor/autoload.php';
use Square\SquareClient;
use Square\Environment;
use Square\Exceptions\ApiException;
use Square\Models\Money;
use Square\Models\CreatePaymentRequest;
use Square\Models\createPayment;
$client = new SquareClient([
'accessToken' => 'EAAAEKE_XXXXXXXXXXXXXXXXXXXXXXXXvs3LXwg0A8TTX2dN5cR5u',
'environment' => Environment::SANDBOX,
]);
$payments_api = $client->getPaymentsApi();
$data = json_decode(file_get_contents('php://input'), true);
$amount = $_POST['amount'];
$amount = $amount * 100;
$money = new Money();
$money->setAmount($amount);
$money->setCurrency('AUD');
$Current_User = 78;
$TransactionID = 'BZ_'.$Current_User.'-'.rand(0000,9999);
$create_payment_request = new CreatePaymentRequest($data['sourceId'], $TransactionID, $money);
$create_payment_request->setNote('Description of Amount');
$response = $payments_api->createPayment($create_payment_request);
if ($response->isSuccess()) {
echo json_encode($response->getResult());
} else {
echo json_encode($response->getErrors());
}
?>
I have tried it with $data['input'] as well as $_POST['amount']
But it always give error of INVALID_AMOUNT_MONEY But If I put the same amount directly in variable $amount = 500; It works perfect.
It is not taking value from the Payment form.

Setup of swagger-ui-express with API Gateway

I am not able to figure out the correct setup of either my API Gateway or swagger-ui-express.
The lambda function runs successful and and return the html but the related resouces are not able to be loaded and get an 404 error.
const app = express();
const swaggerUI = require('swagger-ui-express');
const serverlessExpress = require('#vendia/serverless-express');
const Stage = process.env.Stage;
const apiId = process.env.apiId;
const options = {
customCss: '.swagger-ui .topbar { display: none }',
customCss: '.swagger-ui .topbar { background-color: red }'
}
let serverlessExpressInstance
async function asyncTask() {
// load latest spec from API Gateway export removed to simplicity reasons.
const swaggerDocument = spec;
console.log("load swagger file complete.");
return swaggerDocument
}
async function setup(event, context) {
const swaggerDocument = await asyncTask()
console.log(swaggerDocument)
app.use('/api-doc', swaggerUI.serveWithOptions({ redirect: false }));
app.use('/api-doc', swaggerUI.setup(swaggerDocument, options));
console.log("setup of swagger complete");
serverlessExpressInstance = serverlessExpress({ app })
return serverlessExpressInstance(event, context)
}
function handler(event, context) {
if (serverlessExpressInstance) return serverlessExpressInstance(event, context)
return setup(event, context)
}
exports.handler = handler
Setup on API Gateway is the following:
Both resources are pointing to the lambda function.
When I load the page via: https://.execute-api..amazonaws.com/dev/api-doc
The following errors are raised:
How can I ensure that the resources are loaded correctly via the correct path ...dev/api/doc/...
You're probbably getting these errors because swagger-ui is configured to look for the image/js resources and express doesn't serve these files. You could potentially use something like serverless-http like this, but I'm not really sure it's a good idea to try and force express into the response of an API gateway lambda function.
As an alternative I managed to get swagger up and running on an API Gateway lambda function, fetching the swagger JSON directly.
import { APIGateway } from "aws-sdk";
import { env } from "../../helpers/env";
const API_ID = env("API_ID", "");
export const handler = async () => {
const apiGateway = new APIGateway({
apiVersion: "2018-11-29",
});
const apiGatewayExport = await apiGateway
.getExport({
exportType: "swagger",
restApiId: API_ID,
stageName: "prod",
accepts: "application/json",
parameters: {
extensions: "apigateway",
},
})
.promise();
if (!apiGatewayExport.body) {
throw new Error("No body found in API Gateway Export");
}
return {
statusCode: 200,
headers: {
"Content-Type": "text/html",
},
body: generateSwaggerPageBody(apiGatewayExport.body?.toString()),
};
};
const generateSwaggerPageBody = (swaggerSpec: string) => `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist#3/swagger-ui.css">
</head>
<body>
<div id="swagger"></div>
<script src="https://unpkg.com/swagger-ui-dist#3/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
dom_id: '#swagger',
spec: ${swaggerSpec}
});
</script>
</body>
</html>`;
I'm taking the API information directly from API Gateway via SDK and then I just return an html page with tags loading swagger directly - no express overhead needed.

Telegram Bot API - public download urls for files contain bot token

I need to get public url for file with telegram bot API. The problem with getFile method that it returns url in following format: https://api.telegram.org/file/bot<token>/<file_path> meaning I can't really share it in public because it contains my bot token, sharing this url wouldn't be secure.
Is it possible to get public url for file id that does not have my bot token in it? What are the alternatives?
I have created the following solution as a Proof Of Concept. Please check:
https://gist.github.com/gilpanal/099ff5fc94366fbaabd5e2fbedc7c86f
The idea is that you access to the binary data of your file through an intermediate API where your token is safe.
/*** server.js ***/
/* TESTED WITH NODE VERSION 14+ */
const express = require('express')
const app = express()
const https = require('https')
const port = process.env.PORT || 3000
// Use an Environment Variable to Secure Token Value
const BOT_TOKEN = <BOT_SECRET_TOKEN>
// For better CORS: https://expressjs.com/en/resources/middleware/cors.html
app.use( (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
next()
})
app.get('/', (req, res) => {
res.sendStatus(200)
})
// Inspired by: https://stackoverflow.com/a/21024737
app.get('/fileDownload', (req, res) => {
let uploadResponse = { ok: false, result: null, error: 404, description: 'Not Found' }
if (req._parsedUrl && req._parsedUrl.query) {
const tel_file_path = 'https://api.telegram.org/file/bot' + BOT_TOKEN + req._parsedUrl.query
https.get(tel_file_path, (response) => {
const data = []
response.on('data', (chunk) => {
data.push(chunk)
}).on('end', () => {
const buffer = Buffer.concat(data)
res.send(buffer)
})
})
} else {
res.sendStatus(uploadResponse)
}
})
app.listen(port)
/*** app.js ***/
const TEL_PATH = '/music/file_352.mp3'
const API_FILEDONWLOAD = 'http://localhost:3000/fileDownload?'
const load = () => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', API_FILEDONWLOAD + TEL_PATH, true)
xhr.responseType = 'arraybuffer'
xhr.send()
xhr.addEventListener('progress', (e) => {
console.log(`${e.type}: ${e.loaded} bytes transferred\n`)
})
xhr.addEventListener('load', (e) => {
const audioData = e.target.response || e.target.result
resolve(audioData)
})
xhr.addEventListener('error', () => {
reject(Error('Track ' + TEL_PATH + ' failed to load'))
})
})
}
load().then((audiData) => {
console.log(audiData)
}).catch((err) =>{
console.log(err)
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
BODY
<script src="app.js"></script>
</body>
</html>

How use axios in web worker with vue?

I've try use axios request in web worker by vue plugin
My code looks like this:
//worker.js
import axios from 'axios';
export default function getApiData(args) {
axios.get('/api/test').then(response => {
console.log(response);
});
}
And main file with Vue
//main.js
import getApiData from './worker.js';
Vue.use(VueWorker);
window.vueApp = new Vue({
//...
created: function() {
this.updateWorker = this.$worker.create([
{
message: 'getApiData ',
func: getApiData
}
]);
this.testWorker.postMessage('getApiData ', [this.args])
.then(result => {
console.log(result);
})
},
//...
}
And I got this error
Uncaught ReferenceError: axios__WEBPACK_IMPORTED_MODULE_0___default is
not defined
What I'm doing wrong?
I had the same problem and solved it by going back to the basics - using plain old XMLRequest (see below).
You can't use axios inside the worker because the blob that's created behind the scenes to load the worker.js runs in a different context than your main.js. In order for axios to work, you would have to setup a new webpack bundler to just bundle the worker by itself. I didn't want to do that - it makes the project structure unnecessary complex.
Here is a simple solution (works with json and non-json response).
// worker.js
export default () => {
self.addEventListener('message', e => {
if (!e) return;
// wrap in try/catch if you want to support IE11 and older browsers
// that don't support Promises. The implementation below doesn't work
// even when polyfills are loaded in the main project because
// the worker runs in a different context, ie no webpack bundles here.
try {
const fetchData = (url, isJSON = true) => {
return new Promise((resolve, reject) => {
function reqListener() {
if (this.status !== 200) {
return reject();
}
const response = isJSON
? JSON.parse(this.responseText)
: this.responseText;
resolve(response);
}
const oReq = new XMLHttpRequest();
oReq.addEventListener('load', reqListener);
oReq.open('GET', url);
oReq.send();
});
};
const baseUrl = 'https://static.newsfilter.io/';
const { articleId } = e.data;
const jsonUrl = baseUrl + articleId + '.json';
const htmlUrl = baseUrl + articleId + '.html';
// My use case requires 2 requests in parallel.
const tasks = [fetchData(jsonUrl), fetchData(htmlUrl, false)];
Promise.all(tasks)
.then(data => {
postMessage({ json: data[0], html: data[1] });
})
.catch(error => {
postMessage({ isError: true, error });
});
} catch (error) {
postMessage({ isError: true });
}
});
};

Is it ok to add routes in an Express middleware?

I am building a small authentication middleware (because I want to!) but to work the way I wanted I found I was adding routes dynamically to the app, both for the POST back of the username/password as well as the GET for the authentication page script and styles.
Here it is:
function appAuth(auth, options) {
let oneHourMs = (60 * 60 * 1000);
let sessionStore = {};
let html = `<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<script src="index.js" type="module"></script>
</head>
<body>
</body>
</html>`;
return function (request, response, next) {
if (!request.app.authMiddlewarePOST_setup) {
request.app.post(request.path, upload.array(), async function (req, res) {
let data = req.body;
console.log("data", data);
let { username, password } = data;
if (auth(username, password)) {
let now = new Date();
let sessionId = await makeSessionId(now, getRemoteAddr(req));
sessionStore[sessionId] = {
lastTouch: now,
id: sessionId
};
res.cookie("sessionid", sessionId);
res.redirect(302, req,path);
}
else {
res.status(401).send(html);
}
});
request.app.authMiddlewarePOST_setup = true;
}
// Do authenticated session detection
let sessionId = request.cookies.sessionid;
if (sessionId === undefined) {
response.status(401).send(html);
return;
}
let sessionObject = sessionStore[sessionId];
if (sessionObject === undefined
|| isExpired(sessionObject.lastTouch, oneHourMs)) {
response.status(401).send(html);
return;
}
// Otherwise it's all ok.
next();
};
}
I was wondering:
is it ok to add routes like this?
is it better to add a route with an obfuscated path? for example:
app.post("/" + middlewareId + "/" + randomnumber, ...)
if I'm doing this I suppose I should dispose of the route as well?
what would be some alternatives to doing this?
The git repo is over here - I don't want to clutter up the post with even more superflous code.