Coinbase/GDAX API (401) error with C# Access Attempt - c#

I have my two functions, the access attempt and the HMAC signing. It runs and returns an error(401) unauthorized, however in addition I feel my code is longer than it needs to be or redundant somehow, pointing that out would be very helpful to me, thanks in advance!
void AccessAttempt(){
var message = Epoch.ToString () + "GET" + "/v2/payment-methods";
const string WEBSERVICE_URL = "https://api.coinbase.com/v2/payment-methods";
try
{
var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
if (webRequest != null)
{
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.Headers.Add("CB-ACCESS-SIGN", genHMAC(message));
webRequest.Headers.Add("CB-ACCESS-TIMESTAMP", Epoch.ToString());
webRequest.Headers.Add("CB-ACCESS-KEY", _apiKey);
webRequest.Headers.Add("CB-VERSION",_apiVersion);
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
var jsonResponse = sr.ReadToEnd();
OutputText.text = jsonResponse.ToString();
}
}
}
}
catch (Exception ex)
{
OutputText.text = ex.ToString();
}
}
Below is the HMAC signing function called within main function above:
private string genHMAC(string message)
{
byte [] APISecret_Bytes = System.Text.Encoding.UTF8.GetBytes(_apiSecret);
HMACSHA256 hmac = new HMACSHA256(APISecret_Bytes);
hmac.Initialize ();
byte [] MESSAGE_Bytes = System.Text.Encoding.UTF8.GetBytes(message);
var rawHmac = hmac.ComputeHash(MESSAGE_Bytes);
string rawHmacString = string.Empty;
for (int i=0; i<rawHmac.Length; i++)
{
rawHmacString += rawHmac[i];
}
string hexString = string.Empty;
for (int i=0; i<rawHmac.Length; i++)
{
hexString += rawHmac[i].ToString("X2");
}
return hexString;
}

This is a pretty old question, but in case you don't have an answer yet, it looks like there are a few things wrong with your request - here is some code that works for me
public class CoinbaseV2
{
private string APIKey;
private string Secret;
private const string URL_BASE = "https://api.coinbase.com";
private const string URL_BASE_VERSION = URL_BASE + "/v2/";
private const String GET = "GET";
private const String POST = "POST";
private const String PUT = "PUT";
private const String DELETE = "DELETE";
public CoinbaseV2(string inAPIKey, string inSecret)
{
APIKey = inAPIKey;
Secret = inSecret;
}
public string GetUser()
{
return JsonRequest(URL_BASE_VERSION + "user", GET);
}
public string GetUserAccounts()
{
return JsonRequest(URL_BASE_VERSION + "accounts", GET);
}
private string JsonRequest(string url, string method)
{
// take care of any spaces in params
url = Uri.EscapeUriString(url);
string returnData = String.Empty;
var webRequest = HttpWebRequest.Create(url) as HttpWebRequest;
if (webRequest != null)
{
webRequest.Method = method;
webRequest.ContentType = "application/json";
string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(CultureInfo.CurrentCulture);
string body = "";
string sigurl = url.Replace(URL_BASE,"");
string signature = GenerateSignature(timestamp,method,sigurl,body,Secret);
var whc = new WebHeaderCollection();
whc.Add("CB-ACCESS-SIGN", signature);
whc.Add("CB-ACCESS-TIMESTAMP", timestamp);
whc.Add("CB-ACCESS-KEY", APIKey);
whc.Add("CB-VERSION", "2017-08-07");
webRequest.Headers = whc;
using (WebResponse response = webRequest.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
returnData = reader.ReadToEnd();
}
}
}
return returnData;
}
//https://github.com/bchavez/Coinbase
public static string GenerateSignature(string timestamp, string method, string url, string body, string appSecret)
{
return GetHMACInHex(appSecret, timestamp + method + url + body).ToLower();
}
internal static string GetHMACInHex(string key, string data)
{
var hmacKey = Encoding.UTF8.GetBytes(key);
var dataBytes = Encoding.UTF8.GetBytes(data);
using (var hmac = new HMACSHA256(hmacKey))
{
var sig = hmac.ComputeHash(dataBytes);
return ByteToHexString(sig);
}
}
//https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa/14333437#14333437
static string ByteToHexString(byte[] bytes)
{
char[] c = new char[bytes.Length * 2];
int b;
for (int i = 0; i < bytes.Length; i++)
{
b = bytes[i] >> 4;
c[i * 2] = (char)(87 + b + (((b - 10) >> 31) & -39));
b = bytes[i] & 0xF;
c[i * 2 + 1] = (char)(87 + b + (((b - 10) >> 31) & -39));
}
return new string(c);
}
}

