While posting messages, Yammer is throwing the following error (and not posting the message):
The remote server returned an error: (500) Internal Server Error.
I'm using Yammer .NET wrapper and it's working fine with REST call "https://www.yammer.com/api/v1/messages.json", but posting message gives the above error.
Below is the code giving us the error message,
String consumerkey = "consumerkey";
String clientsecret = "clientsecret";
WebProxy webpro = new WebProxy("ourproxyserver",8080)
webpro.BypassProxyOnLocal = true;
webpro.Credentials = CredentialCache.DefaultCredentials;
String access_token = "https://www.yammer.com/oauth2/access_token.json"+
"?client_id=clientid&"+
"client_secret=cli_secret&code=code_id";
Yammer.Session session = new Yammer.Session(
new OAuth.OAuthKey(
consumerkey, clientsecret, access_token,"token"
),
webpro);
NameValueCollection parameters = new NameValueCollection();
parameters.Add("body", body);
response = Yammer.HttpUtility.Post(Resources.YAMMER_MESSAGES_CREATE, parameters, session);
Any ideas what could be wrong?
You can try following wrapper method to post message on yammer (Please note that this code uses Auth and Authbase class:
public static string PostMessage(string body)
{
NameValueCollection parameters = new NameValueCollection();
parameters.Add("body", body);
string response = string.Empty;
response = Post("https://www.yammer.com/api/v1/messages/", parameters);
return response;
}
public static string Post(string url, NameValueCollection parameters)
{
string nonce, timestamp;
string fullUrl = EncodeUrl(url, parameters);
string signature = GetSignature(WebMethod.POST, fullUrl, out timestamp, out nonce);
HttpWebRequest request = CreateWebRequest(url, WebMethod.POST, nonce, timestamp, signature);
int count = 0;
string queryString = string.Empty;
foreach (string key in parameters.Keys)
{
if (count == 0)
queryString = key + "=" + Rfc3986.Encode(parameters[key]);
else
queryString += "&" + key + "=" + Rfc3986.Encode(parameters[key]);
count++;
}
byte[] postDataBytes = Encoding.ASCII.GetBytes(queryString);
request.ContentLength = postDataBytes.Length;
Stream reqStream = request.GetRequestStream();
reqStream.Write(postDataBytes, 0, postDataBytes.Length);
reqStream.Close();
WebResponse response = null;
string data = string.Empty;
try
{
response = request.GetResponse();
data = response.Headers["Location"];
}
catch (Exception ex)
{
//System.Windows.Forms.MessageBox.Show("Error retrieving web response " + ex.Message);
throw ex;
}
finally
{
if (response != null)
response.Close();
}
return data;
}
private static string EncodeUrl(string url, NameValueCollection parameters)
{
string fullUrl = string.Empty;
int count = 0;
foreach (string key in parameters.Keys)
{
if (count == 0)
fullUrl = url + "?" + key + "=" + Rfc3986.Encode(parameters[key].ToLower());
else
fullUrl += "&" + key + "=" + Rfc3986.Encode(parameters[key].ToLower());
count++;
}
return fullUrl;
}
public static string GetSignature(WebMethod method, string url, out string timestamp, out string nonce)
{
OAuthBase oAuth = new OAuthBase();
nonce = oAuth.GenerateNonce();
timestamp = oAuth.GenerateTimeStamp();
string nurl, nrp;
Uri uri = new Uri(url);
string sig = oAuth.GenerateSignature(
uri,
YOURCONSUMERKEY,
YOURCONSUMER_SECRET,
AuthToken,
AuthTokenSecret,
method.ToString(),
timestamp,
nonce,
OAuthBase.SignatureTypes.PLAINTEXT, out nurl, out nrp);
return System.Web.HttpUtility.UrlEncode(sig);
}
private static HttpWebRequest CreateWebRequest(string fullUrl, WebMethod method, string nonce, string timeStamp, string sig)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fullUrl);
request.Method = method.ToString();
request.Proxy = Yammer.Session.WebProxy;
string authHeader = CreateAuthHeader(method, nonce, timeStamp, sig);
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("Authorization", authHeader);
return request;
}
private static string CreateAuthHeader(WebMethod method, string nonce, string timeStamp, string sig)
{
var sb = new StringBuilder();
sb.Append("OAuth ");
if (method == WebMethod.POST)
sb.Append("realm=\"" + "\",");
else
sb.Append("realm=\"\",");
string authHeader = "oauth_consumer_key=\"" + YOURCONSUMERKEY + "\"," +
"oauth_token=\"" + YOURAUTHTOKEN + "\"," +
"oauth_nonce=\"" + nonce + "\"," +
"oauth_timestamp=\"" + timeStamp + "\"," +
"oauth_signature_method=\"" + "HMAC-SHA1" + "\"," +
"oauth_version=\"" + "1.0" + "\"," +
"oauth_signature=\"" + sig + "\"";
sb.Append(authHeader);
return sb.ToString();
}
Related
I have done code to access yahoo weather API with oath by following all steps provided by yahoo in documentation as
1) Create Yahoo account
2) Create App
3) White list App
4) C# code to access yahoo weather API with oath
I am getting Unauthorized access exception while requesting API.
Here is the code :
public class WeatherYdn
{
public static void Main(string[] args)
{
const string appId = "YOUR-WHITELISTED-APPID";
const string consumerKey = "YOUR-CONSUMER-KEY";
const string consumerSecret = "YOUR-SECRET-KEY";
const string url = "https://weather-ydn-yql.media.yahoo.com/forecastrss";
string timestamp = StringHelper.GenerateTimeStamp();
String oauthNonce = StringHelper.GenerateNonce();
IList<string> parameters = new List<string>();
parameters.Add("oauth_consumer_key=" + consumerKey);
parameters.Add("oauth_nonce=" + oauthNonce);
parameters.Add("oauth_signature_method=HMAC-SHA1");
parameters.Add("oauth_timestamp=" + timestamp);
parameters.Add("oauth_version=1.0");
// Make sure value is encoded
parameters.Add("location=" + HttpUtility.UrlEncode("pune,in", Encoding.UTF8));
parameters.Add("format=json");
((List<string>) parameters).Sort();
StringBuilder parametersList = new StringBuilder();
for (int i = 0; i < parameters.Count; i++)
{
parametersList.Append(((i > 0) ? "&" : "") + parameters.ElementAt(i));
}
var signatureString = "GET&" +
HttpUtility.UrlEncode(url,Encoding.UTF8) + "&" +
HttpUtility.UrlEncode(parametersList.ToString(), Encoding.UTF8);
string signature = null;
try
{
string secretAccessKey = consumerSecret;
byte[] secretKey = Encoding.UTF8.GetBytes(secretAccessKey);
HMACSHA1 hmac = new HMACSHA1(secretKey);
hmac.Initialize();
byte[] bytes = Encoding.UTF8.GetBytes(signatureString);
byte[] rawHmac = hmac.ComputeHash(bytes);
signature = Convert.ToBase64String(rawHmac);
}
catch (Exception e)
{
Console.WriteLine("Unable to append signature");
}
string authorizationLine = "OAuth " +
"oauth_consumer_key=\"" + consumerKey + "\", " +
"oauth_nonce=\"" + oauthNonce + "\", " +
"oauth_timestamp=\"" + timestamp + "\", " +
"oauth_signature_method=\"HMAC-SHA1\", " +
"oauth_signature=\"" + signature + "\", " +
"oauth_version=\"1.0\"";
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url + "?location=pune,in&format=json");
request.Headers.Add("Authorization", authorizationLine);
request.Headers.Add("Yahoo-App-Id", appId);
request.ContentType = "application/json; charset=UTF-8";
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
Console.WriteLine(readStream.ReadLine());
}
}
In which line you get the error? The GetResponse() returns it?
I think that the credentials you are using (appId,consumerKey,consumerSecret) are invalid!
public string appId = "Your app-id";
public string consumerKey = "Your-consumer key";
public string consumerSecret = "Your Consumer Secret key";
// GET: api/Random
[HttpGet("{CityName}")]
public async Task<IActionResult> GetAsync([FromUri] string CityName)
{
string urlss = "https://weather-ydn-yql.media.yahoo.com/forecastrss?location=";
string url = urlss + CityName+ "&format=json&u=c";
JObject jresult;
using (var client = new HttpClient())
{
try
{
var webClient = new WebClient();
webClient.Headers.Add(AssembleOAuthHeader());
var d = webClient.DownloadString(url);
jresult = JObject.Parse(d);
var json_jsonstring = Newtonsoft.Json.JsonConvert.SerializeObject(jresult);
return Ok(json_jsonstring);
}
catch (HttpRequestException httpRequestException)
{
return BadRequest($"Error getting weather from Yahoo Weather: {httpRequestException.Message}");
}
}
}
public string AssembleOAuthHeader()
{
return "Authorization: OAuth " +
"realm=\"yahooapis.com\"," +
"oauth_consumer_key=\"" + consumerKey + "\"," +
"oauth_nonce=\"" + Guid.NewGuid() + "\"," +
"oauth_signature_method=\"PLAINTEXT\"," +
"oauth_timestamp=\"" + ((DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1).Ticks) / (1000 * 10000)) +
"\"," +
"oauth_version=\"1.0\"," +
"oauth_signature=\"" + consumerSecret + "%26\"," +
"oauth_callback=\"oob\"";
}
For yahoo weather new authentication you can use this python library
yahoo-weather
I think your code is fine. The problem lies with a poorly implemented URL Decode on Yahoo's end. Java URL Encode encodes with uppercase while .net HTTPUtility.URLEncode encodes in lower case. I created an extension method for a string that will rectify the problem and URL Encode in a way that the Yahoo API can handle. After doing that all worked well (I had the exact same problem you did).
<Extension>
Public Function UppercaseURLEncode(ByVal sourceString As String) As String
Dim temp As Char() = HttpUtility.UrlEncode(sourceString).ToCharArray()
For i As Integer = 0 To temp.Length - 2
If temp(i).ToString().Equals("%", StringComparison.OrdinalIgnoreCase) Then
temp(i + 1) = Char.ToUpper(temp(i + 1))
temp(i + 2) = Char.ToUpper(temp(i + 2))
End If
Next
Return New String(temp)
End Function
//Here Is The Working Code :
public class YWSample
{
const string cURL = "https://weather-ydn-yql.media.yahoo.com/forecastrss";
const string cAppID = "Your-App-ID";
const string cConsumerKey = "Your-Consumer-Key";
const string cConsumerSecret = "Your-Consumer-Secret";
const string cOAuthVersion = "1.0";
const string cOAuthSignMethod = "HMAC-SHA1";
const string cWeatherID = "woeid=727232"; // Amsterdam, The Netherlands
const string cUnitID = "u=c"; // Metric units
const string cFormat = "xml";
//Code to get timestamp
static string _get_timestamp()
{
var lTS = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64(lTS.TotalSeconds).ToString();
}
//Code to get nonce
static string _get_nonce()
{
return Convert.ToBase64String(
new ASCIIEncoding().GetBytes(
DateTime.Now.Ticks.ToString()
)
);
} // end _get_nonce
static string _get_auth()
{
var lNonce = _get_nonce();
var lTimes = _get_timestamp();
var lCKey = string.Concat(cConsumerSecret, "&");
var lSign = $"format={cFormat}&" + $"oauth_consumer_key={cConsumerKey}&" + $"oauth_nonce={lNonce}&" +
$"oauth_signature_method={cOAuthSignMethod}&" + $"oauth_timestamp={lTimes}&" +
$"oauth_version={cOAuthVersion}&" + $"{cUnitID}&{cWeatherID}";
lSign = string.Concat(
"GET&", Uri.EscapeDataString(cURL), "&", Uri.EscapeDataString(lSign)
);
using (var lHasher = new HMACSHA1(Encoding.ASCII.GetBytes(lCKey)))
{
lSign = Convert.ToBase64String(
lHasher.ComputeHash(Encoding.ASCII.GetBytes(lSign))
);
} // end using
return "OAuth " +
"oauth_consumer_key=\"" + cConsumerKey + "\", " +
"oauth_nonce=\"" + lNonce + "\", " +
"oauth_timestamp=\"" + lTimes + "\", " +
"oauth_signature_method=\"" + cOAuthSignMethod + "\", " +
"oauth_signature=\"" + lSign + "\", " +
"oauth_version=\"" + cOAuthVersion + "\"";
} // end _get_auth
public static void Main(string[] args)
{
const string lURL = cURL + "?" + cWeatherID + "&" + cUnitID + "&format=" + cFormat;
var lClt = new WebClient();
lClt.Headers.Set("Content-Type", "application/" + cFormat);
lClt.Headers.Add("Yahoo-App-Id", cAppID);
lClt.Headers.Add("Authorization", _get_auth());
Console.WriteLine("Downloading Yahoo weather report . . .");
var lDataBuffer = lClt.DownloadData(lURL);
var lOut = Encoding.ASCII.GetString(lDataBuffer);
Console.WriteLine(lOut);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}//end of Main
} // end YWSample
I'm trying to do a function which work with WECHAT API,
Here is my code:
I use the code below to get a connection Token
internal static string Token(string CorpID, string Secret)
{
CorpID = CorpID ?? "wwe1f80304633";
Secret = Secret ?? "Ev7_oVN7RqD9k4yUy5pzkfcZ_QhX9l0VjZnAQ";
string token;
using (var wc = new WebClient())
{
token = wc.DownloadString($"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={CorpID}&corpsecret={Secret}");
}
if (token.Contains("access_token"))
{
return token.Split(',')[2].Split(':')[1].Replace("\"", "");
}
return "";
}
It's successful to get a valid token from WECHAT Server,
And the code below is I want to POST a request to WECHAT API and ask WECHAT to Send Message to selected Department Person.
internal static string SendMsg(string sendtext)
{
string ACTOKEN = "" + PDC.MSGTOKEN + "";
string CONTENT = "" + PDC.CONTENT + "";
string PostUrl;
using (var wc2 = new WebClient())
{
PostUrl = wc2.UploadString($"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}{1}", ACTOKEN, CONTENT);
}
return "";
}
public static void SendMsg2()
{
PDC.CONTENT = "Test Message";
string MsgContent = "{\"toparty\": \"" + PDC.DEPTID + "\",\"msgtype\": \"text\",\"agentid\": \"" + PDC.AGENTID + "\",\"text\": {\"content\": \"" + PDC.CONTENT + "\"},\"safe\":0}";
SendMsg(MsgContent);
MessageBox.Show("" + MsgContent + "");
}
And I Added a button on my WinForm and trying to make it work
private void BtnSendMsg_Click(object sender, EventArgs e)
{
string token = MSG.Token(null, null);
if (!string.IsNullOrEmpty(token))
{
PDC.MSGTOKEN = token;
MessageBox.Show("" + PDC.MSGTOKEN + "");
}
else
{
MessageBox.Show(" Invalid Token ");
}
MSG.SendMsg2();
}
However seems it doesn't work, and if I'm not wrong the problem on this part
internal static string SendMsg(string sendtext)
{
string ACTOKEN = "" + PDC.MSGTOKEN + "";
string CONTENT = "" + PDC.CONTENT + "";
string PostUrl;
using (var wc2 = new WebClient())
{
PostUrl = wc2.UploadString($"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}{1}", ACTOKEN, CONTENT);
}
return "";
}
May anyone can give me some ideas how I can solve this problem ? Many Many Many Thanks ~
I has been done my Code without Problem, this is the code below for everyone who need.
The code to get Token from Https API
internal static string Token(string CorpID, string Secret)
{
CorpID = CorpID ?? "" + PDC.CorpID + "";
Secret = Secret ?? "" + PDC.Secret + "";
string token;
using (var wc = new WebClient())
{
token = wc.DownloadString($"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={CorpID}&corpsecret={Secret}");
}
if (token.Contains("access_token"))
{
return token.Split(',')[2].Split(':')[1].Replace("\"", "");
}
return "";
}
The Method of POST
internal static string PostWebRequest(string PostUrl, string ParamData, Encoding DataEncode)
{
string ret = string.Empty;
try
{
byte[] byteArray = DataEncode.GetBytes(ParamData);
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(PostUrl));
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.ContentLength = byteArray.Length;
Stream newStream = webReq.GetRequestStream();
newStream.Write(byteArray, 0, byteArray.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
ret = sr.ReadToEnd();
sr.Close();
response.Close();
newStream.Close();
}
catch (Exception ex)
{
return ex.Message;
}
return ret;
}
The code to using WECHAT WORK for sending Message
internal static string SendMsg(string CorpID, string Secret, string ParamData, Encoding DataEncode)
{
string AccessToken = Token(CorpID, Secret);
string PostUrl = string.Format("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}", AccessToken);
return PostWebRequest(PostUrl, ParamData, DataEncode);
}
public static void SendMsg2()
{
string sCorpID = "" + PDC.CorpID + "";
string sSecret = "" + PDC.Secret + "";
PDC.CONTENT = "Test Message";
string Message = "Test";
string MsgContent = "{";
MsgContent += "\"totag\": \"" + PDC.DEPTID + "\",";
MsgContent += "\"msgtype\": \"text\",";
MsgContent += "\"agentid\": \"" + PDC.AGENTID + "\",";
MsgContent += "\"text\": {";
MsgContent += " \"content\": \"" + Message + "\"";
MsgContent += "},";
MsgContent += "\"safe\":\"0\"";
MsgContent += "}";
SendMsg(sCorpID, sSecret, MsgContent, Encoding.UTF8);
}
The Button Event for active Send Message Function
private void BtnSendMsg_Click(object sender, EventArgs e)
{
string token = MSG.Token(null, null);
if (!string.IsNullOrEmpty(token))
{
PDC.MSGTOKEN = token;
}
MSG.SendMsg2();
}
I have some code here and I am getting and error 401 unauthorized. I have checked the sign in with twitter box.
public async Task get_Oauth_token_TaskAsync()
{
//variables for action
string oauth_nonce;
string oauth_callback;
string oauth_signature_method;
string oauth_timestamp;
string oauth_consumer_key;
string oauth_signature;
string oauth_version;
string req_url;
//set values to variables
var dt = DateTime.Now;
var ticks = dt.Ticks;
var seconds = ticks / TimeSpan.TicksPerSecond;
oauth_timestamp = seconds.ToString();
oauth_callback = "http://www.localhost:55593/TwitterSync.aspx";
oauth_nonce = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Substring(0, 16).ToString(); //random string
oauth_signature_method = "HMAC-SHA1";
oauth_consumer_key = "xxxx";
oauth_version = "1.0";
req_url = "https://api.twitter.com/oauth/request_token";
oauth_signature = create_auth_Signature_Task(oauth_nonce,oauth_callback,oauth_signature_method,oauth_timestamp,oauth_consumer_key,oauth_version,req_url);
///action
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(req_url);
request.Method = "POST";
request.UserAgent = "themattharris' HTTP Client";
request.Host = "api.twitter.com";
request.Headers.Add(HttpRequestHeader.Authorization, "OAuth oauth_callback = \"" + Uri.EscapeDataString(oauth_callback) + "\"" + ",oauth_consumer_key = \"" + oauth_consumer_key + "\",oauth_nonce = " + "\"" + oauth_nonce + "\", oauth_signature = \"" + oauth_signature + "\", oauth_signature_method = \"HMAC-SHA1\", oauth_timestamp = \"" + oauth_timestamp + "\", oauth_version = \"1.0\"");
WebResponse response = await request.GetResponseAsync();
Stream str = response.GetResponseStream();
StreamReader reader = new StreamReader(str);
dynamic resp = reader.ReadToEndAsync();
}
private string create_auth_Signature_Task(string oauth_nonce, string oauth_callback,
string oauth_signature_method, string oauth_timestamp, string oauth_consumer_key, string oauth_version, string req_url)
{
string oauth_nonce_enc = Uri.EscapeDataString(oauth_nonce);
string oauth_callback_enc = Uri.EscapeDataString(oauth_callback);
string oauth_signature_method_enc = Uri.EscapeDataString(oauth_signature_method);
string oauth_timestamp_enc = Uri.EscapeDataString(oauth_timestamp);
string oauth_consumer_key_enc = Uri.EscapeDataString(oauth_consumer_key);
string oauth_version_enc = Uri.EscapeDataString(oauth_version);
string req_url_enc = Uri.EscapeDataString(req_url);
string secret = "xxxx";
string signature_base = "POST&" + req_url_enc + "&" + Uri.EscapeDataString("oauth_consumer_key=" + oauth_consumer_key_enc + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=" + oauth_signature_method_enc + "&oauth_timestamp=" + oauth_timestamp_enc + "&oauth_version=" + oauth_version_enc);
return ShaHash(signature_base, secret);
}
private string ShaHash(string value, string key)
{
using (var hmac = new HMACSHA1(Encoding.UTF32.GetBytes(key)))
{
return ByteToString(hmac.ComputeHash(Encoding.UTF32.GetBytes(value)));
}
}
static string ByteToString(IEnumerable<byte> data)
{
return string.Concat(data.Select(b => b.ToString("x2")));
}
I did everything according to this page . Now I am just lost, any Idea why does it not work?
You are not calculating the oauth_timestamp correctly. This should be calculated as Unix time which is the number of seconds since 00:00:00 UTC on 1 Jan 1970.
int unixTimestamp = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
or using .NET 4.6
long unixTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
Also the signing key used for creating the signature should be a concatenation of the percent encoded consumer secret and the percent encoded token secret joined by an ampersand (&). In the case of obtaining a request token the token secret is not yet known so you should just use the consumer secret followed by an ampersand (&).
var signingKey = oauth_consumer_key_enc + "&";
Finally you should return the Base64 encoded string after you have computed your hash so your function becomes:
private string ShaHash(string value, string signingKey)
{
using (var hmac = new HMACSHA1(Encoding.ASCII.GetBytes(signingKey)))
{
return Convert.ToBase64String(hmac.ComputeHash(Encoding.ASCII.GetBytes(value)));
}
}
As guidance on https://developer.yahoo.com/oauth/guide/oauth-requesttoken.html, Below are what I did with OAuth to get Yahoo contact list:
Make a GET request to https://api.login.yahoo.com/oauth/v2/get_request_token
to get oauth_token and oauth_token_secret, I successfully get them.
Example url:
OAuthBase oath = new OAuthBase();
string url = "https://api.login.yahoo.com/oauth/v2/get_request_token?" +
"oauth_nonce=" + oath.GenerateNonce() +
"&oauth_timestamp=" + oath.GenerateTimeStamp() +
"&oauth_consumer_key=" + consumerKey+
"&oauth_signature_method=plaintext" +
"&oauth_signature=" + consumerSecret + "%26" + //%26 if plaintext
"&oauth_version=1.0" +
"&oauth_callback=" + "oob";
Using oauth_token of step 1. to make a GET request to https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token={token}, It returned me oauth_verifier
Using paramters of step 1 and 2 to make GET request to https://api.login.yahoo.com/oauth/v2/get_token , it returned me new oauth_token , oauth_token_secret, oauth_session_handle, xoauth_yahoo_guid.
Example url:
string sig = consumerSecret + "%26" + OauthTokenSecret;
string url = "https://api.login.yahoo.com/oauth/v2/get_token?" +
"oauth_consumer_key=" + consumerKey+
"&oauth_signature_method=plaintext" +
"&oauth_signature=" + sig +
"&oauth_timestamp=" + oath.GenerateTimeStamp() +
"&oauth_version=1.0" +
"&oauth_token=" + OAuthToken +
"&oauth_nonce=" + oath.GenerateNonce() +
"&oauth_verifier=" + oauth_verifier;
The final step is to get the contact list:
I make a GET request to https://social.yahooapis.com/v1/user/{xoauth_yahoo_guid}/contacts?format=json
Example
Uri uri = new Uri(url);
string nonce = oath.GenerateNonce();
string timeStamp = oath.GenerateTimeStamp();
string normalizedUrl;
string normalizedRequestParameters;
string sig = oath.GenerateSignature(uri, clientId, clientSecret, yahooToken.OAuthToken,
yahooToken.OauthTokenSecret, "GET", timeStamp, nonce, OAuthBase.SignatureTypes.HMACSHA1,
out normalizedUrl, out normalizedRequestParameters);
Function GenerateSignature:
public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters)
{
normalizedUrl = null;
normalizedRequestParameters = null;
switch (signatureType)
{
case SignatureTypes.PLAINTEXT:
return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret));
case SignatureTypes.HMACSHA1:
string signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters);
HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));
return GenerateSignatureUsingHash(signatureBase, hmacsha1);
case SignatureTypes.RSASHA1:
throw new NotImplementedException();
default:
throw new ArgumentException("Unknown signature type", "signatureType");
}
}
Make request:
using (var client = new WebClient())
{
string authenHeader = "OAuth " +
"realm=\"yahooapis.com\"" +
",oauth_consumer_key=\"" + consumerKey+ "\"" +
",oauth_nonce=\"" + nonce + "\"" +
",oauth_signature_method=\"HMAC-SHA1\"" +
",oauth_timestamp=\"" + timeStamp + "\"" +
",oauth_token=\"" + OAuthToken + "\"" +
",oauth_version=\"1.0\"" +
",oauth_signature=\"" + HttpUtility.UrlEncode(sig) + "\"";
client.Headers.Set("Authorization", authenHeader);
string responseString = client.DownloadString(url);
}
But Yahoo sends me (401) Unauthorized response, Could you tell me where I'm wrong ?
I realized that I am stuck at the exact same place
System.Net.WebException: The remote server returned an error: (401) Unauthorized. at ..GetEmailContacts() in ...
private ArrayList GetEmailContacts() {
OAuthBase oauth = new OAuthBase();
Uri uri = new Uri("https://social.yahooapis.com/v1/user/" + OauthYahooGuid + "/contacts?format=XML");
string nonce = oauth.GenerateNonce();
string timeStamp = oauth.GenerateTimeStamp();
string normalizedUrl;
string normalizedRequestParameters;
string sig = oauth.GenerateSignature(uri, this.sConsumerKey, this.sConsumerSecret, OauthToken, OauthTokenSecret, "GET", timeStamp, nonce, OAuthBase.SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
StringBuilder sbGetContacts = new StringBuilder(uri.ToString());
try {
string returnStr = string.Empty;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sbGetContacts.ToString());
req.Accept = "application/xml";
req.Method = "GET";
ArrayList emails = new ArrayList();
string authHeader = "Authorization: OAuth " +
"realm=\"yahooapis.com\"" +
",oauth_consumer_key=\"" + this.sConsumerKey + "\"" +
",oauth_nonce=\"" + nonce + "\"" +
",oauth_signature_method=\"HMAC-SHA1\"" +
",oauth_timestamp=\"" + timeStamp + "\"" +
",oauth_token=\"" + OauthToken + "\"" +
",oauth_version=\"1.0\"" +
",oauth_signature=\"" + HttpUtility.UrlEncode(sig) + "\"";
req.Headers.Add(authHeader);
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse()) {
:/ sighz
SO I found the issue. Ive changed the content format from XML to JSON
changed the following:
private ArrayList GetEmailContacts() {
OAuthBase oauth = new OAuthBase();
Uri uri = new Uri("https://social.yahooapis.com/v1/user/" + OauthYahooGuid + "/contacts?format=json");
string nonce = oauth.GenerateNonce();
string timeStamp = oauth.GenerateTimeStamp();
string normalizedUrl;
string normalizedRequestParameters;
string sig = oauth.GenerateSignature(uri, this.sConsumerKey, this.sConsumerSecret, OauthToken, OauthTokenSecret, "GET", timeStamp, nonce, OAuthBase.SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
StringBuilder sbGetContacts = new StringBuilder(uri.ToString());
try {
string returnStr = string.Empty;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sbGetContacts.ToString());
req.Accept = "application/json";
req.ContentType = "application/json";
req.Method = "GET";
ArrayList emails = new ArrayList();
string authHeader = "Authorization: OAuth " +
"realm=\"yahooapis.com\"" +
",oauth_consumer_key=\"" + this.sConsumerKey + "\"" +
",oauth_nonce=\"" + nonce + "\"" +
",oauth_signature_method=\"HMAC-SHA1\"" +
",oauth_timestamp=\"" + timeStamp + "\"" +
",oauth_token=\"" + OauthToken + "\"" +
",oauth_version=\"1.0\"" +
",oauth_signature=\"" + HttpUtility.UrlEncode(sig) + "\"";
req.Headers.Add(authHeader);
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse()) {
When I made that change it suddenly returned the emails and no more 406 error code.
I hope that this helps someone.. no idea as to why xml stopped working.
Here is my code,
[WebMethod]
public static bool FirstAccess()
{
string app_id = "139295982898884";
string app_secret = "b5d2a88b56898610d54da2af498e3220";
//string post_login_url = "http://dev.fitbook.com.asp1-23.ord1-1.websitetestlink.com/v4/FitbookContest.aspx";
string post_login_url = "http://localhost:4327/FitbookContest.aspx";
string scope = "publish_stream,manage_pages";
string code = HttpContext.Current.Request["code"] ?? "";
try
{
if (code == "")
{
string dialog_url = "http://www.facebook.com/dialog/oauth?" + "client_id=" + app_id + "&redirect_uri=" + HttpContext.Current.Server.UrlEncode(post_login_url) + "&scope=publish_stream";
// HttpContext.Current.Response.Write(dialog_url);
//HttpContext.Current.Response.Redirect(dialog_url, true);
return false;
}
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, HttpContext.Current.Request.Url.AbsoluteUri, scope, HttpContext.Current.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));
}
}
access_token = tokens["access_token"];
TestFB.GetProfilePic(code);
return true;
}
}
catch (Exception ex)
{
return false;
}
}
Here the lines like
HttpContext.Current.Request["code"] ?? "";
and
HttpContext.Current.Response.Redirect(dialog_url, true);
are not working. So is there any alternative solution for it? Is there any way to use it?
Have you tried this,
string dialog_url = "~http://www.facebook.com/dialog/oauth?" + "client_id=" + app_id + "&redirect_uri=" + HttpContext.Current.Server.UrlEncode(post_login_url) + "&scope=publish_stream";
and, redirect as false indicate Whether execution of current page should terminate
HttpContext.Current.Response.Redirect(dialog_url,false);
Simply try this:
string code = HttpContext.Current.Request["code"];
if (code==null)
{
// code
}
and I think the problem is in the line. You didn't specify accesstoken
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, HttpContext.Current.Request.Url.AbsoluteUri, scope, HttpContext.Current.Request["code"].ToString(), app_secret);