Google Analytics Reporting v4 with streams instead of views - ruby

I've just created a new Google Analytics property and it now defaults to data streams instead of views.
I had some code that was fetching reports through the API that I now need to updated to work with those data streams instead of views since there are not views anymore.
I've looked in the docs but i don't see anything related to data streams, anybody knows how this is done now?
Here's my current code that works with a view ID (I'm using the ruby google-api-client gem):
VIEW_ID = "XXXXXX"
SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'
client = AnalyticsReportingService.new
#server to server auth mechanism using a service account
#creds = ServiceAccountCredentials.make_creds({:json_key_io => File.open('account.json'), :scope => SCOPE})
#creds.sub = "myserviceaccount#example.iam.gserviceaccount.com"
client.authorization = #creds
#metrics
metric_views = Metric.new
metric_views.expression = "ga:pageviews"
metric_unique_views = Metric.new
metric_unique_views.expression = "ga:uniquePageviews"
#dimensions
dimension = Dimension.new
dimension.name = "ga:hostname"
#range
range = DateRange.new
range.start_date = start_date
range.end_date = end_date
#sort
orderby = OrderBy.new
orderby.field_name = "ga:pageviews"
orderby.sort_order = 'DESCENDING'
rr = ReportRequest.new
rr.view_id = VIEW_ID
rr.metrics = [metric_views, metric_unique_views]
rr.dimensions = [dimension]
rr.date_ranges = [range]
rr.order_bys = [orderby]
grr = GetReportsRequest.new
grr.report_requests = [rr]
response = client.batch_get_reports(grr)
I would expect that there would be a stream_id property on the ReportRequest object that I could use instead of the view_id but that's not the case.

Your existing code uses the Google Analytics Reporting api to extract data from a Universal analytics account.
Your new Google analytics property is a Google Analytics GA4 account. To extract data from that you need to use the Google analytics data api These are two completely different systems. You will not be able to just port it.
You can find info on the new api and new library here: Ruby Client for the Google Analytics Data API
$ gem install google-analytics-data

Thanks to Linda's answer i was able to get it working, here's the same code ported to the data API, it might end up being useful to someone:
client = Google::Analytics::Data.analytics_data do |config|
config.credentials = "account.json"
end
metric_views = Google::Analytics::Data::V1beta::Metric.new(name: "screenPageViews")
metric_unique_views = Google::Analytics::Data::V1beta::Metric.new(name: "totalUsers")
dimension = Google::Analytics::Data::V1beta::Dimension.new(name: "hostName")
range = Google::Analytics::Data::V1beta::DateRange.new(start_date: start_date, end_date: end_date)
order_dim = Google::Analytics::Data::V1beta::OrderBy::DimensionOrderBy.new(dimension_name: "screenPageViews")
orderby = Google::Analytics::Data::V1beta::OrderBy.new(desc: true, dimension: order_dim)
request = Google::Analytics::Data::V1beta::RunReportRequest.new(
property: "properties/#{PROPERTY_ID}",
metrics: [metric_views, metric_unique_views],
dimensions: [dimension],
date_ranges: [range],
order_bys: [orderby]
)
response = client.run_report request

Related

Ruby GA4 Data API not returning empty rows in RunReportRequest

After running my code to retrieve a report with the Google Analytics Data gem, the response is not returning all the rows as I would expect. Instead it leaves out the empty rows and only returns ones with data in this case. This is the code I am running, the property and analytics account are models to store access to the account info to pass to the api.
property = my_analytics_property
analytics_account = property.google_analytics_account
analytics_data_service = Google::Analytics::Data.analytics_data do |config|
config.credentials = analytics_account.google_account_oauth.credentials
end
date_dimension = ::Google::Analytics::Data::V1beta::Dimension.new(name: "date")
bounce_rate = ::Google::Analytics::Data::V1beta::Metric.new(name: "bounceRate")
page_views = ::Google::Analytics::Data::V1beta::Metric.new(name: "screenPageViews")
avg_session_duration = ::Google::Analytics::Data::V1beta::Metric.new(name: "averageSessionDuration")
date_range = ::Google::Analytics::Data::V1beta::DateRange.new(start_date: 1.month.ago.to_date.to_s, end_date: Date.current.to_s)
request = ::Google::Analytics::Data::V1beta::RunReportRequest.new(
property: "properties/#{property.remote_property_id}",
metrics: [bounce_rate, page_views, avg_session_duration],
dimensions: [date_dimension],
date_ranges: [date_range],
keep_empty_rows: true
)
response = analytics_data_service.run_report request

