Generating JSON-formatted data from Google Ads results
The code below is what I'm currently using to generate a JSON representation of the captured data. My question is, is the use of the Google.Protobuf.Reflection.MessageDescriptor
and the use of Reflection. The code appears to work. However, is there a better way to do this?
The code is called by a ClearScript-enabled JavaScript instance, thus the strings rather than longs in the parameters.
public string GenerateHistoricalMetrics(GoogleAdsClient client, string customerIdString, string locationIdsList,string languageIdString, string keywordTextsList, string pageUrl, bool debug = true) { if (debug) Debugger.Launch(); long[] locationIds = (from id in locationIdsList.Split(',') select long.Parse(id)).ToArray(); string[] keywordTexts = keywordTextsList.Split(','); long customerId = long.Parse(customerIdString); long languageId = long.Parse(languageIdString); KeywordPlanIdeaServiceClient keywordPlanIdeaService = client.GetService(Services.V10.KeywordPlanIdeaService); // Make sure that keywords and/or page URL were specified. The request must have // exactly one of urlSeed, keywordSeed, or keywordAndUrlSeed set. if (keywordTexts.Length == 0 && string.IsNullOrEmpty(pageUrl)) { return JsonConvert.SerializeObject(new JSON() { Error = "At least one of keywords or page URL is required, but neither was specified." }); } // Specify the optional arguments of the request as a keywordSeed, UrlSeed, // or KeywordAndUrlSeed. GenerateKeywordIdeasRequest request = new GenerateKeywordIdeasRequest() { CustomerId = customerId.ToString(), }; if (keywordTexts.Length == 0) { // Only page URL was specified, so use a UrlSeed. request.UrlSeed = new UrlSeed() { Url = pageUrl }; } else if (string.IsNullOrEmpty(pageUrl)) { // Only keywords were specified, so use a KeywordSeed. request.KeywordSeed = new KeywordSeed(); request.KeywordSeed.Keywords.AddRange(keywordTexts); } else { // Both page URL and keywords were specified, so use a KeywordAndUrlSeed. request.KeywordAndUrlSeed = new KeywordAndUrlSeed { Url = pageUrl }; request.KeywordAndUrlSeed.Keywords.AddRange(keywordTexts); } // Create a list of geo target constants based on the resource name of specified // location IDs. foreach (long locationId in locationIds) { request.GeoTargetConstants.Add(ResourceNames.GeoTargetConstant(locationId)); } request.Language = ResourceNames.LanguageConstant(languageId); // Set the network. To restrict to only Google Search, change the parameter below to // KeywordPlanNetwork.GoogleSearch. request.KeywordPlanNetwork = KeywordPlanNetwork.GoogleSearch; //.GoogleSearchAndPartners; var list = new List<Dictionary<string, object>>(); try { // Generate keyword ideas based on the specified parameters. var response = keywordPlanIdeaService.GenerateKeywordIdeas(request); // Iterate over the results and print its detail. foreach (GenerateKeywordIdeaResult result in response) { KeywordPlanHistoricalMetrics metrics = result.KeywordIdeaMetrics; Google.Protobuf.Reflection.MessageDescriptor descriptor = GenerateKeywordIdeaResult.Descriptor; foreach (var field in descriptor.Fields.InDeclarationOrder()) { object value = field.Accessor.GetValue(result); if (value != null) { var props = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Instance); var dict = new Dictionary<string, object>(); foreach (string key in from prop in props let key = Title(field.JsonName) + "." + prop.Name where key.StartsWith("Keyword") select key ) { dict.Add(key, value); } if (dict.Count() > 0) list.Add(dict); } } } } catch (GoogleAdsException e) { return JsonConvert.SerializeObject(new JSON() { Error = $"Failure: Message: {e.Message}, Failure: {e.Failure}, Request ID: {e.RequestId}" }); } return JsonConvert.SerializeObject(new JSON() { Cargo = list, Crew = resultList }); }