Google Analytics - gapi - tableID - google-analytics

i'm working on google analytics and try to get some data from analytics. What i want is retrieving all table id and name from analytics but really dont know how to do. i spend hours in Google . Is there a way to do that ?
i want to take these all table like Izlesene.com KurtlarVadisi - Mobil uygulama and their ids how can i retrieve them ?
then i want to put them to my html
<td width="138"><strong>Kanal Adı</strong>
<td width="150"><b>Kategori Adı</b></td>
<td width="130"><p><strong>Event Adı</strong></td>
<td width="145"><strong>Toplam</strong>;

You can get that data out via the Management API.
Currently there's no UI to get this data out that I'm aware of.
You can play with it in the Google API's Explorer.
Go to the Google API's Explorer.
Look for the Analytics v3 API.
Select the management.profiles.list method.
Click the authorization button on top right
authorize the API
Fill both required fields with ~all
Click Execute
You will get a JSON feed with the data you want. The API's explorer are just a toy to play with the API though. You better off writing your own script to query it and get the data you need.

function handleAllAccounts(results) {
if (!results.code) {
if (results && results.items && results.items.length) {
// Get the first Google Analytics account
var AccountIds = new Array();
for(var i=0 ;i<results.items.length;i++){
AccountIds[i] = results.items[i].id;
}
queryAllProfiles(AccountIds,results.items.length);
} else {
console.log('No accounts found for this user.')
}
} else {
console.log('There was an error querying accounts: ' + results.message);
}
}
function queryAllProfiles(accountId,count) {
console.log('Querying Profiles.');
var sel = document.getElementById('managementProfiles');
var opt = null;
for(var i=0;i<count;i++){
gapi.client.analytics.management.webproperties.list({
'accountId': accountId[i]
}).execute(function fn(results){
for(var j=0;j<results.items.length;j++){
gapi.client.analytics.management.profiles.list({
'accountId': results.items[j].accountId,
'webPropertyId': results.items[j].id
}).execute(function innertwo(profiles_results){
if (!profiles_results.code) {
if (profiles_results && profiles_results.items && profiles_results.items.length) {
opt = document.createElement('option');
opt.value = 'ga:'+profiles_results.items[0].id;
opt.innerHTML = profiles_results.items[0].name;
sel.appendChild(opt);
}
}
})
}
})
}
sel.style.display ="block" ;
}
In your google analyticle javascript file put these two function these function retrive all management profiles of any google analyticle account authenticated by google

Related

Enhanced ecommerce don't recognize internal promotion view object

I've been implementing all the enhanced eCommerce tracks for the past few weeks and I could do most of the job successfully thanks to Simo Ahava's blog. But now I'm struggling with the internal promotion view tracking.
I choose to implement the view tracking with the concept of True View Impressions also with a base on Simo's work and for products it was ok. So I modified the customTasks from the link to track internal promotion but, for some reason, the enhanced eCommerce isn't recognizing the promoView object. But it's recognizing the promoClick (?).
I've made a test: I substitute the promoClick for a impression object and it works! So, my strong guest, it's that the problem it's really on my object. My object's format can be seen here.
And to illustrate the way the object it's being constructed:
var targetElement = {{Click Element}},
event = {{Event}},
batch = window[promoBatchVariableName],
impressions = google_tag_manager[{{Container ID}}].dataLayer.get('ecommerce.promoView.promotions'),
ecomObj = { };
if (event === 'gtm.click') {
while (!targetElement.getAttribute(promoIdAttribute) && targetElement.tagName !== 'BODY') {
targetElement = targetElement.parentElement;
}
}
var latestPromoImpression = impressions.filter(function(impression) {
return impression.id === targetElement.getAttribute(promoIdAttribute);
}).shift();
var promoImpressionsArr = batch.map(function(id) {
return impressions.filter(function(impression) {
return impression.id === id;
}).shift();
});
if (event === 'gtm.elementVisibility'){
promoImpressionsArr[maxPromoBatch - 1] = latestPromoImpression;
}
console.log(ecomObj)
ecomObj.promoView = { promotions: promoImpressionsArr};
if (event === 'gtm.click') {
ecomObj.promoClick = {
promotions: [latestPromoImpression]
};
console.log("click")
}
return {
ecommerce: ecomObj
};
}
Could someone help me with some ideas?
This answer is just to close the question! As I pointed in the comments:
" I found the problem. And it's not on my object itself only. xD The problem is the undefined elements as you pointed at the beginning of our talk. I'm waiting for the dev team to change the data-attributes of the elements on our site's pages because sometimes we don't get any individual identifier variable. So, in the meantime, I've implemented a way to get always a product id even in these cases but as the identifier doesn't exist in the CSS selector if the element has an id in the 'entrance object', the element is set as undefined. "

