Skip to content

Instantly share code, notes, and snippets.

@brinko99
Last active July 26, 2020 02:50
Show Gist options
  • Save brinko99/b8e3df3a97a8aec113e1385e6cbc976b to your computer and use it in GitHub Desktop.
Save brinko99/b8e3df3a97a8aec113e1385e6cbc976b to your computer and use it in GitHub Desktop.
C# Mint Import of CSV data
// Submits CSV based transations to Mint as cash transaction.
// Used Chrome browser Developer Tools to get your custom cookies, token, etc. as cURL.
// For converting cURL to C# see: https://curl.olsh.me/
// I used LinqPad to run the code.
//
// Inspired by: Mint batch transaction import hack | Blog | Vote Charlie
// https://votecharlie.com/blog/2017/06/mint-batch-transaction-import-hack.html
var handler = new HttpClientHandler();
handler.UseCookies = false;
// If you are using .NET Core 3.0+ you can replace `~DecompressionMethods.None` to `DecompressionMethods.All`
handler.AutomaticDecompression = DecompressionMethods.None;
// CSV in format of <date>,<merchant>,<price>
using (var filestream = new StreamReader(@"C:\temp\transactions.csv"))
using (var httpClient = new HttpClient(handler))
{
int count = 0;
string line;
while ((line = filestream.ReadLine()) != null)
{
// Uncomment for single test transaction, be sure to delete from .csv if successful
//// if (count++ >= 1)
//// {
//// break;
//// }
var lineSplit = line.Split(',');
if (lineSplit.Length != 3)
{
Console.WriteLine($"Failed CSV format: '{line}'");
continue;
}
// Encode date
string date = DateTime.Parse(lineSplit[0]).ToString("MM/dd/yyyy");
date = System.Web.HttpUtility.UrlEncode(date);
// Encode merchant (my bank, chase used all uppers for merchants, converting to TitleCase)
string merchant = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(lineSplit[1].Replace(" ", " ").ToLower());
// Adding prefix to easily find within Mint
merchant = $"Chase: {merchant}";
merchant = System.Web.HttpUtility.UrlEncode(merchant);
string price = lineSplit[2];
// Optional note
string note = "Imported from Chase";
note = System.Web.HttpUtility.UrlEncode(note);
// Copy your content string.
// Note formatting placeholds {0}, {1}, {2}, {3} for date, merchant, price, and note respectively
string unformattedContent = "cashTxnType=on&mtCheckNo=&tag416803=0&tag693949=0&tag416804=0&tag416805=0&task=txnadd&txnId=%3A0&mtType=cash&mtAccount=<my account>&symbol=&note={3}&isInvestment=false&catId=20&category=Uncategorized&merchant={1}&date={0}&amount={2}&mtIsExpense=true&mtCashSplitPref=2&token=<my token>";
string formattedContent = string.Format(unformattedContent, date, merchant, price, note);
// https://curl.olsh.me/ will provide these details for your specific Mint session. Likely the results will be vary similar but may change over time; the cookie will be unique to you
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://mint.intuit.com/updateTransaction.xevent"))
{
request.Content = new StringContent(formattedContent);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded; charset=UTF-8");
request.Headers.TryAddWithoutValidation("Connection", "keep-alive");
request.Headers.TryAddWithoutValidation("X-Requested-With", "XMLHttpRequest");
request.Headers.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36");
request.Headers.TryAddWithoutValidation("Accept", "*/*");
request.Headers.TryAddWithoutValidation("Origin", "https://mint.intuit.com");
request.Headers.TryAddWithoutValidation("Sec-Fetch-Site", "same-origin");
request.Headers.TryAddWithoutValidation("Sec-Fetch-Mode", "cors");
request.Headers.TryAddWithoutValidation("Referer", "https://mint.intuit.com/transaction.event");
request.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate, br");
request.Headers.TryAddWithoutValidation("Accept-Language", "en-US,en;q=0.9");
request.Headers.TryAddWithoutValidation("cookie", "<my very long cookie text>");
var response = await httpClient.SendAsync(request);
if (response.IsSuccessStatusCode == false)
{
Console.WriteLine($"Failed: {line}");
}
}
}
}
@brinko99
Copy link
Author

@Kevin1887

Thanks... I did the best I can do for now with the code comments and screenshots. If you can capture test transactions with Chrome per the screenshots, use https://curl.olsh.me/ to generate the C#. Be sure to to test your code with a single transaction at a time before running it through your whole .csv. Deleting transactions via Mint's UI is a pain.

Sorry for not being able to put together something more thorough.

Good luck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment