Accessing Google Docs with GData - c#

Working Platform: ASP.NET 4.0 C# ( Framework Agnostic )
Google GData is my dependency
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Documents;
I have two pages Auth and List.
Auth redirects to Google Server like this
public ActionResult Auth()
{
var target = Request.Url.ToString().ToLowerInvariant().Replace("auth", "list");
var scope = "https://docs.google.com/feeds/";
bool secure = false, session = true;
var authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
return new RedirectResult(authSubUrl);
}
Now it reaches the List Page if Authentication is successful.
public ActionResult List()
{
if (Request.QueryString["token"] != null)
{
String singleUseToken = Request.QueryString["token"];
string consumerKey = "www.blahblah.net";
string consumerSecret = "my_key";
string sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null).ToString();
var authFactory = new GOAuthRequestFactory("writely", "qwd-asd-01");
authFactory.Token = sessionToken;
authFactory.ConsumerKey = consumerKey;
authFactory.ConsumerSecret = consumerSecret;
//authFactory.TokenSecret = "";
try
{
var service = new DocumentsService(authFactory.ApplicationName) { RequestFactory = authFactory };
var query = new DocumentsListQuery();
query.Title = "project";
var feed = service.Query(query);
var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
return View(result);
}
catch (GDataRequestException gdre)
{
throw;
}
}
}
This fails at the line var feed = service.Query(query); with the error
Execution of request failed: https://docs.google.com/feeds/default/private/full?title=project
The HttpStatusCode recieved on the catch block is HttpStatusCode.Unauthorized
What is wrong with this code? Do I need to get TokenSecret? If so how?

You need to request a token from Google and use it to intialize your DocumentsService instance.
Here's an example using Google's ContactsService. It should be the same for the DocumentsService.
Service service = new ContactsService("My Contacts Application");
service.setUserCredentials("your_email_address_here#gmail.com", "yourpassword");
var token = service.QueryClientLoginToken();
service.SetAuthenticationToken(token);
But as you mentioned, you are using AuthSub. I jumped the gun a bit too fast.
I see that you are requesting a session token. According to the documentation of the API you must use the session token to authenticate requests to the service by placing the token in the Authorization header. After you've set the session token, you can use the Google Data APIs client library.
Here's a complete example (by Google) on how to use AuthSub with the .NET client library:
http://code.google.com/intl/nl-NL/apis/gdata/articles/authsub_dotnet.html
Let me include a shortened example:
GAuthSubRequestFactory authFactory =
new GAuthSubRequestFactory("cl", "TesterApp");
authFactory.Token = (String) Session["token"];
CalendarService service = new CalendarService(authFactory.ApplicationName);
service.RequestFactory = authFactory;
EventQuery query = new EventQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full");
EventFeed calFeed = service.Query(query);
foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries)
{
//...
}
And if I see correctly your example code pretty follows the same steps, except that you set the ConsumerKey and ConsumerSecret for the AuthFactory which is not done in the example by Google.

Used the 3-legged OAuth in the Google Data Protocol Client Libraries
Sample Code
string CONSUMER_KEY = "www.bherila.net";
string CONSUMER_SECRET = "RpKF7ykWt8C6At74TR4_wyIb";
string APPLICATION_NAME = "bwh-wssearch-01";
string SCOPE = "https://docs.google.com/feeds/";
public ActionResult Auth()
{
string callbackURL = String.Format("{0}{1}", Request.Url.ToString(), "List");
OAuthParameters parameters = new OAuthParameters()
{
ConsumerKey = CONSUMER_KEY,
ConsumerSecret = CONSUMER_SECRET,
Scope = SCOPE,
Callback = callbackURL,
SignatureMethod = "HMAC-SHA1"
};
OAuthUtil.GetUnauthorizedRequestToken(parameters);
string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters);
Session["parameters"] = parameters;
ViewBag.AuthUrl = authorizationUrl;
return View();
}
public ActionResult List()
{
if (Session["parameters"] != null)
{
OAuthParameters parameters = Session["parameters"] as OAuthParameters;
OAuthUtil.UpdateOAuthParametersFromCallback(Request.Url.Query, parameters);
try
{
OAuthUtil.GetAccessToken(parameters);
GOAuthRequestFactory authFactory = new GOAuthRequestFactory("writely", APPLICATION_NAME, parameters);
var service = new DocumentsService(authFactory.ApplicationName);
service.RequestFactory = authFactory;
var query = new DocumentsListQuery();
//query.Title = "recipe";
var feed = service.Query(query);
var docs = new List<string>();
foreach (DocumentEntry entry in feed.Entries)
{
docs.Add(entry.Title.Text);
}
//var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
return View(docs);
}
catch (GDataRequestException gdre)
{
HttpWebResponse response = (HttpWebResponse)gdre.Response;
//bad auth token, clear session and refresh the page
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
Session.Clear();
Response.Write(gdre.Message);
}
else
{
Response.Write("Error processing request: " + gdre.ToString());
}
throw;
}
}
else
{
return RedirectToAction("Index");
}
}
This 2-legged sample never worked for me for google docs.