Google app maker: How to list existent groups?

I've created a new google app through their app maker interface. I've added "Google Admin Directory API" as a service and "Directory" as a data source. I created a page that will hold 2 tables, one that list all users within my domain (this is already working) and another table that lists all of the groups within my domain (not working). How can I achieve this? Can this be done through their widgets or do I have to create a script and programmatically call the admin API to then bind the data to the table?
Since you already enabled the Admin Directory API when using the directory model, all you have to do now is to call the sample code from the server script. In a server script, add the sample code:
function listAllGroups() {
var pageToken;
var page;
do {
page = AdminDirectory.Groups.list({
domain: 'example.com',
maxResults: 100,
pageToken: pageToken
});
var groups = page.groups;
if (groups) {
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
Logger.log('%s (%s)', group.name, group.email);
}
} else {
Logger.log('No groups found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
}
Then you can simply call the server script by using the following in the client scripting:
google.script.run.withSuccessHandler(function(response){
console.log(response);
}).withFailureHandler(function(err){
console.log(err);
}).listAllGroups();
You can check the reference here. I hope this helps!

Initiate Appmaker Document Approval from Google Drive

I've customized Document Management System template in Appmaker as per my needs. Now instead of going to Appmaker every time to initiate an approval I want to provide functionality to initiate the workflow from Google Drive.So users can select file for Approval directly from Google Drive.
My question is is there any Rest call or something via which I can initiate DMS workflow from Third party app?
Well I found a way out to achieve the result.
Steps:
Drive API provides a way to add your App in 'Open With' menu in Google Drive.
So I've created my custom app and deployed it. This app will simply receive params from Google Drive 'Open with' menu and pass it to Appmaker Document Approval System.
In Appmaker Create request page parse if request contains these params, if yes then select files using these params.
This way my users can initiate the Document Approval Workflow from Google Drive.
References :
How to add/list your App in Google Drive
Step by Step video guideline to Create and publish your App
Code:
'Open With' App code for redirecting users from Google Drive to Appmaker.
code.gs:
var AUTHORIZE_URL = 'https://accounts.google.com/o/oauth2/auth';
var TOKEN_URL = 'https://accounts.google.com/o/oauth2/token';
var REDIRECT_URL= ScriptApp.getService().getUrl();
var tokenPropertyName = 'GOOGLE_OAUTH_TOKEN';
var CLIENT_ID = 'your client id';
var CLIENT_SECRET = 'your client secrect';
function doGet(e) {
var HTMLToOutput;
if(e.parameters.state){
var state = JSON.parse(e.parameters.state);
if(state.action === 'create'){
HTMLToOutput = "<html><h1>Creation Of Docs Not supported by this App!</h1></html>";
}
else {
var id = state.exportIds;
var file = DriveApp.getFileById(id);
//append params to your appmaker URL
var url = 'yourappmaker published url'+'?param1='+file.getName()+'&param2='+file.getUrl()+'#AddRequest';
HTMLToOutput = HtmlService.createHtmlOutput('<html><script>'
+'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";'
+'if(document.createEvent){'
+' var event=document.createEvent("MouseEvents");'
+' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+' event.initEvent("click",true,true); a.dispatchEvent(event);'
+'}else{ a.click() }'
+'close();'
+'</script>'
// Offer URL as clickable link in case above code fails.
+'<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+'</html>')
.setWidth( 90 ).setHeight( 1 );
}
}
else if(e.parameters.code){//if we get "code" as a parameter in, then this is a callback. we can make this more explicit
getAndStoreAccessToken(e.parameters.code);
HTMLToOutput = '<html><h1>App is installed, you can close this window now or navigate to your Google Drive.</h1></html>';
}
else {//we are starting from scratch or resetting
HTMLToOutput = "<html><h1>Install this App into your Google Drive!</h1><a href='"+getURLForAuthorization()+"'>click here to start</a></html>";
}
console.log(getURLForAuthorization());
return HtmlService.createHtmlOutput(HTMLToOutput);
}
function getURLForAuthorization(){
return AUTHORIZE_URL + '?response_type=code&client_id='+CLIENT_ID+'&redirect_uri='+REDIRECT_URL +
'&scope=https://www.googleapis.com/auth/drive.install https://www.googleapis.com/auth/userinfo.email';
}
function getAndStoreAccessToken(code){
var parameters = { method : 'post',
payload : 'client_id='+CLIENT_ID+'&client_secret='+CLIENT_SECRET+'&grant_type=authorization_code&redirect_uri='+REDIRECT_URL+'&code=' + code};
var response = UrlFetchApp.fetch(TOKEN_URL,parameters).getContentText();
var tokenResponse = JSON.parse(response);
UserProperties.setProperty(tokenPropertyName, tokenResponse.access_token);
}
function getUrlFetchOptions() {
return {'contentType' : 'application/json',
'headers' : {'Authorization' : 'Bearer ' + UserProperties.getProperty(tokenPropertyName),
'Accept' : 'application/json'}};
}
//naive check, not using for now, use refresh tokens and add proper checking
function isTokenValid() {
return UserProperties.getProperty(tokenPropertyName);
}
In Document workflow 'Create Request' page, add event to onAttach() method. Write below function,
//client side
function checkIfRedirected(widget)
{
// console.log(location.origin);
google.script.url.getLocation(function(location) {
var params = location.parameter;
var param1 = params.param1;
var param2 = params.param2;
widget.datasource.item.DocumentName = param1;
widget.datasource.item.DocumentUrl = param2;
widget.datasource.item.Owner = app.user.email;
});
}

Google App Maker how to create Data Source from Google Contacts

Using GoogleAppMaker how to create a data source from google contacts. There is an employee HR example app but I want to similarly manage contacts (add, modify, delete) and use select criteria.
At this time this task is not trivial in App Maker and it is pretty much generic. We can change question wording to CRUD operations with 3rd party datasources. Let's break it into smaller parts and address them separately.
Read/list contacts
This task is relatively easy. You need to use Calculated Model to proxy Apps Scripts Contacts API response. Once you create model with subset of fields from the Contact response you can create datasource for the model and bind it to List or Table widget. You can also try to find some inspiration in Calculated Model Sample.
// Server side script
function getContacts_() {
var contacts = ContactsApp.getContacts();
var records = contacts.map(function(contact) {
var record = app.models.Contact.newRecord();
record.FirstName = contact.getGivenName();
record.LastName = contact.getFamilyName();
var companies = contact.getCompanies();
if (companies.length > 0) {
var company = companies[0];
record.Organization = company.getCompanyName();
record.Title = company.getJobTitle();
}
var emails = contact.getEmails();
if (emails.length > 0) {
record.Email = emails[0].getAddress();
}
var phones = contact.getPhones();
if (phones.length > 0) {
record.Phone = phones[0].getPhoneNumber();
}
return record;
});
return records;
}
Create/Update/Delete
Since Calculated Models have some limitations, we need to turn on our imagination to create, update and delete records from their datasources. The basic strategy will be calling server side scripts for CUD operations in response to user actions on client side. To get user's input from UI we will need to utilize page's Custom Properties, one property for each Contact field:
Here are some snippets that should explain the idea
Create
// Client script
function onSubmitContactClick(submitButton) {
var props = submitButton.root.properties;
var contact = {
FirstName: props.FirstName,
LastName: props.LastName,
Organization: props.Organization,
...
};
google.script.run
.withSuccessHandler(function() {
// Most likely we'll need to navigate user back to the
// page with contacts list and reload its datasource
// to reflect recent changes, because our `CUD` operations
// are fully detached from the list datasource
app.showPage(app.pages.Contacts);
app.datasources.Contacts.load();
})
.withFailureHandler(function() {
// TODO: Handle error
})
.createContact(contact);
}
// Server script
function createContact(contactDraft) {
var contact = ContactsApp.createContact(contactDraft.FirsName,
contactDraft.LastName,
contactDraft.Email);
contact.addCompany(contactDraft.Organization, contactDraft.Title);
contact.addPhone(ContactsApp.Field.WORK_PHONE, contactDraft.Phone);
}
Update
Idea to update contact records will be very similar to the new contact creation flow, so I skip it for now.
Delete
Assuming that delete button is located inside contacts table row.
// Client script
function onDeleteContactClick(deleteButton) {
var email = deleteButton.datasource.item.Email;
google.script.run
.withSuccessHandler(function() {
// To update contacts list we can either reload the entire
// datasource or explicitly remove deleted item on the client.
// Second option will work way faster.
var contactIndex = deleteButton.parent.childIndex;
app.datasources.Contacts.items.splice(contactIndex, 1);
})
.withFailureHandler(function() {
// TODO: Handle error
})
.deleteContact(contact);
}
// Server script
function deleteContact(email) {
var contact = ContactsApp.getContact(email);
ContactsApp.deleteContact(contact);
}

Analytics Scripts Insufficient Permission from Google Sheets

I'm trying to write a script to grab Google Analytics data & add it to a Google Sheet.
When running the following code, I get the following error on the sheet:
"User does not have sufficient permissions for this profile."
Just a few quick check-box items:
Yes, I have admin permissions for the Analytics account I'm trying to access
Yes, I have admin permissions for the Google Sheet from which I'm creating the script
Yes, I've double-checked my current Google login to make sure I'm on the right account.
Here is the code:
function runDemo() {
try {
var results = getReportDataForProfile();
outputToSpreadsheet(results);
} catch(error) {
Browser.msgBox(error.message);
}
}
function getReportDataForProfile() {
var profileId = 'xxxxxxxx'; //firstProfile.getId();
var tableId = 'ga:' + profileId;
var startDate = getLastNdays(14); // 2 weeks (a fortnight) ago.
var endDate = getLastNdays(0); // Today.
var optArgs = {
'dimensions': 'ga:keyword', // Comma separated list of dimensions.
'sort': '-ga:sessions,ga:keyword', // Sort by sessions descending, then keyword.
'segment': 'dynamic::ga:isMobile==Yes', // Process only mobile traffic.
'filters': 'ga:source==google', // Display only google traffic.
'start-index': '1',
'max-results': '250' // Display the first 250 results.
};
// Make a request to the API.
var results = Analytics.Data.Ga.get(
tableId, // Table id (format ga:xxxxxx).
startDate, // Start-date (format yyyy-MM-dd).
endDate, // End-date (format yyyy-MM-dd).
'ga:sessions,ga:pageviews', // Comma seperated list of metrics.
optArgs);
if (results.getRows()) {
return results;
} else {
throw new Error('No views (profiles) found');
}
}
OK, I screwed around with this for a while and then it started working.
My best guess is I copied the property ID from Google Analytics wrong. After going back and recopying it, everything worked well.

Resources