My goal is to use data from Google Spreadsheets as parameters for bulk creation of AdWords Remarketing Audiences from Google Analytics stats data.
My code is based on this article.
API connection seems to be working. Audiences are being created but I have an issue with specifying segment parameters that should include/exclude audience based on the ga:pagePath.
So my questions are:
What do I do wrong?
Can someone give a hint or an advice how to make it working?
Spreadsheet table
| Audience Name | URL include 1 | URL include 2 | URL include 3 | URL exclude 1 | URL exclude 2 | URL exclude 3 | Duration |
|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----------|
| Test 1 | /test | /test2 | | | | | 540 |
|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----------|
| Test 2 | /test3 | /test4 | | | | | 540 |
|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----------|
Spreadsheet macro script
function main() {
var settings = {'linkedView':"XXXXXXXXX",
'linkedAccountId':"XXX-XXX-XXXX",
'accountId':'XXXXXXXX',
'propertyID':'UA-XXXXXXXX-X'};
var spreadsheet = SpreadsheetApp.openByUrl('XXXXXX');
var sheet = spreadsheet.getSheetByName('test');
var range = sheet.getRange(2, 1, sheet.getLastRow(), 8);
var values = range.getValues();
for(var i = 0; i < values.length; i++) {
var name = values[i][0];
var categoryUrl = values[i][1];
var duration = Math.floor(values[i][7]);
Logger.log(duration);
var inludeSegment = '';
var exludeSegment = '';
if(values[i][1]) {
inludeSegment += 'users::condition::ga:pagePath=#'+ values[i][1];
}
/*
if(values[i][2]) {
inludeSegment += ';ga:pagePath==' + values[i][2];
}
if(values[i][3]) {
inludeSegment += ';ga:pagePath==' + values[i][3];
}
if(values[i][4]) {
exludeSegment += 'sessions::condition::ga:pagePath==' + values[i][4];
}
if(values[i][5]) {
exludeSegment += ';ga:pagePath==' + values[i][5];
}
if(values[i][6]) {
exludeSegment += ';ga:pagePath==' + values[i][6];
}*/
var newAudience = Analytics.Management.RemarketingAudience.insert(
{
'name': name,
'linkedViews': [settings.linkedView],
'linkedAdAccounts': [{
'type': 'ADWORDS_LINKS',
'linkedAccountId': settings.linkedAccountId,
}],
'description' : 'test',
'audienceType': 'SIMPLE',
'audienceDefinition': {
'includeConditions': {
'daysToLookBack': 14,
'segment': inludeSegment,
'membershipDurationDays': duration,
'isSmartList': false
}
}
},
settings.accountId,
settings.propertyID
);
Logger.log(newAudience);
Logger.log(i + ' Audience ' + name + ' has been created');
};
}
I see you have issue with segments definition.
https://developers.google.com/analytics/devguides/reporting/core/v3/segments-feature-reference
This article helps you.
Because when you use ';' between pagePathes it means session must include both.
users::condition::ga:pagePath=#/category1;ga:pagePath=#/category2
This segment will collect all user who are visit 2 categories.
If we using ','
users::condition::ga:pagePath=#/category1**,**ga:pagePath=#/category2
This segment will collect all users from 1 and 2 categories, even user has visited only one.
you should use '!' To exclude something from segment
sessions::condition::**!**ga:exitPagePath==/
Hope it helps you!
Related
I’m not an expert in Google Sheets but can anyone can help me on how to put a timestamp on every updates made on one certain cell, please?
Please check link:
Let’s say that B2 is the total amount of B4-B7 and I want to update the Acct1 from 100.00 to 600.00 that auto updates the B2 to 1500.00. My question is, how do I keep track the updates that has been made on B2 i.e., putting timestamps to another sheet or somewhere in the active sheet. Thank you in advance!
I've some people keeping them in notes
function onEdit(e) {
e.range.setNote(e.range.getNote() + '\n' + new Date());
}
Create another sheet for logging. And in onEdit, you can log the changed information to the sheet.
Following is an example code.
function onEdit(e) {
try{
var dataSheetName = "Sheet1";
var logSheetName = "Sheet2";
if ( SpreadsheetApp.getActiveSheet().getName() !== dataSheetName ){ // check it is the target sheet name
return;
}
var range = e.range;
var row = range.getRow();
var col = range.getColumn();
if ( row < 3 || col !== 2 ){ // check it is Amount cell.
return;
}
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = spreadSheet.getSheetByName(dataSheetName);
var logSheet = spreadSheet.getSheetByName(logSheetName);
var nextRow = logSheet.getLastRow() + 1;
// set timestamp
logSheet.getRange(nextRow, 1).setValue(new Date());
// copy data
var srcRange = dataSheet.getRange(row, 1, 1, 2);
var dstRange = logSheet.getRange(nextRow, 2, 1, 2);
dstRange.setValues(srcRange.getValues());
}
catch(e){
Browser.msgBox(e);
}
}
I made an example spreadsheet, feel free to make a copy and check the behavior.
https://docs.google.com/spreadsheets/d/1g0pL7hwuzaS5Yr7Dh7hm_SyRG5TYxwwrlND2Zx3Bo7w/edit?usp=sharing
KQL beginner here - I have some CEF logs hitting one of my servers and I need to get into the data to get some meaningful reports from it.
Take this log - not json, just a string
CEF:0|vendor1|vendorproduct|1.0|Event1|Event2|1|source_ip=0.0.0.0 rt=2020-04-28T04:17:05.475Z data1=example1 group=example2 endpoint=55555555 user=444444
I want to access each field and store as a var for further query use. What is the best way to achieve this so I can have results such as the below? Regex? String functions?
| extend vendorname = // = vendor1
| extend source_ip = // = 0.0.0.0
| extend endpoint = // = 55555555
// etc
OK, I figured this one out - see below for KQL to achieve what I was looking for:
Syslog
| where SyslogMessage has "vendor-name"
| extend logs = split(SyslogMessage, "|")
| extend vendor = logs[1]
| extend app = logs[2]
| extend version = logs[3]
| extend event = logs[4]
| extend msg = logs[5]
| parse SyslogMessage with * "source_ip=" source_ip "rt=" rt " id=" id " data1=" data1 " group=" group " endpoint=" endpoint "user=" user
| project vendor, app, version, event, msg, rt, data1, source_ip, id, group, endpoint, user
Hi I am working on a web scraper, first I was trying to scrape using php CURL, but then I faced a problem that I wasn't able to scrape the sites which loads through AJAX and then I shifted to 'phantom JS' and 'casper JS`.
Now I have successfully installed the webkit and can scrape the data from any website, but I am unable to save the data for long use in a database. Simply, for later use. What I want to do is, whatever data I have scraped I want to save that to mySql database.
Is there any way I can achieve such functionality? I have tried sending Ajax request to send the data to the database but failed.
I came up with one another solution for instance, that is when I scrape the data from the specified website, I push the data to an array called data[] and then I write that data to a .json file. Where each bunch of data is saved in array of objects form which is get from JSON.stringify(data).
Now, I don't know if how can I get that file data and save it in database? Is it possible that, whenever the scraping is finished, right after I grab data from that .json file and save it to database.
For now just take this code as an example
var casper = require('casper').create();
var file = require('fs');
var data = [];
casper.start('http://casperjs.org/', function() {
data.push(this.getTitle());
file.write("file.json", JSON.stringify(data), "a");
});
casper.run();
A Proof Of Concept, using jq :
#!/bin/bash
casperjs script.js
[[ -s file.json ]] || exit 1
jq '"UPDATE ROW SET XXX = "+ .[] + " WHERE FOO=BAR;"' file.json | mysql -D DB_name
The file.json :
[
"foo",
"bar",
"base"
]
jq output :
jq -r '"UPDATE ROW SET XXX = "+ .[] + " WHERE FOO=BAR;"' file.json
UPDATE ROW SET XXX = foo WHERE FOO=BAR;
UPDATE ROW SET XXX = bar WHERE FOO=BAR;
UPDATE ROW SET XXX = base WHERE FOO=BAR;
Check https://stedolan.github.io/jq/
Simple solution I found is to make ajax request to the server, inside the evaluate function :
casper.then(function() {
details = this.evaluate(function() {
var elDet = document.getElementsByClassName("job-description-column")[0];
var detLen = elDet.children[2].children[0].children.length;
var details = elDet.children[2].children[0].children;
var linkedData = [];
for (var i = 0; i < detLen; i++) {
if (details[i].nodeName == "H3" && details[i].id != "if-this-sounds-like-you,-apply") {
linkedData.push({
head: details[i].textContent,
description: details[i + 1].textContent,
title: elDet.children[0].children[0].children[0].textContent,
loc: elDet.children[0].children[0].children[1].textContent,
date: elDet.children[0].children[0].children[2].textContent
})
i++;
} else {
linkedData.push({
head: "No Head",
description: details[i].textContent,
title: elDet.children[0].children[0].children[0].textContent,
loc: elDet.children[0].children[0].children[1].textContent,
date: elDet.children[0].children[0].children[2].textContent
})
}
}
var s = JSON.stringify(linkedData);
console.log(linkedData);
$.ajax({
method: "POST",
url: "http://localhost/fiverr/Crawl%20The%20Jobs/modal_scripts.php",
data: "add_jobdets=true&job_details=" + s,
async: false
})
return linkedData;
})
})
Just beginning with firebase... :-(
How do I set a property of an item?
This is my data structure:
myproject
|
- players
|
- -JPUAYuKUNeevXxaCMxM
|
- name: "John"
|
- skill
|
- mu: 25
|
- sigma: 8.333
- -JPUAYuRyJBH8sF93pNt
...
I can add a player with:
var ref = new Firebase(FIREBASE_URL + '/' + 'players');
ref.child(id).set(player);
The question is: how do I update only one property of an item (for example, 'skill') ?
I did try with:
var skill = {};
skill.mu = 27.0;
skill.sigma = 7.0;
ref.child(id).skill.update(skill);
I think I know what's going on here.
You expected ref.child(id) to have a property skill. However, you actually want the "skill" child; ref.child(id).child("skill").
I'm using the fullcalendar resourceviews fork version 1.6.1.6...
I used an older version which had the resources on the top and the times on the left axis.
But now it is different. The times are on the top and the resources are on the left axis. It's not that good anymore. Is there a way to change it?
I need the newer version of it because of the refetchResources function.
I modified the resource object (using Ike Lin fullCalendar) and added an array which includes the number of the day, start time and end time like 0 -> 09:00 -> 12:00, 1 10:00 -> 15:30 ...
Then I changed the fullcalendar.js
function updateCells() {
var i;
var headCell;
var bodyCell;
var date;
var d;
var maxd;
var today = clearTime(new Date());
for (i=0; i<colCnt; i++) {
date = resourceDate(i);
headCell = dayHeadCells.eq(i);
if(resources[i].anwesenheit[date.getDay()-1] != null){
var von = resources[i].anwesenheit[date.getDay()-1].von;
var _von = von.substring(0, 5);
var bis = resources[i].anwesenheit[date.getDay()-1].bis;
var _bis = bis.substring(0, 5);
headCell.html(resources[i].name + "<p style='font-weight: normal; font-size: 11px;'>" + _von + " - " + _bis + " Uhr</p>");
} else {
headCell.html(resources[i].name);
}
headCell.attr("id", resources[i].id);
bodyCell = dayBodyCells.eq(i);
if (+date == +today) {
bodyCell.addClass(tm + '-state-highlight fc-today');
}else{
bodyCell.removeClass(tm + '-state-highlight fc-today');
}
setDayID(headCell.add(bodyCell), date);
}
}
This shows the work time from each resource right unter the name of the resource.
Also I added a serverside function to the select function which checks if the resource is available. If yes, then the event will be created, else the event won't be created and I get an error message.
Now I can work with it. It's not exactly what I wanted, but it's nice to use now. It updates the times under the resource name on every day change so I have an overview when a resource is available and when it's not available.