I have a lot of potential users for my website (not open to the public).
I do have a Google Analytics account and everything is working well.
I don't want to iterate through all potential users because calling for each individual user will take a very long time (I have about 1200 users).
Instead, I want a list of only active users in the given time period.
Surely this must be possible
(Simple problem, I am happy to answer any questions as I know this is a very brief question I am asking)
EDITED:
I am working in python and need to write code to achieve this
If you're looking for a list of user ids that you can use with the user activity API, the analytics API has a dimension called 'ga:clientId' that you can call and then filter using the standard parameters - there's a list of options of what you can filter on here:
https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/reports/batchGet#reportrequest
Depending on how you are describing 'active users', below is an example calling the REST API from python:
import requests
import json
credentials = #{ 'your credentials as a dict' }
r = requests.post("https://www.googleapis.com/oauth2/v4/token", data = {
"client_id": credentials["client_id"],
"client_secret": credentials["client_secret"],
"refresh_token": credentials["refresh_token"],
"grant_type": "refresh_token"
}
)
access_token =json.loads(r.text)
body = {
"reportRequests": [
{
'viewId': # "your ga view ID",
'pageSize': 100000,
"includeEmptyRows": True,
"samplingLevel": "LARGE",
'dateRanges': [
{
'startDate': "7DaysAgo",
'endDate': "yesterday"
}
],
'metrics': [
{
'expression': "ga:sessions"
}
],
'filtersExpression': "ga:sessions>2",
'dimensions': [
{
'name': "ga:clientId"
}
]
}
]
}
resp = requests.post("https://analyticsreporting.googleapis.com/v4/reports:batchGet",
json=body,
headers = {"Authorization" : "Bearer " + access_token["access_token"]}
)
resp = resp.json()
print(json.dumps(resp, indent = 4))
clientIds = [ x["dimensions"][0] for x in resp["reports"][0]["data"]["rows"] ]
print(clientIds)
To build on the answer above, you need to use a combination of the above plus the useractivity.list method.
I have written a full blog post on it https://medium.com/#alrowe/how-to-pull-out-the-user-explorer-report-with-python-useractivity-search-369bc5052093
Once you have used the above to get a list of client ids, you then need to iterate through those.
My 2 api calls look like this:
return analytics.reports().batchGet(
body = {
"reportRequests": [
{
'viewId': VIEW_ID,
'pageSize': 100000,
'includeEmptyRows': True,
'samplingLevel': 'LARGE',
'dateRanges': [
{
'startDate': '30DaysAgo',
'endDate': 'yesterday'
}
],
'metrics': [
{
'expression': 'ga:sessions'
}
],
'filtersExpression': 'ga:sessions>2',
'dimensions': [
{
'name': "ga:clientId"
}
]
}
]
}
).execute()
and then
def get_client_list_report(analytics,client_id):
return analytics.userActivity().search(
body = {
'user': {
'type': 'CLIENT_ID',
'userId': client_id
},
'dateRange':
{
'startDate': '30DaysAgo',
'endDate': 'yesterday'
},
'viewId': VIEW_ID,
'pageSize': 100000,
}
).execute()
Related
I have an Eve app publishing a simple read-only (GET) interface. It is interfacing a MongoDB collection called centroids, which has documents like:
[
{
"name":"kachina chasmata",
"location":{
"type":"Point",
"coordinates":[-116.65,-32.6]
},
"body":"ariel"
},
{
"name":"hokusai",
"location":{
"type":"Point",
"coordinates":[16.65,57.84]
},
"body":"mercury"
},
{
"name":"caƱas",
"location":{
"type":"Point",
"coordinates":[89.86,-31.188]
},
"body":"mars"
},
{
"name":"anseris cavus",
"location":{
"type":"Point",
"coordinates":[95.5,-29.708]
},
"body":"mars"
}
]
Currently, (Eve) settings declare a DOMAIN as follows:
crater = {
'hateoas': False,
'item_title': 'crater centroid',
'url': 'centroid/<regex("[\w]+"):body>/<regex("[\w ]+"):name>',
'datasource': {
'projection': {'name': 1, 'body': 1, 'location.coordinates': 1}
}
}
DOMAIN = {
'centroids': crater,
}
Which will successfully answer to requests of the form http://hostname/centroid/<body>/<name>. Inside MongoDB this represents a query like: db.centroids.find({body:<body>, name:<name>}).
What I would like to do also is to offer an endpoint for all the documents of a given body. I.e., a request to http://hostname/centroids/<body> would answer the list of all documents with body==<body>: db.centroids.find({body:<body>}).
How do I do that?
I gave a shot by including a list of rules to the DOMAIN key centroids (the name of the database collection) like below,
crater = {
...
}
body = {
'item_title': 'body craters',
'url': 'centroids/<regex("[\w]+"):body>'
}
DOMAIN = {
'centroids': [crater, body],
}
but didn't work...
AttributeError: 'list' object has no attribute 'setdefault'
Got it!
I was assuming the keys in the DOMAIN structure was directly related to the collection Eve was querying. That is true for the default settings, but it can be adjusted inside the resources datasource.
I figured that out while handling an analogous situation as that of the question: I wanted to have an endpoint hostname/bodies listing all the (unique) values for body in the centroids collection. To that, I needed to set an aggregation to it.
The following settings give me exactly that ;)
centroids = {
'item_title': 'centroid',
'url': 'centroid/<regex("[\w]+"):body>/<regex("[\w ]+"):name>',
'datasource': {
'source': 'centroids',
'projection': {'name': 1, 'body': 1, 'location.coordinates': 1}
}
}
bodies = {
'datasource': {
'source': 'centroids',
'aggregation': {
'pipeline': [
{"$group": {"_id": "$body"}},
]
},
}
}
DOMAIN = {
'centroids': centroids,
'bodies': bodies
}
The endpoint, for example, http://127.0.0.1:5000/centroid/mercury/hokusai give me the name, body, and coordinates of mercury/hokusai.
And the endpoint http://127.0.0.1:5000/bodies, the list of unique values for body in centroids.
Beautiful. Thumbs up to Eve!
I am trying to get a search volume metric from the Google Ads API. I am running into trouble when I using the "SearchVolumeSearchParameter" argument. This argument requires an "operation" field and the documentation does not do a great job on explaining what these operations can be. Preferably, I would like the script to return a list of keywords and their respective search volumes for the previous month.
adwords_client = adwords.AdWordsClient.LoadFromStorage()
targeting_idea_service = adwords_client.GetService(
'TargetingIdeaService', version='v201809')
selector = {
'ideaType': 'KEYWORD',
'requestType': 'STATS'
}
selector['requestedAttributeTypes'] = [
'KEYWORD_TEXT',
'SEARCH_VOLUME',
# 'TARGETED_MONTHLY_SEARCHES',
]
offset = 0
PAGE_SIZE = 500
selector['paging'] = {
'startIndex': str(offset),
'numberResults': str(PAGE_SIZE)
}
selector['searchParameters'] = [{
'xsi_type': 'SearchVolumeSearchParameter',
'operation': []
}]
page = targeting_idea_service.get(selector)
You use maximum, minimum like so:
selector['searchParameters'] = [
{
'xsi_type': 'RelatedToQuerySearchParameter',
'queries': search_keywords
},
{
'xsi_type': 'LocationSearchParameter',
'locations': [
{'id': location_id}
]
},
{
'xsi_type': 'SearchVolumeSearchParameter',
'operation': [
{'minimum': 100}
]
}
]
I've got an analytics reporting api v4 script in Python which returns to me the sessions for certain landing pages and which city the sessions have come from.
Is there a way to limit this to only the top 50 city locations per landing page for sessions so I don't get returned the city's that are landing on them which have like 1 session for example.
Here is the base code for the analytics request:
api_client = google_build(serviceName=api_name, version=api_version,
http=authorized)
for i in developments:
sample_request = {
'viewId': '6690350',
'pageSize': 100000,
'dateRanges': {
'startDate': datetime.strftime(datetime.now() - timedelta(days = 30),'%Y-%m-%d'),
'endDate': datetime.strftime(datetime.now(),'%Y-%m-%d')
},
'metrics': [{'expression': 'ga:sessions'}],
'orderBys':
[
{'fieldName': 'ga:pagePath', 'sortOrder': 'ASCENDING'},
{'fieldName': 'ga:sessions', 'sortOrder': 'DESCENDING'}
],
'dimensions': [{'name': 'ga:pagePath'},{'name': 'ga:city'},{'name': 'ga:latitude'},{'name': 'ga:longitude'}],
'dimensionFilterClauses' : [
{
EDIT - To get top x cities for a particular landing page is not feasible through a single query, you will have to either use Content Grouping feature or process the broader response to achieve this.
Original response -
Added to your code might not be complete, look at metricFilterClauses section added only
You can get the top 50 results by using pagination and using PageSize to restrict the number of rows that you get. Just make sure to use ordering to sort before you apply pagination.
You will have to use batchGet request to execute this - link to official guide of batchquest
api_client = google_build(serviceName=api_name, version=api_version,
http=authorized)
for i in developments:
sample_request = {
'viewId': '6690350',
'pageSize': 100000,
'dateRanges': {
'startDate': datetime.strftime(datetime.now() - timedelta(days = 30),'%Y-%m-%d'),
'endDate': datetime.strftime(datetime.now(),'%Y-%m-%d')
},
'metrics': [{'expression': 'ga:sessions'}],
#add this metric filter to filter out with session more than 50
'metricFilterClauses': [{
"filters": [{
"metricName": "ga:sessions",
"operator": "GREATER_THAN",
"comparisonValue": "50"
}]
}]
'orderBys':
[
{'fieldName': 'ga:pagePath', 'sortOrder': 'ASCENDING'},
{'fieldName': 'ga:sessions', 'sortOrder': 'DESCENDING'}
],
'dimensions': [{'name': 'ga:pagePath'},{'name': 'ga:city'},{'name': 'ga:latitude'},{'name': 'ga:longitude'}]
#top 50 results
'pageSize': 50
You can use MetricFilterClauses to filter out particular metric that you need. You can use different operators available to you to filter out based on conditions you want to use.
I have completely read out the documentation of dynamic facebook marketing.Also successfully created an ad based on custom audience and pixel events.But the problem is that every time i am creating an ad it shows same product in ad templates.
Here is the code for setting up the Product set
product_set = ProductSet(None, <CATALOG ID>) # <CATALOG ID>
product_set[ProductSet.Field.name] = 'Product Set'
product_set[ProductSet.Field.filter] = {
'product_type': {
'i_contains': 'example product type',
},
}
product_set.remote_create()
product_set_id = product_set[ProductSet.Field.id]
And Code for creating AD after setting campaign and adset :
adset = AdSet(parent_id='<ACCOUNT_ID>')
adset[AdSet.Field.name] = 'Product Adset'
adset[AdSet.Field.bid_amount] = 9100
adset[AdSet.Field.billing_event] = AdSet.BillingEvent.link_clicks
adset[AdSet.Field.optimization_goal] = AdSet.OptimizationGoal.link_clicks
adset[AdSet.Field.daily_budget] = 45500
adset[AdSet.Field.campaign_id] = campaign_id
adset[AdSet.Field.targeting] = {
Targeting.Field.publisher_platforms: ['facebook', 'audience_network'],
Targeting.Field.device_platforms: ['desktop','mobile'],
Targeting.Field.geo_locations: {
Targeting.Field.countries: ['IN'],
},
Targeting.Field.product_audience_specs: [
{
'product_set_id': product_set_id,
'inclusions': [
{
'retention_seconds': 2592000,
'rule': {
'event': {
'eq': 'ViewContent',
},
},
},
],
'exclusions': [
{
'retention_seconds': 259200,
'rule': {
'event': {
'eq': 'Purchase',
},
},
},
],
},
],
Targeting.Field.excluded_product_audience_specs: [
{
'product_set_id': product_set_id,
'inclusions': [
{
'retention_seconds': 259200,
'rule': {
'event': {
'eq': 'ViewContent',
},
},
},
],
},
],
}
adset[AdSet.Field.promoted_object] = {
'product_set_id': product_set_id,
}
adset.remote_create()
adset_id = adset[AdSet.Field.id]
Can you guys help me out for the creating dynamic products from product set ?
Does your product catalog have items with product_type containing 'example product type'? you can make a api call to verify how many products are under that product set by /<PRODUCT_SET_ID>?fields=product_count,products
when the ads start running, it'll automatically render the relevant products from the product set automatically.
for the creative preview, you can specify specific product items to render in the preview: e.g. product_item_ids=["catalog:1000005:MTIzNDU2"]
more details about creative preview of Dynamic Ads: https://developers.facebook.com/docs/marketing-api/dynamic-product-ads/ads-management/v2.9
I'm trying to adapt the asynch_query.py script found at https://github.com/GoogleCloudPlatform/bigquery-samples-python/tree/master/python/samples for use in executing a query and having the output go to a BigQuery table. The JSON section of the script as I've created it for seting the parameters is as follows:
job_data = {
'jobReference': {
'projectId': project_id,
'job_id': str(uuid.uuid4())
},
'configuration': {
'query': {
'query': queryString,
'priority': 'BATCH' if batch else 'INTERACTIVE',
'createDisposition': 'CREATE_IF_NEEDED',
'defaultDataset': {
'datasetId': 'myDataset'
},
'destinationTable': {
'datasetID': 'myDataset',
'projectId': project_id,
'tableId': 'testTable'
},
'tableDefinitions': {
'(key)': {
'schema': {
'fields': [
{
'description': 'eventLabel',
'fields': [],
'mode': 'NULLABLE',
'name': 'eventLabel',
'type': 'STRING'
}]
}
}
}
}
}
}
When I run my script I get an error message that a "Required parameter is missing". I've been through the documentation at https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.query trying to figure out what is missing, but attempts at various configurations have failed. Can anyone identify what is missing and how I would fix this error?
Not sure what's going on. To insert the results of a query into another table I use this code:
def create_table_from_query(connector, query,dest_table):
body = {
'configuration': {
'query': {
'destinationTable': {
'projectId': your_project_id,
'tableId': dest_table,
'datasetId': your_dataset_id
},
'writeDisposition': 'WRITE_TRUNCATE',
'query': query,
},
}
}
response = connector.jobs().insert(projectId=self._project_id,
body=body).execute()
wait_job_completion(response['jobReference']['jobId'])
def wait_job_completion(connector, job_id):
while True:
response = connector.jobs().get(projectId=self._project_id,
jobId=job_id).execute()
if response['status']['state'] == 'DONE':
return
where connector is build('bigquery', 'v2', http=authorization)
Maybe you could start from there and keep adding new fields as you wish (notice that you don't have to define the schema of the table as it's already contained in the results of the query).