youtube api use oauth token to get info on user in .NET - c#

I have an app(ios) that you can login with google and I ask the user to give permissions to access his youtube data,
func doOAuthGoogle(){
let oauthswift = OAuth2Swift(
consumerKey: GoogleYoutube["consumerKey"]!,
consumerSecret: GoogleYoutube["consumerSecret"]!,
authorizeUrl: "https://accounts.google.com/o/oauth2/auth",
accessTokenUrl: "https://accounts.google.com/o/oauth2/token",
responseType: "code"
)
oauthswift.authorizeWithCallbackURL( NSURL(string: "W2GCW24QXG.com.xxx.xxx:/oauth-swift")!, scope: "https://www.googleapis.com/auth/youtube", state: "", success: {
credential, response, parameters in
print("oauth_token:\(credential.oauth_token)")
let parameters = Dictionary<String, AnyObject>()
//TODO: send oauth to server
Alamofire.request(.GET, "http://xxx.azurewebsites.net:80/api/Login/Google/", parameters: ["access_token" : credential.oauth_token]).responseJSON { response in
print(response)
let resultDic : NSDictionary = (response.result.value as? NSDictionary)!
defaults.setObject(resultDic.valueForKey("userId"), forKey: "UserId")
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("vcGroupsViewController") as? GroupsController
self.navigationController?.pushViewController(vc!, animated: true)
}
}, failure: {(error:NSError!) -> Void in
print("ERROR: \(error.localizedDescription)")
})
}
after that I get the credential.oauth_token and send it to the server that is .NET.
on the server I have the library
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
and now I want to get the user music playlist but I cant find example code for that, like in facebook that have the facebookclient
var accessToken = access_token;
var client = new FacebookClient(accessToken);
// 1 : hit graph\me?fields=
dynamic me = client.Get("me", new { fields = new[] { "id", "name", "first_name", "last_name", "picture.type(large)", "email", "updated_time" } });
dynamic meMusic = client.Get("me/music");

OK, i found my answer to my own question,
send the access token to the server and then use web client to call the youtube data api v3 with the proper headers, the result will be youtube playlist ids , from there take watchHistory node and save it to local var, and use it in webclient2 to call the list items.
hope it will help others.
internal User SaveGoogleYoutubeLogin(string access_token)
{
var accessToken = access_token;
string watchHistoryList = "";
using (WebClient webclient = new WebClient())
{
webclient.Headers.Add(HttpRequestHeader.Authorization,"Bearer " + accessToken);
webclient.Headers.Add("X-JavaScript-User-Agent", "Google APIs Explorer");
var respone2 = webclient.DownloadString("https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true&key={your_api_key}");
Debug.Print(respone2);
JObject jResponse = JObject.Parse(respone2);
watchHistoryList = (string)jResponse["items"][0]["contentDetails"]["relatedPlaylists"]["watchHistory"].ToString();
}
using (WebClient webclient2 = new WebClient())
{
webclient2.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + accessToken);
webclient2.Headers.Add("X-JavaScript-User-Agent", "Google APIs Explorer");
var respone2 = webclient2.DownloadString("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId="+ watchHistoryList + "&key={your_api_key}");
Debug.Print(respone2);
JObject jResponse = JObject.Parse(respone2);
foreach (var item in jResponse["items"])
{
Debug.Print(item.ToString());
}
}

Related

Authorization_RequestDenied when i have access token code

