How to filter by dimension using Google Analytics Data API (GA4) Java client library? - google-analytics-api

I am trying to call Google Analytics Data API (GA4) using the Java client library and applying a dimension filter. This is the call which is working if I don't use the setDimensionFilter call:
RunReportRequest request =
RunReportRequest.newBuilder()
.setProperty(propertyId)
.addDimensions(com.google.analytics.data.v1beta.Dimension.newBuilder().setName("pageLocation"))
.addMetrics(com.google.analytics.data.v1beta.Metric.newBuilder().setName("screenPageViews"))
.addMetrics(com.google.analytics.data.v1beta.Metric.newBuilder().setName("activeUsers"))
// .setDimensionFilter(FilterExpression.newBuilder().setFilter(Filter.newBuilder().setStringFilter(
// Filter.StringFilter.newBuilder()
// .setMatchType(Filter.StringFilter.MatchType.FULL_REGEXP)
// .setField(Descriptors.FieldDescriptor, "pageLocation")
// .setValue("MY_REGEXP")
// .build())))
.addDateRanges(com.google.analytics.data.v1beta.DateRange.newBuilder()
.setStartDate(startDate.toStringYYYYMMDDWithDashes())
.setEndDate(endDate.toStringYYYYMMDDWithDashes()))
.setKeepEmptyRows(true)
.build();
I don't know how to use setDimensionFilter. If the usage which is commented in the previous code is correct, then the only thing missing is the call to setField. I don't know how to generate the Descriptors.FieldDescriptor instance (or even its meaning).
I have reviewed the client library javadoc, and also the code samples (which are really simple and unfortunately do not show any usage of setDimensionFilter).

The Descriptors.FieldDescriptor isn't part of the GA4 Data API and is an internal functionality of the protobuf framework
If you are trying to call this filter on a field with the name 'pageLocation' instead of using setField, I think you can do something like this
RunReportRequest request =
RunReportRequest.newBuilder()
.setProperty("properties/" + propertyId)
.addDimensions(com.google.analytics.data.v1beta.Dimension.newBuilder().setName("pageLocation"))
.addMetrics(com.google.analytics.data.v1beta.Metric.newBuilder().setName("screenPageViews"))
.addMetrics(com.google.analytics.data.v1beta.Metric.newBuilder().setName("activeUsers"))
.setDimensionFilter(FilterExpression.newBuilder()
.setFilter(Filter.newBuilder()
.setFieldName("pageLocation")
.setStringFilter(Filter.StringFilter.newBuilder()
.setMatchType(Filter.StringFilter.MatchType.FULL_REGEXP)
.setValue("MY_REGEXP"))))
.addDateRanges(com.google.analytics.data.v1beta.DateRange.newBuilder()
.setStartDate("2020-03-31")
.setEndDate("2021-03-31"))
.build();
Also, if you want an additional example of how to use setDimensionFilter, here is another code example that might help
RunReportRequest request =
RunReportRequest.newBuilder()
.setProperty("properties/" + propertyId)
.addDimensions(Dimension.newBuilder().setName("city"))
.addMetrics(Metric.newBuilder().setName("activeUsers"))
.addDateRanges(DateRange.newBuilder().setStartDate("2020-03-31").setEndDate("today"))
.setDimensionFilter(FilterExpression.newBuilder()
.setAndGroup(FilterExpressionList.newBuilder()
.addExpressions(FilterExpression.newBuilder()
.setFilter(Filter.newBuilder()
.setFieldName("platform")
.setStringFilter(Filter.StringFilter.newBuilder()
.setMatchType(Filter.StringFilter.MatchType.EXACT)
.setValue("Android"))))
.addExpressions(FilterExpression.newBuilder()
.setFilter(Filter.newBuilder()
.setFieldName("eventName")
.setStringFilter(Filter.StringFilter.newBuilder()
.setMatchType(Filter.StringFilter.MatchType.EXACT)
.setValue("in_app_purchase"))))))
.setMetricFilter(FilterExpression.newBuilder()
.setFilter(Filter.newBuilder()
.setFieldName("sessions")
.setNumericFilter(Filter.NumericFilter.newBuilder()
.setOperation(Filter.NumericFilter.Operation.GREATER_THAN)
.setValue(NumericValue.newBuilder()
.setInt64Value(1000)))))
.build();

