I am trying to retrieve some information about my ads in google. I have done the same for campaigns, adgroups and keywords and I haven't got a single issue, however, when it comes to ads and their metrics, I cannot manage to extract something other than adCost.
I have the following code to retrieve the info I need from google ads:
def ad_data(service, view_id, start_date, end_date):
# Initialize request with first page of results
request = {
'reportRequests': [
{
'viewId': view_id,
'dateRanges': [
{
'startDate': start_date,
'endDate': end_date
}
],
'metrics': [
{
'expression': 'ga:adCost'
},
{
'expression': 'ga:adClicks'
},
{
'expression': 'ga:adImpressions'
}
],
'dimensions': [
{
'name': 'ga:date'
},
{
'name': 'ga:campaign'
},
{
'name': 'ga:adContent'
}
],
'pageSize': 1000
}
]
}
all_data = []
while True:
# Make API call and get response
response = service.reports().batchGet(body=request).execute()
report = response.get('reports', [])[0]
rows = report.get('data', {}).get('rows', [])
all_data.extend(rows)
# Check if there are more pages of results
page_token = report.get('nextPageToken', None)
if not page_token:
break
# Update request with next page of results
request['reportRequests'][0]['pageToken'] = page_token
return all_data
The issue that I have is that for some reason I'm not being ale to retrieve metrics other than adCost, hence it shows me the following error:
HttpError: <HttpError 400 when requesting https://analyticsreporting.googleapis.com/v4/reports:batchGet?alt=json returned "Unknown metric(s): ga:adImpressions
For details see https://developers.google.com/analytics/devguides/reporting/core/dimsmets.". Details: "Unknown metric(s): ga:adImpressions
For details see https://developers.google.com/analytics/devguides/reporting/core/dimsmets.">
Could anyone help me out?
Related
I am running karate tests.
I am posting a request object and i recieve a response object . however in the response object i have one extra field populated .How will i handle the scenario ?
the following is my test
#NFRSubscription.feature
Feature: NFR Subscription API Tests
Background:
* url __arg.test_service.url
* configure ssl = false
* configure httpVersion = 'http2'
Scenario: Create/Patch/Delete NRF subscription by nfInstanceId subscription condition
* def subscriptionId = ''
* def createSubscriptionByNfInstanceIdRequest = read('subscription/subscriptionCreateRequest.json')
* def patchSubscriptionByNfInstanceIdResponse = read('subscription/subscriptionPatchResponse.json')
* def createSubscriptionByNfInstanceIdResponse = createSubscriptionByNfInstanceIdRequest
# Create the NRF subscription by nfInstanceId
Given path '/nnrf-nfm/v1/subscriptions/'
And header Content-Type = 'application/json; charset=utf-8'
And print createSubscriptionByNfInstanceIdRequest
And request createSubscriptionByNfInstanceIdRequest
When method post
Then status 201
And match response == createSubscriptionByNfInstanceIdResponse
And match response.subscriptionId == '#present'
And print response
the content of subscription/subscriptionCreateRequest.json is as follows.
{
"nfStatusNotificationUri": "http://localhost:8080/ip/test",
"reqNfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76",
"subscrCond": {
"nfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76"
},
"validityTime": "2022-02-18T10:15:15Z",
"reqNotifEvents": [
"NF_REGISTERED"
],
"plmnId": {"mcc": "454", "mnc" : "93" },
"nid": "2465aEB5ff1",
"notifCondition": {
"monitoredAttributes": [
"testattri"
]
},
"reqNfType": "NRF",
"reqNfFqdn": "com.openet.com",
"reqSnssais": [
{ "sst": 10, "sd": "aA82a7" }
],
"reqPlmnList": [
{"mcc": "454", "mnc" : "93" }
],
"reqSnpnList": [
{"mcc": "454", "mnc" : "93" }
],
"servingScope": [
"any string"
],
"nrfSupportedFeatures": "CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d"
}
the content of the file subscription/subscriptionPatchResponse.json is as follows.
{
"nfStatusNotificationUri": "http://localhost:8080/ip/test",
"reqNfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76",
"subscrCond": {
"nfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76"
},
"validityTime": "2023-03-07T23:20:50Z",
"reqNotifEvents": [
"NF_REGISTERED"
],
"plmnId": {"mcc": "454", "mnc" : "93" },
"nid": "2465aEB5ff1",
"notifCondition": {
"monitoredAttributes": [
"testattri"
]
},
"reqNfType": "NRF",
"reqNfFqdn": "com.openet.com",
"reqSnssais": [
{ "sst": 10, "sd": "aA82a7" }
],
"reqPlmnList": [
{"mcc": "454", "mnc" : "93" }
],
"reqSnpnList": [
{"mcc": "454", "mnc" : "93" }
],
"servingScope": [
"any string"
],
"nrfSupportedFeatures": "CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d"
}
in the response I would expect a new field called subscriptionId .
my test fails at the moment with the following error .
16:00:57 com.intuit.karate.exception.KarateException: NFRSubscription.feature:24 - path: $, actual: {nfStatusNotificationUri=http://localhost:8080/ip/test, reqNfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76, subscrCond={nfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76}, subscriptionId=608425, validityTime=2022-02-18T10:15:15Z, reqNotifEvents=["NF_REGISTERED"], plmnId={mcc=454, mnc=93}, nid=2465aEB5ff1, notifCondition={monitoredAttributes=["testattri"]}, reqNfType=NRF, reqNfFqdn=com.openet.com, reqSnssais=[{"sst":10,"sd":"aA82a7"}], reqPlmnList=[{"mcc":"454","mnc":"93"}], reqSnpnList=[{"mcc":"454","mnc":"93"}], servingScope=["any string"], nrfSupportedFeatures=CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d}, expected: {nfStatusNotificationUri=http://localhost:8080/ip/test, reqNfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76, subscrCond={nfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76}, validityTime=2022-02-18T10:15:15Z, reqNotifEvents=["NF_REGISTERED"], plmnId={mcc=454, mnc=93}, nid=2465aEB5ff1, notifCondition={monitoredAttributes=["testattri"]}, reqNfType=NRF, reqNfFqdn=com.openet.com, reqSnssais=[{"sst":10,"sd":"aA82a7"}], reqPlmnList=[{"mcc":"454","mnc":"93"}], reqSnpnList=[{"mcc":"454","mnc":"93"}], servingScope=["any string"], nrfSupportedFeatures=CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d}, reason: actual value has 1 more key(s) than expected: {subscriptionId=608425}
any idea how should i formulate createSubscriptionByNfInstanceIdResponse object to handle an extra dynamically generated field . in other words how can i do the following
add response.subscriptionId into createSubscriptionByNfInstanceIdResponse and then compare response and
createSubscriptionByNfInstanceIdResponse object .
And match response == createSubscriptionByNfInstanceIdResponse
I have changed the test to add the subscriptionId field in the response object and then asserted it .
# Create the NRF subscription by nfInstanceId
Given path '/nnrf-nfm/v1/subscriptions/'
And header Content-Type = 'application/json; charset=utf-8'
And print createSubscriptionByNfInstanceIdRequest
And request createSubscriptionByNfInstanceIdRequest
When method post
Then status 201
And match response.subscriptionId == '#present'
And print response
And set createSubscriptionByNfInstanceIdResponse.subscriptionId = response.subscriptionId
And match response == createSubscriptionByNfInstanceIdResponse
I have a webhook, that call this function when
event["type"] == "payment_intent.amount_capturable_updated"
def capture_order(session):
ordered_uuid = uuid.UUID(session["metadata"]["pk_order"])
try:
order = Ordered.objects.filter(
pk=ordered_uuid
).prefetch_related(
"from_ordered", "from_ordered__to_product"
).get()
except Ordered.DoesNotExist:
stripe.PaymentIntent.cancel(session["id"])
return HttpResponse(status=400)
try:
products = set()
for ordered_product in order.from_ordered.all():
product = ordered_product.to_product
product.stock -= ordered_product.quantity
if product.stock < 0:
raise ValueError()
products.add(product)
with transaction.atomic():
Product.objects.bulk_update(list(products), ("stock",))
stripe.PaymentIntent.capture(session["id"])
except ValueError:
stripe.PaymentIntent.cancel(session["id"])
except IntegrityError:
stripe.PaymentIntent.cancel(session["id"])
return HttpResponse(status=200)
and I get this error:
This PaymentIntent could not be captured because it has a status of canceled. Only a PaymentIntent with one of the following statuses may be captured: requires_capture.
I had instantiate my checkout like this:
checkout_session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[
{
'price_data': {
'currency': 'eur',
'unit_amount_decimal': get_amount(self.object, with_delivery=True).quantize(TWO_PLACES),
'product_data': {
'name': f'Order #{self.object.pk}',
},
},
'quantity': 1,
},
],
payment_intent_data={
"capture_method": "manual",
"metadata": {
"pk_order": self.object.pk
}
})
any idea ?
You should inspect your dashboard logs - I suspect that one of your error paths is canceling the payment intent before you try to capture it. You'll need to trace through your login to figure out why that's happening.
I am trying to filter my GA api V4 in python by removing pageviews under 200 in my request...
surprisingly, as i follow exactly the syntax of the documentation, i get an error message :
> "Invalid JSON payload received. Unknown name "comparisonValue" at 'report_req
uests[0].metric_filter_clauses[0].filters[0]': Proto field is not repeating, cannot start list.". Details: "[{'
#type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'report_requests[0].metric_f
ilter_clauses[0].filters[0]', 'description': 'Invalid JSON payload received. Unknown name "comparisonValue" at
\'report_requests[0].metric_filter_clauses[0].filters[0]\': Proto field is not repeating, cannot start list.'}]
}]"
obviously there is a problem in my coding, but I cannot understand what it is : it is a copy paste of the documentation in https://developers.google.com/analytics/devguides/reporting/core/v4/basics#filtering...
is there a difference between the JSON POST from documentation and the one in the batch get from python?
here is the part where I build my request the problematic filter is at the end...:
return analytics.reports().batchGet(
body={
'reportRequests': [
{
'viewId': VIEW_ID,
'dateRanges': [{'startDate': '2021-07-20', 'endDate': '2021-07-27'}],
'metrics': [
{
'expression': 'ga:sessions',
'expression': 'ga:pageviews'
}],
'dimensions': [
{
'name': 'ga:pagePath'
}],
'orderBys': [
{
'orderType': 'VALUE',
'sortOrder': "DESCENDING",
'fieldName': 'ga:pageviews'
}],
'dimensionFilterClauses': [
{
'filters': [
{
'dimensionName':'ga:country',
'operator':'BEGINS_WITH',
'expressions':['fra']
}],
}],
'metricFilterClauses': [
{
'filters': [
{
'metricName':'ga:pageviews',
'operator':'GREATER_THAN',
'comparisonValue':['200']
}]
}]
}]
}
).execute()
any idea why it don't work?
thanks :)
Jacques,
comparisonValue field value should be a string, not a list, e.g. '200' instead of ['200'].
A good way to eliminate possible coding issues is to test your query directly using the Google Analytics API Explorer.
I am trying to build a free/busy body request to Google Calendar API via Python 3.8 . However, when I try to insert a new item into the body request, I am getting a bad request and can't use it.
This code is working:
SUBJECTA = '3131313636#resource.calendar.google.com'
SUBJECTB = '34343334#resource.calendar.google.com'
body = {
"timeMin": now,
"timeMax": nownext,
"timeZone": 'America/New_York',
"items": [{'id': SUBJECTA},{"id": SUBJECTB} ]
}
Good Body result:
{'timeMin': '2019-11-05T11:42:21.354803Z',
'timeMax': '2019-11-05T12:42:21.354823Z',
'timeZone': 'America/New_York',
'items': [{'id': '131313636#resource.calendar.google.com'},
{'id': '343334#resource.calendar.google.com'}]}
However,
While using this code:
items = "{'ID': '1313636#resource.calendar.google.com'},{'ID': '3383137#resource.calendar.google.com'},{'ID': '383733#resource.calendar.google.com'}"
body = {
"timeMin": now,
"timeMax": nownext,
"timeZone": 'America/New_York',
"items": items
}
The Body results contain additional quotes at the start and end position, failing the request:
{'timeMin': '2019-11-05T12:04:41.189784Z',
'timeMax': '2019-11-05T13:04:41.189804Z',
'timeZone': 'America/New_York',
'items': ["{'ID': 13131313636#resource.calendar.google.com},{'ID':
53333383137#resource.calendar.google.com},{'ID':
831383733#resource.calendar.google.com},{'ID':
33339373237#resource.calendar.google.com},{'ID':
393935323035#resource.calendar.google.com}"]}
What is the proper way to handle it and send the item list in an accurate way?
In your situation, the value of items is given by the string of "{'ID': '1313636#resource.calendar.google.com'},{'ID': '3383137#resource.calendar.google.com'},{'ID': '383733#resource.calendar.google.com'}".
You want to use as the object by parsing the string value with python.
The result value you expect is [{'ID': '1313636#resource.calendar.google.com'}, {'ID': '3383137#resource.calendar.google.com'}, {'ID': '383733#resource.calendar.google.com'}].
You have already been able to use Calender API.
If my understanding is correct, how about this answer? Please think of this as just one of several answers.
Sample script:
import json # Added
items = "{'ID': '1313636#resource.calendar.google.com'},{'ID': '3383137#resource.calendar.google.com'},{'ID': '383733#resource.calendar.google.com'}"
items = json.loads(("[" + items + "]").replace("\'", "\"")) # Added
body = {
"timeMin": now,
"timeMax": nownext,
"timeZone": 'America/New_York',
"items": items
}
print(body)
Result:
If now and nownext are the values of "now" and "nownext", respectively, the result is as follows.
{
"timeMin": "now",
"timeMax": "nownext",
"timeZone": "America/New_York",
"items": [
{
"ID": "1313636#resource.calendar.google.com"
},
{
"ID": "3383137#resource.calendar.google.com"
},
{
"ID": "383733#resource.calendar.google.com"
}
]
}
Note:
If you can retrieve the IDs as the string value, I recommend the following method as a sample script.
ids = ['1313636#resource.calendar.google.com', '3383137#resource.calendar.google.com', '383733#resource.calendar.google.com']
items = [{'ID': id} for id in ids]
If I misunderstood your question and this was not the result you want, I apologize.
I am having trouble accessing custom dimensions available through GUI using their API names. Is there any way to find the actual api name of all available custom dimensions and metrics. Currently I am using name of the format ga:dimension<indexidfromGUI> like ga:dimension4 but this returns a unknown dimension error.
HttpError: <HttpError 400 when requesting https://analyticsreporting.googleapis.com/v4/reports:batchGet?alt=json returned "Unknown dimension(s): ga:dimension11
Here is my report body:
body={
'reportRequests': [
{
'viewId': VIEW_ID,
'dateRanges': [{'startDate': '1daysAgo', 'endDate': '1daysAgo'}],
'metrics': [
{'expression': 'ga:sessions'},
],
'dimensions': [
{'name': 'ga:date'},
{'name': 'ga:dimension4'},
#{'name': 'ga:dimension11'},
#{'name': 'ga:dimension13'},
#{'name': 'ga:dimension14'},
],
"dimensionFilterClauses": [
{
"filters": [
{
"dimensionName": "ga:eventAction",
"operator": "PARTIAL",
"expressions": ["ScreenView"]
}
]
}
],
}]
}
).execute()
If the format for api dim name is wrong, how do i find it out? It is not available in Analytics GUI as far as I know. Is there a documentation for this? I am aware of https://developers.google.com/analytics/devguides/reporting/core/dimsmets.
But this doesnt include custom dimensions.