Blockquoteafter access token when I called graph API that returns Authorization_RequestDenied request for the access token
using (var webClient = new WebClient())
{
var requestParameters = new NameValueCollection();
requestParameters.Add("resource", resource);
requestParameters.Add("client_id", clientID);
requestParameters.Add("grant_type", "client_credentials");
requestParameters.Add("client_secret", secret);
var url = $"https://login.microsoftonline.com/{tenant}/oauth2/token";
var responsebytes = await webClient.UploadValuesTaskAsync(url,"POST",requestParameters);
var responsebody =Encoding.UTF8.GetString(responsebytes);
var obj = JsonConvert.DeserializeObject<JObject>(responsebody);
var token = obj["access_token"].Value<string>();
access_token = token;
}
after when i request form get the user list from Azure AD by this way
public async Task<List<listItems>> GetData1( string token)
{
HttpClient http = new HttpClient();
string query = "https://graph.microsoft.com/v1.0/users";
HttpRequestMessage httpClient = new HttpRequestMessage(HttpMethod.Get, query);
httpClient.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
var res = await http.SendAsync(httpClient);
var res1= await res.Content.ReadAsStringAsync();
List<listItems> lstUsers = new List<listItems>();
JObject results = JObject.Parse(res1); listItems itm;
foreach (var Jelem in results["value"])
{
string id = (string)Jelem["id"];
string displayName = (string)Jelem["displayName"];
itm = new listItems(); itm.id = id;
itm.displayname = displayName; lstUsers.Add(itm);
}
return lstUsers;
}
than i got "error": { "code": "Authorization_RequestDenied", "message": "Insufficient privileges to complete the operation.", "innerError": { "request-id": "1ba8a3e3-7e27-4bad-affd-6929b9af3a9f", "date": "2019-03-26T10:56:26" } the above error
please help me to solve this error
CAUSE
This problem occurs because the application does not have the required permission to access the user information. So you need to assign necessary privileged for this request.
SOLUTION
To access https://graph.microsoft.com/v1.0/users API One of the following permissions is required.
Permission type (from least to most privileged)
Delegated (work or school account) User.Read, User.ReadWrite,
User.ReadBasic.All,
User.Read.All, User.ReadWrite.All, Directory.Read.All,
Directory.ReadWrite.All,
Directory.AccessAsUser.All
Delegated (personal Microsoft account) User.Read, User.ReadWrite
Application User.Read.All, User.ReadWrite.All, Directory.Read.All,
Directory.ReadWrite.All
See the screen shot below:
AZURE PORTAL WAY OUT
To assign permission on azure portal see the screen shot below:
ASP.NET WEB FORM EXAMPLE:
1. Add New Aspx page To project
Take a new web form, here I have taken as Token.aspx and set its property like below
<%# Page Language="C#" AutoEventWireup="true" Async="true"
CodeBehind="Token.aspx.cs" Inherits="WebFormTest.Token" %>
2. Add New Reference from Nuget
In your project reference add a new service reference from nuget package manager console Like below:
3. Token.aspx.cs
Paste following code outside the scope of Page_Load method You might need to add following reference on your namespace once you encounter missing reference error.
using System.Net.Http;
using System.Net.Http.Headers;
class AccessToken
{
public string access_token { get; set; }
}
// Resource Owner Password Credentials Format
private async Task<string> GetTokenByROPCFormat()
{
string tokenUrl = $"https://login.microsoftonline.com/YourTenantId/oauth2/token";
var req = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
req.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["client_id"] = "ApplicationID",
["client_secret"] = "ApplicationSecret",
["resource"] = "https://graph.microsoft.com",
["username"] = "userEmailwithAccessPrivilege",
["password"] = "YourPassword"
});
dynamic json;
dynamic results;
HttpClient client = new HttpClient();
var res = await client.SendAsync(req);
json = await res.Content.ReadAsStringAsync();
//Token Output
results = JsonConvert.DeserializeObject<AccessToken>(json);
Console.WriteLine(results.access_token);
//New Block For Accessing Data from Microsoft Graph API
HttpClient newClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
HttpResponseMessage response = await newClient.SendAsync(request);
string output = await response.Content.ReadAsStringAsync();
Console.WriteLine("Responsed data Is-\n\n" + output + "");
return output;
}
4. Call GetTokenByROPCFormat() Method inside Page_Load
Now call GetTokenByROPCFormat inside the Page_Load like below
RegisterAsyncTask(new PageAsyncTask(GetTokenByROPCFormat));
5. Token Output
If you set debugger on results variable you would get your token like below
6. Access Microsoft Graph API
Now move to following line and set your debugger like below
string output = await response.Content.ReadAsStringAsync();
You would see following output
Hope it would solve your problem. Thank you.