Related

How to wrap up external api response in order to meet json datasource backend requirements

I’m trying to create a grafana datasource plugin which is to return a response with table type format.
There is a third party rest API which should provide data to the datasource, however, the request/response format of this external API do not conform with the example simple-json-datasource plugin urls and requests formats.
Is there a way I could wrap up the external api response in the datasource backend methods (/query) which is then called by the front-end part of datasource? (external api URL will be provided at the datasource settings UI while adding the datasource)
I'll appreciate the answers/suggestion.
You would have to write code that transforms the third party API response into the table type format.
You may want to start off of something like this: https://github.com/grafana/simple-json-datasource
Clone that project, and change the url values passed in options to the doRequest() function, those values should point to your third party API.
The doRequest() function seems to return a Promise, so you can do your data transformation when they are fulfilled, for example:
// simple-json-datasource/src/datasource.js
// in the query() function
return this.doRequest(options).then(function(result) {
// your transform code here;
return transformedResult;
})

Grails REST API hide "class" in respond list

I'm using Grails 2.3.2 working on a REST API using the built in Grails REST support. I'm having trouble getting rid of the "class" element in the JSON response. Based on a tutorial by Bobby Warner, I have found adding the following to the resources.groovy file:
meterRenderer(JsonRenderer, Meter) {
excludes = ['class']
}
This works fine for show, but for the index controller function, I'm responding with a list of Meters. In this, the "class" doesn't go away. What does it take to get rid of this in the list response?
Edit: To clarify, I am looking for a way to leverage the Content Negotiation feature of Grails new respond functionality without locking myself down to render as JSON implementions.
I guess if you switch to using GSON (github) instead of JSON then you need not worry about that particular exclusion.
That is driven by a config setting provided by the plugin as grails.converters.gson.domain.include.class (default is false).
nickdos' SO link had the answer. I added the following to my BootStrap.groovy:
grails.converters.JSON.registerObjectMarshaller(Meter) {
return it.properties.findAll {k,v -> k != 'class'}
}
And the respond call results in no "class" item. Oddly enough, I lost the "id" item in the process, but I'll save that for another SO question. :)

Integrate AngularJS App with SoftwareAG webMethods Integration Server

I have been trying to set up a sample AngularJS app with webMethods Integration Server on the backend. Using $resource, I can easily pull normal JSON files and manipulate the data within the file. However, the goal is that I want to create services in webMethods Designer and call them from AngularJS using $resource to display the data in my app. The problem is that from AngularJS I cannot extract the data I need from the service that I'm creating in Designer. In Designer I can use (in WMPublic) documentToJSONString, and output something like:
jsonString {"id":"1", "name":"Dan", "quantity":"3"}
But I cannot extract the data because this is not a pure JSON string. Does anyone know how to (1) extract the JSON string output data using AnularJS or (2) output a JSON document from Designer? I am calling a REST service; something to the effect of
http://localhost:2222/rest/Get/getOrderData
from my services.js file in AngularJS.
Here is my services.js file:
/* Services */
var orderServices = angular.module('orderServices', ['ngResource']);
orderServices.factory('Order', ['$resource',
function($resource){
return $resource('http://localhost:2222/rest/REST/getOrderData', {}, {
query: {method:'GET', isArray:true}
});
}]);
Then, in my app, I want to use an ng-repeat to call things like {{order.id}}, {{order.name}} etc. Is anyone good with webMethods and Angular or done this before?
To force the response that you want, I would have used the service
pub.flow:setResponse mapping the jsonString to it's string parameter and probably hardcoded (eww!) the contentType parameter to 'application/json'
You may also need to use the service pub.flow:setResponseCode to set the response code.
They would be the last services in getOrderData
I would have invoked it using the below (where namespace is the folder structure in designer)
http://localhost:2222/invoke/namespace:getOrderData
The above applies to Integration Server V8 and it looks like you're using V9 since some of the services that you mention didn't exist in V8. This would also apply to a normal flow service, not a specific REST one (assuming they exist in V9).

