I am trying to look for an example of how to simply post a tweet on my Twitter account using C# and DotNetOpenAuth. I want to do it from a WinForms application. The examples I found seem to be using ASP.NET and WebForms. Specifically, i'm getting hung up on the "verifier code". Here is the code I have so far:
private McMurryTokenManager TokenManager
{
get
{
McMurryTokenManager tokenManager = null;
string consumerKey = ConsumerKey;
string consumerSecret = ConsumerSecret;
if (!string.IsNullOrEmpty(consumerKey))
{
tokenManager = new McMurryTokenManager
{ ConsumerKey = consumerKey, ConsumerSecret = consumerSecret };
}
return tokenManager;
}
}
public Form1()
{
InitializeComponent();
var twitter = new DesktopConsumer(TwitterConsumer.ServiceDescription, TokenManager);
string requestToken;
twitter.RequestUserAuthorization(null, null, out requestToken);
var accessTokenResponse = twitter.ProcessUserAuthorization(requestToken, null);
}
I'm getting an error saying the verifier code can't be null.
Here's what you need to do:
The RequestUserAuthorization method returns a URL to an authorization page.
You should redirect the user to that page, typically Process.Start(url), where the user will authorize your application.
Twitter the redirects the user to a page with a multi-digit number, which is the verifier.
After you've sent the user to the authorization page, your application should wait with a dialog or prompt so that the user can enter the verifier and submit it to your application.
Once you have the verifier, pass it as the 2nd argument to ProcessUserAuthorization.
Here's a blog post that say's something similar and has a code example:
http://whelkaholism.blogspot.com/2010/08/c-doing-stuff-with-google-using-oauth.html
Related
I am using TweetSharp to send tweets to users (currently testing it) however it keeps coming back with Bad Authentication Data
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
I have checked my app settings and it has full read and write access. I have also tried to regenerate my consumer keys but still not luck.
here is my code
public ActionResult AccessToken()
{
string oauth_consumer_key = "<consumer key>";
string oauth_consumer_secret = "<consumer secret>";
var service = new TwitterService(oauth_consumer_key, oauth_consumer_secret);
// Now we need the Token and TokenSecret
OAuthRequestToken requestToken = service.GetRequestToken("http://localhost:37808/");
string authURL = service.GetAuthorizationUri(requestToken).ToString();
Process.Start(authURL);
SendTweetOptions options = new SendTweetOptions();
options.Status = "Hello there Twitter";
service.SendTweet(options);
var re = service.Response.Response;
return View();
}
Am I doing anything wrong?
Finally solved the issue and it works well. Based upon comments from Yort.
public ActionResult AccessToken()
{
// Step 1 - Retrieve an OAuth Request Token
TwitterService service = new TwitterService(ConfigurationManager.AppSettings["TwitterConsumerKey"], ConfigurationManager.AppSettings["TwitterConsumerSecret"]);
// This is the registered callback URL
OAuthRequestToken requestToken = service.GetRequestToken("http://localhost:37808/Twitter/OToken");
// Step 2 - Redirect to the OAuth Authorization URL
Uri uri = service.GetAuthorizationUri(requestToken);
return new RedirectResult(uri.ToString(), false /*permanent*/);
//return View();
}
public ActionResult OToken()
{
return View();
}
public ActionResult UserInfo(string oauth_token, string oauth_verifier)
{
var requestToken = new OAuthRequestToken { Token = oauth_token };
// Step 3 - Exchange the Request Token for an Access Token
TwitterService service = new TwitterService(ConfigurationManager.AppSettings["TwitterConsumerKey"],
ConfigurationManager.AppSettings["TwitterConsumerSecret"]);
OAuthAccessToken accessToken = service.GetAccessToken(requestToken, oauth_verifier);
// Step 4 - User authenticates using the Access Token
service.AuthenticateWith(accessToken.Token, accessToken.TokenSecret);
TwitterUser user = service.VerifyCredentials(new VerifyCredentialsOptions());
ViewBag.Message = string.Format("{0}", user.ScreenName);
// Step 5 - Send Tweet to User TimeLine
SendTweetOptions options = new SendTweetOptions();
string URL = "file:\\C:\\Users\\<User>\\Desktop\\test.jpg";
string path = new Uri(URL).LocalPath;
// Sending with Media
using (var stream = new FileStream(path, FileMode.Open))
{
service.SendTweetWithMedia(new SendTweetWithMediaOptions
{
Status = "<status>",
Images = new Dictionary<string, Stream> { { path, stream } }
});
}
var responseText = service.Response.StatusCode;
if (responseText.ToString() == "OK")
{
ViewBag.Message = "Tweet Successful";
}
else
{
ViewBag.Message = "Tweet Unsuccessful";
}
return View();
}
}
I don't believe you can send Tweets as just a consumer, the Tweets have to be "owned" by a user account. You need to register a Twitter account, then do the full oauth authentication process to get an access token (in addition to the consumer token), then reauthorise the TweetSharp service using both tokens.
Your code above nearly gets there (I think). After the Process.start call there needs to be logic to use the verifier returned in the browser (a number displayed after the user logs in) to complete the auth process and act as that user. At the moment, your code gets half way through that process but does not complete it, so when you try to tweet your TweetSharp service is only authed as the app and not the user.
The originalTweetSharp readme.md does include the missing bits of code. Step 3 needs the actual verifier returned in the browser after login:
// Step 3 - Exchange the Request Token for an Access Token
string verifier = "123456"; // <-- This is input into your application by your user
OAuthAccessToken access = service.GetAccessToken(requestToken, verifier);
// Step 4 - User authenticates using the Access Token
service.AuthenticateWith(access.Token, access.TokenSecret);
//Now your tweet call should work here.
It also looks like you're doing this in a web app on the server? In which case you're using entirely the wrong oauth flow (I believe). This one is designed for desktop apps, hence the call that starts a new browser process for the user to login with. I'm not entirely sure how the web flow works as I've never used it, but I believe you need to redirect the user to the authorisation url you receive, and the callback registered with Twitter should point back to your site. I think there is some kind of state parameter that can be passed back through the oauth flow so you can implement your own logic to pickup where you left off based on a session id or similar.
I worked on this subject before. You have to developer account before the send tweet because you need tokens and keys. It's my windows service project.
I wrote my tokens and key codes in App.config
<appSettings>
<add key="twitterAccessToken" value="*****"/>
<add key="twitterAccessTokenSecret" value="*****"/>
<add key="twitterConsumerKey" value="*****"/>
<add key="twitterConsumerSecret" value="*****"/>
public static void SendTweet()
{
try
{
GetPixelImageFile();
string key = ConfigurationSettings.AppSettings.Get("twitterConsumerKey");
string secret = ConfigurationSettings.AppSettings.Get("twitterConsumerSecret");
string token = ConfigurationSettings.AppSettings.Get("twitterAccessToken");
string tokenSecret = ConfigurationSettings.AppSettings.Get("twitterAccessTokenSecret");
string message = "Color, Colorful, Pixel, Art, PixelColouring, Follow";
var service = new TweetSharp.TwitterService(key, secret);
service.AuthenticateWith(token, tokenSecret);
using (var stream = new FileStream(#"C:\Images\Pixel.png", FileMode.Open))
{
var result = service.SendTweetWithMedia(new SendTweetWithMediaOptions
{
Status = message,
Images = new Dictionary<string, Stream> { { "john", stream } }
});
SendMail("SendTweet", (result == null ? "" : result.Text));
}
}
catch (Exception ex)
{
SendMail("SendTweet", ex.Message);
}
}
I have been using facebook api to share post on facebook page as facebook app. I have created facebook app.
The post also gets shared but the problem is, it is not being posted as a facebook app. Instead it asks user for login and then it shares post as a user. Any help regarding how could I share a post as a Facebook App would be appreciated as I have been trying this for a long time.
Thanx in advance friends.
The code that I have been using is as follows.
using Facebook;
protected void CheckAuthorization()
{
string authorizationCode = Request.QueryString["code"];
string access_token = Facebook_GetAccessToken(authorizationCode);
FacebookShare(access_token);
}
private string Facebook_GetAccessToken(string pAuthorizationCode)
{
string urlGetAccessToken = "https://graph.facebook.com/oauth/access_token";
urlGetAccessToken += "?client_id=my app id";
urlGetAccessToken += "&client_secret=app secret";
urlGetAccessToken += "&redirect_uri=" + Facebook_GetRedirectUri();
urlGetAccessToken += "&code=" + pAuthorizationCode;
string responseData = RequestResponse(urlGetAccessToken);
if (responseData == "")
{
return "";
}
NameValueCollection qs = HttpUtility.ParseQueryString(responseData);
string access_token = qs["access_token"] == null ? "" : qs["access_token"];
return access_token;
}
protected void FacebookShare(string token)
{
if (token != null)
{
Int64 transactionid = Convert.ToInt64(Cache["transactionid"]);
string app_id = "my app id";
string app_secret = "app secret";
string scope = "offline_access,read_stream,publish_actions,publish_stream,manage_pages,status_update";
dynamic parameters = new ExpandoObject();
parameters.link = "my website link";
parameters.name = "my project name";
parameters.picture= "my website logo";
var client = new FacebookClient(token);
client.Post("/1374775846180409/feed", parameters); // this is my facebook page id where I want to share post.
Response.Cookies["transaction"].Expires = DateTime.Now;
}
else
{
}
}
Regarding above code, I am getting Facebook Authorization code successfully.
You can only ask your user who has logged into your app to post on facebook, apps as such are not allowed to post.
You will need a page access token to post as the page, which have permissions to modify the data belonging to a Facebook Page. To obtain a page access token you need to start by obtaining a user access token, for which your user has to be logged into your app and asking for the manage_pages permission scope. Next, you can GET /me/accounts, which will return a page access token for each page that you manage.
This can not be accomplished using offline access or without logging in.
I have created a facebook page and a facebook application for my website and now I need to post messages onto the facebook page with help of facebook SDK .NET.
This is what I got so far :
public static bool UploadPost(string message)
{
dynamic result;
//https://developers.facebook.com/tools/explorer/
//https://developers.facebook.com/tools/access_token/
FacebookClient client = new FacebookClient("secret access token");
result = client.Get("oauth/access_token", new
{
client_id = "[Client ID number]",
client_secret = "[Client sercret",
grant_type = "client_credentials",
});
result = client.Post("[facebook app Id]/feed", new { message = "Test Message from app" });
//result.id;
result = client.Get("[facebook app Id]");
return false;
}
When running this I get : Additional information: (OAuthException - #200) (#200) The user hasn't authorized the application to perform this action on client.Post. If I remove the client.Post row every thing works good, the correct data is fetched.
I have tried follow some helps on facebook SDK .NET website but it is still not working.
The main problem now is that I get permission exception. I was hoping that my facebook app hade enouth permissions to publish post from my website to the facebook page.
Here is a step wise tutorial to register your application with facebook and get an app Id for your application.
Then for permissions ::
private const string ExtendedPermissions = "user_about_me,read_stream,publish_stream";
This is a string of permissions. Pass it on further for getting correct permissions to post messages on page. Post using your standard code for posting no FB pages.
Cheers. Hope it helps.
Are you trying to post to [facebook app id]?
I would recomend to post to "me/feed" and test if that works.
Also, to post to Facebook you have to have the publish_stream permission
private async Task Authenticate()
{
string message = String.Empty;
try
{
session = await App.FacebookSessionClient.LoginAsync("user_about_me,read_stream,publish_actions");
App.AccessToken = session.AccessToken;
App.FacebookId = session.FacebookId;
Dispatcher.BeginInvoke(() => NavigationService.Navigate(new Uri("/Pages/LandingPage.xaml", UriKind.Relative)));
}
catch (InvalidOperationException e)
{
message = "Login failed! Exception details: " + e.Message;
MessageBox.Show(message);
}
}
Should work :)
The following should work.
var fb = new FacebookClient("access_token");
fb.PostCompleted += (o, e) => {
if(e.Error == null) {
var result = (IDictionary<string, object>)e.GetResultData();
var newPostId = (string)result.id;
}
};
var parameters = new Dictionary<string, object>();
parameters["message"] = "My first wall post using Facebook SDK for .NET";
fb.PostAsync("me/feed", parameters);
This was taken directly from the documentation.
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 have made a demo which is about authenticate the user through tWitter.
I want to callback to this url http://localhost:56501/home/authorize.
When I tried to set this url in my application settings it's not work. I got the error that url is not valid.
Do someone help me on get it worked on my side.
I have run some code from here https://github.com/danielcrenna/tweetsharp
At first you need to set callback link in the your twitter application (http://dev.twitter.com/apps/). Replase "localhost" with "127.0.0.1". For example, mine looks like - http ://127.0. 0.1:31820 /Home/AuthorizeCallback
Create TwitterService instanse using you ConsumerKey and ConsumerSecret.
var service = new TwitterService(_consumerKey, _consumerSecret);
Following method gets request token:
public ActionResult Login()
{
var requestToken = service.GetRequestToken(CallBackURL);
var url = service.GetAuthenticationUrl(requestToken);
return Redirect(url.ToString());
}
It redirects user to twitter login form. When user enters his credentials and submits form, it redirects to your callback link.
public ActionResult AuthorizeCallback(string oauth_token, string oauth_verifier)
{
var requestToken = new OAuthRequestToken() {Token = oauth_token};
var accessToken = service.GetAccessToken(requestToken, oauth_verifier);
service.AuthenticateWith(accessToken.Token, accessToken.TokenSecret);
var twitteruser = service.VerifyCredentials();
return RedirectToAction("Index");
}
Good luck!
I am having a problem retrieving the user's access token after he/she has authorized my Facebook application to access their information and post for them, etc... Facebook returns a code query string to my website, so I can receive the access token for the user. I use the following code to get the access code.
string AppKey = "[REMOVED]";
string AppSecret = "[REMOVED]";
var oAuth = new Facebook.FacebookOAuthClient();
oAuth.AppId = AppKey;
oAuth.AppSecret = AppSecret;
oAuth.RedirectUri = new Uri("http://www.mywebsite.com");
Label3.Text = Request.QueryString["code"];
try
{
var accessToken = oAuth.ExchangeCodeForAccessToken(Request.QueryString["code"]);
string accessTokenString = accessToken.ToString();
HttpCookie aCookie = new HttpCookie("MyWebsite_FBAccessToken");
aCookie.Value = accessTokenString;
Response.Cookies.Add(aCookie);
Response.Redirect("~/Process/ProcessToken.aspx");
}
catch (Facebook.FacebookOAuthException error)
{
Label2.Text = error.Message;
}
My code gets held up here:
var accessToken = oAuth.ExchangeCodeForAccessToken(Request.QueryString["code"]);
And I receive the following error.
(OAuthException) Error validating verification code.
Does this seem like there is a problem with my code, or does it look like there may be a setting problem with my Facebook application? I know my App ID and Secret are correct.