Updates

Midday Engine

Midday Engine

The core of Midday is based on our customers transactions. Using this data, we can do a lot to help you run your business smarter when it comes to financial insights, reconciling receipts, and more.


Today we support 3 different banking providers which enables us to connect to over 20 000+ banks in 33 countries across US, Canada, UK and Europe and more to come.


Here is an overview of the technologies and services we use to build our engine.


Engine - Providers


Architecture

We provide an API that gives our services transformed transactions, accounts, and balances for Midday to use. Here is how we built it and the technologies we chose.



Cloudflare

We use a lot of services in Cloudflare. Workers is the compute where our API is hosted, using Hono as our framework.


The API uses OpenAPI v3.0 and exposes endpoints for transactions, accounts, search, and balances.

We use Cloudflare KV for session caching with GoCardless to avoid hitting any rate limits and for general caching purposes.


In the end, we have one interface for our customers to search for their institution. To support this, we retrieve all institutions from our providers, transform the information, and store it in Typesense. We use a simple Cron job in Cloudflare every 24 hours to ensure we have the most recent information.


To connect to Teller, you need to use mTLS to authenticate. Thanks to Cloudflare, we can just upload our certificate and configure our worker to use it when needed.


Hono

We chose to use the Hono framework because it's portable, super lightweight, and provides an incredible developer experience among other features:

  • Caching - we cache directly in Cloudflare
  • Zod - for parsing and validating payloads
  • OpenAPI - generate our specification

Typesense

For our customers, we want just one interface for them to search and find their bank. For that to be possible, we needed an index, and we went with Typesense because it's super powerful and easy to use.

We show banks based on country, fuzzy search, and priority.


Unkey

We will soon offer Engine to other companies to use. We will use Unkey for API key management, rate limits, and analytics.


Trigger.dev

Our platform fetches transactions regularly with the help of background jobs hosted by Trigger.dev, communicating with our Engine API via RPC. We also use:

  • Retries
  • Logging
  • Error handling

Sentry

To deliver a great service, it's super important to fix bugs and issues fast. With the help of Sentry, we can see what's going on and where we have issues. Additionally, we can also know when external APIs underperform or if we have any other bottlenecks.

  • Logging and debugging
  • Alerts
  • Performance metrics

OpenStatus

Because we rely on external APIs, it's important for us to monitor their statuses. In our Engine, we expose a /health endpoint that requests each service’s endpoints so we can use OpenStatus to monitor our Engine's health.

Based on this status, we can exclude providers that have temporary issues and get a single source of truth about how our Engine works.

  • Status page
  • Alerts

What's next

We are currently updating our engine. In the end, other companies will be able to use our engine to support a wider range of banks with just one API in their systems.

If you are interested, feel free to sign up here for more information.


Midday is fully open source. Feel free to check out our code here.

Updates

Introducing Midday Assistant

Introducing Midday Assistant

Our most requested feature is now ready for you to try! Introducing Midday Assistant. With help from the community, we have implemented many great features. Here are some highlights of what you can do using the assistant today:


  • Find the things you are looking for (transactions, invoices, documents, and more)
  • Watch your spending
  • View your profit, revenue, burn rate, and revenue graphs
  • Find transactions without receipts

These are just some examples. You can ask follow-up questions and dig deeper into your data.


This is just the beginning of Midday Assistant, and we will continue to invest and listen to your feedback so you have everything you need to run your business. Don't hesitate to give us feedback directly from the assistant or by scheduling a quick 15-minute call with us to share your thoughts!


If you are running Midday on Mac, you should update to v1.9 for the latest version.


To get started you can sign in here.

Engineering

How we are sending notifications easy with Novu

How we are sending notifications easy with Novu

Midday is all about being on top of your business. Stay informed about your business insights, track when you get paid, receive updates on new transactions, and access general information how your business actually are doing. And that includes well-timed notifications via emails and push notifications, carefully curated for your convenience.


The challenge: Implementing a unified infrastructure for notifications

From the beginning, we knew the importance of a unified approach to managing our notifications. From past experiences of stitching together different solutions to support various notification needs, we were determined to create a system that could seamlessly support web, desktop, and mobile applications. Our goal is to ensure that our notification system can scale alongside our growth.


The solution: Novu

While we tried a bunch of different providers we decided to go with Novu based on our requirements:

  • Support Resend, Expo
  • In App notifications
  • User Preferences

Novu not only ticked every box they also got a huge bonus for being open source and you get 30K events/month for free.


Implementation and SDKs

We started with created our own package @midday/notifications where we installed @novu/node dependency, where we register our notification types for convenience:

// Our notification templates

export enum Templates {

  Transaction = "transaction",

  Transactions = "transactions",

  Inbox = "inbox",

  Match = "match",

}



// Our notification types (email|in-app)

export enum Events {

  TransactionNewInApp = "transaction_new_in_app",

  TransactionsNewInApp = "transactions_new_in_app",

  TransactionNewEmail = "transaction_new_email",

  InboxNewInApp = "inbox_new_in_app",

  MatchNewInApp = "match_in_app",

}

And using our New Transactions email as an example, which is sent from a background job using Trigger.dev when you have new transactions.

import { Notifications, Types, Events } from "@midday/notifications";



// Generate html from react-email

const html = await renderAsync(

  TransactionsEmail({

    fullName: user.full_name,

    transactions,

    locale: user.locale,

  })

);



await Notifications.trigger({

  name: Events.TransactionNewEmail,

  payload: {

    type: Types.Transaction,

    subject: t("transactions.subject"),

    html,

  },

  user: {

    subscriberId: user.id,

    teamId: team_id,

    email: user.email,

    fullName: user.full_name,

    avatarUrl: user.avatar_url,

  },

});

Because we are sending the email with the variables subject and html with the generated content we are just adding those to Novu and then we're done.


Novu - Variables


And to send In App Notifications it's just a matter of changing the Events and Types.

import { Notifications, Types, Events } from "@midday/notifications";



await Notifications.trigger({

  name: Events.TransactionNewInApp,

  payload: {

    recordId: transaction.id,

    type: Types.Transaction,

    description: t("notifications.transaction", {

      from: transaction.name,

    }),

  },

  user: {

    subscriberId: user.id,

    teamId: team_id,

    email: user.email,

    fullName: user.full_name,

    avatarUrl: user.avatar_url,

  },

});

The results: Beautiful In App Notifications and Emails


Midday - In App Notifications


Thanks to the SDK @novu/headless we implemented the notification center for Midday in a matter of hours to match our branding exacly like we wanted while Novu delivers the notifications in realtime.


And for user preferences we just use their API together with a simple server action.


Midday - In App Notifications


The future of Midday x Novu

We are really happy that we chose to use Novu, We have several smart notifications planned that will offer valuable business insights. Plus, Novu will integrate smoothly with our upcoming mobile app, allowing us to send push notifications effortlessly via Expo by just connecting a new provider.


GitHub

While this is just a draft on how we are using Novu in production you can dig deeper into the codebase in our repository.