Related

How to do DIGEST with POST, PUT and PATCH

I am at a total loss here. Im currently having success doing a GET request against a web service that implements DIGEST MD5-sess authentication. This works fine. I get the expected result so I figure my 'BUILD DIGEST AUTH HEADER' method works as intended.
I then get the requirement to also support POST, PUT and PATCH but now I run into a whole heap of problems. First request obviously returns a 401 and I read the info in the WWW-Authenticate header and make a MD5-sess auth header taking into account that this is now a POST, PUT or PATCH request.
var methodString = urlResolverStrategy.ResolverDataModel.HttpMethod.ToString();
var ha2 = CalculateMd5Hash(string.Format("{0}:{1}", methodString, dir));
I keep everything the same but do also obviously add the content to the request on POST, PUT and PATCH. But for some reason I cannot figure out Im locked out of the service. Second request return another 401 even.
Is there something special that needs to be done for DIGEST Auth when method is POST, PUT and PATCH that Im missing?
I have all my requests setup in Postman as well put Postman does not have the same problem. Second call in Postman gets the expected results. A 200 and the expected data on POST, PUT and PATCH.
Im using a slightly modified version DigestAuthFixer.cs that's also available on some other posts here in stackoverflow.
Code below is currently hardcoded to use the MD5-sess method.
public class DigestAuthFixer
{
private static readonly Random random = new Random(DateTime.Now.Millisecond);
private readonly AuthData authData;
readonly UrlResolverStrategyBase urlResolverStrategy;
public HttpStatusCode StatusCode { get; private set; }
public DigestAuthFixer(BasicAuth basicAuth, UrlResolverStrategyBase urlResolverStrategy)
{
// TODO: Complete member initialization
authData = new AuthData
{
Host = urlResolverStrategy.GetHostName(),
User = basicAuth.GetUsername(),
Password = basicAuth.GetPassword(),
};
this.urlResolverStrategy = urlResolverStrategy;
}
private string CalculateMd5Hash(string input)
{
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = MD5.Create().ComputeHash(inputBytes);
var sb = new StringBuilder();
foreach (var b in hash)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
private string GrabHeaderVar(string varName, string header)
{
var regHeader = new Regex(string.Format(#"{0}=""([^""]*)""", varName));
var matchHeader = regHeader.Match(header);
if (matchHeader.Success)
{
return matchHeader.Groups[1].Value;
}
throw new ApplicationException(string.Format("Header {0} not found", varName));
}
private string GetDigestHeader(string dir)
{
authData.NC++;
string ha1;
if (authData.Algorithm == "MD5-sess")
{
var ha0 = CalculateMd5Hash(string.Format("{0}:{1}:{2}", authData.User, authData.Realm, authData.Password));
ha1 = CalculateMd5Hash(string.Format("{0}:{1}:{2}", ha0, authData.Nonce, authData.Cnonce));
}
else
{
ha1 = CalculateMd5Hash(string.Format("{0}:{1}:{2}", authData.User, authData.Realm, authData.Password));
}
var methodString = urlResolverStrategy.ResolverDataModel.HttpMethod.ToString();
var ha2 = CalculateMd5Hash(string.Format("{0}:{1}", methodString, dir));
var digestResponse = CalculateMd5Hash(string.Format("{0}:{1}:{2:00000000}:{3}:{4}:{5}", ha1, authData.Nonce, authData.NC, authData.Cnonce, authData.Qop, ha2));
var authString = string.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", algorithm=\"{4}\", qop={5}, nc={6:00000000}, cnonce=\"{7}\", response=\"{8}\"", authData.User, authData.Realm, authData.Nonce, dir, authData.Algorithm, authData.Qop, authData.NC, authData.Cnonce, digestResponse);
return authString;
}
public string GrabResponse(string nUrl, string content)
{
var uri = new Uri(authData.Host + nUrl);
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = urlResolverStrategy.ResolverDataModel.HttpMethod.ToString();
// If we've got a recent Auth header, re-use it!
if (!string.IsNullOrEmpty(authData.Cnonce) && DateTime.Now.Subtract(authData.CnonceDate).TotalHours < 1.0)
{
request.Headers.Add("Authorization", GetDigestHeader(nUrl));
}
if (!string.IsNullOrEmpty(urlResolverStrategy.ResolverDataModel.IfMatchHeaderValue))
{
request.Headers.Add(HttpHelper.IfMatchHeaderName, urlResolverStrategy.ResolverDataModel.IfMatchHeaderValue);
}
AddContentToBody(request, content);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
StatusCode = response.StatusCode;
}
catch (WebException ex)
{
// Try to fix a 401 exception by adding a Authorization header
if (ex.Response == null || ((HttpWebResponse)ex.Response).StatusCode != HttpStatusCode.Unauthorized)
throw;
var wwwAuthenticateHeader = ex.Response.Headers["WWW-Authenticate"];
authData.Realm = GrabHeaderVar("realm", wwwAuthenticateHeader);
authData.Nonce = GrabHeaderVar("nonce", wwwAuthenticateHeader);
authData.Qop = GrabHeaderVar("qop", wwwAuthenticateHeader);
authData.Algorithm = "MD5-sess"; // GrabHeaderVar("algorithm", wwwAuthenticateHeader);
authData.NC = 0;
authData.Cnonce = RandomString(8);
authData.CnonceDate = DateTime.Now;
string debug = wwwAuthenticateHeader + Environment.NewLine + nUrl + Environment.NewLine + uri.ToString() + Environment.NewLine + authData.ToString();
var digestRequest = (HttpWebRequest)WebRequest.Create(uri);
digestRequest.Method = urlResolverStrategy.ResolverDataModel.HttpMethod.ToString();
AddContentToBody(digestRequest, content);
var authHeader = GetDigestHeader(nUrl);
debug += uri.ToString() + Environment.NewLine;
debug += nUrl + Environment.NewLine;
debug += authHeader + Environment.NewLine;
digestRequest.Headers.Add("Authorization", authHeader);
if (!string.IsNullOrEmpty(urlResolverStrategy.ResolverDataModel.IfMatchHeaderValue))
{
request.Headers.Add(HttpHelper.IfMatchHeaderName, urlResolverStrategy.ResolverDataModel.IfMatchHeaderValue);
}
HttpWebResponse digestResponse = null;
try
{
//return authHeader;
digestResponse = (HttpWebResponse)digestRequest.GetResponse();
StatusCode = digestResponse.StatusCode;
response = digestResponse;
}
catch (Exception digestRequestEx)
{
if (digestResponse != null)
{
StatusCode = response.StatusCode;
}
else
{
StatusCode = HttpStatusCode.InternalServerError;
}
//return "It broke" + Environment.NewLine + debug;
return "There was a problem with url, username or password (" + digestRequestEx.Message + ")";
}
}
var reader = new StreamReader(response.GetResponseStream());
return reader.ReadToEnd();
}
public string RandomString(int length)
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var stringChars = new char[length];
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = chars[random.Next(chars.Length)];
}
return new string(stringChars);
}
private void AddContentToBody(HttpWebRequest request, string content)
{
if (string.IsNullOrEmpty(content))
return;
var data = Encoding.Default.GetBytes(content); // note: choose appropriate encoding
request.ContentLength = data.Length;
request.ContentType = HttpHelper.MediaTypes.Json;
request.Accept = "*/*";
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(content);
}
}
}
internal class AuthData
{
public string Host;
public string User;
public string Password;
public string Realm;
public string Nonce;
public string Qop;
public string Cnonce;
public DateTime CnonceDate;
public int NC;
public string Algorithm;
public override string ToString()
{
string newLine = Environment.NewLine;
string result = Host + newLine;
result += User + newLine;
result += Realm + newLine;
result += Nonce + newLine;
result += Qop + newLine;
result += Cnonce + newLine;
result += CnonceDate + newLine;
result += NC + newLine;
result += Algorithm + newLine;
return result;
}
}
So apparently it matters in which order you add all the headers to the request. With hookbin I was able to detect that even though I have put an Authorization header on my digestRequest object it did not follow through to hookbin.
My placing the Authorization header addition to just below the setting the method line it all works...
I had no idea that that could pose a problem. The reason my GET method work is because is because 'content' is empty so no headers are added.
var digestRequest = (HttpWebRequest)WebRequest.Create(uri);
digestRequest.Method = urlResolverStrategy.ResolverDataModel.HttpMethod.ToString();
digestRequest.Headers.Add("Authorization", GetDigestHeader(nUrl));