The definitive guide to posting a Facebook Feed item using pure C#

Does anyone have a definitive way to post to a user's wall, using nothing but the .NET Framework, or Silverlight?
Problems deriving from people's attempts have been asked here on SO, but I cannot find a full, clear explanation of the Graph API spec and a simple example using WebClient or some similar class from System.Net.
Do I have to send all feed item properties as parameters in the query string? Can I construct a JSON object to represent the feed item and send that (with the access token as the only parameter)?
I expect its no more than a 5 line code snippet, else, point me at the spec in the FB docs.
Thanks for your help,
Luke
This is taken from how we post to a user's wall. We place the data for the post in the request body (I think we found this to be more reliable than including all the parameters in the query part of the request), it has the same format as a URL encoded query string.
I agree that the documentation is rather poor at explaining how to interact with a lot of resources. Typically I look at the documentation for information on fields and connections, then work with the Graph API Explorer to understand how the request needs to be constructed. Once I've got that down it's pretty easy to implement in C# or whatever. The only SDK I use is Facebook's Javascript SDK. I've found the others (especially 3rd party) are more complicated, buggy, or broken than rolling my own.
private void PostStatus (string accessToken, string userId)
{
UriBuilder address = new UriBuilder ();
address.Scheme = "https";
address.Host = "graph.facebook.com";
address.Path = userId + "/feed";
address.Query = "access_token=" + accessToken;
StringBuilder data = new StringBuilder ();
data.Append ("caption=" + HttpUtility.UrlEncodeUnicode ("Set by app to describe the app."));
data.Append ("&link=" + HttpUtility.UrlEncodeUnicode ("http://example.com/some_resource_to_go_to_when_clicked"));
data.Append ("&description=" + HttpUtility.UrlEncodeUnicode ("Message set by user."));
data.Append ("&name=" + HttpUtility.UrlEncodeUnicode ("App. name"));
data.Append ("&picture=" + HttpUtility.UrlEncodeUnicode ("http://example.com/image.jpg"));
WebClient client = new WebClient ();
string response = client.UploadString (address.ToString (), data.ToString ());
}
I don't know much about .net or silverlight, but the facebook api works with simple http requests.
All the different sdks (with the exception of the javascript one) are mainly just wrappers for the http requests with the "feature" of adding the access token to all requests.
Not in all requests the parameters are sent as querystring, in some POST requests you need to send them in the request body (application/x-www-form-urlencoded), and you can not send the data as json.
If the C# sdk is not to your liking, you can simply create one for your exact needs.
As I wrote, you just need to wrap the requests, and you can of course have a method that will get a json as parameter and will break it to the different parameters to be sent along with the request.
I would point you to the facebook documentation but you haven't asked anything specific so there's nothing to point you to except for the landing page.

How to post a file in grails

I am trying to use HTTP to POST a file to an outside API from within a grails service. I've installed the rest plugin and I'm using code like the following:
def theFile = new File("/tmp/blah.txt")
def postBody = [myFile: theFile, foo:'bar']
withHttp(uri: "http://picard:8080/breeze/project/acceptFile") {
def html = post(body: postBody, requestContentType: URLENC)
}
The post works, however, the 'myFile' param appears to be a string rather than an actual file. I have not had any success trying to google for things like "how to post a file in grails" since most of the results end up dealing with handling an uploaded file from a form.
I think I'm using the right requestContentType, but I might have missed something in the documentation.
POSTing a file is not as simple as what you have included in your question (sadly). Also, it depends on what the API you are calling is expecting, e.g. some API expect files as base64 encoded text, while others accept them as mime-multipart.
Since you are using the rest plugin, as far as I can recall it uses the Apache HttpClient, I think this link should provide enough info to get you started (assuming you are dealing with mime-multipart). It shouldn't be too hard to change it around to work with your API and perhaps make it a bit 'groovy-ier'