using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Net; using System.IO; using System.Text; using System.Xml; using System.Collections.Specialized; using System.Diagnostics; /// /// Summary description for GoogleAnalytics /// public class GoogleAnalytics { //Oauth not implemented yet, check out API docs for more public enum mode { ClientLogin, AuthSub } //used when you want to manage email/pass from within your app public static string getSessionTokenClientLogin(string email, string password) { //Google analytics requires certain variables to be POSTed string postData = "Email=" + email + "&Passwd=" + password; //defined - should not channge much postData = postData + "&accountType=HOSTED_OR_GOOGLE" + "&service=analytics" + "&source=akamarketing-testapp-1"; ASCIIEncoding encoding = new ASCIIEncoding(); byte[] data = encoding.GetBytes(postData); HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("https://www.google.com/accounts/ClientLogin"); myRequest.Method = "POST"; myRequest.ContentType = "application/x-www-form-urlencoded"; myRequest.ContentLength = data.Length; Stream newStream = myRequest.GetRequestStream(); // Send the data. newStream.Write(data, 0, data.Length); newStream.Close(); HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); Stream responseBody = myResponse.GetResponseStream(); Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); StreamReader readStream = new StreamReader(responseBody, encode); //returned from Google Analytics API string response = readStream.ReadToEnd(); //get the data we need string[] auth = response.Split(new string[] { "Auth=" }, StringSplitOptions.None); //return it (the authorization token) return auth[1]; } //used when you have authenticated on Google (via AuthSub & query params) & have a temp token public static string getSessionTokenAuthSub(string tempToken) { string response = GArequestResponseHelper("https://www.google.com/accounts/AuthSubSessionToken", tempToken, mode.AuthSub); //temp (once off) token will have been exchanged for session token, return it return response.Split('=')[1]; } public static NameValueCollection getAccountInfo(string sessionToken, mode mode) { string response = GArequestResponseHelper("https://www.google.com/analytics/feeds/accounts/default", sessionToken, mode); //response will contain an XML formatted string similar to //http://code.google.com/p/ga-api-http-samples/source/browse/trunk/src/v1/accountFeedResponse.xml //we need to convert it to proper XML for parsing XmlDocument accountinfoXML = new XmlDocument(); accountinfoXML.LoadXml(response); //each account/profile combo the current user is authorized for will an 'entry' element XmlNodeList entries = accountinfoXML.GetElementsByTagName("entry"); NameValueCollection profiles = new NameValueCollection(); for (int i = 0; i < entries.Count; i++) { //profile name, profile ID - profile ID is needed for ID what data you want from the API profiles.Add(entries.Item(i).ChildNodes[2].InnerText,entries.Item(i).ChildNodes[6].Attributes["value"].Value); } return profiles; } public static string getData(string sessionToken, string profileID, mode mode) { //we'll also want to pass in non hardcoded dates and report specifiers //month in format yyyy-mm-dd etc. alternatively we could have static //metrics for each of the tasks our system needs to do, eg. getTopContent(), //getTopBrowswer() etc. //At the moment we just getting pageview metric for our sites URLs //so for the purposes of demostration the URL in this method is //almost fully hardcoded string response = GArequestResponseHelper("https://www.google.com/analytics/feeds/data?ids=ga:" + profileID + "&dimensions=ga:pageTitle&metrics=ga:pageviews&sort=-ga:pageviews&start-date=2009-03-01&end-date=2009-03-31&prettyprint=true&max-results=20", sessionToken, mode); //response will contain an XML formatted string similar to //http://code.google.com/p/ga-api-http-samples/source/browse/trunk/src/v1/dataFeedResponse.xml return response; } public static string GArequestResponseHelper(string url, string token, mode mode) { HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url); //will always be a token of some sort required in the header but the format //it is passed in will depend on what type of authorization is being used if (mode == mode.ClientLogin) { myRequest.Headers.Add("Authorization: GoogleLogin auth=" + token); } else if (mode == mode.AuthSub) { myRequest.Headers.Add("Authorization: AuthSub token=" + token); } //obviously you need some kind of try/catch here //but OK to bubble auth/connection failures up for demo HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); Stream responseBody = myResponse.GetResponseStream(); Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); StreamReader readStream = new StreamReader(responseBody, encode); //return string itself (easier to work with) return readStream.ReadToEnd(); } }