Serverless budget tracking

I use a very neat application to bugdet and track my spending, or let me confess, I’ve been trying to use this bugeting app to but a lid on my careless spending habit, YNAB (You need a budget) is an application for budgeting your income with a great philosphy behind it: “you give every dollar a job”.

One of the things I’ve been failing at is tracking each payment, while adding transaction to the app is user friendly, but doing so for every payment you do however small is tiresome, that’s why when I started using card payment for all of my purchase, an idea came to me.

My bank sends me an sms for each payment done with either of the the cards I have, this message include the amount paid, and the name of the payment recciever, these two are what you need to add a transaction to YNAB, so let’s automate it.

Automation flow

What makes automating of transaction entry is that YNAB provide an API for that, we just need to call the API to add a transaction for each SMS received.

I decieded to use azure function to do recieve the sms message, decode the payment, and call YNAB api

[FunctionName("AddTransaction")]
public async Task<IActionResult> AddTransaction([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] string purchaseSms)
{
    _logger.LogInformation("received new sms for processing sms text: {sms}",purchaseSms);
    var numbers = Regex.Matches(purchaseSms, DecimalsExpression, RegexOptions.None);
    var payee = Regex.Matches(purchaseSms, PayeeExpression, RegexOptions.None)[0].Value.Replace("at","").Trim();
    var transaction = new TransactionRequest
    {
        transaction = new Transaction
        {
            account_id = YnabConstants.NBDDebitAccountId,
            amount = -numbers[0].Value.ToYnabMilliUnit(),
            payee_name = payee,
            approved = true,
            memo = purchaseSms,
            date = DateTime.UtcNow.ToString(YnabConstants.DateFormat),
            category_id = YnabConstants.TempCategory,
        }
    };
    await _ynabapi.AddTransaction(YnabConstants.BudgetId,transaction);

    return new OkResult();
}

The function is going to be an http triggered function (I will tell you in a moment how it will be triggered), getting the payment sms, will extract the payment amount, and the name of the payment recciever to be used as payee in YNAB, next it will construct a transaction object capturing this transaction info, and then commit it to YNAB api using refit generated api implementation

public interface IYnabapi
{
    [Post("/budgets/{budgetId}/transactions")]
    Task AddTransaction(string budgetId, [Body] TransactionRequest transactionRequest);
}

Calling (Triggering) the function

To trigger the function I need to make a post request to its url, passing the sms as the content, to do that I decided to use IFTTT.

The two recepies I’m using is the Andoind sms and the webhook. the first one (Android sms) tracks the recieved sms matching a pattern to my phone, matched sms gets passes to the second item in the recepie, the webhook, this recieves the sms text and makes a POST call to my function url, triggering the function (the part I mentioned earlier).

with this payments I do on my card gets added to YNAP as transaction.