AWS TranslateText REST API call adding signature v4

Actually this is not a question, but an answer for those that are trying to use AWS TranslateText without SDK. I have had many problems until I got a running version.
In my opinion, the AWS documentation for this service is not complete and there are not many examples to check (at least for .Net).
At first, I thought I was not generating the correct V4 signature, but after checking the steps and values once again, I decided to use Postman to call the service. It was very helpful.
Postman can generate the AWS signature! (yeah, I did not know) so finally I noticed the signature value was not the problem.
Checking the request I could see the headers needed and some of its values.
The problem in my case was that I was not sending the "x-amz-target" header.
And by chance I found that the value for this header must be "AWSShineFrontendService_20170701.TranslateText"
(I saw a similar value here https://rdrr.io/cran/aws.translate/src/R/translateHTTP.R)
This other link was also helpful
Ivona Request Signing Issue - signature does not match (AWS Signature Version 4)
So now I have a running version, I want to share my .Net code. I hope it helps :) !!
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web.Script.Serialization;
namespace AWS_TranslateTextTest
{
class AWS_TranslateText
{
// Replace this with your own values
const string AccessKey = "AKI_ADD_YOUR_ACCESSKEY";
const string SecretKey = "ADD_YOUR_SECRETKEY";
static void Main()
{
try
{
string text = "Translate this text from English to German.";
string sourceLang = "en";
string targetLang = "de";
string responseText = TranslateText(text, sourceLang, targetLang);
JObject json = JObject.Parse(responseText);
string translatedText = ""; // to do read response from json or responseText
if (json.ToString().Contains("TranslatedText")){
//To access to the properties in "dot" notation use a dynamic object
dynamic obj = json;
translatedText = obj.TranslatedText.Value;
Console.WriteLine("TranslatedText is: {0}", translatedText);
}
else{
Console.WriteLine("TranslatedText not found in response.");
throw new Exception(json.ToString());
}
}
catch (WebException ex)
{
Console.WriteLine(ex.Message);
if (ex.Response != null){
foreach (string header in ex.Response.Headers)
{
Console.WriteLine("{0}: {1}", header, ex.Response.Headers[header]);
}
using (var responseStream = ex.Response.GetResponseStream())
{
if (responseStream != null)
{
using (var streamReader = new StreamReader(responseStream))
{
Console.WriteLine(streamReader.ReadToEnd());
}
}
} }
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static string TranslateText(string text, string sourceLang, string targetLang)
{
var date = DateTime.UtcNow;
const string algorithm = "AWS4-HMAC-SHA256";
const string regionName = "eu-west-1";
const string serviceName = "translate";
const string method = "POST";
const string canonicalUri = "/";
const string canonicalQueryString = "";
const string x_amz_target_header = "AWSShineFrontendService_20170701.TranslateText";
const string contentType = "application/x-amz-json-1.1";
const string host = serviceName + "." + regionName + ".amazonaws.com";
var obj = new
{
SourceLanguageCode = sourceLang,
TargetLanguageCode = targetLang,
Text = text
};
var requestPayload = new JavaScriptSerializer().Serialize(obj);
var hashedRequestPayload = HexEncode(Hash(ToBytes(requestPayload)));
var dateStamp = date.ToString("yyyyMMdd");
var requestDate = date.ToString("yyyyMMddTHHmmss") + "Z";
var credentialScope = string.Format("{0}/{1}/{2}/aws4_request", dateStamp, regionName, serviceName);
var bytes = ToBytes(requestPayload);
var headers = new SortedDictionary<string, string>
{
{"content-length", bytes.Length.ToString()},
{"content-type", contentType},
{"host", host},
{"x-amz-date", requestDate},
{"x-amz-target", x_amz_target_header}
};
string canonicalHeaders =
string.Join("\n", headers.Select(x => x.Key.ToLowerInvariant() + ":" + x.Value.Trim())) + "\n";
string signedHeaders =
string.Join(";", headers.Select(x => x.Key.ToLowerInvariant() ));
// Task 1: Create a Canonical Request For Signature Version 4
var canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQueryString +
'\n' + canonicalHeaders + '\n' + signedHeaders + '\n' + hashedRequestPayload;
var hashedCanonicalRequest = HexEncode(Hash(ToBytes(canonicalRequest)));
// Task 2: Create a String to Sign for Signature Version 4
// StringToSign = Algorithm + '\n' + RequestDate + '\n' + CredentialScope + '\n' + HashedCanonicalRequest
var stringToSign = string.Format("{0}\n{1}\n{2}\n{3}", algorithm, requestDate, credentialScope,
hashedCanonicalRequest);
// Task 3: Calculate the AWS Signature Version 4
// HMAC(HMAC(HMAC(HMAC("AWS4" + kSecret,"20130913"),"eu-west-1"),"tts"),"aws4_request")
byte[] signingKey = GetSignatureKey(SecretKey, dateStamp, regionName, serviceName);
// signature = HexEncode(HMAC(derived-signing-key, string-to-sign))
var signature = HexEncode(HmacSha256(stringToSign, signingKey));
// Task 4: Prepare a signed request
// Authorization: algorithm Credential=access key ID/credential scope, SignedHeadaers=SignedHeaders, Signature=signature
var authorization =
string.Format("{0} Credential={1}/{2}/{3}/{4}/aws4_request, SignedHeaders={5}, Signature={6}",
algorithm, AccessKey, dateStamp, regionName, serviceName, signedHeaders, signature);
// Send the request
string endpoint = "https://" + host; // + canonicalUri ;
var webRequest = WebRequest.Create(endpoint);
webRequest.Method = method;
webRequest.Timeout = 20000;
webRequest.ContentType = contentType;
webRequest.Headers.Add("X-Amz-Date", requestDate);
webRequest.Headers.Add("Authorization", authorization);
webRequest.Headers.Add("X-Amz-Target", x_amz_target_header);
webRequest.ContentLength = bytes.Length;
using (Stream newStream = webRequest.GetRequestStream())
{
newStream.Write(bytes, 0, bytes.Length);
newStream.Flush();
}
var response = (HttpWebResponse)webRequest.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (var streamReader = new StreamReader(responseStream))
{
string res = streamReader.ReadToEnd();
return res;
}
}
}
return null;
}
private static byte[] GetSignatureKey(String key, String dateStamp, String regionName, String serviceName)
{
byte[] kDate = HmacSha256(dateStamp, ToBytes("AWS4" + key));
byte[] kRegion = HmacSha256(regionName, kDate);
byte[] kService = HmacSha256(serviceName, kRegion);
return HmacSha256("aws4_request", kService);
}
private static byte[] ToBytes(string str)
{
return Encoding.UTF8.GetBytes(str.ToCharArray());
}
private static string HexEncode(byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", string.Empty).ToLowerInvariant();
}
private static byte[] Hash(byte[] bytes)
{
return SHA256.Create().ComputeHash(bytes);
}
private static byte[] HmacSha256(String data, byte[] key)
{
return new HMACSHA256(key).ComputeHash(ToBytes(data));
}
}
}