Update contact in Google People API

I'm having trouble updating the notes of contacts through Googles People API. I used some code from a previous stackoverflow answer, but it doesn't seem to work anymore. Below is the function I'm using. I'm attempting to change the notes of a particular contact to "changed bio xyz".
What am I doing wrong? The api does read a listing of the contacts, but I haven't been able to successfully write yet.
Thanks and please let me know if I can make this question more clear
results = service.people().connections().list(
resourceName='people/me',
pageSize=1500,
personFields='names,emailAddresses,phoneNumbers,biographies').execute()
connections = results.get('connections', [])
aContact = service.people().get(
resourceName = 'people/c1589313158061148817',
personFields = 'biographies' ).execute()
notesNames = aContact['biographies'][0]
notesNames['value'] = 'changed bio xyz'
result = service.people().updateContact(
resourceName = 'people/c1589313158061148817',
body = aContact,
updatePersonFields = 'biographies'
).execute()
I figured it out. The update goes in the body section, and it needs to follow a dictionary format
aContact = service.people().get(
resourceName = 'people/c36943406266964946',
personFields = 'names,nicknames'
).execute()
print ('this is acontact', aContact)
NickNames = aContact['nicknames'][0]
NickNames['value'] = 'newNickName'
aContact['nicknames'] = NickNames
result = service.people().updateContact(
resourceName = 'people/c36943406266964946',
body = aContact,
updatePersonFields = 'nicknames'
).execute()

"Insufficient permission to access this report." - youtube analytics api

I am trying to run this report:
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly','https://www.googleapis.com/auth/yt-analytics.force-ssl','https://www.googleapis.com/auth/yt-analytics-monetary.readonly','https://www.googleapis.com/auth/youtube.readonly']
API_SERVICE_NAME = 'youtubeAnalytics'
API_VERSION = 'v2'
CLIENT_SECRETS_FILE = '/Users/secret.json'
def initialize_analyticsreporting():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
flags = parser.parse_args([])
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_FILE, scope=SCOPES,
message=tools.message_if_missing(CLIENT_SECRETS_FILE))
storage = file.Storage('analyticsreporting.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow, storage, flags)
http = credentials.authorize(http=httplib2.Http())
analytics = build('youtubeAnalytics', 'v2', http=http)
return analytics
def execute_api_request(client_library_function, **kwargs):
response = client_library_function(
**kwargs
).execute()
print(response)
youtubeAnalytics = initialize_analyticsreporting()
execute_api_request(
youtubeAnalytics.reports().query,
ids='channel==MINE',
startDate='2020-05-01',
endDate='2020-12-31',
dimensions='video',
metrics='views,likes,dislikes,shares,adImpressions',
maxResults=200,
sort='-views'
)
But I get :
"Insufficient permission to access this report."
I am authenticated with OAuth, I am the content owner but I cant get the adImpressions metric to work.
My end goal is to simply get the impressions of a video using youtube analytics API. I've seen multiple threads on this topic but neither answers the question.
As DalmTo mentioned in the comments:
After adding additional scopes:
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly']
To
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly',
'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',
'https://www.googleapis.com/auth/youtube.readonly']
And reauthenticating - deleting the .dat file, and letting a new one to be created, now I am able to receive the desired metrics.

How to query google analytics api using the google api ruby gem?

The documentation of the google api ruby client lacks of practical examples, it only documents the classes and methods, so it's very hard to guess how should we use the gem in real life. For example, I'm trying to obtain all purchases from enhanced ecommerce to see where they came from (Acquisition Channel or Channel Grouping), but im only interested on transactions that took 5 sessions to convert the transaction ( our unconvinced clients).
First you will need your analytics view_id, can be obtained in the url at the end, after the letter p
Then you need to export the route to the credentials:
In your terminal:
export GOOGLE_APPLICATION_CREDENTIALS = 'folder/yourproject-a91723dsa8974.json'
For more info about credentials see google-auth-gem documentation
After setting this, you can query the api like this
require 'googleauth'
require 'google/apis/analyticsreporting_v4'
scopes = ['https://www.googleapis.com/auth/analytics']
date_from = 10.days.ago
date_to = 2.days.ago
authorization = Google::Auth.get_application_default(scopes)
analytics = Google::Apis::AnalyticsreportingV4::AnalyticsReportingService.new
analytics.authorization = authorization
view_id = '189761131'
date_range = Google::Apis::AnalyticsreportingV4::DateRange.new(start_date: date_from.strftime('%Y-%m-%d'), end_date: date_to.strftime('%Y-%m-%d'))
metric = Google::Apis::AnalyticsreportingV4::Metric.new(expression: 'ga:transactions')
transaction_id_dimension = Google::Apis::AnalyticsreportingV4::Dimension.new(name: 'ga:transactionID')
adquisition_dimension = Google::Apis::AnalyticsreportingV4::Dimension.new(name: 'ga:channelGrouping')
filters = 'ga:sessionsToTransaction==5'
request = Google::Apis::AnalyticsreportingV4::GetReportsRequest.new(
report_requests: [Google::Apis::AnalyticsreportingV4::ReportRequest.new(
view_id: view_id,
metrics: [metric],
dimensions: [transaction_id_dimension, adquisition_dimension],
date_ranges: [date_range],
filters_expression: filters
)]
)
response = analytics.batch_get_reports(request)
response.reports.first.data.rows.each do |row|
dimensions = row.dimensions
puts "TransactionID: #{dimensions[0]} - Channel: #{dimensions[1]}"
end
note filters_expression: filters
Where filters variable is in the form of ga:medium==cpc,ga:medium==organic;ga:source==bing,ga:source==google
Where commas (,) mean OR and semicolons (;) mean AND (where OR takes precedence over AND)
you can check the query explorer to play around with filters.
Here is filters documentation
If the report brings more than 1000 rows (default max rows), a next_page_token attribute will appear.
response.reports.first.next_page_token
=> "1000"
You will have to store that number to use it in the next ReportRequest
next_request = Google::Apis::AnalyticsreportingV4::GetReportsRequest.new(
report_requests: [Google::Apis::AnalyticsreportingV4::ReportRequest.new(
view_id: view_id,
metrics: [metric],
dimensions: [transaction_id_dimension, adquisition_dimension],
date_ranges: [date_range],
filters_expression: filters,
page_token: "1000"
)]
)
until
next_response.reports.first.next_page_toke
=> nil
Alternatively you can change the default page size of the report request by adding
page_size: 10_000 for example.

Reporting in Microsoft AdCenter (Sandbox) - RoR

I am using AdCenter API for my RoR application. I searched a lot on Internet to find example of ruby code to fetch account performance report using API, But didn't get.. Now I have written following code but submitGenerateReport returns nil
Here is my code.
report_request = AccountPerformanceReportRequest.new
start_date = 10.days.ago.strftime("%Y-%m-%d")
end_date = Time.zone.now.strftime("%Y-%m-%d")
scope = AccountReportScope.new
scope.accountIds = [AppConfig.adcenter['accountId']]
# Specify the format of the report.
report_request.format = 'Xml'
report_request.returnOnlyCompleteData = false
report_request.language = 'English'
report_request.reportName = "My Account Report"
report_request.aggregation = 'Daily'
report_request.time = ReportTime.new(start_date, end_date)
report_request.columns = %w[ AccountName AccountName GregorianDate CurrentMaxCpc Impressions Clicks ]
report_request.scope = scope
report_request.filter = nil
report = SubmitGenerateReportRequest.new(report_request)
# Returns nil
puts response = svc.submitGenerateReport(report)
I have campaigns, adgroups as well as ads in specified account.
Can anyone please guide me where I am wrong or give some example of reporting adcenter through api using ruby?
Thanks in advance
Got the solution...
The time was not in right format so, start time and end time was unrecognisable in soap request. SOAP debugging helped me a lot..

Resources