How to fetch Adwords campaign data from Google Analytics API? - analytics

Hi i am using Google Analytics API and interested in extracting the AdWords Campaigning data which is available under OverAll Traffic>>Acquisition>>Adwords>>Campaigns and my query for the same is
return service.data().ga().get(
ids='ga:' + profile_id,
start_date=start_date,
end_date=end_date,
metrics='ga:CPC,ga:transactions,ga:transactionsPerSession,ga:adCost,
ga:transactionRevenue,ga:bounceRate,ga:impressions,ga:adClicks,
ga:sessions',dimensions='ga:campaign,ga:deviceCategory',
sort ='-ga:adClicks',
segment = 'gaid::-1').execute()
but the above query is giving me the data related to all the campaigns but i only want to fetch the data that is related to Adwords Campaigns only.So, please help me in getting this done. I guess there should be some filter or any thing else by which we can extract the desired data.

ga:sourceMedium==google / cpc
Use the above filter in your API request.
Or
Pull dimension ga:sourceMedium and then filter google / cpc from the result set.

auth: jwt,
ids: "ga:" + view_id,
"start-date": "YYYY-MM-DD",
"end-date": "YYYY-MM-DD",
metrics: "ga:adCost",
dimensions: "ga:campaign",
"start-index": "1",
"max-results": "1000"
You can do something like this

Related

Journey builder's custom activity: Fetch data extension data in bulk

I am new to Salesforce Marketing Cloud and journey builder.
https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/creating-activities.html
We are building journey builder's custom activity in which it will use a data extension as the source and when the journey builder is invoked, it will fetch a row and send this data to our company's internal endpoint. The team got that part working. We are using the postmonger.js.
I have a couple of questions:
Is there a way to retrieve the data from data extension in bulk so that we can call our company's internal bulk endpoint? Calling the endpoint for each record in the data extension for our use case would not be efficient enough and won't work.
When the journey is invoked and an entry in the data extension is retrieved and that data is sent to our internal endpoint, is there a machanism to mark this entry as already sent such that next time the journey is run, it won't process the entry that's already sent?
Here is a snippet of our customActivity.js in which this is populating one record. (I changed some variable names.). Is there a way to populate multiple records such that when "execute" is called, it is passing a list of payloads as input to our internal endpoint.
function save() {
try {
var TemplateNameValue = $('#TemplateName').val();
var TemplateIDValue = $('#TemplateID').val();
let auth = "{{Contact.Attribute.Authorization.Value}}"
payload['arguments'].execute.inArguments = [{
"vendorTemplateId": TemplateIDValue,
"field1": "{{Contact.Attribute.DD.field1}}",
"eventType": TemplateNameValue,
"field2": "{{Contact.Attribute.DD.field2}}",
"field3": "{{Contact.Attribute.DD.field3}}",
"field4": "{{Contact.Attribute.DD.field4}}",
"field5": "{{Contact.Attribute.DD.field5}}",
"field6": "{{Contact.Attribute.DD.field6}}",
"field7": "{{Contact.Attribute.DD.field7}}",
"messageMetadata" : {}
}];
payload['arguments'].execute.headers = `{"Authorization":"${auth}"}`;
payload['configurationArguments'].stop.headers = `{"Authorization":"default"}`;
payload['configurationArguments'].validate.headers = `{"Authorization":"default"}`;
payload['configurationArguments'].publish.headers = `{"Authorization":"default"}`;
payload['configurationArguments'].save.headers = `{"Authorization":"default"}`;
payload['metaData'].isConfigured = true;
console.log(payload);
connection.trigger('updateActivity', payload);
} catch(err) {
document.getElementById("error").style.display = "block";
document.getElementById("error").innerHtml = err;
}
console.log("Template Name: " + JSON.stringify(TemplateNameValue));
console.log("Template ID: " + JSON.stringify(TemplateIDValue));
}
});
Any advise or idea is highly appreciated!
Thank you.
Grace
Firstly, i implore you to not proceed with the design pattern of fetching data for each subscriber, from Marketing Cloud, that gets sent through the custom activity, for arguments sake i'll list two big issues.
You have no way of limiting the configuration of data extensions columns or column names in SFMC (Salesforce Marketing Cloud). If any malicious user or by human error would delete a column or change a column name your service would stop receiving that value.
Secondly, Marketing Cloud has 2 sets of API limitations, yearly and minute by minute. Depending on your licensing, you could run into the yearly limit.
The problem you have with limitation on minutes (2500 for REST and 2000 for SOAP) is that each usage of the custom activity in journey builder would multiple the amount of invocations per minute. Hitting this limit would cause issues for incremental data flows into SFMC.
I'd also suggest not retrieving any data from Marketing Cloud when a customer gets sent through a custom activity. Users should pick which corresponding rows/data that should be sent to the custom activity in their segmentation.
The eventDefinitionKey can be picked up from postmonger after requestedTriggerEventDefinition in the eventDefinitionModel function. eventDefinitionKey can then be used to programmatically populate SFMC's POST call with data from the Journey Data model, thus allowing marketers to select what data to be sent with the subscriber.
Following is some code to show how it would work in your customActivity.js
connection.on(
'requestedTriggerEventDefinition',
function (eventDefinitionModel) {
var eventKey = eventDefinitionModel['eventDefinitionKey'];
save(eventKey);
}
);
function save(eventKey) {
// subscriberKey fetched directly from Contact model
// columnName is populated from the Journey Data model
var params = {
subscriberKey: '{{Contact.key}}',
columnName: '{{Event.' + eventKey + '.columnName}}',
};
payload['arguments'].execute.inArguments = [params];
}