Need to login in to remote website using c#

I am trying to log in to a remote website via a login form so I can access a sub page via iFrame so I have to pass the validation to set a cookie or a session so I can get to the sub page with the iFrame Maybe there is a better way to do this I am not 100% sure if anyone has any suggestions please let me know. I am getting access denied error:
<script type="text/javascript">
function submitEstimoteLogin() {
setTimeout(function () {
var ifr = document.getElementById("iFrameLogin");
var ifrDoc = ifr.contentDocument || ifr.contentWindow.document;
var theForm = ifrDoc.forms[0];
var username = theform.getElementById("username");
username.value = "email";
var password = theform.getElementById("password");
password.value = "password";
var sbutton = thefrom.getElementById("");
}, 5000);
}
</script>
<iframe id="iFrameLogin" src="http://cloud.estimote.com" onload="submitEstimoteLogin();" ></iframe>
I have also tried it via code behind I am getting a 404 error:
public String GetWebContent(String username, String password)
{
String urlSignin = "https://cloud.estimote.com/";
String urlLogin = "https://cloud.estimote.com/";
Uri uriSignin = new Uri(urlSignin);
Uri uriLogin = new Uri(urlLogin);
Hashtable formData = new Hashtable();
formData.Add("username", new Hashtable());
formData.Add("password", new Hashtable());
((Hashtable)formData["username"])["value"] = username;
((Hashtable)formData["password"])["value"] = password;
String postData = "";
foreach (string name in formData.Keys)
{
postData += "&" + name + "=" + ((Hashtable)formData[name])["value"];
}
postData = postData.Substring(1);
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
HttpWebRequest webReq;
HttpWebResponse webResp;
CookieContainer cookies = new CookieContainer();
String responseString = "";
try
{
webReq = (HttpWebRequest)WebRequest.Create(urlSignin);
webResp = (HttpWebResponse)webReq.GetResponse();
for (int i = 0; i < webResp.Headers.Count; i++)
{
string name = webResp.Headers.GetKey(i);
if (name != "Set-Cookie")
continue;
string value = webResp.Headers.Get(i);
foreach (var singleCookie in value.Split(','))
{
Match match = Regex.Match(singleCookie, "(.+?)=(.+?);");
if (match.Captures.Count == 0)
continue;
webResp.Cookies.Add(
new Cookie(
match.Groups[1].ToString(),
match.Groups[2].ToString(),
"/",
webReq.Host.Split(':')[0]));
}
}
cookies.Add(webResp.Cookies);
string sessionCookie = webResp.Headers["Set-Cookie"];
responseString = new StreamReader(webResp.GetResponseStream()).ReadToEnd();
string respCookie = sessionCookie.Substring(0, sessionCookie.IndexOf(';'));
char[] separator = { '=' };
string[] cookieValues = respCookie.Split(separator);
string part1 = HttpUtility.UrlEncode(cookieValues[1]);
cookies.Add(new Cookie(cookieValues[0], part1 , "/", "cloud.estimote.com"));
webReq = (HttpWebRequest)WebRequest.Create(urlLogin);
webReq.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
webReq.Referer = urlSignin;
webReq.KeepAlive = true;
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.ContentLength = data.Length;
webReq.AllowAutoRedirect = false;
webReq.CookieContainer = cookies;
webReq.Timeout = 30000;
webReq.ReadWriteTimeout = 60000;
webReq.GetRequestStream().Write(data, 0, data.Length);
webReq.GetRequestStream().Close();
webResp = (HttpWebResponse)webReq.GetResponse();
responseString = new StreamReader(webResp.GetResponseStream()).ReadToEnd();
webResp.Close();
return responseString;
}
catch (Exception ex)
{
throw ex;
}
}

