I am trying to connect to the Google Analytics reporting API to get basic pageview stats. Im trying to follow this tutorial (http://www.arboundy.com/2012/04/getting-started-with-google-analytics-in-c/). I'm having trouble setting the correct bits to get a successful auth as it seems google has changed the APIs a lot lately so the original config doesn't seem to work.
Heres what I currently have:
Service = new AnalyticsService("MyDemoApp");
Service.setUserCredentials("user#gmail.com", "password");
AccountQuery AccountsQuery = new AccountQuery("https://www.googleapis.com/analytics/v3/data/ga"/*Not sure what goes here this gives a 400*/);
AccountFeed AccountsFeed = Service.Query(AccountsQuery); // 400 error here
Any ideas how to connect to this via the V3 api (which appears to be the one I got from NuGet)
this must work for u in c#. (i have tried and worked)
string username = "youremailuser#domain.com";
string pass = "yourpassword";
string gkey = "?key=YourAPIkEY";
string dataFeedUrl = "https://www.google.com/analytics/feeds/data" + gkey;
string accountFeedUrl = "https://www.googleapis.com/analytics/v2.4/management/accounts" + gkey;
AnalyticsService service = new AnalyticsService("WebApp");
service.setUserCredentials(username, pass);
DataQuery query1 = new DataQuery(dataFeedUrl);
query1.Ids = "ga:12345678";
query1.Metrics = "ga:visits";
query1.Sort = "ga:visits";
query1.GAStartDate = new DateTime(2012, 1, 2).ToString("yyyy-MM-dd");
query1.GAEndDate = DateTime.Now.ToString("yyyy-MM-dd");
query1.StartIndex = 1;
DataFeed dataFeedVisits = service.Query(query1);
foreach (DataEntry entry in dataFeedVisits.Entries)
{
string st = entry.Title.Text;
string ss = entry.Metrics[0].Value;
visits = ss;
}
for more details Read data from Google data API
Related
I have an ONVIF ip camera.
I want to to capture an image from the camera so that I can process that image and save it to the file system.
I found out that there is an onvif api which provides a method GetSnapshotUri which should provide me with an image snapshot:
http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
I managed to import this api in visual studio by adding a service reference to it:
How do I construct a client to call GetSnapshotUri from this service?
So, after lots of searching I managed to capture an image from the camera.
The first Problem was that I have used "Add Service Reference->Advanced->Add Web reference" instead of typing the service address directly in the "Add Service Reference" box.
Here, I added the address: http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
Then I could use the MediaClient class, correctly pointed out by pepOS in a comment, and the final code looks like:
var messageElement = new TextMessageEncodingBindingElement();
messageElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();
httpBinding.AuthenticationScheme = AuthenticationSchemes.Basic;
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
EndpointAddress mediaAddress = new EndpointAddress("http://192.168.1.168:10001/onvif/Media");
MediaClient mediaClient = new MediaClient(bind, mediaAddress);
mediaClient.ClientCredentials.UserName.UserName = "admin";
mediaClient.ClientCredentials.UserName.Password = "admin";
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[1].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);
The uri of the image could then be fount at the MediaUri.Uriaddress
The GetSnapshotUri returns a uri for downloading an image using HTTP get.
So in theory you just need to call this function, and use the returned uri in the function shown in this Stackoverflow article:
https://stackoverflow.com/a/3615831/4815603
I am using onvif device manager dll here. To implement this method camera's IP, username and password must be known.
// Onvif ODM
using onvif.services;
using odm.core;
using onvif.utils;
using utils;
public string GetSnapshotUrl()
{
try
{
string camera_ip = "http://" + camIp + "/onvif/device_service";
Uri Camuri = new Uri(camera_ip);
NvtSessionFactory sessionFactory = new NvtSessionFactory(account);
INvtSession session = sessionFactory.CreateSession(Camuri);
Profile[] Profiles = session.GetProfiles().RunSynchronously();
var snapshotlink = session.GetSnapshotUri(Profiles[0].token).RunSynchronously(); // taking snapshot on the first profile of the camera
return snapshotlink.uri;
}
catch (Exception ex)
{
return null;
}
}
For me basic authentication didn't work. The following code works for me and downloads the image:
string username = "username";
string password = "password";
string cameraIP = "";
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(
EnvelopeVersion.Soap12, AddressingVersion.None)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
MediaClient mediaClient = new MediaClient(bind, new EndpointAddress($"http://{cameraIP}/onvif/device_service"));
mediaClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.UserName = username;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[0].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);
WebClient webCl = new WebClient()
{
Credentials = new NetworkCredential(username, password)
};
webCl.DownloadFile(mediaUri.Uri, #"D:\test.jpg");
I am creating shared contacts in google, it creates the contact, but I can't see the contacts in the directory in google contacts.
I have looked for answers and found this probably closest.. but I can't seem to get it right...
Here is some code:
string s = "https://www.google.com/m8/feeds";
string targetUri = #"https://www.google.com/m8/feeds/contacts/mycompany.com/full";
string serviceAccountEmail = "123456789012-xxxx1x1xx11x1xxxxxxx11xxxx1xxx11#developer.gserviceaccount.com";
string serviceClientId = "123456789012-xxxx1x1xx11x1xxxxxxx11xxxx1xxx11.apps.googleusercontent.com";
X509Certificate2 certificate = new X509Certificate2(#"C:\All\mygcertificate-1xx1xxx1xx11.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[]
{
"http://www.google.com/m8/feeds/contacts/"
},
User = "my.user#mycompany.com"
}.FromCertificate(certificate));
string AuthenticationToken1 = string.Empty;
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
AuthenticationToken1 = credential.Token.AccessToken;
}
Service service = new Service(s, serviceClientId);
GAuthSubRequestFactory factory = new GAuthSubRequestFactory(s, serviceClientId);
factory.Token = AuthenticationToken1;
service.RequestFactory = factory;
Contact ct = new Contact();
ct.Name = new Google.GData.Extensions.Name() { GivenName = "Ron", FamilyName = "Swanson", FullName = "Ron Swanson" };
ct.Emails.Add(new Google.GData.Extensions.EMail("Ron.Swanson#someclient.com", #"http://schemas.google.com/g/2005#work") { Primary = true });
ct.Phonenumbers.Add(new Google.GData.Extensions.PhoneNumber("2345555522") { Rel = #"http://schemas.google.com/g/2005#work", Primary = true});
AtomCategory atc = new AtomCategory();
atc.Term = #"http://schemas.google.com/contact/2008#contact";
atc.Scheme = #"http://schemas.google.com/g/2005#kind";
ct.Categories.Add(atc);
var atomentrytoinsert = ct.AtomEntry;
var result = service.Insert(new Uri(targetUri), atomentrytoinsert);
//Stream getresult = service.Query(new Uri(targetUri)); //this read actually gets the records i inserted...
If i run that last commented out line, i can see the entries I created ... but when I go to google contacts and click directory - They are not there. Also not on autocomplete when I compose email... Am I missing a attribute somewhere.
I have left the entries over 24 hours (I created them on Friday).
Would appreciate any input.
I tryed the sharedcontact API yesterday, the new contacts were not visible in directory.
But this morning the autocomplete has suggested the new contacts! To make them visible in the directory I had to open the Admin google Console->google apps-> contacts -> advanced settings and checked the " shows both the profiles of the domain is the Domain Shared Contacts"
It worked immediately for me, I hope help you!
I'm developing an application to insert row to one of my spreadsheet (like database). The problem is, it always asking new access code. Please help me to avoid expiring the access code or I just want to update my google drive account excel. Sometimes there will be a easy code, may I using wrong code? Below is my code:
string CLIENT_ID = "HIDE";
string CLIENT_SECRET = "HIDE";
string SCOPE = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.ClientId = CLIENT_ID;
parameters.ClientSecret = CLIENT_SECRET;
parameters.RedirectUri = REDIRECT_URI;
parameters.Scope = SCOPE;
string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
auth.Text = authorizationUrl;
info.Text = ("Please visit the URL above to authorize your OAuth " +"request token. Once that is complete, type in your access code to "+ "continue...");
parameters.AccessCode = accc.Text;
OAuthUtil.GetAccessToken(parameters);
string accessToken = parameters.AccessToken;
acc2.Text = accessToken;
GOAuth2RequestFactory requestFactory =
new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
string USERNAME = "HIDE";
string PASSWORD = "HIDE";
service.setUserCredentials(USERNAME, PASSWORD);
SpreadsheetQuery query = new SpreadsheetQuery();
SpreadsheetFeed feed = service.Query(query);
if (feed.Entries.Count == 0)
{
Console.WriteLine("None");
}
SpreadsheetEntry spreadsheet = (SpreadsheetEntry)feed.Entries[0];
Console.WriteLine(spreadsheet.Title.Text);
WorksheetFeed wsFeed = spreadsheet.Worksheets;
WorksheetEntry worksheet = (WorksheetEntry)wsFeed.Entries[0];
AtomLink listFeedLink = worksheet.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null);
ListQuery listQuery = new ListQuery(listFeedLink.HRef.ToString());
ListFeed listFeed = service.Query(listQuery);
ListEntry row = new ListEntry();
row.Elements.Add(new ListEntry.Custom() { LocalName = "no.", Value = "#" });
service.Insert(listFeed, row);
You can make a request for "offline" access when requesting the access token. The server will return a "refresh token" and with this toke you can request a new "access token" when it expires without having the user to grant permissions again.
Here you can find documentation on that.
Check this tutorial, it will help you to obtain the access token and refresh token programmatically instead of having to open the browser and copy the token.
I trying using Google Analytics with C# to get stats information to display in my webiste
Here is my code
public ActionResult Index()
{
string userName = "admin#email.com";
string passWord = "mypass";
string profileId = "ga:xxxxxxxx";
string key = "2d751338cb092ef8da65f716e37a48604386c9sw";
string dataFeedUrl = "https://www.google.com/analytics/feeds/data"+key;
var service = new AnalyticsService("API Project");
service.setUserCredentials(userName, passWord);
var dataQuery = new DataQuery(dataFeedUrl)
{
Ids = profileId,
Metrics = "ga:pageviews",
Sort = "ga:pageviews",
GAStartDate = new DateTime(2010, 3, 1).ToString("yyyy-MM-dd"),
GAEndDate = DateTime.Now.ToString("yyyy-MM-dd")
};
var dataFeed = service.Query(dataQuery);
var totalEntry = dataFeed.Entries[0];
ViewData["Total"] = ((DataEntry)(totalEntry)).Metrics[0].Value;
dataQuery.GAStartDate = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
dataQuery.GAEndDate = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
dataFeed = service.Query(dataQuery);
var yesterdayEntry = dataFeed.Entries[0];
ViewData["Yesterday"] = ((DataEntry)(yesterdayEntry)).Metrics[0].Value;
dataQuery.GAStartDate = DateTime.Now.ToString("yyyy-MM-dd");
dataQuery.GAEndDate = DateTime.Now.ToString("yyyy-MM-dd");
dataFeed = service.Query(dataQuery);
var todayEntry = dataFeed.Entries[0];
ViewData["Today"] = ((DataEntry)(todayEntry)).Metrics[0].Value;
return View(dataFeed.Entries);
}
But when i run the code it always said "{"Invalid credentials"}"
Not sure why i facing this error while i checked many time about the key,username,password and profileId
Anyone facing this problem,can help me?
Many thanks
I think that your url is wrong. try in this way (you are missing ?key=).
string dataFeedUrl = "https://www.google.com/analytics/feeds/data?key="+key;
refer this google example where there is this example that should help you
public DataFeedExample()
{
// Configure GA API.
AnalyticsService asv = new AnalyticsService("gaExportAPI_acctSample_v2.0");
// Client Login Authorization.
asv.setUserCredentials(CLIENT_USERNAME, CLIENT_PASS);
// GA Data Feed query uri.
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Dimensions = "ga:source,ga:medium";
query.Metrics = "ga:visits,ga:bounces";
query.Segment = "gaid::-11";
query.Filters = "ga:medium==referral";
query.Sort = "-ga:visits";
query.NumberToRetrieve = 5;
query.GAStartDate = "2010-03-01";
query.GAEndDate = "2010-03-15";
Uri url = query.Uri;
Console.WriteLine("URL: " + url.ToString());
// Send our request to the Analytics API and wait for the results to
// come back.
feed = asv.Query(query);
}
refer also this guide to configure your project
Also follow this guide to use OAuth 2.0
Here is what im trying to do , i got a webpage with signin page with cresedentials from our database , then once is logged in it should redirect you to main page where you should see the data in charts.
The problem is I used gdata v2.4 but every time i want make a request i have to set the cresedentials again, then v3.0 with oauth 2.0 it said we don't need to this anymore by access token.
I managed to make it work but the problem is if the user been asked to login with gmail account and the email and password doesnt match the profile id of the request it gives the 403 error (forbidden access) this is the code . i tried to use service account no chance , any one knows whats the problem?
log4net.Config.XmlConfigurator.Configure();
//string Scope = AnalyticsService.Scopes.Analytics.ToString().ToLower();
//string scopeUrl = "https://www.google.com/analytics/feeds/" + Scope;
string Scope = "https://www.google.com/analytics/feeds/";
const string ServiceAccountId = "xxxxxxxxxxx.apps.googleusercontent.com";
const string ServiceAccountUser = "xxxxxxxxxxx#developer.gserviceaccount.com";
string key = string.Empty;
foreach (string keyname in Directory.GetFiles(Server.MapPath("/"), "*.p12", SearchOption.AllDirectories))
{
key = keyname;
}
AssertionFlowClient client = new AssertionFlowClient(
GoogleAuthenticationServer.Description, new X509Certificate2(key, "notasecret", X509KeyStorageFlags.Exportable))
{
Scope = Scope,
ServiceAccountId = ServiceAccountUser//,ServiceAccountUser = ServiceAccountUser
};
WebServerClient myWebServerClient = new WebServerClient(GoogleAuthenticationServer.Description);
myWebServerClient.ClientIdentifier = this.ClientID;
myWebServerClient.ClientSecret = this.ClientSecret;
OAuth2Authenticator<WebServerClient> authenticator = new OAuth2Authenticator<WebServerClient>(myWebServerClient, GetAuthorization);
AnalyticsService service = new AnalyticsService(authenticator);
string profileId = Session["_ProfileID"].ToString() ;
string startDate = StartDate;
string endDate = EndDate;
string metrics = "ga:visits";
DataResource.GaResource.GetRequest request = service.Data.Ga.Get(profileId, startDate, endDate, metrics);
request.Dimensions = "ga:date";
request.StartIndex = 1;
request.MaxResults = 500;
GaData data = request.Fetch();
return data;
dont bother anymore , i got it right with offline access . Thanks for showing the SUPPORT