Selling Partner API Feeds API

I am using the Feeds API to update inventory using the this link. I am able to perform the Step 1 :- Create a feed document response is
{
"payload":{"encryptionDetails":
{
"standard":"AES","initializationVector":"vHLW3sNN41sEQp1e9wjNSg==",
"key":"oQvgdrwiBbBO3SLf4p81zQuIgROkTDA9Yikv6DvMIcg="
},
"feedDocumentId":"amzn1.tortuga.3.11ef10ee-e839-4a0b-b7a4-dcfbe78900ae.T1OWK0QMT4NDF7",
"url":"https://tortuga-prod-eu.s3-eu-west-1.amazonaws.com/%2FNinetyDays/amzn1.tortuga.3.11ef10ee-e839-4a0b-b7a4-dcfbe78900ae.T1OWK0QMT4NDF7?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210117T190852Z&X-Amz-SignedHeaders=&X-Amz-Expires=300&X-Amz-Credential=&X-Amz-Signature="
}
}
At Step 2 Encrypt and upload the feed data Response :-
SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method.XXXXXXXXXXXXXXXXXXXXAWS4-HMAC-SHA256 20210117T190852Z 20210117/eu-west-1/s3/aws4_request 6efdf3105b88a49723fed6068792a6f1a5858196f957e3a52f76e4cee2ccb07e9197ea9212ce444f640080a3df1d628de0bc26d9a0cafea9577fd23d2c1b3fc6 BYTESPUT //NinetyDays/amzn1.tortuga.3.11ef10ee-e839-4a0b-b7a4-dcfbe78900ae.T1OWK0QMT4NDF7 X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=CREDENTIAL&X-Amz-Date=20210117T190852Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-type%3Bhost content-type:application/json host:tortuga-prod-eu.s3-eu-west-1.amazonaws.com content-type;host UNSIGNED-PAYLOADBYTESEA417EC74F012746CpSqzu64eIWZv0Y7JWoylN5rrCAJzort9+7EGhH0KqaSHknlV+ZYuX76zqv2shr+yFDksDntFNI=
Anybody facing the same problem or any ideas where the problem is

query data in a airtable database using url

I want to implement URL for search specific data in my base using filterByFormula
below are my link and I got an error and how to resolve that
my url:
api.airtable.com/v0/APPID/Stories?filterByFormula=(FIND(“Car (in robot form) will offer a hug when I am stressed out”,{User want}) &api_key=MYKEY
Error :
{
"error": {
"type": "INVALID_FILTER_BY_FORMULA",
"message": "The formula for filtering records is invalid: Invalid formula. Please check your formula text."
}
}
I tried using postman, please help me.
While querying filtered data from Airtable via API, you don't have to use FIND keyword. You can filter data with simple Airtable formula like structure. For example,
{Email} = 'johnwick#neverdie.com'
Above filter retrieve all the records from the table whose Email is simply johnwick#neverdie.com
To limit number of records retrieve by API maxRecord parameter is available for that. For more info about various parameters please refer my answer here AirTable API Find record by email or official Airtable API Documentation
In your case
API url would be structured like,
api.airtable.com/v0/APPID/Stories?filterByFormula=Car+(in+robot+form)+will+offer+a+hug+when+I+am+stressed+out%3D%22User+want%22&api_key=MYKEY
For more info about Airtable API encoding, check this https://codepen.io/airtable/full/rLKkYB?baseId=app1C5TVoophmmr8M&tableId=tblvILr4aSAYI98oa
Hope this helps!

REST request to query Google datastore

Is there a way to make a POST request to query google datastore and get back results? I know there's a way to do this with BigQuery, but I'm unable to find a way to query DS.
Google API docs mention the runQuery request but that doesn't come back with the results.
https://cloud.google.com/datastore/docs/reference/rest/v1/projects/runQuery#QueryResultBatch
To be more specific, I get the response below when I call runQuery:
Request body to runQuery
{
"gqlQuery": {
"allowLiterals": true,
"queryString": "SELECT * from Products where name > 'App' "
}
}
Response body
"batch": {
"moreResults": "NO_MORE_RESULTS",
"endCursor": "CgA=",
"entityResultType": "FULL"
}
My expectation was that the batch object should have the results.
Would appreciate any help!
Thanks,
Sammy

Using the API to get google directory contacts

I am a Google Apps customer and want to use the Contact API to search for a user in the company directory.
I am able to access contacts using for example:
feed = gd_client.GetContacts()
However the contacts this returns is only a subset of my contacts and is not those in the company directory.
Has anyone had experience of this or give me any pointers.
I think what you are looking for is the Domain Shared Contact API instead of the Contact API. Check this out (https://developers.google.com/google-apps/domain-shared-contacts/)
Try to run the get request against the domain, you should be able to retrieve your directory contacts instead of personal contacts (https://developers.google.com/admin-sdk/domain-shared-contacts/#Retrieving)
Try using Query to get result feed. You can specify max results to get in query. This way your result feed will be returned with more contacts in other groups as well.
URL FeedURL = new URL("https://www.google.com/m8/feeds/contacts/default/full");
Query MyQuery = new Query(FeedURL);
MyQuery.setMaxResults(200);
ContactFeed ResultFeed = MyService.query(MyQuery, ContactFeed.class);

Resources