Related

Remembering log in credentials/permissions UWP/C# (Microsoft Cloud API)

I'm creating an app that access the Microsoft Cloud API to get health data. It uses OAuth to log in when you hit the Sign In Button
private void signinButton_Click(object sender, RoutedEventArgs e)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_authorize.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&scope={0}", Uri.EscapeDataString(Scopes));
query.Append("&response_type=code");
uri.Query = query.ToString();
this.webView.Visibility = Visibility.Visible;
this.webView.Navigate(uri.Uri);
}
This brings up a webView with the page to log in using Microsoft credentials. Once completed, it leads to this:
private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
//
// When the web view navigates to our redirect URI, extract the authorization code from
// the URI and use it to fetch our access token. If no authorization code is present,
// we're completing a sign-out flow.
//
if (args.Uri.LocalPath.StartsWith("/oauth20_desktop.srf", StringComparison.OrdinalIgnoreCase))
{
WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(args.Uri.Query);
var code = decoder.FirstOrDefault((entry) => entry.Name.Equals("code", StringComparison.OrdinalIgnoreCase));
var error = decoder.FirstOrDefault((entry) => entry.Name.Equals("error", StringComparison.OrdinalIgnoreCase));
var errorDesc = decoder.FirstOrDefault((entry) => entry.Name.Equals("error_description", StringComparison.OrdinalIgnoreCase));
// Check the code to see if this is sign-in or sign-out
if (code != null)
{
// Hide the browser again, no matter what happened...
sender.Visibility = Visibility.Collapsed;
if (error != null)
{
this.responseText.Text = string.Format("{0}\r\n{1}", error.Value, errorDesc.Value);
return;
}
var tokenError = await this.GetToken(code.Value, false);
if (string.IsNullOrEmpty(tokenError))
{
this.responseText.Text = "Successful sign-in!";
this.signoutButton.IsEnabled = true;
this.signinButton.IsEnabled = false;
this.getProfileButton.IsEnabled = true;
this.getDevicesButton.IsEnabled = true;
this.getActivitiesButton.IsEnabled = true;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = true;
}
else
{
this.responseText.Text = tokenError;
}
}
else
{
this.responseText.Text = "Successful sign-out!";
this.signoutButton.IsEnabled = false;
this.signinButton.IsEnabled = true;
this.getProfileButton.IsEnabled = false;
this.getDevicesButton.IsEnabled = false;
this.getActivitiesButton.IsEnabled = false;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = false;
}
}
}
private async Task<string> GetToken(string code, bool isRefresh)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_token.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&client_secret={0}", Uri.EscapeDataString(ClientSecret));
if (isRefresh)
{
query.AppendFormat("&refresh_token={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=refresh_token");
}
else
{
query.AppendFormat("&code={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=authorization_code");
}
uri.Query = query.ToString();
var request = WebRequest.Create(uri.Uri);
try
{
using (var response = await request.GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
using (var streamReader = new StreamReader(stream))
{
var responseString = streamReader.ReadToEnd();
var jsonResponse = JObject.Parse(responseString);
this.creds.AccessToken = (string)jsonResponse["access_token"];
this.creds.ExpiresIn = (long)jsonResponse["expires_in"];
this.creds.RefreshToken = (string)jsonResponse["refresh_token"];
string error = (string)jsonResponse["error"];
return error;
}
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
I don't want users to have to accept the permissions every time the app is launched. Is there a way to save credentials locally so that it automatically authenticates on launch? Thanks!
You can use
Windows.Storage.ApplicationData.Current.LocalSettings
This process good described by this answer Best Way to keep Settings for a WinRT App?
The code in link identity to UWP
Store the needed oauth parts in the credential locker API. Never store these kind of information in the normal settings API.
On start read the oauth information and use the refreshtoken to get a new access token.
More Information here.
https://msdn.microsoft.com/en-us/library/windows/apps/mt270189.aspx

MailChimp Integaration with MVC 5

I am working on an MVC5 project, the client is interested in using MailChimp for sending emails. I have explored the MailChimp and wrappers ( MailChimp.NET ) and tried in my project as well. I tested the REST API as well and it seems to work , for example; I was able to grab lists and templates using REST API. But, still I am having issues with sending email through MailChimp.
So far, I have tried the following code and its working. Now I want to send an email to a newly registered user. Kindly give me detailed code example that How can I achieve this, because I am totally struck here..
var apiKey = "myapikey-us11";
var listId = "mylistid";
var subscribeRequest = new
{
apikey = apiKey,
id = listId,
email = new
{
email = "muhammad.waqas#seventechnology.co.uk"
},
double_optin = true,
};
var requestJson = JsonConvert.SerializeObject(subscribeRequest);
var reqresult = CallMailChimpApi("lists/", requestJson);
CallMailChimApi
private static string CallMailChimpApi(string method, string requestJson)
{
var endpoint = String.Format("https://{0}.api.mailchimp.com/3.0/{1}", "us11", method);
var wc = new WebClient();
try
{
return wc.UploadString(endpoint, requestJson);
}
catch (WebException we)
{
using (var sr = new StreamReader(we.Response.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
}
I Use this function and it work successfully
public void SendEmailByApiMailChimp ()
{
try
{
string UserEmail = " Exemple#gmail.com ";
MailChimpManager mc = new MailChimpManager("16d***********-us14");
EmailParameter email = new EmailParameter()
{
Email = UserEmail
};
EmailParameter resulte = mc.Subscribe("yourlistnumber", email);
var test = resulte;
}
catch (Exception ex)
{
var ters = ex;
}
}

Can't register application on Instagram

I am writing C# client for Instagram. I've registered my application and filled the fields: Application Name, Description, Website, OAuth redirect_uri. But I receive this error message in my C# client:
This client is not xAuth enabled.
I think the problem is in Website, OAuth redirect_uri fields. What values must I put in these fields?
Here is method that have to get access_token (HttpRequest class from xNet library):
private string GetAccessToken()
{
using (var request = new HttpRequest())
{
var urlParams = new RequestParams();
urlParams["client_id"] = "ce3c76b914cb4417b3721406d7fe3456";
urlParams["client_secret"] = "b8ad0c21ce8142d0a8c0fa2d2bd78f53";
urlParams["username"] = this.login;
urlParams["password"] = this.password;
urlParams["grant_type"] = "password";
urlParams["scope"] = "comments likes relationships";
try
{
this.json = request.Post("https://api.instagram.com/oauth/access_token", urlParams).ToString();
var values = JsonConvert.DeserializeObject<InstagramResponse>(this.json);
return values.access_token;
}
catch (Exception)
{
return null;
}
}
}

LinqToTwitter status update only works sometimes

I'm trying to send a tweet using LinqToTwitter. My problem is that it almost never works. I've gotten it to work maybe three times out of thirty, and usually that's when I try to debug. I'm thinking it might have something to do with timing and authentication, but I don't know how to do it. The code runs without errors, but no tweet is generated.
public static async Task SendTweetAsync(string text)
{
// Get the authorization credentials
var auth = GetCredentials();
// Create the twitter context
var ctx = new TwitterContext(auth);
try
{
Status responseTweet = await ctx.TweetAsync(text);
}
catch (Exception e) {
throw e;
}
}
private static AspNetAuthorizer GetCredentials()
{
return new AspNetAuthorizer
{
CredentialStore = new InMemoryCredentialStore()
{
ConsumerSecret = "##########",
ConsumerKey = "##########",
OAuthToken = "##########",
OAuthTokenSecret = "##########",
UserID = ##########
}
};
}
I don't know what happened to the answer that was here before, by #JoeMayo, but the thing that worked for me was to change the AspNetAuthorizer to SingleUserAuthorizer.
private static SingleUserAuthorizer GetCredentials()
{
return new SingleUserAuthorizer
{
CredentialStore = new InMemoryCredentialStore()
{
ConsumerSecret = "##########",
ConsumerKey = "##########",
OAuthToken = "##########",
OAuthTokenSecret = "##########",
UserID = ##########
}
};
}
Also, I added await auth.AuthorizeAsync();
var auth = GetCredentials();
await auth.AuthorizeAsync();
As I said, the credit should really go to #JoeMayo, but his answer is gone.

Unable Post tweet From C# Aaplication

i'm using oauth and twitterizer in my C# apps, and after trying for several times. and it won't get any exception, error. but it's doesn't want to post it to twitter.
here is my code
protected void Page_Load(object sender, EventArgs e)
{
BLTgUser objBLTgUser = new BLTgUser();
if (!objBLTgUser.IsLogin) objBLTgUser.GoToLoginPage(HttpContext.Current.Request.Url.AbsoluteUri);
m_strIdGods = objBLTgUser.IdGods;
BLGodsProfile objGods = new BLGodsProfile();
tbmgodsprofile objGodsProfile = objGods.GetGodsByIdGods(m_strIdGods);
string reqToken = Request.QueryString["oauth_token"].ToString();
string pin = Request.QueryString["oauth_verifier"].ToString();
var oauth_consumerKey = System.Configuration.ConfigurationManager.AppSettings["TwitterConsumerKey"];
var oauth_consumerSecret = System.Configuration.ConfigurationManager.AppSettings["TwitterConsumerSecret"];
var tokens = OAuthUtility.GetAccessToken(
oauth_consumerKey,
oauth_consumerSecret,
reqToken,
pin);
string accessToken = tokens.Token;
string accessTokenSecret = tokens.TokenSecret;
objGodsProfile.twittertoken = accessToken;
objGodsProfile.twitterpin = accessTokenSecret;
objGodsProfile.twitterstatus = "1";
objGods.UpdateGodsProfile(objGodsProfile);
}
i'm trying store the token and tokensecret to Database, it's for the next uses.
string v_str = "";
BLEnumHelper m_BLEnumHelper = new BLEnumHelper();
BLGodsProfile userprofile = new BLGodsProfile();
tbmgodsprofile godsAccessToken = userprofile.GetGodsByIdGods(m_strIdGods);
string reqToken = godsAccessToken.twittertoken;
string reqTokenAccess = godsAccessToken.twitterpin;
var oauth_consumerKey = System.Configuration.ConfigurationManager.AppSettings["TwitterConsumerKey"];
var oauth_consumerSecret = System.Configuration.ConfigurationManager.AppSettings["TwitterConsumerSecret"];
OAuthTokens accesstoken = new OAuthTokens()
{
AccessToken = reqToken,
AccessTokenSecret = reqTokenAccess ,
ConsumerKey = oauth_consumerKey,
ConsumerSecret = oauth_consumerSecret
};
TwitterResponse<TwitterStatus> response = TwitterStatus.Update(accesstoken,p_strMessage);
if (response.Result == RequestResult.Success)
{
Response.Write("we did it!");
}
else
{
Response.Write("it's all bad.");
}
and after the 2nd code be called, it wont' post to twitter.
Twitterizer is no longer maintained.
https://github.com/Twitterizer/Twitterizer/blob/develop/README.mediawiki
Twitterizer not supporting Twitter's new API version 1.1, you can't use it for development.
As an alternative, I recommend CoreTweet for you.

Categories

Resources