Get order list from Google Wallet

I sell Android apps in Google Play and all orders go through Google Wallet as usual. Google Wallet doesn't allow grouping and filtering the order list, so I wanted to create a small utility (C#, WinForms) to show that order list in a more convenient way. I managed to find the following URL allows downloading a CSV file with the order information and this file fully meets my requirements "https://wallet.google.com/merchant/pages/u/0/bcid-XXX/oid-YYY/cid-ZZZ/purchaseorderdownload?startTime=...&endTime=...". However, I'm unable to authorize to Google and I cannot use this URL without being redirected to the login page. Since I'm going to create a WinForms tool, I cannot use this login page. So, the question is, how to authorize to Google in a sort of automatic mode, so that I can use this URL and download CSV files for further processing in my tool?
Ted, here is my code:
private const string LoginUrl = "https://accounts.google.com/ServiceLoginAuth";
private const string WalletUrl = "https://wallet.google.com/merchant/pages";
private readonly DateTime _unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private const string Username = "YourUserName#gmail.com";
private const string Password = "YourPassword";
private readonly DateTime _startDate = new DateTime(2014, 9, 1);
private readonly DateTime _endDate = new DateTime(2014, 9, 30);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string orders = GetLoginHtml();
}
private string GetLoginHtml()
{
var request = (HttpWebRequest)WebRequest.Create(LoginUrl);
var cookieJar = new CookieContainer();
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = cookieJar;
using (var requestStream = request.GetRequestStream())
{
string content = "Email=" + Username + "&Passwd=" + Password;
requestStream.Write(Encoding.UTF8.GetBytes(content), 0, Encoding.UTF8.GetBytes(content).Length);
using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))
{
string html = sr.ReadToEnd();
string galxValue = ParseOutValue(html, "GALX");
return GetLoginHtml2(galxValue, cookieJar);
}
}
}
private string GetLoginHtml2(string galx, CookieContainer cookieJar)
{
var request = (HttpWebRequest)WebRequest.Create(LoginUrl);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = cookieJar;
using (var requestStream = request.GetRequestStream())
{
string content = "Email=" + Username + "&Passwd=" + Password + "&GALX=" + galx;
requestStream.Write(Encoding.UTF8.GetBytes(content), 0, Encoding.UTF8.GetBytes(content).Length);
using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))
{
string html = sr.ReadToEnd();
return GetLoginHtml3(galx, cookieJar);
}
}
}
private string GetLoginHtml3(string galx, CookieContainer cookieJar)
{
var request = (HttpWebRequest)WebRequest.Create(WalletUrl);
request.Method = "GET";
request.ContentType = "text/xml";
request.CookieContainer = cookieJar;
using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))
{
string html = sr.ReadToEnd();
string bcid = ParseOutBcid(html);
string oid = ParseOutOid(html);
string cid = ParseOutCid(html);
string orders = GetOrders(cookieJar, bcid, oid, cid, _startDate, _endDate);
return orders;
}
}
private string GetOrders(CookieContainer cookieJar, string bcid, string oid, string cid, DateTime startDate, DateTime endDate)
{
var st = (long)(startDate.ToUniversalTime() - _unixEpoch).TotalMilliseconds;
var et = (long)(endDate.ToUniversalTime() - _unixEpoch).TotalMilliseconds;
var request = (HttpWebRequest)WebRequest.Create(WalletUrl + "/u/0/bcid-" + bcid + "/oid-" + oid + "/cid-" + cid + "/purchaseorderdownload?startTime=" + st + "&endTime=" + et);
request.Method = "GET";
request.ContentType = "text/xml";
request.CookieContainer = cookieJar;
using (var sr = new StreamReader(request.GetResponse().GetResponseStream()))
{
string html = sr.ReadToEnd();
return html;
}
}
private string ParseOutValue(string html, string value)
{
int ndx1 = html.IndexOf("<input name=\"" + value + "\"", StringComparison.Ordinal);
int ndx2 = html.IndexOf("value=", ndx1, StringComparison.Ordinal);
return html.Substring(ndx2 + 7, html.IndexOf("\"", ndx2 + 7, StringComparison.Ordinal) - ndx2 - 7);
}
private string ParseOutBcid(string html)
{
int ndx1 = html.IndexOf("bcid-", StringComparison.Ordinal);
int ndx2 = html.IndexOf("/oid", ndx1, StringComparison.Ordinal);
return html.Substring(ndx1 + 5, ndx2 - ndx1 - 5);
}
private string ParseOutOid(string html)
{
int ndx1 = html.IndexOf("/oid-", StringComparison.Ordinal);
int ndx2 = html.IndexOf("/cid", ndx1, StringComparison.Ordinal);
return html.Substring(ndx1 + 5, ndx2 - ndx1 - 5);
}
private string ParseOutCid(string html)
{
int ndx1 = html.IndexOf("/cid-", StringComparison.Ordinal);
string retval = "";
ndx1 = ndx1 + 5;
while (char.IsNumber(html[ndx1]))
{
retval = retval + html[ndx1];
ndx1++;
}
return retval;
}
A couple of things. First, you need to change the Username to whatever your gmail username is and change the Password to whatever your password is. Also, set the _startDate and _endDate to whatever time frame you are trying to pull. You shouldn't have to change anything else. Just call the "GetLoginHtml()" function and it will return your Wallet orders!
Keep in mind, I haven't had a chance to optimize the code yet. Its very raw and there might still be bugs. Also, one other thing, if you get an indexing error while running it, its because you have to open Internet Explorer and log into your Google Account for the first time. Once you log in, you can close Internet Explorer and the program should work after that. I need to figure out a way around that, which I didn't yet.
Let me know what you think!