How to programatically apply an existing SSL certificate to an Azure web app

I'm using the Azure Fluent Management API to automate our deployment process. Up until now, I've had minimal problems.
We have SSL certificates already uploaded into Azure and can manually bind them to a web site through the Azure portal. But I can't find a mechanism for doing this programmatically.
The closest I can find is below and in the documentation here.
webApp.Update()
.DefineSslBinding()
.ForHostname(domainName)
.WithPfxCertificateToUpload(pfxFile, password)
.WithSniBasedSsl()
.Attach();
However, this is obviously uploading a new certificate, not using an existing one.
There are two other options after the ForHostName() call:
WithExistingAppServiceCertificateOrder(certificateOrder)
and
WithNewStandardSslCertificateOrder(certificateOrderName)
But my understanding is that these are related to purchasing the certificates through Azure/Microsoft.
I also can't see anything in the REST API documentation.
So, how can I associate an existing certificate with a web app, in code?
Obviously this was not critical given I've only found an answer 9 months later.
Anyhow, the answer below is copied from the link provided.
await azure
.WebApps
.Inner
.CreateOrUpdateHostNameBindingWithHttpMessagesAsync(
resourceGroupName,
webAppName,
domain,
new HostNameBindingInner(
azureResourceType: AzureResourceType.Website,
hostNameType: HostNameType.Verified,
customHostNameDnsRecordType: CustomHostNameDnsRecordType.CName,
sslState: SslState.SniEnabled,
thumbprint: thumbprint));
As far as I know, the Azure Fluent Management API’s version is 1.0.0-beta50, so it maybe not contain the method add existing certificate to the host name.
I suggest you could use REST API to achieve it.
I suggest you could send request to below url.
Url: https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{snapshotName}?api-version={api-version}
Method: PUT
Parameter:
subscriptionId The identifier of your subscription where the snapshot is being created.
resourceGroup The name of the resource group that will contain the snapshot.
WebappName The name of the WebappName.
api-version The version of the API to use.
Request content:
{
"properties": {
"HostNameSslStates": [
{
"SslState": "the SSL state",
"ToUpdate": "True",
"Thumbprint": "The Thumbprint of the certificate, you could find it in the portal",
"Name": "yourwebsitename"
}
]
},
"kind": "app",
"location": "yourlocation",
"tags": {
"hidden-related:/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.Web/serverfarms/{yourserviceplan}": "empty"
}
}
More details, you could refer to below C# codes:
Json.txt:
{
"properties": {
"HostNameSslStates": [
{
"SslState": "1",
"ToUpdate": "True",
"Thumbprint": "BE58B05C5CADE03628D0D58B369D0DA6F535B0FA",
"Name": "test.azureclubs.com"
}
]
},
"kind": "app",
"location": "East Asia",
"tags": {
"hidden-related:/subscriptions/xxxxxxxxxxxxxxxx/resourcegroups/xxxxxxxxxxxxx/providers/Microsoft.Web/serverfarms/BrandoTestServicePlan": "empty"
}
}
Code:
string body = File.ReadAllText(#"D:\json.txt");
// Display the file contents to the console. Variable text is a string.
string tenantId = "xxxxxxxxxxxxxxxxxxxxxxxxx";
string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
string clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxx";
string subscriptionid = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
string resourcegroup = "BrandoSecondTest";
string appname = "BrandoTestApp";
string version = "2015-08-01";
string authContextURL = "https://login.windows.net/" + tenantId;
var authenticationContext = new AuthenticationContext(authContextURL);
var credential = new ClientCredential(clientId, clientSecret);
var result = authenticationContext.AcquireTokenAsync(resource: "https://management.azure.com/", clientCredential: credential).Result;
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/sites/{2}?api-version={3}", subscriptionid, resourcegroup, appname, version));
request.Method = "PUT";
request.Headers["Authorization"] = "Bearer " + token;
request.ContentType = "application/json";
try
{
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(body);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// Get the response
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
Console.WriteLine(streamReader.ReadToEnd());
}
This solution works in 2021. You only need to know the thumbprint of your certificate and it should be in the same resource group as your web app.
var webApp = azure.WebApps
.GetById("webapp resource Id goes here")
.Update()
.DefineSslBinding()
.ForHostname("host name goes here")
.WithExistingCertificate("thumbprint goes here")
.WithSniBasedSsl()
.Attach()
.Apply();

Updating a Password in RackSpace using C#

I'm just trying to change a password of the main account and a sub user in RackSpaceCloud using C# but I keep running into a UserNotAuthorized exception. Its weird because I can do anything else without this error, reset Api keys, list users and userID's(etc.). Sample Code
net.openstack.Core.Domain.CloudIdentity cloudIdentity = new CloudIdentity()//Admin Credits
{
Username = "me",
APIKey = "blahblahblah",
};
CloudIdentityProvider cloudIdentityProvider = new CloudIdentityProvider(cloudIdentity);
cloudIdentityProvider.SetUserPassword("correctUserID", "newP#ssw0rd", cloudIdentity);
And then I error which is confusing because methods like,
cloudIdentityProvider.ListUsers(cloudIdentity)
cloudIdentityProvider.ResetApiKey("UserID", cloudIdentity);
Work Perfectly. Any Help or Ideas would be appreciated.
Oh and Btw the addition info on the exception is always the same. "Unable to authenticate user and retrieve authorized service endpoints"
This is a bug. I have opened issue 528 but in the meantime here is a workaround.
var cloudIdentity = new CloudIdentity
{
Username = "{username}",
APIKey = "{api-key}"
};
var cloudIdentityProvider = new CloudIdentityProvider(cloudIdentity);
var userAccess = cloudIdentityProvider.Authenticate(cloudIdentity);
var request = new HttpRequestMessage(HttpMethod.Post, string.Format("https://identity.api.rackspacecloud.com/v2.0/users/{0}", userAccess.User.Id));
request.Headers.Add("X-Auth-Token", userAccess.Token.Id);
var requestBody = JObject.FromObject(new { user = new { username = userAccess.User.Name } });
((JObject)requestBody["user"]).Add("OS-KSADM:password", "{new-password}");
request.Content = new StringContent(requestBody.ToString(), Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
var response = client.SendAsync(request).Result;
}
The cloud identity used must be an admin if you need to change another user's password, otherwise non-admins may only change their own password.

how to post to facebook page wall from .NET

I've created Facebook page.
I have no application secret and no access token.
I want to post to this page from my .NET desktop application.
How can I do it? Can anyone help please, where can I get access token for this?
Should I create a new Facebook Application? If yes, how can I grant permissions to this application to post on page's wall?
UPD1:
I have no website.
I need to post company's news from .NET desktop application to company's Facebook page.
All I have is Login/Password for Facebook Page Account.
UPD2:
I've created Facebook Application. With AppID/SecretKey. I can get access token. But...
How can I grant permissions to post to page's wall?
(OAuthException) (#200) The user hasn't authorized the application to perform this action
I have created a video tutorial showing how to do this at this location:
http://www.markhagan.me/Samples/Grant-Access-And-Post-As-Facebook-User-ASPNet
You will notice that, in my example, I am asking for both "publish_stream" and "manage_pages". This let's you also post on pages of which that users is an admin. Here is the full code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Facebook;
namespace FBO
{
public partial class facebooksync : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CheckAuthorization();
}
private void CheckAuthorization()
{
string app_id = "374961455917802";
string app_secret = "9153b340ee604f7917fd57c7ab08b3fa";
string scope = "publish_stream,manage_pages";
if (Request["code"] == null)
{
Response.Redirect(string.Format(
"https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}",
app_id, Request.Url.AbsoluteUri, scope));
}
else
{
Dictionary<string, string> tokens = new Dictionary<string, string>();
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&scope={2}&code={3}&client_secret={4}",
app_id, Request.Url.AbsoluteUri, scope, Request["code"].ToString(), app_secret);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string vals = reader.ReadToEnd();
foreach (string token in vals.Split('&'))
{
//meh.aspx?token1=steve&token2=jake&...
tokens.Add(token.Substring(0, token.IndexOf("=")),
token.Substring(token.IndexOf("=") + 1, token.Length - token.IndexOf("=") - 1));
}
}
string access_token = tokens["access_token"];
var client = new FacebookClient(access_token);
client.Post("/me/feed", new { message = "markhagan.me video tutorial" });
}
}
}
}
You need to ask the user for the publish_stream permission. In order to do this you need to add publish_stream to the scope in the oAuth request you send to Facebook. The easiest way to do all of this is to use the facebooksdk for .net which you can grab from codeplex. There are some examples there of how to do this with a desktop app.
Once you ask for that permission and the user grants it you will receive an access token which you can use to post to your page's wall. If you need to store this permission you can store the access token although you might need to ask for offline_access permission in your scope in order to have an access token that doesn't expire.
You can use
https://www.nuget.org/packages/Microsoft.Owin.Security.Facebook/ to obtain users login and permission and
https://www.nuget.org/packages/Facebook.Client/
to post to feeds.
Below example is for ASP.NET MVC 5:
public void ConfigureAuth(IAppBuilder app)
{
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Facebook
var facebookOptions = new FacebookAuthenticationOptions
{
AppId = "{get_it_from_dev_console}",
AppSecret = "{get_it_from_dev_console}",
BackchannelHttpHandler = new FacebookBackChannelHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location",
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = context =>
{
context.Identity.AddClaim(new Claim("FacebookAccessToken", context.AccessToken)); // user acces token needed for posting on the wall
return Task.FromResult(true);
}
}
};
facebookOptions.Scope.Add("email");
facebookOptions.Scope.Add("publish_actions"); // permission needed for posting on the wall
facebookOptions.Scope.Add("publish_pages"); // permission needed for posting on the page
app.UseFacebookAuthentication(facebookOptions);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
On the callback you get user access token:
public ActionResult callback()
{
// Here we skip all the error handling and null checking
var auth = HttpContext.GetOwinContext().Authentication;
var loginInfo = auth.GetExternalLoginInfo();
var identityInfo = auth.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie);
var email = loginInfo.Email // klaatuveratanecto#gmail.com
var name = loginInfo.ExternalIdentity.Name // Klaatu Verata Necto
var provider = loginInfo.Login.LoginProvider // Facebook | Google
var fb_access_token = loginInfo.identityInfo.FindFirstValue("FacebookAccessToken");
// Save this token to database, for the purpose of this example we will save it to Session.
Session['fb_access_token'] = fb_access_token;
// ...
}
Which then you can use to post to user's feed or page
public class postcontroller : basecontroller
{
public ActionResult wall()
{
var client = new FacebookClient( Session['fb_access_token'] as string);
var args = new Dictionary<string, object>();
args["message"] = "Klaatu Verata N......(caugh, caugh)";
try
{
client.Post("/me/feed", args); // post to users wall (feed)
client.Post("/{page-id}/feed", args); // post to page feed
}
catch (Exception ex)
{
// Log if anything goes wrong
}
}
}
You need to grant the permission "publish_stream".
Possibly the easiest way to do this is via Facebook PowerShell Module, http://facebookpsmodule.codeplex.com. This allows the same sort of operations as FacebookSDK, but via an IT-Admin scripting interface rather than a developer-oriented interface.
AFAIK there is still a limitation of Facebook Graph API that you will not be able to post references to other pages (e.g. #Microsoft) using the Facebook Graph API. This will apply to FacebookSDK, FacebookPSModule, and anything else built over Facebook Graph API.
You will get information on how to create a facebook app or link your website to facebook on https://developers.facebook.com/?ref=pf.
You will be able to download facebook sdk at http://facebooksdk.codeplex.com/. There are some good example given in the document section of the site.
public void PostImageOnPage()
{
string filename=string.Empty;
if(ModelState.IsValid)
{
//-------- save image in image/
if (System.Web.HttpContext.Current.Request.Files.Count > 0)
{
var file = System.Web.HttpContext.Current.Request.Files[0];
// fetching image
filename = Path.GetFileName(file.FileName);
filename = DateTime.Now.ToString("yyyyMMdd") + "_" + filename;
file.SaveAs(Server.MapPath("~/images/Advertisement/") + filename);
}
}
string Picture_Path = Server.MapPath("~/Images/" + "image3.jpg");
string message = "my message";
try
{
string PageAccessToken = "EAACEdEose0cBAAoWM3X";
// ————————create the FacebookClient object
FacebookClient facebookClient = new FacebookClient(PageAccessToken);
// ————————set the parameters
dynamic parameters = new ExpandoObject();
parameters.message = message;
parameters.Subject = "";
parameters.source = new FacebookMediaObject
{
ContentType = "image/jpeg",
FileName = Path.GetFileName(Picture_Path)
}.SetValue(System.IO.File.ReadAllBytes(Picture_Path));
// facebookClient.Post("/" + PageID + "/photos", parameters);// working for notification on user page
facebookClient.Post("me/photos", parameters);// woring using bingoapp access token not page in(image album) Post the image/picture to User wall
}
catch (Exception ex)
{
}
}

Post twitter update with Twitterizer

I have this piece of code:
var settings = WebConfigurationManager.AppSettings;
var consumerKey = settings["Twitter.ConsumerKey"];
var consumerSecret = settings["Twitter.ConsumerSecret"];
var authToken = settings["Twitter.OAuthToken"];
var authVerifier = settings["Twitter.OAuthVerifier"];
//var accessToken = GetAccessToken(
// consumerKey, consumerSecret, authToken, string.Empty);
var tokens = new OAuthTokens()
{
AccessToken = authToken,
AccessTokenSecret = authVerifier,
ConsumerKey = consumerKey,
ConsumerSecret = consumerSecret
};
TwitterStatus.Update(tokens, txtComment.Text);
All I need it to to is update my twitter status. Unfortunately it is not working. It only worked once when I initially logged in to twitter to grant the application access. I then stored the authToken and authVerifier so I can reuse them for future updates.
Any idea what is wrong?
UPDATE: I just changed the code to :
TwitterResponse<TwitterStatus> tweetResponse = TwitterStatus.Update(tokens, txtComment.Text);
if (tweetResponse.Result == RequestResult.Success)
lblMessage.Text = "Twitter status successfully posted.";
else
lblMessage.Text = string.Format("Twitter status update failed with Error: '{0}'",
tweetResponse.ErrorMessage);
and I get an error message: "Invalid / expired token".
You are storing the wrong values. The authToken and verifier values need to be quickly exchanged for an access token using OAuthUtility.GetAccessToken(...). The access token that is returned from that method is what should be stored and supplied to Twitterizer.
-Ricky
The Twitterizer Author
I wanted to be able to make a simple status update from C#/.NET, but didn't want to embed a big library.
So I wrote a small OAuth.Manager class that does this stuff.
It's described here:
OAuth with Verification in .NET
Sample code to update status:
var oauth = new OAuth.Manager();
oauth["consumer_key"] = CONSUMER_KEY;
oauth["consumer_secret"] = CONSUMER_SECRET;
oauth["token"] = your_stored_access_token;
oauth["token_secret"] = your_stored_access_secret;
var url = "http://api.twitter.com/1/statuses/update.xml?status=Hello+World";
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Headers.Add("Authorization", authzHeader);
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
MessageBox.Show("There's been a problem trying to tweet:" +
Environment.NewLine +
response.StatusDescription +
Environment.NewLine +
Environment.NewLine +
"You will have to tweet manually." +
Environment.NewLine);
}
For the first time through, you need to get an access token and secret. This is done in a multi-step process, starting with this code:
var oauth = new OAuth.Manager();
oauth["consumer_key"] = MY_APP_SPECIFIC_KEY;
oauth["consumer_secret"] = MY_APP_SPECIFIC_SECRET;
oauth.AcquireRequestToken("https://api.twitter.com/oauth/request_token", "POST");
Step 2 is to tell the user** to visit https://api.twitter.com/oauth/authorize?oauth_token=XXXX where xxxx is replaced with the actual token received, accessible in this case by oauth["token"]. Step 3 is to tell the user to grab (ctrl-c) the PIN from the webpage and paste it into your app, where you use the pin to get another type of token.
A better way is to automate that web UI sequence by using a Windows Form with an embedded WebBrowser control. When you set the Url property of that control to the appropriate value, it will show that webpage for you, inside the main form of your own app. You can also automate the part where you retrieve the PIN. This reduces context switches for your user and makes things simpler to understand.
Anyway, with the pin you do, step 4:
oauth.AcquireAccessToken("https://api.twitter.com/oauth/access_token",
"POST",
pin);
...which sends out another HTTP REST request, and when it returns you will have an accesss token and secret, available in oauth["token"] and oauth["token_secret"].
This authorization stuff with the web UI needs to happen only once; after you get the access token and secret once, you can store them and re-use them. They never expire, says Twitter.
You can then proceed to sending the status update...
var url = "http://api.twitter.com/1/statuses/update.xml?status=Hello+World";
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
...
...as above.
I know I am late to the game, but I created an end-to-end video tutorial showing exactly how to do this: I create an application on dev.twitter.com, install twitterizer using nuget, write the code to handle the oauth and finally write the code to use the access tokens received from twitter to make a tweet.
Video: http://www.youtube.com/watch?v=TGEA1sgMMqU
Tutorial: http://www.markhagan.me/Samples/Grant-Access-And-Tweet-As-Twitter-User-ASPNet
Code (in case you don't wan to leave this page):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Twitterizer;
namespace PostFansTwitter
{
public partial class twconnect : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var oauth_consumer_key = "YOUR_CONSUMER_KEY_HERE";
var oauth_consumer_secret = "YOUR_CONSUMER_SECRET_KEY_HERE";
if (Request["oauth_token"] == null)
{
OAuthTokenResponse reqToken = OAuthUtility.GetRequestToken(
oauth_consumer_key,
oauth_consumer_secret,
Request.Url.AbsoluteUri);
Response.Redirect(string.Format("http://twitter.com/oauth/authorize?oauth_token={0}",
reqToken.Token));
}
else
{
string requestToken = Request["oauth_token"].ToString();
string pin = Request["oauth_verifier"].ToString();
var tokens = OAuthUtility.GetAccessToken(
oauth_consumer_key,
oauth_consumer_secret,
requestToken,
pin);
OAuthTokens accesstoken = new OAuthTokens()
{
AccessToken = tokens.Token,
AccessTokenSecret = tokens.TokenSecret,
ConsumerKey = oauth_consumer_key,
ConsumerSecret = oauth_consumer_secret
};
TwitterResponse<TwitterStatus> response = TwitterStatus.Update(
accesstoken,
"Testing!! It works (hopefully).");
if (response.Result == RequestResult.Success)
{
Response.Write("we did it!");
}
else
{
Response.Write("it's all bad.");
}
}
}
}
}

Categories