Created
December 3, 2020 16:36
-
-
Save romanych/61ee873aa56e592f255a86932a645b98 to your computer and use it in GitHub Desktop.
Miniproxy for DV360 IR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const axios = require("axios"); | |
const rax = require("retry-axios"); | |
const { GoogleAuth } = require('google-auth-library'); | |
async function getDV360AccessToken() { | |
const auth = new GoogleAuth({ scopes: [ 'https://www.googleapis.com/auth/doubleclickbidmanager' ] }); | |
return await auth.getAccessToken(); | |
}; | |
const Functions = new function () { | |
const dbmAPI = axios.create({ | |
baseURL: "https://www.googleapis.com/doubleclickbidmanager/v1.1", | |
}); | |
dbmAPI.interceptors.request.use(async function (config) { | |
config.headers["Authorization"] = `Bearer ${await getDV360AccessToken()}`; | |
return config; | |
}); | |
dbmAPI.defaults.raxConfig = { | |
instance: dbmAPI, | |
retry: 5, | |
noResponseRetries: 3, | |
retryDelay: 1500, | |
httpMethodsToRetry: ["GET", "DELETE", "PUT", "POST"], | |
statusCodesToRetry: [ [100, 199], [429, 429], [500, 599] ], | |
onRetryAttempt: err => { | |
const cfg = rax.getConfig(err); | |
console.log(`Retry attempt #${cfg.currentRetryAttempt}`); | |
} | |
}; | |
rax.attach(dbmAPI); | |
this.getQueries = async ({pageToken}) => { | |
const response = await dbmAPI.get("/queries", { params: { pageToken: pageToken } }); | |
return response.data; | |
}; | |
this.getQuery = async ({queryId}) => { | |
const response = await dbmAPI.get(`/query/${queryId}`); | |
return response.data; | |
}; | |
this.createQuery = async ({query}) => { | |
const queriesResponse = await dbmAPI.post("/query", query); | |
return queriesResponse.data; | |
}; | |
this.runQuery = async ({queryId, data}) => { | |
const response = await dbmAPI.post(`/query/${queryId}`, data); | |
return response.data; | |
}; | |
this.getQueryReports = async ({queryId, pageToken}) => { | |
const response = await dbmAPI.get(`/queries/${queryId}/reports`, { params: { pageToken: pageToken } }); | |
return response.data; | |
}; | |
}; | |
const ALLOWED_REPORTS = { | |
"TYPE_GENERAL": { | |
metrics: ["METRIC_IMPRESSIONS"], | |
dimensions: ["FILTER_PARTNER", "FILTER_PARTNER_NAME", "FILTER_ADVERTISER", "FILTER_ADVERTISER_NAME", "FILTER_MEDIA_PLAN", "FILTER_MEDIA_PLAN_NAME", "FILTER_INSERTION_ORDER", "FILTER_INSERTION_ORDER_NAME", "FILTER_DATE", "FILTER_LINE_ITEM", "FILTER_LINE_ITEM_TYPE"] | |
}, | |
"TYPE_TRUEVIEW": { | |
metrics: [ "METRIC_IMPRESSIONS", "METRIC_RICH_MEDIA_VIDEO_FIRST_QUARTILE_COMPLETES", "METRIC_RICH_MEDIA_VIDEO_MIDPOINTS", "METRIC_RICH_MEDIA_VIDEO_THIRD_QUARTILE_COMPLETES", "METRIC_RICH_MEDIA_VIDEO_COMPLETIONS" ], | |
dimensions: [ "FILTER_PARTNER", "FILTER_PARTNER_NAME", "FILTER_ADVERTISER", "FILTER_ADVERTISER_NAME", "FILTER_INSERTION_ORDER", "FILTER_INSERTION_ORDER_NAME", "FILTER_DATE", "FILTER_LINE_ITEM", "FILTER_LINE_ITEM_TYPE", "FILTER_TRUEVIEW_GENDER", "FILTER_TRUEVIEW_AGE", "FILTER_TRUEVIEW_COUNTRY" ] | |
}, | |
"TYPE_REACH_AND_FREQUENCY": { | |
metrics: ["METRIC_UNIQUE_REACH_IMPRESSION_REACH"], | |
dimensions: [ "FILTER_PARTNER", "FILTER_PARTNER_NAME", "FILTER_ADVERTISER", "FILTER_ADVERTISER_NAME", "FILTER_MEDIA_PLAN", "FILTER_MEDIA_PLAN_NAME", "FILTER_INSERTION_ORDER", "FILTER_INSERTION_ORDER_NAME", "FILTER_DATE", "FILTER_LINE_ITEM", "FILTER_LINE_ITEM_TYPE", "FILTER_COUNTRY" ] | |
} | |
}; | |
async function processRequest(request) { | |
if (request.operation === "createQuery") { | |
console.log(request.arguments); | |
const { type, groupBys, filters, metrics } = request.arguments.query.params; | |
const allowedConfiguration = ALLOWED_REPORTS[type]; | |
if (!type) { | |
throw new Error(`Not allowed query type ${type} attempted to be created`); | |
} | |
const notAllowedMetrics = metrics.filter(m => allowedConfiguration.metrics.indexOf(m) === -1); | |
const queriedDimensions = [...groupBys, ...filters.map(f => f.type)]; | |
const notAllowedDimensions = queriedDimensions.filter(d => allowedConfiguration.dimensions.indexOf(d) === -1); | |
if (notAllowedDimensions.length !== 0 || notAllowedMetrics.length !== 0) { | |
throw new Error(`Requested not allowed metrics (${notAllowedMetrics}) or dimensions ${notAllowedDimensions}`); | |
} | |
} | |
const operationFunction = Functions[request.operation]; | |
if (!operationFunction) { | |
throw new Error(`Called unspupported operaion ${request.operation}`); | |
} | |
const result = await operationFunction.call(null, request.arguments); | |
return result; | |
} | |
exports.miniproxy = (req, res) => { | |
console.log("Incoming request", req.body); | |
processRequest(req.body).then(response => { | |
console.log("Operation successfully executed"); | |
res.status(200); | |
res.json(response); | |
}, err => { | |
console.log("Operation failed", err.message); | |
res.status(200); | |
res.json({error: true, message: err.message}); | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "miniproxy", | |
"version": "1.0.0", | |
"private": true, | |
"dependencies": { | |
"axios": "^0.19.2", | |
"google-auth-library": "^6.1.3", | |
"retry-axios": "^2.2.1" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment