I have written some simple code for using my Twitter developer key and secret to read tweets from a public timeline. This is so I can display a user's latest tweets in their own website. The code is below.
I now wish to do something similar with their blog on Google's Blogger. I had assumed there would be a way to use my Google API key and secret to read the public content of a blog without the user needing to authenticate. I only need blog titles and dates so I can link through to the Blogger site. But I've spent 24 hours scouring the internet and cannot find any examples for getting an access token using just the key and secret.
Using the Google API SDK I have got as far as the code below but can't find a way to get the access token without getting the user to authenticate. Any advice appreciated - feel I'm banging my head against a wall! Happy to take any approach - I just want to get some Blogger content on a website I'm building...
Authenticate with Twitter:
var oAuthConsumerKey = _key;
var oAuthConsumerSecret = _secret;
var oAuthUrl = "https://api.twitter.com/oauth2/token";
// Do the Authenticate
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oAuthConsumerKey) + ":" +
Uri.EscapeDataString((oAuthConsumerSecret)))
));
var postBody = "grant_type=client_credentials";
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl);
authRequest.Headers.Add("Authorization", authHeader);
authRequest.Method = "POST";
authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (Stream stream = authRequest.GetRequestStream())
{
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
authRequest.Headers.Add("Accept-Encoding", "gzip");
WebResponse authResponse = authRequest.GetResponse();
// deserialize into an object
string objectText;
using (authResponse)
{
using (var reader = new StreamReader(authResponse.GetResponseStream()))
{
objectText = reader.ReadToEnd();
}
}
// objectText is JSON and contains access_token
Authenticate with Blogger??
private bloggerTest()
{
// Register the authenticator.
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description)
{
ClientIdentifier = _key,
ClientSecret = _secret
};
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
// Create the service.
var service = new BloggerService(new BaseClientService.Initializer()
{
Authenticator = auth
});
var result = service.Posts.List(_blogID).Fetch();
}
private IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
var state = new AuthorizationState(new[] { BloggerService.Scopes.BloggerReadonly.GetStringValue() });
// I am stuck here!
}
For accessing a public feed it is way simpler than what you are doing. There are a bunch of classes built into the .Net framework for processing RSS feeds, you can start with SyndicationFeed. To get the feed items (blog posts) is quite simple:
XDocument feed = XDocument.Load(rssUrl); //rssUrl is the URL to the rss page that (most) blogs publish
SyndicationFeed sf = SyndicationFeed.Load(feed.CreateReader());
foreach (SyndicationItem si in sf.Items)
{
..you've now got your feed item...
}
Note that this will give you the feed items but it won't give you the full web page that they appear in. (although you will get a URL for that).
Related
How to get Number of shares and Likes for a URL using Facebook Graph API? There are a few posts answering a similar question but every post offers a different method/fb API.
I am using the C# SDK and I guess I should be using the Graph API since FQL is not supported in the latest FB API.
This answer looks nice but the poster said the returned value for shares is sum of shares and likes for this URL and I need them separately.
After Posting post into facebook you will get Post ID(138885734110127_1484064888656364) in return from facebook. Using that post id you can get counts of likes and comments and who likes and comments, and what comment posted. I don't know about shares.
For getting likes and comments here is the code:
var fb = new FacebookClient("Your Access token here");
var WallPost = fb.Get("138885734110127_1484064888656364");
JObject jObj = JObject.Parse(WallPost.ToString());
var Comments = jObj.Property("comments");
var Likes = jObj.Property("likes");
You will get in json. Hope this helps. :)
I think I maybe rather late, but here is my code for getting shares,likes and comments for URL, please observe that it doesn't require an access token, hope this helps in some way!.
string url = "http://www.youtube.com";
string QUrl = "https://graph.facebook.com/?fields=id,share,og_object{engagement{count},likes.summary(true).limit(0),comments.limit(0).summary(true)}&id=" + url;
System.Net.HttpWebRequest Request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(QUrl);
Request.ContentType = "text/json";
Request.Timeout = 10000;
Request.Method = "GET";
string content;
using (WebResponse myResponse = Request.GetResponse())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8))
{
content = sr.ReadToEnd();
}
};
var json = JObject.Parse(content);
var like_count = json["og_object"]["likes"]["summary"]["total_count"];
Console.WriteLine("Like Count :" + like_count);
var share_count = json["share"]["share_count"];
Console.WriteLine("Share Count :" + share_count);
var comment_count = json["og_object"]["comments"]["summary"]["total_count"];
Console.WriteLine("Comment Count :" + comment_count);
I've been using the Google Blogger API v2 for a long time, using GDATA to authenticate and post new posts. However, this is not supported now anymore and they are requiring an OAuth authentication.
Unfortunately I cannot find any .Net documentation I fully understand.
I followed them as best as I could, and I don't see any errors, so I do not know what else to try, please help me.
My first approach was to go like this: Google.GData.Client.GDataRequestException - Authentication suddenly fails in old code
Here an example for Google Spread Sheets is given. However, I do not know with what to replace the line "var service = new SpreadsheetsService(null)", since I do not know if there is a Blogger service.
In the second approach I first got an OAuth2 token like before and then followed the description from https://developers.google.com/blogger/docs/3.0/using?hl=de about publishing posts. So I created a WebRequest as follows:
var http = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
http.Accept = "application/json";
http.ContentType = "application/json";
http.Method = "POST";
http.Headers.Add("Authorization", "Bearer " + token);
var vm = new { kind = "blogger#post", blog = new { id = "id" }, title = "Testtitle", content = "testcontent" };
var dataString = JsonConvert.SerializeObject(vm);
string parsedContent = dataString;
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(parsedContent);
Stream newStream = http.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
But here, I got 403 (not allowed). Why?
Thanks in advance!
Best, Oliver
I need your help!.
Im trying to insert a new photo into a Picasa Album using Oauth 2.0 and a simple HttpRequest process. The result is that I cant insert a new photo into my Picasa web album after following the instructions listed on: https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol#Auth
I also have to say that I tried using the .Net library that they provide with the same results.
The implementation that I'm using now is the following:
public static string PostImage(
string streamImageConvertedToString)
{
string url = string.Format("https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}", "username#gmail.com", "idAlbum");
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "image/jpeg";
request.ContentLength = Encoding.UTF8.GetByteCount(data);
request.Method = "POST";
request.Headers.Add("GData-Version", "2");
request.Headers.Add("Slug", "cute_baby_kitten.jpg");
request.Headers.Add("Authorization", "Bearer " + GetToken());
if (data != null)
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(data);
}
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
return result;
}
private static string GetToken() {
const string ServiceAccountEmail = "someid#developer.gserviceaccount.com";
var servicio = new PicasaService(null);
var certificate = new X509Certificate2(HttpContext.Current.Server.MapPath("/key2.p12"), "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://picasaweb.google.com/data/" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
return credential.Token.AccessToken;
}
Any help is welcome!!
(403) Forbidden
Means that you are trying to use a method insert which requires authorization to do.
you are connecting to service account someid#developer.gserviceaccount.com which should give you access to someid#developer.gserviceaccount.com pictures then.
you appear to be trying to access username#gmail.com unless you have given someid#developer.gserviceaccount.com access to insert pictures on behalf of username#gmail.com (Which I am not even sure is possible) you are not going to have permission to do this.
Remember a service account is a sudo user it has its own drive account, calendar account ... it does not have access to a random users data unless that user has given them access like they would any other user.
Note: Google .net client library does not support gdata APIs. Picasa is a gdata library I like how are trying to merge the two I am have to test this.
You're best (imho) approach would be to forget libraries and forget service accounts. Get a refresh token for the google user account you're trying to insert to, and use the raw HTTP REST API to invoke Picasa.
Simply put, I'm trying to create a webpage with Visual Studio 2012 wherein the user will log into a page, which, when authorized, will post a tweet, and enable them to use the rest of the features on the page. I'd like to remember said users credentials to also limit the rate at which they use a certain feature.
The problem is, I have been searching for days and I am unable to find an UP TO DATE and working example for me to follow. Everything seems to be outdated. (Twitterizer ; TweetSharp) I've switched from Java to C# & .NET and still no progress.
I am now seeking direct help.. Code snippets .. Tutorials .. Anything .. So that I can accomplish this task. I'm new to .NET but used to Java & C/C++ so I don't expect to be confused by too trivial of code..
My exact request is to be able to log in with twitter, save credentials (or the user's access token, whatever) & post a tweet.
This is a basic example of how to authenticate and retrieve a user's timeline:
// You need to set your own keys and screen name
var oAuthConsumerKey = "superSecretKey";
var oAuthConsumerSecret = "superSecretSecret";
var oAuthUrl = "https://api.twitter.com/oauth2/token";
var screenname = "aScreenName";
// Do the Authenticate
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oAuthConsumerKey) + ":" +
Uri.EscapeDataString((oAuthConsumerSecret)))
));
var postBody = "grant_type=client_credentials";
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl);
authRequest.Headers.Add("Authorization", authHeader);
authRequest.Method = "POST";
authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (Stream stream = authRequest.GetRequestStream())
{
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
authRequest.Headers.Add("Accept-Encoding", "gzip");
WebResponse authResponse = authRequest.GetResponse();
// deserialize into an object
TwitAuthenticateResponse twitAuthResponse;
using (authResponse)
{
using (var reader = new StreamReader(authResponse.GetResponseStream())) {
JavaScriptSerializer js = new JavaScriptSerializer();
var objectText = reader.ReadToEnd();
twitAuthResponse = JsonConvert.DeserializeObject<TwitAuthenticateResponse>(objectText);
}
}
// Do the timeline
var timelineFormat = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&include_rts=1&exclude_replies=1&count=5";
var timelineUrl = string.Format(timelineFormat, screenname);
HttpWebRequest timeLineRequest = (HttpWebRequest)WebRequest.Create(timelineUrl);
var timelineHeaderFormat = "{0} {1}";
timeLineRequest.Headers.Add("Authorization", string.Format(timelineHeaderFormat, twitAuthResponse.token_type, twitAuthResponse.access_token));
timeLineRequest.Method = "Get";
WebResponse timeLineResponse = timeLineRequest.GetResponse();
var timeLineJson = string.Empty;
using (timeLineResponse)
{
using (var reader = new StreamReader(timeLineResponse.GetResponseStream()))
{
timeLineJson = reader.ReadToEnd();
}
}
public class TwitAuthenticateResponse {
public string token_type { get; set; }
public string access_token { get; set; }
}
Please see here (The github project has asp.net and asp.net mvc examples):
Authenticate and request a user's timeline with Twitter API 1.1 oAuth
I created an an open source project for it but unfortunately it doesn't yet include the ability to send tweets. I don't think it would be difficult but I am short on time at the moment.
If I was to implement it I would find out exactly what needs to be posted by the api, as detailed here:
https://dev.twitter.com/docs/api/1.1/post/statuses/update
For the assisting of other persons who have fallen into the same gap I did... Check out this site
It will help with authenticating & signing in & retrieving basic information.
I am trying to setup a simple app that consumes the Yahoo Fantasy sports API, and allows queries to be executed through YQL.
class Program
{
static void Main(string[] args)
{
string yql = "select * from fantasysports.games where game_key in ('268')";
//var xml = QueryYahoo(yql);
// Console.Write(xml.InnerText);
string consumerKey = "--my key--";
string consumerSecret = "--my secret--";
var xml = QueryYahoo(yql, consumerKey, consumerSecret);
Console.Write(xml.InnerText);
}
private static XmlDocument QueryYahoo(string yql)
{
string url = "http://query.yahooapis.com/v1/public/yql?format=xml&diagnostics=false&q=" + Uri.EscapeUriString(yql);
var req = System.Net.HttpWebRequest.Create(url);
var xml = new XmlDocument();
using (var res = req.GetResponse().GetResponseStream())
{
xml.Load(res);
}
return xml;
}
private static XmlDocument QueryYahoo(string yql, string consumerKey, string consumerSecret)
{
string url = "http://query.yahooapis.com/v1/yql?format=xml&diagnostics=true&q=" + Uri.EscapeUriString(yql);
url = OAuth.GetUrl(url, consumerKey, consumerSecret);
var req = System.Net.HttpWebRequest.Create(url);
var xml = new XmlDocument();
using (var res = req.GetResponse().GetResponseStream())
{
xml.Load(res);
}
return xml;
}
There is some hidden in here, I have a custom class to make the url ok for the Yahoo API. Here is the structure of the URL that the OAuth.GetUrl() method returns
http://query.yahooapis.com/v1/yql?diagnostics=true&format=xml&oauth_consumer_key=mykey&oauth_nonce=rlfmxniesu&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1332785286&oauth_version=1.0&q=select%20%2A%20from%20fantasysports.games%20where%20game_key%20in%20%28%27268%27%29&oauth_signature=NYKIbhjoirJwB6ADxVq5DOgLW1w%3D
With this, I always seem to get
Authentication Error. The table fantasysports.games requires a higher security level than is provided, you provided APP but at least USER is expected
I am not sure what this means, I am passing my auth information to the api, but it seems I need more permissions. Has anyone have a working example of this. If needed, I can supply code to the GetUrl method, but it is more or less a copy paste from here
http://andy.edinborough.org/Getting-Started-with-Yahoo-and-OAuth
Let me know if you have any questions. Thanks!
I couldn't make it work using the YQL, but I was able to get the players data and draft result etc, by directly using the APIs at https://fantasysports.yahooapis.com/fantasy/v2/
e.g. to get NFL player David Johnson details:
GET /fantasy/v2/players;player_keys=371.p.28474 HTTP/1.1
Host: fantasysports.yahooapis.com
Authorization: Bearer [[Base64 encoded ClientId:Secret]]
Content-Type: application/json