I'm running into a bit of an issue with the Google Calendar API. I'm trying to create an even on a calendar, but I'm getting stuck at querying the calendar service. I'm using this guide I found on codeproject (Guide), and it links you to this authentication guide (Authentication Guide). I was able to make it through step 5 under "OAuth 2.0 flows" on the Authentication guide, and got the access token, and refresh token, but when I attempt to query the calendar service, I get this error:
"Execution of request failed: https://www.google.com/calendar/feeds/default/allcalendars/full", "The remote server returned an error: (401) Unauthorized."
I'm not sure what I'm doing wrong, I authorized the user and have the access token. So I would think I'm missing something small, but I have been banging my head for the past day trying to figure it out.
This is the code I'm using:
Google.GData.Client.GAuthSubRequestFactory authFactory = new Google.GData.Client.GAuthSubRequestFactory("cl", "API Project");
authFactory.Token = "ya29...";
authFactory.KeepAlive = true;
Google.GData.Calendar.CalendarService service = new CalendarService("API Project");
service.RequestFactory = authFactory;
Uri postUri = new Uri(AllCalendarFeed);
Google.GData.Calendar.CalendarQuery CalendarQuery = new Google.GData.Calendar.CalendarQuery();
CalendarQuery.Uri = postUri;
//Errors out on this line:
Google.GData.Calendar.CalendarFeed calFeed = service.Query(CalendarQuery);
string CalendarID = "";
if (calFeed != null && calFeed.Entries.Count > 0)
{
foreach (CalendarEntry CalEntry in calFeed.Entries)
{
//Commented to post the new appointments
//on the main calendar instead of cleverfox calendar
//if (CalEntry.Title.Text.Contains("Cleverfox") == true)
//{
//CalendarID = CalEntry.Title.Text;
CalendarID = CalEntry.EditUri.ToString().Substring(CalEntry.EditUri.ToString().LastIndexOf("/") + 1);
break;
//}
}
}
Any help is greatly appreciated. Thank you.
Related
I have been using the Google.GData.Analytics and Google.GData.Client
to retrieve some Google Analytics data though the Google Analytics API v2 in my web application.
The code was as follows:
string username = "abc#gmail.com";
string password = "myPasswordHere";
string profileId = "ga:88376970";
string _from = Convert.ToDateTime(dtpFrom.SelectedDate.Value.ToString()).ToString("yyyy-MM-dd");
string _to = Convert.ToDateTime(dtpTo.SelectedDate.Value.ToString()).ToString("yyyy-MM-dd");
AccountQuery AccountsQuery = new AccountQuery();
service = new AnalyticsService("DoogalAnalytics");
service.setUserCredentials(username, password);
try
{
DataFeedUrl = "https://www.google.com/analytics/feeds/data";
DataQuery PageViewQuery = new DataQuery(DataFeedUrl)
{
Ids = profileId ,
Metrics = "ga:pageviews",
Dimensions = "ga:date",
Sort = "ga:date",
GAStartDate = _from,
GAEndDate = _to
};
StringBuilder strData = new StringBuilder();
int maxValue = 0;
int today = 0;
List<int> gList = new List<int>();
foreach (DataEntry entry in service.Query(PageViewQuery).Entries)
{
var value = entry.Metrics.First().IntegerValue;
gList.Add(value);
maxValue = value > maxValue ? value : maxValue;
today = entry.Metrics.Last().IntegerValue;
strData.AppendFormat("{0},", value);
}
}
catch (Exception ex)
{
Response.Write(ex.Message.ToString());
}
This code was working perfectly fine until about 5 days ago and I have been using this code for the last 7 or 8 months, but now suddenly I am facing the error
Execution of authentication request returned unexpected result: 404.
When I searched google.
I have searched alot but could not find any solution.
Any help or guidance will be greatly appreciated.
Client login which was discontinued / shutdown began on April 20 2015 and probably completed around May 26 2015. You can no longer use client login (Login and password) with the Google Analytics API, you need to switch to Oauth2. You will need to change your code to use Oauth2 or a service account.
Its best to grab the newest version of the client library which uses Google Analytics V3 you are using V2.
PM> Install-Package Google.Apis.Analytics.v3
If this is data you already own you may want to consider a service account. A service account will let you set up access to your google analytics account and it wont require a user to authenticate your code. If this is not your Google Analytics account but in fact one owned by another user then you will need to use Oauth2 and request authentication from the user.
My Tutorial: Google Analytics API Authentication with C#
Code ripped from tutorial above the tutorial is kept up to date this code may not be:
string[] scopes = new string[] {
AnalyticsService.Scope.Analytics, // view and manage your Google Analytics data
AnalyticsService.Scope.AnalyticsEdit, // Edit and manage Google Analytics Account
AnalyticsService.Scope.AnalyticsManageUsers, // Edit and manage Google Analytics Users
AnalyticsService.Scope.AnalyticsReadonly}; // View Google Analytics Data
String CLIENT_ID = "6.apps.googleusercontent.com"; // found in Developer console
String CLIENT_SECRET = "xxx";// found in Developer console
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential =
GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets {
ClientId = CLIENT_ID
, ClientSecret = CLIENT_SECRET
}
, scopes
, Environment.UserName
, CancellationToken.None
, new FileDataStore("Daimto.GoogleAnalytics.Auth.Store")).Result;
AnalyticsService service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Analytics API Sample",
});
DataResource.GaResource.GetRequest request = service.Data.Ga.Get("ga:8903098", "2014-01-01", "2014-01-01", "ga:sessions");
request.MaxResults = 1000;
GaData result = request.Execute();
I am using Google Plus API for .Net for implementing sharing on google plus using WebAuthenticationBroker. It returns a token after the user gets logged in but when I send a moments post request it returns error 401.
My code on clicking on image is
String GoogleURL = "https://accounts.google.com/o/oauth2/auth?client_id=xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://www.google.com&response_type=code&scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.stream.write https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.login");
PlusService service = new PlusService();
System.Uri StartUri = new Uri(GoogleURL);
System.Uri EndUri = new Uri("https://accounts.google.com/o/oauth2/approval?");
WebAuthenticationBroker.AuthenticateAndContinue(new Uri(GoogleURL), EndUri);
now when it returns after authenticating I have called method upload on google in continue which is as follows--
PlusService service = new PlusService();
Moment body = new Moment();
ItemScope itemScope = new ItemScope();
itemScope.Id = "replacewithuniqueforaddtarget";
itemScope.Image = "http://www.google.com/s2/static/images/GoogleyEyes.png";
itemScope.Type = "";
itemScope.Description = "The description for the action";
itemScope.Name = "An example of add activity";
body.Object = itemScope;
body.Type = "http://schema.org/AddAction";
MomentsResource.InsertRequest insert =
new MomentsResource.InsertRequest(
service,
body,
"me",
MomentsResource.InsertRequest.CollectionEnum.Vault);
Moment wrote = insert.Execute();
But it returns exception 401. The code to post I found on Google Console Help. Can somebody help in this?
I finally found out that google APIs are not directly open to third party developers and it just made my case void and had to use HTTP method for this. Thanks #DalmTo for answering.
I have a website made with ASP.NET webform .NET 4.5 C#. This site contains a forum(homemade by me), parts of this forum needs to be posted to the specific facebook wall(made for this webpage). What I need :
Post just created thread(message) from specific part of the forum to the corsponding facebook wall.
Optional : Sync the forum thread on webpage with message/comments on the specific facebook page
I have looked at these guides :
http://www.codeproject.com/Articles/569920/Publish-a-post-on-Facebook-wall-using-Graph-API
http://www.c-sharpcorner.com/UploadFile/raj1979/post-on-facebook-users-wall-using-Asp-Net-C-Sharp/
But im not sure that this is really the solution for me? I have tried to follow the guide but it does not look the same.
Edit :
dynamic result;
//https://developers.facebook.com/tools/explorer/
//https://developers.facebook.com/tools/access_token/
FacebookClient client = new FacebookClient(ConfigurationManager.AppSettings["FacebookAppToken"]);
//result = client.Get("debug_token", new
//{
// input_token = ConfigurationManager.AppSettings["FacebookAppToken"],
// access_token = ConfigurationManager.AppSettings["FacebookAppToken"]
//});
//result = client.Get("oauth/access_token", new
// {
// client_id = ConfigurationManager.AppSettings["FacebookAppId"],
// client_secret = ConfigurationManager.AppSettings["FacebookAppSecret"],
// grant_type = "client_credentials",
// //redirect_uri = "http://www.MyDomain.net/",
// //code = ""
// });
result = client.Get("oauth/access_token", new
{
client_id = ConfigurationManager.AppSettings["FacebookAppId"],
client_secret = ConfigurationManager.AppSettings["FacebookAppSecret"],
grant_type = "client_credentials"
});
client.AccessToken = result.access_token;
result = client.Post("[IdOfFacebookPage]/feed", new { message = "Test Message from app" });
//result.id;
result = client.Get("[IdOfFacebookPage]");
return false;
Approach to post to a facebook wall:
You need to register in facebook developer tools.
Create a app (fill a form).
Download FGT 5.0.480 (Facebook graph toolkit)
Reference FGT dlls in your web application.
FGT has methods to post to facebook wall but needs appId.
Use the app id of your app created in step 2.
To post to an user's wall through facebook, it is only possible through an app.
Try this asp .net app, which will allow you to post in your wall:
https://apps.facebook.com/aspdotnetsample/?fb_source=search&ref=br_tf
This will allow you to envision what you need.
Your app gets an appId with which you need to generate auth token.
Limitation: The user's wall where you want to post should have added the app created at step 2, this is compulsory and there is no work around.
When the user accesses the app for the first time, it automatically asks for permission to post to wall--> the user needs to accept it.
Hope this gives you an idea on how to go about doing this.
You can then post into the user's wall.
For Banshee's below request using Facebook SDK for .NET:
userId - facebook user id, wall to post the message
This user should have added the app created by you in step 1 else it will say unauthorized access.
dynamic messagePost = new ExpandoObject();
messagePost.picture = "http://www.stackoverflow.com/test.png";
messagePost.link = "http://www.stackoverflow.com";
messagePost.name = "This is a test name";
messagePost.caption = "CAPTION 1";
messagePost.description = "Test desc";
messagePost.message = "message"
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new {
client_id = "app_id",
client_secret = "app_secret",
grant_type = "client_credentials"
});
fb.AccessToken = result.access_token;
try
{
var postId = fb.Post(userId + "/feed", messagePost);
}
catch (FacebookOAuthException ex)
{
//handle oauth exception
}
catch (FacebookApiException ex)
{
//handle facebook exception
}
You will need an extended token to publish to a wall.. Steps to get extended token is explained well by Banshee..
Edit: How to get extended token by Banshee:
Please follow this post
By creating a extended page token and use it to make the post everything works just fine. See this : How to get Page Access Token by code?
Im surprised that this simple task was so hard to get running and that there was vary little help to get.
I am attempting to download metric data from Google Analytics using C# and am performing user authentication with OAuth 2.0. I'm using the Installed Application authorisation flow, which requires logging into Google and copy-and-pasting a code into the application. I'm following the code taken from google-api-dotnet-client:
private void DownloadData()
{
Service = new AnalyticsService(new BaseClientService.Initializer() {
Authenticator = CreateAuthenticator(),
});
var request = service.Data.Ga.Get(AccountID, StartDate, EndDate, Metrics);
request.Dimensions = Dimensions;
request.StartIndex = 1;
request.MaxResults = 10000;
var response = request.Execute(); // throws Google.GoogleApiException
}
private IAuthenticator CreateAuthenticator()
{
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description) {
ClientIdentifier = "123456789012.apps.googleusercontent.com",
ClientSecret = "xxxxxxxxxxxxxxxxxxxxxxxx",
};
return new OAuth2Authenticator<NativeApplicationClient>(provider, Login);
}
private static IAuthorizationState Login(NativeApplicationClient arg)
{
// Generate the authorization URL.
IAuthorizationState state = new AuthorizationState(new[] { AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user by opening a browser window.
Process.Start(authUri.ToString());
Console.Write("Google Authorization Code: ");
string authCode = Console.ReadLine();
// Retrieve the access token by using the authorization code.
state = arg.ProcessUserAuthorization(authCode, state);
return state;
}
The Google account xxxxxx#gmail.com registered the Client ID and secret. The same account has full administration rights in Google Analytics. When I try to pull data from Google Analytics, it goes through the authorisation process, which appears to work properly. Then it fails with:
Google.GoogleApiException
Google.Apis.Requests.RequestError
User does not have sufficient permissions for this profile. [403]
Errors [
Message[User does not have sufficient permissions for this profile.] Location[ - ] Reason [insufficientPermissions] Domain[global]
]
I've been struggling with this for a few hours. I've double checked that the correct user is being used, and is authorised on Google Analytics. I'm at a loss as to what is misconfigured. Any ideas as to what requires configuring or changing?
If auth seems to be working working then my suggestion is that you make sure you're providing the correct ID because based on your code snippet:
var request = service.Data.Ga.Get(AccountID, StartDate, EndDate, Metrics);
one can only assume that you're using the Account ID. If so, that is incorrect and you'd receive the error you've encountered. You need to query with the Profile ID.
If you login to Google Analytics using the web interface you'll see the following pattern in URL of the browser's address bar:
/a12345w654321p9876543/
The number following the p is the profile ID, so 9876543 in the example above. Make sure you're using that and actually you should be using the table id which would be ga:9876543.
If it isn't an ID issue then instead query the Management API to list accounts and see what you have access to and to verify auth is working correctly.
This can help : https://developers.google.com/analytics/devguides/reporting/core/v3/coreErrors, look error 403.
//Thanks for this post. The required profile id can be read from the account summaries.
Dictionary profiles = new Dictionary();
var accounts = service.Management.AccountSummaries.List().Execute();
foreach (var account in accounts.Items)
{
var profileId = account.WebProperties[0].Profiles[0].Id;
profiles.Add("ga:" + profileId, account.Name);
}
So i've been using Linq-To-Twitter to add Twitter Integration to my Windows 8 Store App, Moreso for playing around with it, but i've come accross a problem. My current authentication codeblock is
var auth = new WinRtAuthorizer
{
Credentials = new LocalDataCredentials
{
ConsumerKey = "",
ConsumerSecret = ""
},
UseCompression = true,
Callback = new Uri("http://linqtotwitter.codeplex.com/")
};
if (auth == null || !auth.IsAuthorized)
{
await auth.AuthorizeAsync();
}
Which works great, unless I go into the authentication screen and click the back button on the top left, to exit authentication without supplying details. at which point i get a TwitterQueryException: Bad Authentication data at:
var timelineResponse =
(from tweet in twitterCtx.Status
where tweet.Type == StatusType.Home
select tweet)
.ToList();
Obviously because the Authentication Information was wrong, I'm trying to find a way to stop proceeding to the rest of the code if the authentication fails/is backed out.
I've tried simple boolean checks to no effect. I've been melting my brain over this for hours, so any help would be greatly appreciated. Thanks a bunch!
You can query Account.VerifyCredentials to ensure the user is logged in before performing any other operation. Here's an example:
const int BadAuthenticationData = 215;
var twitterCtx = new TwitterContext(auth);
try
{
var account =
(from acct in twitterCtx.Account
where acct.Type == AccountType.VerifyCredentials
select acct)
.SingleOrDefault();
await new MessageDialog(
"Screen Name: " + account.User.Identifier.ScreenName,
"Verification Passed")
.ShowAsync();
}
catch (TwitterQueryException tqEx)
{
if (tqEx.ErrorCode == BadAuthenticationData)
{
new MessageDialog(
"User not authenticated",
"Error During Verification.")
.ShowAsync();
return;
}
throw;
}
Your error handling strategy will differ from this, which is just a sample, but it shows you how to know that the error occurred and gives you the opportunity to react to the problem before resuming normal operation.
TwitterQueryException will include the Twitter error code in the ErrorCode property. It also sets Message to the error message that Twitter returns. InnerException provides the underlying exception with the original stack trace, which is often a WebException thrown because of the HTTP error code returned from Twitter.