Generating JSON-formatted data from Google Ads results

145 Views Asked by At

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 });
}

0

There are 0 best solutions below