Google Speech Recognition not working

So i recently decided to again redo the infrastructure of my Jarvis AI. Now i'm using a mix of the code (Google and Microsoft). The Google part of the code will not trigger for some reason and display any words or text when spoken into microphone.
public const int DEFAULT_BIT_RATE = 8000;
public const string DEFAULT_LANGUAGE = "en-US";
static string client = "Jarvis";
public class SpeechInputResult
{
static public string ID;
public int status;
public class Hypothesis
{
public string utterance;
public double confidence = -1.0d;//-1 = No Value
public override string ToString()
{
return "'" +utterance + "'" + ((confidence == -1) ? "" : "#" + confidence);
}
public List<Hypothesis> hypotheses = new List<Hypothesis>();
public Hypothesis getBestHypothesis()
{
if (hypotheses.Count() <=0)
return null;
Hypothesis H = hypotheses[0];
foreach (Hypothesis h in hypotheses)
{
if (h.confidence>=H.confidence)
{
H = h;
}
return H;
}
return null;
}
public string json_men = "";
public void FromJSON(String JSON)
{
json_men = JSON;
JSON = JSON.Replace("\n","").Trim();
Match M;
//status
M = new Regex("\\\"status\\\"\\:([0-9]*),", RegexOptions.IgnoreCase).Match(JSON);
//ID
M = new Regex ("\\\"id\\\"\\:\\\"([^\\\"]*)\\\",", RegexOptions.IgnoreCase).Match(JSON);
ID = M.Groups[1].Value;
//Hypotheses
int l1 = JSON.IndexOf("hypotheses");
l1 = JSON.IndexOf("[",l1);
int r1 = JSON.LastIndexOf("]");
string JSON2 = JSON.Substring(l1, r1-l1+1);
MatchCollection m2 = new Regex("{([^\\}]*)}", RegexOptions.IgnoreCase).Matches(JSON2);
foreach (Match g in m2)
{
string s = g.Value;
SpeechInputResult.Hypothesis h = new SpeechInputResult.Hypothesis();
M = new Regex("\\\"utterance\\\"\\:\\\"([^\\\"]*)\\\"", RegexOptions.IgnoreCase).Match(s);
h.utterance = M.Groups[1].Value;
M = new Regex("\\\"confidence\\\"\\:([0-9\\.]*)", RegexOptions.IgnoreCase).Match(s);
string confidence = M.Groups[1].Value;
confidence = confidence.Replace(".", ",");
if (confidence != "")
{
h.confidence = float.Parse(confidence);
}
hypotheses.Add(h);
}
}
}
public static SpeechInputResult ProcessFlacFile(string FlacFileName, int BIT_RATE = DEFAULT_BIT_RATE, string language = DEFAULT_LANGUAGE, uint maxresults = 1)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/speech-api/v1/recognize?xjerr=1" + "&client=" + client + "&lang=" + language + "&maxresults=" + maxresults + "&pfilter=0");
FileStream fStream = new FileStream(FlacFileName, FileMode.Open, FileAccess.Read);
request.Proxy = null;
request.Timeout = 60000;
request.KeepAlive = true;
request.Method = "POST";
request.ContentType = "audio/x-flac; rate=8000";
//bitrate must = .flac file
request.UserAgent = client;
FileInfo fInfo = new FileInfo(FlacFileName);
long numbytes = fInfo.Length;
byte[] data = null;
using (FileStream fstream = new FileStream(FlacFileName, FileMode.Open, FileAccess.Read))
data = new byte[fstream.Length];
fStream.Read(data, 0, Convert.ToInt32(fStream.Length));
fStream.Close();
using (Stream wrStream = request.GetRequestStream())
{
wrStream.Write(data, 0, data.Length);
}
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
dynamic resp = response.GetResponseStream();
if (resp != null)
{
StreamReader sr = new StreamReader(resp);
MessageBox.Show(sr.ReadToEnd());
//resp.Close();
//resp.Dispose();
}
}
catch (System.Exception ee)
{
MessageBox.Show("hi"+ee);
}
return null;
}
}
}
The code here is all from this website.
After getting it to no errors it still doesn't return or do anything, please help!
Parsing JSON with regular expressions will usually cause you problems. Consider using a library like JSON.NET to parse the string into an object instead.

Categories

Resources